diff options
author | John McCall <rjmccall@apple.com> | 2010-07-13 22:12:14 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-07-13 22:12:14 +0000 |
commit | 8e3f86193995c47ee0d229e4336c3382410f09f5 (patch) | |
tree | 0668cf7ba484f2e863aa0d937fd156672b004af5 /lib/CodeGen/CGObjCMac.cpp | |
parent | ae415dc21ee6402cee1675ec8bb965a24f9e5b6b (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.cpp | 28 |
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) { |