]> granicus.if.org Git - clang/commitdiff
Pull the terminate handler up so that we can use it for the catch
authorMike Stump <mrs@apple.com>
Wed, 2 Dec 2009 19:53:57 +0000 (19:53 +0000)
committerMike Stump <mrs@apple.com>
Wed, 2 Dec 2009 19:53:57 +0000 (19:53 +0000)
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

lib/CodeGen/CGException.cpp

index 63edd2c3d1fea42105bda905531ae302d2127d9e..f4d235c8e6e097c1f7892f00540530297490f94a 100644 (file)
@@ -265,6 +265,10 @@ void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) {
                                                       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 @@ void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) {
   // 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 @@ void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) {
   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 @@ void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) {
   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 @@ void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) {
     // 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 @@ void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) {
       CopyObject(*this, CatchParam->getType().getNonReferenceType(),
                  ExcObject, GetAddrOfLocalVar(CatchParam));
 #endif
+      setInvokeDest(MatchHandler);
     }
 
     EmitStmt(CatchBody);
@@ -387,7 +411,7 @@ void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) {
     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 @@ void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) {
 
     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 @@ void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) {
     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);
   }