diff options
author | John McCall <rjmccall@apple.com> | 2010-07-07 06:56:46 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-07-07 06:56:46 +0000 |
commit | 59a7000a79118e4c140885ccbb2ac6a686a73092 (patch) | |
tree | 803331196f70138a85888e168a5ce1721c6c425b /lib/CodeGen/CGException.cpp | |
parent | 8b5dec3002bd3e17061a8bf1fc35ba82912ec768 (diff) |
Teach function-try-blocks on constructors and destructors to implicitly
rethrow. Fixes rdar://problem/7696603
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@107757 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGException.cpp')
-rw-r--r-- | lib/CodeGen/CGException.cpp | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp index 1645e66d55..085dddd95d 100644 --- a/lib/CodeGen/CGException.cpp +++ b/lib/CodeGen/CGException.cpp @@ -563,13 +563,12 @@ void CodeGenFunction::EmitEndEHSpec(const Decl *D) { } void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) { - CXXTryStmtInfo Info = EnterCXXTryStmt(S); + EnterCXXTryStmt(S); EmitStmt(S.getTryBlock()); - ExitCXXTryStmt(S, Info); + ExitCXXTryStmt(S); } -CodeGenFunction::CXXTryStmtInfo -CodeGenFunction::EnterCXXTryStmt(const CXXTryStmt &S) { +void CodeGenFunction::EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) { unsigned NumHandlers = S.getNumHandlers(); EHCatchScope *CatchScope = EHStack.pushCatch(NumHandlers); @@ -593,8 +592,6 @@ CodeGenFunction::EnterCXXTryStmt(const CXXTryStmt &S) { CatchScope->setCatchAllHandler(I, Handler); } } - - return CXXTryStmtInfo(); } /// Check whether this is a non-EH scope, i.e. a scope which doesn't @@ -1103,8 +1100,7 @@ static void BeginCatch(CodeGenFunction &CGF, CGF.EmitLocalBlockVarDecl(*CatchParam, &InitCatchParam); } -void CodeGenFunction::ExitCXXTryStmt(const CXXTryStmt &S, - CXXTryStmtInfo TryInfo) { +void CodeGenFunction::ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) { unsigned NumHandlers = S.getNumHandlers(); EHCatchScope &CatchScope = cast<EHCatchScope>(*EHStack.begin()); assert(CatchScope.getNumHandlers() == NumHandlers); @@ -1123,6 +1119,12 @@ void CodeGenFunction::ExitCXXTryStmt(const CXXTryStmt &S, if (HaveInsertPoint()) Builder.CreateBr(ContBB); + // Determine if we need an implicit rethrow for all these catch handlers. + bool ImplicitRethrow = false; + if (IsFnTryBlock) + ImplicitRethrow = isa<CXXDestructorDecl>(CurCodeDecl) || + isa<CXXConstructorDecl>(CurCodeDecl); + for (unsigned I = 0; I != NumHandlers; ++I) { llvm::BasicBlock *CatchBlock = Handlers[I].Block; EmitBlock(CatchBlock); @@ -1137,6 +1139,14 @@ void CodeGenFunction::ExitCXXTryStmt(const CXXTryStmt &S, // Initialize the catch variable and set up the cleanups. BeginCatch(*this, C); + // If there's an implicit rethrow, push a normal "cleanup" to call + // _cxa_rethrow. This needs to happen before _cxa_end_catch is + // called. + if (ImplicitRethrow) { + CleanupBlock Rethrow(*this, NormalCleanup); + EmitCallOrInvoke(getReThrowFn(*this), 0, 0); + } + // Perform the body of the catch. EmitStmt(C->getHandlerBlock()); |