aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGException.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-07-07 06:56:46 +0000
committerJohn McCall <rjmccall@apple.com>2010-07-07 06:56:46 +0000
commit59a7000a79118e4c140885ccbb2ac6a686a73092 (patch)
tree803331196f70138a85888e168a5ce1721c6c425b /lib/CodeGen/CGException.cpp
parent8b5dec3002bd3e17061a8bf1fc35ba82912ec768 (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.cpp26
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());