Fix <rdar://problem/6210791> clang ObjC rewriter: @try / @catch block with no @finally does not call objc_exception_try_exit.

Need a couple tweaks to RewriteObjCTryStmt(). Need to deal with implicit finally clauses (to make sure objc_exception_try_exit is called). Also fixed a related bug where we need to generate an implicit @catch else clause (to again make sure objc_exception_try_exit is called).


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@56104 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Driver/RewriteObjC.cpp b/Driver/RewriteObjC.cpp
index b89e811..bd809be 100644
--- a/Driver/RewriteObjC.cpp
+++ b/Driver/RewriteObjC.cpp
@@ -1455,9 +1455,16 @@
     SourceLocation bodyLoc = lastCatchBody->getLocEnd();
     assert(*SM->getCharacterData(bodyLoc) == '}' &&
            "bogus @catch body location");
-    bodyLoc = bodyLoc.getFileLocWithOffset(1);
-    buf = " } } /* @catch end */\n";
   
+    // Insert the last (implicit) else clause *before* the right curly brace.
+    bodyLoc = bodyLoc.getFileLocWithOffset(-1);
+    buf = "} /* last catch end */\n";
+    buf += "else {\n";
+    buf += " _rethrow = _caught;\n";
+    buf += " objc_exception_try_exit(&_stack);\n";
+    buf += "} } /* @catch end */\n";
+    if (!S->getFinallyStmt())
+      buf += "}\n";
     InsertText(bodyLoc, buf.c_str(), buf.size());
     
     // Set lastCurlyLoc
@@ -1488,6 +1495,12 @@
     
     // Set lastCurlyLoc
     lastCurlyLoc = body->getLocEnd();
+  } else { /* no finally clause - make sure we synthesize an implicit one */
+    buf = "{ /* implicit finally clause */\n";
+    buf += " if (!_rethrow) objc_exception_try_exit(&_stack);\n";
+    buf += " if (_rethrow) objc_exception_throw(_rethrow);\n";
+    buf += "}";
+    ReplaceText(lastCurlyLoc, 1, buf.c_str(), buf.size());
   }
   // Now emit the final closing curly brace...
   lastCurlyLoc = lastCurlyLoc.getFileLocWithOffset(1);