diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Parse/ParseObjc.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 3 | ||||
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 11 |
3 files changed, 13 insertions, 5 deletions
diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp index f45562644f..338e770cd6 100644 --- a/lib/Parse/ParseObjc.cpp +++ b/lib/Parse/ParseObjc.cpp @@ -1202,7 +1202,7 @@ Parser::OwningStmtResult Parser::ParseObjCThrowStmt(SourceLocation atLoc) { } } ConsumeToken(); // consume ';' - return Actions.ActOnObjCAtThrowStmt(atLoc, move(Res)); + return Actions.ActOnObjCAtThrowStmt(atLoc, move(Res), CurScope); } /// objc-synchronized-statement: @@ -1284,7 +1284,7 @@ Parser::OwningStmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) { ConsumeToken(); // consume catch if (Tok.is(tok::l_paren)) { ConsumeParen(); - ParseScope CatchScope(this, Scope::DeclScope); + ParseScope CatchScope(this, Scope::DeclScope|Scope::AtCatchScope); if (Tok.isNot(tok::ellipsis)) { DeclSpec DS; ParseDeclarationSpecifiers(DS); 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 *". |