ValueFlow: Fixed valueFlowForward, when condition is false and else-block returns dont set values below the else-code

This commit is contained in:
Daniel Marjamäki 2015-01-05 16:39:47 +01:00
parent 39fde3c8c7
commit 1f698ca493
2 changed files with 24 additions and 4 deletions

View File

@ -690,8 +690,15 @@ static bool valueFlowForward(Token * const startToken,
++indentlevel;
else if (indentlevel >= 0 && tok2->str() == "}") {
--indentlevel;
if (indentlevel == 0 && isReturn(tok2) && Token::simpleMatch(tok2->link()->previous(), ") {")) {
const Token *condition = tok2->link()->linkAt(-1)->astOperand2();
if (indentlevel == 0 && isReturn(tok2) && Token::Match(tok2->link()->previous(), "else|) {")) {
const Token *condition = tok2->link();
const bool iselse = Token::simpleMatch(condition->tokAt(-2), "} else {");
if (iselse)
condition = condition->linkAt(-2);
if (condition && Token::simpleMatch(condition->previous(), ") {"))
condition = condition->linkAt(-1)->astOperand2();
else
condition = nullptr;
if (!condition) {
if (settings->debugwarnings)
bailout(tokenlist, errorLogger, tok2, "variable " + var->name() + " valueFlowForward, bailing out since it's unknown if conditional return is executed");
@ -700,7 +707,11 @@ static bool valueFlowForward(Token * const startToken,
bool bailoutflag = false;
for (std::list<ValueFlow::Value>::const_iterator it = values.begin(); it != values.end(); ++it) {
if (conditionIsTrue(condition, getProgramMemory(condition->astParent(), varid, *it))) {
if (!iselse && conditionIsTrue(condition, getProgramMemory(condition->astParent(), varid, *it))) {
bailoutflag = true;
break;
}
if (iselse && conditionIsFalse(condition, getProgramMemory(condition->astParent(), varid, *it))) {
bailoutflag = true;
break;
}

View File

@ -1295,10 +1295,19 @@ private:
" if (x == 5) {\n"
" panic();\n"
" }\n"
" a = x;\n"
" a = x;\n" // <- x can't be 5
"}";
ASSERT_EQUALS(false, testValueOfX(code, 7U, 5));
code = "void f() {\n"
" int x;\n"
" for (x = 0; x < 5; x++) {}\n"
" if (x < 5) {}\n"
" else return;\n"
" a = x;\n" // <- x can't be 5
"}";
ASSERT_EQUALS(false, testValueOfX(code, 6U, 5));
// hang
code = "void f() {\n"
" for(int i = 0; i < 20; i++)\n"