Pull the terminate handler up so that we can use it for the catch
parameter setup code and set up the catch parameter setup code to
protect that code with terminate.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90340 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp
index 63edd2c..f4d235c 100644
--- a/lib/CodeGen/CGException.cpp
+++ b/lib/CodeGen/CGException.cpp
@@ -265,6 +265,10 @@
                                                       true),
                               "__gxx_personality_v0");
   Personality = llvm::ConstantExpr::getBitCast(Personality, PtrToInt8Ty);
+  llvm::Value *llvm_eh_exception =
+    CGM.getIntrinsic(llvm::Intrinsic::eh_exception);
+  llvm::Value *llvm_eh_selector =
+    CGM.getIntrinsic(llvm::Intrinsic::eh_selector);
 
   llvm::BasicBlock *PrevLandingPad = getInvokeDest();
   llvm::BasicBlock *TryHandler = createBasicBlock("try.handler");
@@ -283,6 +287,28 @@
   // Jump to end if there is no exception
   EmitBranchThroughCleanup(FinallyEnd);
 
+  // Set up terminate handler
+  llvm::BasicBlock *TerminateHandler = createBasicBlock("terminate.handler");
+  EmitBlock(TerminateHandler);
+  llvm::Value *Exc = Builder.CreateCall(llvm_eh_exception, "exc");
+  // We are required to emit this call to satisfy LLVM, even
+  // though we don't use the result.
+  llvm::SmallVector<llvm::Value*, 8> Args;
+  Args.clear();
+  Args.push_back(Exc);
+  Args.push_back(Personality);
+  Args.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
+                                        0));
+  Builder.CreateCall(llvm_eh_selector, Args.begin(), Args.end());
+  llvm::CallInst *TerminateCall = 
+    Builder.CreateCall(getTerminateFn(*this));
+  TerminateCall->setDoesNotReturn();
+  TerminateCall->setDoesNotThrow();
+  Builder.CreateUnreachable();
+
+  // Clear the insertion point to indicate we are in unreachable code.
+  Builder.ClearInsertionPoint();
+
   // Emit the handlers
   EmitBlock(TryHandler);
   
@@ -293,16 +319,13 @@
   PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty);
   llvm::Constant *Null = llvm::ConstantPointerNull::get(PtrToInt8Ty);
   llvm::SmallVector<llvm::Value*, 8> SelectorArgs;
-  llvm::Value *llvm_eh_exception =
-    CGM.getIntrinsic(llvm::Intrinsic::eh_exception);
-  llvm::Value *llvm_eh_selector =
-    CGM.getIntrinsic(llvm::Intrinsic::eh_selector);
   llvm::Value *llvm_eh_typeid_for =
     CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for);
   // Exception object
-  llvm::Value *Exc = Builder.CreateCall(llvm_eh_exception, "exc");
+  Exc = Builder.CreateCall(llvm_eh_exception, "exc");
   llvm::Value *RethrowPtr = CreateTempAlloca(Exc->getType(), "_rethrow");
 
+  Args.clear();
   SelectorArgs.push_back(Exc);
   SelectorArgs.push_back(Personality);
 
@@ -330,7 +353,6 @@
   llvm::Value *Selector
     = Builder.CreateCall(llvm_eh_selector, SelectorArgs.begin(),
                          SelectorArgs.end(), "selector");
-  llvm::BasicBlock *TerminateHandler = 0;
   for (unsigned i = 0; i<S.getNumHandlers(); ++i) {
     const CXXCatchStmt *C = S.getHandler(i);
     VarDecl *CatchParam = C->getExceptionDecl();
@@ -362,6 +384,7 @@
     // Bind the catch parameter if it exists.
     if (CatchParam) {
       QualType CatchType = CatchParam->getType().getNonReferenceType();
+      setInvokeDest(TerminateHandler);
       if (!CatchType.getTypePtr()->isPointerType())
         CatchType = getContext().getPointerType(CatchType);
       ExcObject =
@@ -377,6 +400,7 @@
       CopyObject(*this, CatchParam->getType().getNonReferenceType(),
                  ExcObject, GetAddrOfLocalVar(CatchParam));
 #endif
+      setInvokeDest(MatchHandler);
     }
 
     EmitStmt(CatchBody);
@@ -387,7 +411,7 @@
     llvm::Value *Exc = Builder.CreateCall(llvm_eh_exception, "exc");
     // We are required to emit this call to satisfy LLVM, even
     // though we don't use the result.
-    llvm::SmallVector<llvm::Value*, 8> Args;
+    Args.clear();
     Args.push_back(Exc);
     Args.push_back(Personality);
     Args.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
@@ -400,12 +424,6 @@
 
     EmitBlock(MatchEnd);
 
-    // Set up terminate handler
-    bool GenerateTerminate = false;
-    if (!TerminateHandler) {
-      TerminateHandler = createBasicBlock("terminate.handler");
-      GenerateTerminate = true;
-    }
     llvm::BasicBlock *Cont = createBasicBlock("invoke.cont");
     Builder.CreateInvoke(getEndCatchFn(*this),
                          Cont, TerminateHandler,
@@ -421,28 +439,6 @@
     Builder.CreateStore(Exc, RethrowPtr);
     EmitBranchThroughCleanup(FinallyRethrow);
 
-    if (GenerateTerminate) {
-      GenerateTerminate = false;
-      EmitBlock(TerminateHandler);
-      Exc = Builder.CreateCall(llvm_eh_exception, "exc");
-      // We are required to emit this call to satisfy LLVM, even
-      // though we don't use the result.
-      Args.clear();
-      Args.push_back(Exc);
-      Args.push_back(Personality);
-      Args.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
-                                            0));
-      Builder.CreateCall(llvm_eh_selector, Args.begin(), Args.end());
-      llvm::CallInst *TerminateCall = 
-        Builder.CreateCall(getTerminateFn(*this));
-      TerminateCall->setDoesNotReturn();
-      TerminateCall->setDoesNotThrow();
-      Builder.CreateUnreachable();
-
-      // Clear the insertion point to indicate we are in unreachable code.
-      Builder.ClearInsertionPoint();
-    }
-
     if (Next)
       EmitBlock(Next);
   }