From: Chris Lattner Date: Sat, 18 Apr 2009 22:35:34 +0000 (+0000) Subject: I didn't understand how @catches were chained. Now that I get it, fix X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=dabbad04ee3173f76b324d3825ede0287a304022;p=clang I didn't understand how @catches were chained. Now that I get it, fix the scope checker to not think @catches are nested in each other, eliminating some bogus notes. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69486 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 4ec32b738a..9cc7c6bf6b 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -3022,15 +3022,8 @@ 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(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; ++CI) { Stmt *SubStmt = *CI; @@ -3063,11 +3056,17 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned ParentScope) { 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()) + // Jump from the catch to the finally or try is not valid. + for (ObjCAtCatchStmt *AC = AT->getCatchStmts(); AC; + AC = AC->getNextCatchStmt()) { + Scopes.push_back(GotoScope(ParentScope, + diag::note_protected_by_objc_catch, + AC->getAtCatchLoc())); // @catches are nested and it isn't - BuildScopeInformation(AC, ParentScope); + BuildScopeInformation(AC->getCatchBody(), Scopes.size()-1); + } + // Jump from the finally to the try or catch is not valid. if (ObjCAtFinallyStmt *AF = AT->getFinallyStmt()) { Scopes.push_back(GotoScope(ParentScope, diag::note_protected_by_objc_finally, diff --git a/test/SemaObjC/scope-check.m b/test/SemaObjC/scope-check.m index 0833a1696d..fb9bd4570d 100644 --- a/test/SemaObjC/scope-check.m +++ b/test/SemaObjC/scope-check.m @@ -39,8 +39,8 @@ L3: ; goto L8; // expected-error{{illegal goto into protected scope}} @try { - } @catch (A *c) { // expected-note {{jump bypasses initialization of @catch block}} - } @catch (B *c) { // expected-note {{jump bypasses initialization of @catch block}} + } @catch (A *c) { + } @catch (B *c) { } @catch (C *c) { // expected-note {{jump bypasses initialization of @catch block}} L8: ; }