ValueFlow: better analysis in valueFlowAfterCondition of 'if|while ( %var% )' etc
This commit is contained in:
parent
9999ce9468
commit
13761927ff
|
@ -780,14 +780,23 @@ static void valueFlowAfterCondition(TokenList *tokenlist, ErrorLogger *errorLogg
|
||||||
}
|
}
|
||||||
if (!vartok->isName() || !numtok->isNumber())
|
if (!vartok->isName() || !numtok->isNumber())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
} else if (tok->str() == "!") {
|
} else if (tok->str() == "!") {
|
||||||
vartok = tok->astOperand1();
|
vartok = tok->astOperand1();
|
||||||
numtok = nullptr;
|
numtok = nullptr;
|
||||||
if (!vartok || !vartok->isName())
|
if (!vartok || !vartok->isName())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
} else if (tok->isName() &&
|
||||||
|
(Token::Match(tok->astParent(), "%oror%|&&") ||
|
||||||
|
Token::Match(tok->tokAt(-2), "if|while ( %var% )"))) {
|
||||||
|
vartok = tok;
|
||||||
|
numtok = nullptr;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const unsigned int varid = vartok->varId();
|
const unsigned int varid = vartok->varId();
|
||||||
if (varid == 0U)
|
if (varid == 0U)
|
||||||
continue;
|
continue;
|
||||||
|
@ -821,11 +830,11 @@ static void valueFlowAfterCondition(TokenList *tokenlist, ErrorLogger *errorLogg
|
||||||
Token *startToken = nullptr;
|
Token *startToken = nullptr;
|
||||||
if (Token::Match(tok, "==|>=|<=|!") && Token::simpleMatch(top->link(), ") {"))
|
if (Token::Match(tok, "==|>=|<=|!") && Token::simpleMatch(top->link(), ") {"))
|
||||||
startToken = top->link()->next();
|
startToken = top->link()->next();
|
||||||
else if (tok->str() == "!=" && Token::simpleMatch(top->link()->linkAt(1), "} else {"))
|
else if (Token::Match(tok, "%var%|!=") && Token::simpleMatch(top->link()->linkAt(1), "} else {"))
|
||||||
startToken = top->link()->linkAt(1)->tokAt(2);
|
startToken = top->link()->linkAt(1)->tokAt(2);
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
if (startToken)
|
if (startToken)
|
||||||
ok &= valueFlowForward(startToken->next(), startToken->link(), var, varid, values, true, tokenlist, errorLogger, settings);
|
ok = valueFlowForward(startToken->next(), startToken->link(), var, varid, values, true, tokenlist, errorLogger, settings);
|
||||||
|
|
||||||
// After conditional code..
|
// After conditional code..
|
||||||
if (ok && !scopeEnd.empty() && Token::simpleMatch(top->link(), ") {")) {
|
if (ok && !scopeEnd.empty() && Token::simpleMatch(top->link(), ") {")) {
|
||||||
|
|
|
@ -761,6 +761,16 @@ private:
|
||||||
"}";
|
"}";
|
||||||
ASSERT_EQUALS(true, testValueOfX(code, 2U, 0));
|
ASSERT_EQUALS(true, testValueOfX(code, 2U, 0));
|
||||||
|
|
||||||
|
// if (var)
|
||||||
|
code = "void f(int x) {\n"
|
||||||
|
" if (x) { a = x; }\n" // <- x is not 0
|
||||||
|
" else { b = x; }\n" // <- x is 0
|
||||||
|
" c = x;\n" // <- x might be 0
|
||||||
|
"}";
|
||||||
|
ASSERT_EQUALS(false, testValueOfX(code, 2U, 0));
|
||||||
|
ASSERT_EQUALS(true, testValueOfX(code, 3U, 0));
|
||||||
|
ASSERT_EQUALS(true, testValueOfX(code, 4U, 0));
|
||||||
|
|
||||||
// After while
|
// After while
|
||||||
code = "void f(int x) {\n"
|
code = "void f(int x) {\n"
|
||||||
" while (x != 3) {}\n"
|
" while (x != 3) {}\n"
|
||||||
|
|
Loading…
Reference in New Issue