aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-04-18 19:50:02 +0000
committerChris Lattner <sabre@nondot.org>2009-04-18 19:50:02 +0000
commita9768b72bb5ea061c9f10d6aa51b3be3241f3ec2 (patch)
treeeb0fb2af4a830253c6725bd7c9aa4ee308ccff65 /lib/Sema/SemaDecl.cpp
parent366920a45e3e278d35cbc3bc74d9d0676ae87dfe (diff)
Improve switch diagnostic to emit the "jump" message on the
specific bad case instead of on the switch. Putting it on the switch means you don't know what case is the problem. For example: scope-check.c:54:3: error: illegal switch case into protected scope case 2: ^ scope-check.c:53:9: note: jump bypasses initialization of variable length array int a[x]; ^ git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69462 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r--lib/Sema/SemaDecl.cpp37
1 files changed, 20 insertions, 17 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 48351407d9..814b730575 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -2953,7 +2953,8 @@ private:
bool StatementCreatesScope(DeclStmt *S, unsigned ParentScope);
void BuildScopeInformation(Stmt *S, unsigned ParentScope);
void VerifyJumps();
- void CheckJump(Stmt *S, unsigned JumpTargetScope, unsigned JumpDiag);
+ void CheckJump(Stmt *From, Stmt *To,
+ SourceLocation DiagLoc, unsigned JumpDiag);
};
} // end anonymous namespace
@@ -3067,14 +3068,13 @@ void JumpScopeChecker::VerifyJumps() {
Stmt *Jump = Jumps.pop_back_val();
if (GotoStmt *GS = dyn_cast<GotoStmt>(Jump)) {
- assert(LabelAndGotoScopes.count(GS->getLabel()) && "Label not visited?");
- CheckJump(GS, LabelAndGotoScopes[GS->getLabel()],
+ CheckJump(GS, GS->getLabel(), GS->getGotoLoc(),
diag::err_goto_into_protected_scope);
} else if (SwitchStmt *SS = dyn_cast<SwitchStmt>(Jump)) {
for (SwitchCase *SC = SS->getSwitchCaseList(); SC;
SC = SC->getNextSwitchCase()) {
assert(LabelAndGotoScopes.count(SC) && "Case not visited?");
- CheckJump(SS, LabelAndGotoScopes[SC],
+ CheckJump(SS, SC, SC->getLocStart(),
diag::err_switch_into_protected_scope);
}
continue;
@@ -3088,22 +3088,25 @@ void JumpScopeChecker::VerifyJumps() {
/// CheckJump - Validate that the specified jump statement is valid: that it is
/// jumping within or out of its current scope, not into a deeper one.
-void JumpScopeChecker::CheckJump(Stmt *Jump, unsigned JumpTargetScope,
- unsigned JumpDiag) {
- assert(LabelAndGotoScopes.count(Jump) && "Jump didn't get added to scopes?");
- unsigned JumpScope = LabelAndGotoScopes[Jump];
+void JumpScopeChecker::CheckJump(Stmt *From, Stmt *To,
+ SourceLocation DiagLoc, unsigned JumpDiag) {
+ assert(LabelAndGotoScopes.count(From) && "Jump didn't get added to scopes?");
+ unsigned FromScope = LabelAndGotoScopes[From];
+ assert(LabelAndGotoScopes.count(To) && "Jump didn't get added to scopes?");
+ unsigned ToScope = LabelAndGotoScopes[To];
+
// Common case: exactly the same scope, which is fine.
- if (JumpScope == JumpTargetScope) return;
+ if (FromScope == ToScope) return;
// The only valid mismatch jump case happens when the jump is more deeply
// nested inside the jump target. Do a quick scan to see if the jump is valid
// because valid code is more common than invalid code.
- unsigned TestScope = Scopes[JumpScope].ParentScope;
+ unsigned TestScope = Scopes[FromScope].ParentScope;
while (TestScope != ~0U) {
// If we found the jump target, then we're jumping out of our current scope,
// which is perfectly fine.
- if (TestScope == JumpTargetScope) return;
+ if (TestScope == ToScope) return;
// Otherwise, scan up the hierarchy.
TestScope = Scopes[TestScope].ParentScope;
@@ -3111,23 +3114,23 @@ void JumpScopeChecker::CheckJump(Stmt *Jump, unsigned JumpTargetScope,
// If we get here, then we know we have invalid code. Diagnose the bad jump,
// and then emit a note at each VLA being jumped out of.
- S.Diag(Jump->getLocStart(), JumpDiag);
+ S.Diag(DiagLoc, JumpDiag);
// FIXME: This is N^2 and silly.
while (1) {
// Diagnose that the jump jumps over this declaration.
- const GotoScope &TargetScope = Scopes[JumpTargetScope];
+ const GotoScope &TargetScope = Scopes[ToScope];
S.Diag(TargetScope.Loc, TargetScope.Diag);
// Walk out one level.
- JumpTargetScope = Scopes[JumpTargetScope].ParentScope;
- assert(JumpTargetScope != ~0U && "Didn't find top-level function scope?");
+ ToScope = Scopes[ToScope].ParentScope;
+ assert(ToScope != ~0U && "Didn't find top-level function scope?");
// Check to see if the jump is valid now.
- unsigned TestScope = JumpScope;
+ unsigned TestScope = FromScope;
while (TestScope != ~0U) {
// If we found the jump target, the the jump became valid.
- if (TestScope == JumpTargetScope) return;
+ if (TestScope == ToScope) return;
// Otherwise, scan up the hierarchy.
TestScope = Scopes[TestScope].ParentScope;