aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGExprAgg.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2011-11-10 10:43:54 +0000
committerJohn McCall <rjmccall@apple.com>2011-11-10 10:43:54 +0000
commit6f103ba42cb69d50005a977c5ea583984ab63fc4 (patch)
treeebadb2d10dc505112b39803e795db603c221e178 /lib/CodeGen/CGExprAgg.cpp
parent3fe0aad1a6f692f691b8f953a7d079f49dfac314 (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.cpp15
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();
}
//===----------------------------------------------------------------------===//