Fix <rdar://problem/6243503> [sema] @throw; accepted outside catch block.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64318 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index c236b89..aafddc5 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -1033,7 +1033,8 @@
                                               StmtArg Catch, StmtArg Finally);
 
   virtual OwningStmtResult ActOnObjCAtThrowStmt(SourceLocation AtLoc,
-                                                ExprArg Throw);
+                                                ExprArg Throw, 
+                                                Scope *CurScope);
   virtual OwningStmtResult ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc,
                                                        ExprArg SynchExpr,
                                                        StmtArg SynchBody);
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index f4eb22d..989de0c 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -981,10 +981,17 @@
 }
 
 Action::OwningStmtResult
-Sema::ActOnObjCAtThrowStmt(SourceLocation AtLoc, ExprArg expr) {
+Sema::ActOnObjCAtThrowStmt(SourceLocation AtLoc, ExprArg expr,
+                           Scope *CurScope) {
   Expr *ThrowExpr = static_cast<Expr*>(expr.release());
   if (!ThrowExpr) {
-    // FIXME: verify the 'rethrow' is within a @catch block
+    // @throw without an expression designates a rethrow (which much occur
+    // in the context of an @catch clause).
+    Scope *AtCatchParent = CurScope;
+    while (AtCatchParent && !AtCatchParent->isAtCatchScope())
+      AtCatchParent = AtCatchParent->getParent();
+    if (!AtCatchParent)
+      Diag(AtLoc, diag::error_rethrow_used_outside_catch);
   } else {
     QualType ThrowType = ThrowExpr->getType();
     // Make sure the expression type is an ObjC pointer or "void *".