Do a proper recursive lookup when deciding whether a class's usual
deallocation function has a two-argument form. Store the result of this
check in new[] and delete[] nodes.
Fixes rdar://problem/8913519
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124373 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp
index 7177a64..4f1d176 100644
--- a/lib/CodeGen/CGExprCXX.cpp
+++ b/lib/CodeGen/CGExprCXX.cpp
@@ -395,7 +395,7 @@
if (IsPlacementOperatorNewArray(CGF.getContext(), OperatorNew))
return CharUnits::Zero();
- return CGF.CGM.getCXXABI().GetArrayCookieSize(E->getAllocatedType());
+ return CGF.CGM.getCXXABI().GetArrayCookieSize(E);
}
static llvm::Value *EmitCXXNewAllocSize(ASTContext &Context,
@@ -1065,7 +1065,7 @@
if (AllocSize != AllocSizeWithoutCookie) {
assert(E->isArray());
NewPtr = CGM.getCXXABI().InitializeArrayCookie(CGF, NewPtr, NumElements,
- AllocType);
+ E, AllocType);
}
// If there's an operator delete, enter a cleanup to call it if an
@@ -1271,18 +1271,19 @@
/// Emit the code for deleting an array of objects.
static void EmitArrayDelete(CodeGenFunction &CGF,
- const FunctionDecl *OperatorDelete,
+ const CXXDeleteExpr *E,
llvm::Value *Ptr,
QualType ElementType) {
llvm::Value *NumElements = 0;
llvm::Value *AllocatedPtr = 0;
CharUnits CookieSize;
- CGF.CGM.getCXXABI().ReadArrayCookie(CGF, Ptr, ElementType,
+ CGF.CGM.getCXXABI().ReadArrayCookie(CGF, Ptr, E, ElementType,
NumElements, AllocatedPtr, CookieSize);
assert(AllocatedPtr && "ReadArrayCookie didn't set AllocatedPtr");
// Make sure that we call delete even if one of the dtors throws.
+ const FunctionDecl *OperatorDelete = E->getOperatorDelete();
CGF.EHStack.pushCleanup<CallArrayDelete>(NormalAndEHCleanup,
AllocatedPtr, OperatorDelete,
NumElements, ElementType,
@@ -1352,7 +1353,7 @@
cast<llvm::PointerType>(Ptr->getType())->getElementType());
if (E->isArrayForm()) {
- EmitArrayDelete(*this, E->getOperatorDelete(), Ptr, DeleteTy);
+ EmitArrayDelete(*this, E, Ptr, DeleteTy);
} else {
EmitObjectDelete(*this, E->getOperatorDelete(), Ptr, DeleteTy);
}