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
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
index 7293537..2992867 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 @@
     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 @@
     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) {