diff options
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/Sema.h | 3 | ||||
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 11 |
2 files changed, 11 insertions, 3 deletions
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index c236b89a5e..aafddc5a03 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -1033,7 +1033,8 @@ public: 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 f4eb22df1f..989de0cdbf 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -981,10 +981,17 @@ Sema::ActOnObjCAtTryStmt(SourceLocation AtLoc, } 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 *". |