diff options
author | John McCall <rjmccall@apple.com> | 2011-11-10 10:43:54 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-11-10 10:43:54 +0000 |
commit | 6f103ba42cb69d50005a977c5ea583984ab63fc4 (patch) | |
tree | ebadb2d10dc505112b39803e795db603c221e178 /lib/CodeGen/CGExprAgg.cpp | |
parent | 3fe0aad1a6f692f691b8f953a7d079f49dfac314 (diff) |
Whenever explicitly activating or deactivating a cleanup, we
need to provide a 'dominating IP' which is guaranteed to
dominate the (de)activation point but which cannot be avoided
along any execution path from the (de)activation point to
the push-point of the cleanup. Using the entry block is
bad mojo.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@144276 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGExprAgg.cpp')
-rw-r--r-- | lib/CodeGen/CGExprAgg.cpp | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp index f3e86fbb44..bc8b0818ee 100644 --- a/lib/CodeGen/CGExprAgg.cpp +++ b/lib/CodeGen/CGExprAgg.cpp @@ -687,6 +687,7 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) { QualType::DestructionKind dtorKind = elementType.isDestructedType(); llvm::AllocaInst *endOfInit = 0; EHScopeStack::stable_iterator cleanup; + llvm::Instruction *cleanupDominator = 0; if (CGF.needsEHCleanup(dtorKind)) { // In principle we could tell the cleanup where we are more // directly, but the control flow can get so varied here that it @@ -694,7 +695,7 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) { // alloca. endOfInit = CGF.CreateTempAlloca(begin->getType(), "arrayinit.endOfInit"); - Builder.CreateStore(begin, endOfInit); + cleanupDominator = Builder.CreateStore(begin, endOfInit); CGF.pushIrregularPartialArrayCleanup(begin, endOfInit, elementType, CGF.getDestroyer(dtorKind)); cleanup = CGF.EHStack.stable_begin(); @@ -794,7 +795,7 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) { } // Leave the partial-array cleanup if we entered one. - if (dtorKind) CGF.DeactivateCleanupBlock(cleanup); + if (dtorKind) CGF.DeactivateCleanupBlock(cleanup, cleanupDominator); return; } @@ -843,6 +844,7 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) { // We'll need to enter cleanup scopes in case any of the member // initializers throw an exception. SmallVector<EHScopeStack::stable_iterator, 16> cleanups; + llvm::Instruction *cleanupDominator = 0; // Here we iterate over the fields; this makes it simpler to both // default-initialize fields and skip over unnamed fields. @@ -886,6 +888,9 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) { = field->getType().isDestructedType()) { assert(LV.isSimple()); if (CGF.needsEHCleanup(dtorKind)) { + if (!cleanupDominator) + cleanupDominator = CGF.Builder.CreateUnreachable(); // placeholder + CGF.pushDestroy(EHCleanup, LV.getAddress(), field->getType(), CGF.getDestroyer(dtorKind), false); cleanups.push_back(CGF.EHStack.stable_begin()); @@ -905,7 +910,11 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) { // Deactivate all the partial cleanups in reverse order, which // generally means popping them. for (unsigned i = cleanups.size(); i != 0; --i) - CGF.DeactivateCleanupBlock(cleanups[i-1]); + CGF.DeactivateCleanupBlock(cleanups[i-1], cleanupDominator); + + // Destroy the placeholder if we made one. + if (cleanupDominator) + cleanupDominator->eraseFromParent(); } //===----------------------------------------------------------------------===// |