aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGObjCMac.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-07-13 22:12:14 +0000
committerJohn McCall <rjmccall@apple.com>2010-07-13 22:12:14 +0000
commit8e3f86193995c47ee0d229e4336c3382410f09f5 (patch)
tree0668cf7ba484f2e863aa0d937fd156672b004af5 /lib/CodeGen/CGObjCMac.cpp
parentae415dc21ee6402cee1675ec8bb965a24f9e5b6b (diff)
Allow for the possibility that __cxa_end_catch might throw for a catch-all block
or a catch of a record type by value or reference. Also convert this to a lazy cleanup. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@108287 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGObjCMac.cpp')
-rw-r--r--lib/CodeGen/CGObjCMac.cpp28
1 files changed, 21 insertions, 7 deletions
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
index 7293537302..2992867cbc 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -32,6 +32,7 @@
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Support/CallSite.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetData.h"
#include <cstdio>
@@ -5712,6 +5713,22 @@ namespace {
llvm::BasicBlock *Block;
llvm::Value *TypeInfo;
};
+
+ struct CallObjCEndCatch : EHScopeStack::LazyCleanup {
+ CallObjCEndCatch(bool MightThrow, llvm::Value *Fn) :
+ MightThrow(MightThrow), Fn(Fn) {}
+ bool MightThrow;
+ llvm::Value *Fn;
+
+ void Emit(CodeGenFunction &CGF, bool IsForEH) {
+ if (!MightThrow) {
+ CGF.Builder.CreateCall(Fn)->setDoesNotThrow();
+ return;
+ }
+
+ CGF.EmitCallOrInvoke(Fn, 0, 0);
+ }
+ };
}
void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
@@ -5801,13 +5818,10 @@ void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
Exn->setDoesNotThrow();
// Add a cleanup to leave the catch.
- {
- CodeGenFunction::CleanupBlock EndCatchBlock(CGF, NormalAndEHCleanup);
-
- // __objc_end_catch never throws.
- CGF.Builder.CreateCall(ObjCTypes.getObjCEndCatchFn())
- ->setDoesNotThrow();
- }
+ bool EndCatchMightThrow = (Handler.Variable == 0);
+ CGF.EHStack.pushLazyCleanup<CallObjCEndCatch>(NormalAndEHCleanup,
+ EndCatchMightThrow,
+ ObjCTypes.getObjCEndCatchFn());
// Bind the catch parameter if it exists.
if (const VarDecl *CatchParam = Handler.Variable) {