diff options
author | Chris Lattner <sabre@nondot.org> | 2009-04-18 21:28:52 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-04-18 21:28:52 +0000 |
commit | 07e775d5a1d5262a9cfe1ff333af713535b8cbab (patch) | |
tree | 5945f04eb0b22d4adeaadfaf206277397c2ce57f /lib/Sema/SemaDecl.cpp | |
parent | b56593725243becfe2685f39eec47406299801ae (diff) |
reject invalid jumps among pieces of @try blocks. This seems to work
reasonably well except for the problem that @catches are nested within
each other in the AST, giving the ugly diagnostics in L8.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69477 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 9424fc685c..903ddf2600 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -3022,6 +3022,13 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned ParentScope) { // it. This makes the second scan not have to walk the AST again. LabelAndGotoScopes[S] = ParentScope; Jumps.push_back(S); + } else if (ObjCAtCatchStmt *AC = dyn_cast<ObjCAtCatchStmt>(S)) { + // @catch always starts a new scope. + // FIXME: We have to do this because @catches are nested inside each other, + // which seems weird and causes us to emit wierd diagnostics. + Scopes.push_back(GotoScope(ParentScope,diag::note_protected_by_objc_catch, + AC->getAtCatchLoc())); + ParentScope = Scopes.size()-1; } for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end(); CI != E; @@ -3050,10 +3057,24 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned ParentScope) { // Disallow jumps into any part of an @try statement by pushing a scope and // walking all sub-stmts in that scope. if (ObjCAtTryStmt *AT = dyn_cast<ObjCAtTryStmt>(SubStmt)) { - Scopes.push_back(GotoScope(ParentScope, diag::note_protected_by_objc_try, + // Recursively walk the AST for the @try part. + Scopes.push_back(GotoScope(ParentScope,diag::note_protected_by_objc_try, AT->getAtTryLoc())); - // Recursively walk the AST. - BuildScopeInformation(SubStmt, Scopes.size()-1); + if (Stmt *TryPart = AT->getTryBody()) + BuildScopeInformation(TryPart, Scopes.size()-1); + + // Jump from the catch or finally to the try is not valid. + if (ObjCAtCatchStmt *AC = AT->getCatchStmts()) + // @catches are nested and it isn't + BuildScopeInformation(AC, ParentScope); + + if (ObjCAtFinallyStmt *AF = AT->getFinallyStmt()) { + Scopes.push_back(GotoScope(ParentScope, + diag::note_protected_by_objc_finally, + AF->getAtFinallyLoc())); + BuildScopeInformation(AF, Scopes.size()-1); + } + continue; } // FIXME: what about jumps into C++ catch blocks, what are the rules? |