From 576cf17055c92e7d1ae8fb9fd9f79433a16a4394 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Tue, 6 Sep 2011 18:53:03 +0000 Subject: [PATCH] Rearrange code so that we pass the right pointer to delete[] when an exception is thrown constructing the array elements in an array new expression. Fixes PR10870. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@139158 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGExprCXX.cpp | 18 +++++++++--------- test/CodeGenCXX/exceptions.cpp | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp index 9f21abd20c..6a0387c557 100644 --- a/lib/CodeGen/CGExprCXX.cpp +++ b/lib/CodeGen/CGExprCXX.cpp @@ -1086,15 +1086,6 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { Builder.CreateCondBr(isNull, contBB, notNullBB); EmitBlock(notNullBB); } - - assert((allocSize == allocSizeWithoutCookie) == - CalculateCookiePadding(*this, E).isZero()); - if (allocSize != allocSizeWithoutCookie) { - assert(E->isArray()); - allocation = CGM.getCXXABI().InitializeArrayCookie(*this, allocation, - numElements, - E, allocType); - } // If there's an operator delete, enter a cleanup to call it if an // exception is thrown. @@ -1105,6 +1096,15 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { operatorDeleteCleanup = EHStack.stable_begin(); } + assert((allocSize == allocSizeWithoutCookie) == + CalculateCookiePadding(*this, E).isZero()); + if (allocSize != allocSizeWithoutCookie) { + assert(E->isArray()); + allocation = CGM.getCXXABI().InitializeArrayCookie(*this, allocation, + numElements, + E, allocType); + } + llvm::Type *elementPtrTy = ConvertTypeForMem(allocType)->getPointerTo(AS); llvm::Value *result = Builder.CreateBitCast(allocation, elementPtrTy); diff --git a/test/CodeGenCXX/exceptions.cpp b/test/CodeGenCXX/exceptions.cpp index 18a3d108dd..0fbb09c262 100644 --- a/test/CodeGenCXX/exceptions.cpp +++ b/test/CodeGenCXX/exceptions.cpp @@ -406,4 +406,22 @@ namespace test8 { void test() { throw makeA(); } + // CHECK: define void @_ZN5test84testEv +} + +// Make sure we generate the correct code for the delete[] call which +// happens if A::A() throws. (We were previously calling delete[] on +// a pointer to the first array element, not the pointer returned by new[].) +// PR10870 +namespace test9 { + struct A { + A(); + ~A(); + }; + A* test() { + return new A[10]; + } + // CHECK: define {{%.*}}* @_ZN5test94testEv + // CHECK: [[TEST9_NEW:%.*]] = call noalias i8* @_Znam + // CHECK: call void @_ZdaPv(i8* [[TEST9_NEW]]) } -- 2.40.0