From 76958099828bac6ebd45abef9f76934b3e99e397 Mon Sep 17 00:00:00 2001 From: Mike Stump Date: Wed, 9 Dec 2009 23:31:35 +0000 Subject: [PATCH] Add terminate handler for copy constructors for thrown objects. WIP. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90994 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGException.cpp | 18 ++++++++++++++++-- test/CodeGenCXX/eh.cpp | 5 +++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp index d1edde5273..5e26e9bbea 100644 --- a/lib/CodeGen/CGException.cpp +++ b/lib/CodeGen/CGException.cpp @@ -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()->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; } diff --git a/test/CodeGenCXX/eh.cpp b/test/CodeGenCXX/eh.cpp index 3dd7219d9a..ec457dd418 100644 --- a/test/CodeGenCXX/eh.cpp +++ b/test/CodeGenCXX/eh.cpp @@ -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 -- 2.40.0