]> granicus.if.org Git - clang/commitdiff
Add terminate handler for copy constructors for thrown objects. WIP.
authorMike Stump <mrs@apple.com>
Wed, 9 Dec 2009 23:31:35 +0000 (23:31 +0000)
committerMike Stump <mrs@apple.com>
Wed, 9 Dec 2009 23:31:35 +0000 (23:31 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90994 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGException.cpp
test/CodeGenCXX/eh.cpp

index d1edde527366e5c1af47d76e42bc6abc62b26288..5e26e9bbea52037e3cf0785678ecd143e5a55552 100644 (file)
@@ -165,6 +165,10 @@ static void CopyObject(CodeGenFunction &CGF, const Expr *E, llvm::Value *N) {
 
       llvm::Value *Src = CGF.EmitLValue(E).getAddress();
 
+      llvm::BasicBlock *TerminateHandler = CGF.getTerminateHandler();
+      llvm::BasicBlock *PrevLandingPad = CGF.getInvokeDest();
+      CGF.setInvokeDest(TerminateHandler);
+
       // Stolen from EmitClassAggrMemberwiseCopy
       llvm::Value *Callee = CGF.CGM.GetAddrOfCXXConstructor(CopyCtor,
                                                             Ctor_Complete);
@@ -179,6 +183,7 @@ static void CopyObject(CodeGenFunction &CGF, const Expr *E, llvm::Value *N) {
         CopyCtor->getType()->getAs<FunctionType>()->getResultType();
       CGF.EmitCall(CGF.CGM.getTypes().getFunctionInfo(ResultType, CallArgs),
                    Callee, CallArgs, CopyCtor);
+      CGF.setInvokeDest(PrevLandingPad);
     } else
       llvm::llvm_unreachable("uncopyable object");
   }
@@ -253,7 +258,6 @@ void CodeGenFunction::EmitCXXThrowExpr(const CXXThrowExpr *E) {
                        llvm::ConstantInt::get(SizeTy, TypeSize),
                        "exception");
 
-  // FIXME: terminate protect this
   CopyObject(*this, E->getSubExpr(), ExceptionPtr);
   
   // Now throw the exception.
@@ -685,6 +689,13 @@ CodeGenFunction::EHCleanupBlock::~EHCleanupBlock() {
 }
 
 llvm::BasicBlock *CodeGenFunction::getTerminateHandler() {
+  llvm::BasicBlock *Cont = 0;
+
+  if (HaveInsertPoint()) {
+    Cont = createBasicBlock("cont");
+    EmitBranch(Cont);
+  }
+
   llvm::Constant *Personality =
     CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty
                                                       (VMContext),
@@ -706,7 +717,7 @@ llvm::BasicBlock *CodeGenFunction::getTerminateHandler() {
   Args.push_back(Exc);
   Args.push_back(Personality);
   Args.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
-                                        0));
+                                        1));
   Builder.CreateCall(llvm_eh_selector, Args.begin(), Args.end());
   llvm::CallInst *TerminateCall = 
     Builder.CreateCall(getTerminateFn(*this));
@@ -717,5 +728,8 @@ llvm::BasicBlock *CodeGenFunction::getTerminateHandler() {
   // Clear the insertion point to indicate we are in unreachable code.
   Builder.ClearInsertionPoint();
 
+  if (Cont)
+    EmitBlock(Cont);
+
   return TerminateHandler;
 }
index 3dd7219d9afdf3a57329bcbe1af0edc6363bbb29..ec457dd4187f8032cade97cf56a017d27c9e65f6 100644 (file)
@@ -34,8 +34,9 @@ void test2() {
 // CHECK-NEXT:entry:
 // CHECK-NEXT:  %exception = call i8* @__cxa_allocate_exception(i64 16)
 // CHECK-NEXT:  %0 = bitcast i8* %exception to %struct.test2_D*
-// CHECK-NEXT:  call void @_ZN7test2_DC1ERKS_(%struct.test2_D* %0, %struct.test2_D* @d2)
-// CHECK-NEXT:  call void @__cxa_throw(i8* %exception, i8* bitcast (%0* @_ZTI7test2_D to i8*), i8* null) noreturn
+// CHECK:       invoke void @_ZN7test2_DC1ERKS_(%struct.test2_D* %0, %struct.test2_D* @d2)
+// CHECK-NEXT:     to label %invoke.cont unwind label %terminate.handler
+// CHECK:  call void @__cxa_throw(i8* %exception, i8* bitcast (%0* @_ZTI7test2_D to i8*), i8* null) noreturn
 // CHECK-NEXT:  unreachable