diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp index 5845f1ec0260..58af36a56d58 100644 --- a/clang/lib/CodeGen/CGException.cpp +++ b/clang/lib/CodeGen/CGException.cpp @@ -179,8 +179,7 @@ llvm::Value *CodeGenFunction::initFullExprCleanup() { // Initialize it to false at a site that's guaranteed to be run // before each evaluation. llvm::BasicBlock *block = OutermostConditional->getStartingBlock(); - new llvm::StoreInst(Builder.getFalse(), run, - block->getFirstNonPHIOrDbg()); + new llvm::StoreInst(Builder.getFalse(), run, &block->back()); // Initialize it to true at the current location. Builder.CreateStore(Builder.getTrue(), run); diff --git a/clang/lib/CodeGen/CGTemporaries.cpp b/clang/lib/CodeGen/CGTemporaries.cpp index cfbd2af99028..3b4c50910bf8 100644 --- a/clang/lib/CodeGen/CGTemporaries.cpp +++ b/clang/lib/CodeGen/CGTemporaries.cpp @@ -16,39 +16,11 @@ using namespace clang; using namespace CodeGen; namespace { - struct DestroyTemporary : EHScopeStack::Cleanup { - const CXXTemporary *Temporary; - llvm::Value *Addr; - llvm::Value *CondPtr; - - DestroyTemporary(const CXXTemporary *Temporary, llvm::Value *Addr, - llvm::Value *CondPtr) - : Temporary(Temporary), Addr(Addr), CondPtr(CondPtr) {} - - void Emit(CodeGenFunction &CGF, bool IsForEH) { - llvm::BasicBlock *CondEnd = 0; - - // If this is a conditional temporary, we need to check the condition - // boolean and only call the destructor if it's true. - if (CondPtr) { - llvm::BasicBlock *CondBlock = - CGF.createBasicBlock("temp.cond-dtor.call"); - CondEnd = CGF.createBasicBlock("temp.cond-dtor.cont"); - - llvm::Value *Cond = CGF.Builder.CreateLoad(CondPtr); - CGF.Builder.CreateCondBr(Cond, CondBlock, CondEnd); - CGF.EmitBlock(CondBlock); - } - - CGF.EmitCXXDestructorCall(Temporary->getDestructor(), - Dtor_Complete, /*ForVirtualBase=*/false, - Addr); - - if (CondPtr) { - // Reset the condition to false. - CGF.Builder.CreateStore(CGF.Builder.getFalse(), CondPtr); - CGF.EmitBlock(CondEnd); - } + struct DestroyTemporary { + static void Emit(CodeGenFunction &CGF, bool forEH, + const CXXDestructorDecl *dtor, llvm::Value *addr) { + CGF.EmitCXXDestructorCall(dtor, Dtor_Complete, /*ForVirtualBase=*/false, + addr); } }; } @@ -56,23 +28,9 @@ namespace { /// Emits all the code to cause the given temporary to be cleaned up. void CodeGenFunction::EmitCXXTemporary(const CXXTemporary *Temporary, llvm::Value *Ptr) { - llvm::AllocaInst *CondPtr = 0; - - // Check if temporaries need to be conditional. If so, we'll create a - // condition boolean, initialize it to 0 and - if (isInConditionalBranch()) { - CondPtr = CreateTempAlloca(llvm::Type::getInt1Ty(VMContext), "cond"); - - // Initialize it to false. This initialization takes place right after - // the alloca insert point. - InitTempAlloca(CondPtr, llvm::ConstantInt::getFalse(VMContext)); - - // Now set it to true. - Builder.CreateStore(Builder.getTrue(), CondPtr); - } - - EHStack.pushCleanup(NormalAndEHCleanup, - Temporary, Ptr, CondPtr); + pushFullExprCleanup(NormalAndEHCleanup, + Temporary->getDestructor(), + Ptr); } RValue diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index ea362d3bf15e..dcd617376332 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -214,6 +214,7 @@ public: template class UnconditionalCleanup2 : public Cleanup { A0 a0; A1 a1; + public: UnconditionalCleanup2(A0 a0, A1 a1) : a0(a0), a1(a1) {} void Emit(CodeGenFunction &CGF, bool IsForEHCleanup) { T::Emit(CGF, IsForEHCleanup, a0, a1); @@ -226,17 +227,18 @@ public: class ConditionalCleanup2 : public ConditionalCleanup { typedef typename SavedValueInCond::saved_type A0_saved; typedef typename SavedValueInCond::saved_type A1_saved; - A0_saved a0; A1_saved a1; + A0_saved a0_saved; + A1_saved a1_saved; void EmitImpl(CodeGenFunction &CGF, bool IsForEHCleanup) { - A0 a0 = SavedValueInCond::restore(CGF, a0); - A1 a1 = SavedValueInCond::restore(CGF, a1); + A0 a0 = SavedValueInCond::restore(CGF, a0_saved); + A1 a1 = SavedValueInCond::restore(CGF, a1_saved); T::Emit(CGF, IsForEHCleanup, a0, a1); } public: ConditionalCleanup2(llvm::Value *cond, A0_saved a0, A1_saved a1) - : ConditionalCleanup(cond), a0(a0), a1(a1) {} + : ConditionalCleanup(cond), a0_saved(a0), a1_saved(a1) {} }; private: diff --git a/clang/test/CodeGenCXX/exceptions.cpp b/clang/test/CodeGenCXX/exceptions.cpp index c60f2a1b45d0..2413eb0f6d51 100644 --- a/clang/test/CodeGenCXX/exceptions.cpp +++ b/clang/test/CodeGenCXX/exceptions.cpp @@ -196,10 +196,10 @@ namespace test3 { // CHECK-NEXT: [[CLEANUPACTIVE:%.*]] = alloca i1 // CHECK-NEXT: [[TMP:%.*]] = alloca [[A]], align 8 // CHECK: [[TMPACTIVE:%.*]] = alloca i1 - // CHECK-NEXT: store i1 false, i1* [[TMPACTIVE]] // CHECK-NEXT: store i1 false, i1* [[CLEANUPACTIVE]] // CHECK: [[COND:%.*]] = trunc i8 {{.*}} to i1 + // CHECK-NEXT: store i1 false, i1* [[TMPACTIVE]] // CHECK-NEXT: br i1 [[COND]] return (cond ? diff --git a/clang/test/CodeGenCXX/temporaries.cpp b/clang/test/CodeGenCXX/temporaries.cpp index 74b11fdb8e91..348d51e019a6 100644 --- a/clang/test/CodeGenCXX/temporaries.cpp +++ b/clang/test/CodeGenCXX/temporaries.cpp @@ -502,9 +502,9 @@ namespace PR8623 { // CHECK: [[TMP:%.*]] = alloca [[A:%.*]], align 1 // CHECK-NEXT: [[LCONS:%.*]] = alloca i1 // CHECK-NEXT: [[RCONS:%.*]] = alloca i1 + // CHECK: store i1 false, i1* [[LCONS]] // CHECK-NEXT: store i1 false, i1* [[RCONS]] - // CHECK-NEXT: store i1 false, i1* [[LCONS]] - // CHECK: br i1 + // CHECK-NEXT: br i1 // CHECK: call void @_ZN6PR86231AC1Ei([[A]]* [[TMP]], i32 2) // CHECK-NEXT: store i1 true, i1* [[LCONS]] // CHECK-NEXT: br label @@ -514,12 +514,10 @@ namespace PR8623 { // CHECK: load i1* [[RCONS]] // CHECK-NEXT: br i1 // CHECK: call void @_ZN6PR86231AD1Ev([[A]]* [[TMP]]) - // CHECK-NEXT: store i1 false, i1* [[RCONS]] // CHECK-NEXT: br label // CHECK: load i1* [[LCONS]] // CHECK-NEXT: br i1 // CHECK: call void @_ZN6PR86231AD1Ev([[A]]* [[TMP]]) - // CHECK-NEXT: store i1 false, i1* [[LCONS]] // CHECK-NEXT: br label // CHECK: ret void b ? A(2) : A(3);