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
diff --git a/lib/CodeGen/CGCleanup.cpp b/lib/CodeGen/CGCleanup.cpp
index 9e079c6..f9ffc93 100644
--- a/lib/CodeGen/CGCleanup.cpp
+++ b/lib/CodeGen/CGCleanup.cpp
@@ -251,8 +251,7 @@
 
   // 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(), active, &block->back());
+  setBeforeOutermostConditional(Builder.getFalse(), active);
 
   // Initialize it to true at the current location.
   Builder.CreateStore(Builder.getTrue(), active);
@@ -1000,14 +999,15 @@
 /// extra uses *after* the change-over point.
 static void SetupCleanupBlockActivation(CodeGenFunction &CGF,
                                         EHScopeStack::stable_iterator C,
-                                        ForActivation_t Kind) {
+                                        ForActivation_t kind,
+                                        llvm::Instruction *dominatingIP) {
   EHCleanupScope &Scope = cast<EHCleanupScope>(*CGF.EHStack.find(C));
 
   // We always need the flag if we're activating the cleanup in a
   // conditional context, because we have to assume that the current
   // location doesn't necessarily dominate the cleanup's code.
   bool isActivatedInConditional =
-    (Kind == ForActivation && CGF.isInConditionalBranch());
+    (kind == ForActivation && CGF.isInConditionalBranch());
 
   bool needFlag = false;
 
@@ -1030,32 +1030,44 @@
   // If it hasn't yet been used as either, we're done.
   if (!needFlag) return;
 
-  llvm::AllocaInst *Var = Scope.getActiveFlag();
-  if (!Var) {
-    Var = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(), "cleanup.isactive");
-    Scope.setActiveFlag(Var);
+  llvm::AllocaInst *var = Scope.getActiveFlag();
+  if (!var) {
+    var = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(), "cleanup.isactive");
+    Scope.setActiveFlag(var);
+
+    assert(dominatingIP && "no existing variable and no dominating IP!");
 
     // Initialize to true or false depending on whether it was
     // active up to this point.
-    CGF.InitTempAlloca(Var, CGF.Builder.getInt1(Kind == ForDeactivation));
+    llvm::Value *value = CGF.Builder.getInt1(kind == ForDeactivation);
+
+    // If we're in a conditional block, ignore the dominating IP and
+    // use the outermost conditional branch.
+    if (CGF.isInConditionalBranch()) {
+      CGF.setBeforeOutermostConditional(value, var);
+    } else {
+      new llvm::StoreInst(value, var, dominatingIP);
+    }
   }
 
-  CGF.Builder.CreateStore(CGF.Builder.getInt1(Kind == ForActivation), Var);
+  CGF.Builder.CreateStore(CGF.Builder.getInt1(kind == ForActivation), var);
 }
 
 /// Activate a cleanup that was created in an inactivated state.
-void CodeGenFunction::ActivateCleanupBlock(EHScopeStack::stable_iterator C) {
+void CodeGenFunction::ActivateCleanupBlock(EHScopeStack::stable_iterator C,
+                                           llvm::Instruction *dominatingIP) {
   assert(C != EHStack.stable_end() && "activating bottom of stack?");
   EHCleanupScope &Scope = cast<EHCleanupScope>(*EHStack.find(C));
   assert(!Scope.isActive() && "double activation");
 
-  SetupCleanupBlockActivation(*this, C, ForActivation);
+  SetupCleanupBlockActivation(*this, C, ForActivation, dominatingIP);
 
   Scope.setActive(true);
 }
 
 /// Deactive a cleanup that was created in an active state.
-void CodeGenFunction::DeactivateCleanupBlock(EHScopeStack::stable_iterator C) {
+void CodeGenFunction::DeactivateCleanupBlock(EHScopeStack::stable_iterator C,
+                                             llvm::Instruction *dominatingIP) {
   assert(C != EHStack.stable_end() && "deactivating bottom of stack?");
   EHCleanupScope &Scope = cast<EHCleanupScope>(*EHStack.find(C));
   assert(Scope.isActive() && "double deactivation");
@@ -1071,7 +1083,7 @@
   }
 
   // Otherwise, follow the general case.
-  SetupCleanupBlockActivation(*this, C, ForDeactivation);
+  SetupCleanupBlockActivation(*this, C, ForDeactivation, dominatingIP);
 
   Scope.setActive(false);
 }