ValueFlow: Improved analysis after switch

This commit is contained in:
Daniel Marjamäki 2014-06-30 17:56:42 +02:00
parent ec59f1d9df
commit b7d7633b97
2 changed files with 20 additions and 4 deletions

View File

@ -691,6 +691,13 @@ static bool valueFlowForward(Token * const startToken,
} }
else if (indentlevel <= 0 && Token::Match(tok2, "break|continue|goto")) { else if (indentlevel <= 0 && Token::Match(tok2, "break|continue|goto")) {
if (tok2->str() == "break") {
const Scope *scope = tok2->scope();
if (scope && scope->type == Scope::eSwitch) {
tok2 = const_cast<Token *>(scope->classEnd);
continue;
}
}
if (settings->debugwarnings) if (settings->debugwarnings)
bailout(tokenlist, errorLogger, tok2, "variable " + var->nameToken()->str() + ". noreturn conditional scope."); bailout(tokenlist, errorLogger, tok2, "variable " + var->nameToken()->str() + ". noreturn conditional scope.");
return false; return false;

View File

@ -468,8 +468,7 @@ private:
" case 2: if (x==5) {} break;\n" " case 2: if (x==5) {} break;\n"
" };\n" " };\n"
"}"); "}");
ASSERT_EQUALS("[test.cpp:3]: (debug) ValueFlow bailout: variable x stopping on break\n" ASSERT_EQUALS("[test.cpp:3]: (debug) ValueFlow bailout: variable x stopping on break\n", errout.str());
"[test.cpp:4]: (debug) ValueFlow bailout: variable x. noreturn conditional scope.\n", errout.str());
bailout("void f(int x, int y) {\n" bailout("void f(int x, int y) {\n"
" switch (y) {\n" " switch (y) {\n"
@ -477,8 +476,7 @@ private:
" case 2: if (x==5) {} break;\n" " case 2: if (x==5) {} break;\n"
" };\n" " };\n"
"}"); "}");
ASSERT_EQUALS("[test.cpp:3]: (debug) ValueFlow bailout: variable x stopping on return\n" ASSERT_EQUALS("[test.cpp:3]: (debug) ValueFlow bailout: variable x stopping on return\n", errout.str());
"[test.cpp:4]: (debug) ValueFlow bailout: variable x. noreturn conditional scope.\n", errout.str());
} }
void valueFlowBeforeConditionMacro() { void valueFlowBeforeConditionMacro() {
@ -745,6 +743,17 @@ private:
" }\n" " }\n"
"}\n"; "}\n";
ASSERT_EQUALS(false, testValueOfX(code, 8U, 2)); // x is not 2 at line 8 ASSERT_EQUALS(false, testValueOfX(code, 8U, 2)); // x is not 2 at line 8
code = "void f() {\n"
" int x;\n"
" switch (ab) {\n"
" case A: x = 12; break;\n"
" case B: x = 34; break;\n"
" }\n"
" v = x;\n"
"}";
ASSERT_EQUALS(true, testValueOfX(code, 7U, 12));
ASSERT_EQUALS(true, testValueOfX(code, 7U, 34));
} }
void valueFlowAfterCondition() { void valueFlowAfterCondition() {