Fix <rdar://problem/6252084> [sema] jumps into Obj-C exception blocks should be disallowed.

This builds on Eli's work from http://llvm.org/viewvc/llvm-project?view=rev&revision=65678.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69073 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 7675d5a..7cc3029 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -2897,21 +2897,22 @@
 }
 
 static bool StatementCreatesScope(Stmt* S) {
-  DeclStmt *DS = dyn_cast<DeclStmt>(S);
-  if (DS == 0) return false;
   
-  for (DeclStmt::decl_iterator I = DS->decl_begin(), E = DS->decl_end();
-       I != E; ++I) {
-    if (VarDecl *D = dyn_cast<VarDecl>(*I)) {
-      if (D->getType()->isVariablyModifiedType() ||
-          D->hasAttr<CleanupAttr>())
-        return true;
-    } else if (TypedefDecl *D = dyn_cast<TypedefDecl>(*I)) {
-      if (D->getUnderlyingType()->isVariablyModifiedType())
-        return true;
+  if (DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
+    for (DeclStmt::decl_iterator I = DS->decl_begin(), E = DS->decl_end();
+         I != E; ++I) {
+      if (VarDecl *D = dyn_cast<VarDecl>(*I)) {
+        if (D->getType()->isVariablyModifiedType() ||
+            D->hasAttr<CleanupAttr>())
+          return true;
+      } else if (TypedefDecl *D = dyn_cast<TypedefDecl>(*I)) {
+        if (D->getUnderlyingType()->isVariablyModifiedType())
+          return true;
+      }
     }
+  } else if (isa<ObjCAtTryStmt>(S)) {
+    return true;
   }
-  
   return false;
 }
 
diff --git a/test/SemaObjC/scope-check-try-catch.m b/test/SemaObjC/scope-check-try-catch.m
new file mode 100644
index 0000000..b11eb04
--- /dev/null
+++ b/test/SemaObjC/scope-check-try-catch.m
@@ -0,0 +1,18 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+@class A, B, C;
+
+void f() {
+  goto L; // expected-error{{illegal jump}}
+  goto L2; // expected-error{{illegal jump}}
+  goto L3; // expected-error{{illegal jump}}
+  @try {
+L: ;
+  } @catch (A *x) {
+L2: ;
+  } @catch (B *x) {
+  } @catch (C *c) {
+  } @finally {
+L3: ;
+  }
+}