From: Eli Friedman Date: Wed, 31 Oct 2012 23:55:28 +0000 (+0000) Subject: Correctly reject gotos in function-level try blocks. PR14225. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1e95d4bb1e748216e07006e9084a7b181883e286;p=platform%2Fupstream%2Fllvm.git Correctly reject gotos in function-level try blocks. PR14225. llvm-svn: 167184 --- diff --git a/clang/lib/Sema/JumpDiagnostics.cpp b/clang/lib/Sema/JumpDiagnostics.cpp index a76a552..e2ec1cc 100644 --- a/clang/lib/Sema/JumpDiagnostics.cpp +++ b/clang/lib/Sema/JumpDiagnostics.cpp @@ -332,6 +332,29 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned &origParentScope) Jumps.push_back(S); break; + case Stmt::CXXTryStmtClass: { + CXXTryStmt *TS = cast(S); + unsigned newParentScope; + Scopes.push_back(GotoScope(ParentScope, + diag::note_protected_by_cxx_try, + diag::note_exits_cxx_try, + TS->getSourceRange().getBegin())); + if (Stmt *TryBlock = TS->getTryBlock()) + BuildScopeInformation(TryBlock, (newParentScope = Scopes.size()-1)); + + // Jump from the catch into the try is not allowed either. + for (unsigned I = 0, E = TS->getNumHandlers(); I != E; ++I) { + CXXCatchStmt *CS = TS->getHandler(I); + Scopes.push_back(GotoScope(ParentScope, + diag::note_protected_by_cxx_catch, + diag::note_exits_cxx_catch, + CS->getSourceRange().getBegin())); + BuildScopeInformation(CS->getHandlerBlock(), + (newParentScope = Scopes.size()-1)); + } + return; + } + default: break; } @@ -428,30 +451,6 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned &origParentScope) continue; } - // Disallow jumps into any part of a C++ try statement. This is pretty - // much the same as for Obj-C. - if (CXXTryStmt *TS = dyn_cast(SubStmt)) { - Scopes.push_back(GotoScope(ParentScope, - diag::note_protected_by_cxx_try, - diag::note_exits_cxx_try, - TS->getSourceRange().getBegin())); - if (Stmt *TryBlock = TS->getTryBlock()) - BuildScopeInformation(TryBlock, (newParentScope = Scopes.size()-1)); - - // Jump from the catch into the try is not allowed either. - for (unsigned I = 0, E = TS->getNumHandlers(); I != E; ++I) { - CXXCatchStmt *CS = TS->getHandler(I); - Scopes.push_back(GotoScope(ParentScope, - diag::note_protected_by_cxx_catch, - diag::note_exits_cxx_catch, - CS->getSourceRange().getBegin())); - BuildScopeInformation(CS->getHandlerBlock(), - (newParentScope = Scopes.size()-1)); - } - - continue; - } - // Disallow jumps into the protected statement of an @autoreleasepool. if (ObjCAutoreleasePoolStmt *AS = dyn_cast(SubStmt)){ // Recursively walk the AST for the @autoreleasepool part, protected by a new diff --git a/clang/test/SemaCXX/scope-check.cpp b/clang/test/SemaCXX/scope-check.cpp index 78228c0..8fd23f4 100644 --- a/clang/test/SemaCXX/scope-check.cpp +++ b/clang/test/SemaCXX/scope-check.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -fblocks %s -Wno-unreachable-code -// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=gnu++11 %s -Wno-unreachable-code +// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -fcxx-exceptions %s -Wno-unreachable-code +// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -fcxx-exceptions -std=gnu++11 %s -Wno-unreachable-code namespace test0 { struct D { ~D(); }; @@ -260,3 +260,17 @@ namespace test14 { goto *ip; } } + +// PR14225 +namespace test15 { + void f1() try { + goto x; // expected-error {{goto into protected scope}} + } catch(...) { // expected-note {{jump bypasses initialization of catch block}} + x: ; + } + void f2() try { // expected-note {{jump bypasses initialization of try block}} + x: ; + } catch(...) { + goto x; // expected-error {{goto into protected scope}} + } +}