Fixed #8173 (ValueFlow: use AST when setting values in assignment RHS ((n=42) && n=='A'))

This commit is contained in:
Daniel Marjamäki 2017-09-14 22:49:47 +02:00
parent 927b14b60f
commit ef1f3fbee6
2 changed files with 24 additions and 8 deletions

View File

@ -1819,16 +1819,24 @@ static bool valueFlowForward(Token * const startToken,
// bailout: assignment
else if (Token::Match(tok2->previous(), "!!* %name% %assign%")) {
// simplify rhs
for (Token *tok3 = tok2->tokAt(2); tok3; tok3 = tok3->next()) {
if (tok3->varId() == varid) {
std::stack<Token *> rhs;
rhs.push(const_cast<Token *>(tok2->next()->astOperand2()));
while (!rhs.empty()) {
Token *rtok = rhs.top();
rhs.pop();
if (!rtok)
continue;
if (rtok->str() == "(" && Token::Match(rtok->astOperand1(), "sizeof|typeof|typeid"))
continue;
if (Token::Match(rtok, "++|--|?|:|;|,"))
continue;
if (rtok->varId() == varid) {
std::list<ValueFlow::Value>::const_iterator it;
for (it = values.begin(); it != values.end(); ++it)
setTokenValue(tok3, *it, settings);
} else if (Token::Match(tok3, "++|--|?|:|;|,"))
break;
// Skip sizeof etc
else if (Token::Match(tok3, "sizeof|typeof|typeid ("))
tok3 = tok3->linkAt(1);
setTokenValue(rtok, *it, settings);
}
rhs.push(const_cast<Token *>(rtok->astOperand1()));
rhs.push(const_cast<Token *>(rtok->astOperand2()));
}
if (settings->debugwarnings)
bailout(tokenlist, errorLogger, tok2, "assignment of " + tok2->str());

View File

@ -2646,6 +2646,14 @@ private:
"}";
values = tokenValues(code, "x ; }");
ASSERT_EQUALS(true, values.empty());
// return (#8173)
code = "int repeat() {\n"
" const char *n;\n"
" return((n=42) && *n == 'A');\n"
"}";
values = tokenValues(code, "n ==");
ASSERT_EQUALS(true, values.size() != 1U || !values.front().isUninitValue());
}
};