ValueFlow: Value of expression after condition

This commit is contained in:
Daniel Marjamäki 2018-12-31 17:37:38 +01:00
parent 9dc8faa3b6
commit 4918a18bfb
2 changed files with 19 additions and 3 deletions

View File

@ -4657,14 +4657,20 @@ static void valueFlowContainerAfterCondition(TokenList *tokenlist,
static void valueFlowFwdAnalysis(const TokenList *tokenlist, const Settings *settings) static void valueFlowFwdAnalysis(const TokenList *tokenlist, const Settings *settings)
{ {
for (const Token *tok = tokenlist->front(); tok; tok = tok->next()) { for (const Token *tok = tokenlist->front(); tok; tok = tok->next()) {
if (tok->str() != "=" || !tok->astOperand1() || !tok->astOperand2()) if (!Token::Match(tok, "=|==") || !tok->astOperand1() || !tok->astOperand2())
continue; continue;
if (!tok->scope()->isExecutable()) if (!tok->scope()->isExecutable())
continue; continue;
if (!tok->astOperand2()->hasKnownIntValue()) if (!tok->astOperand2()->hasKnownIntValue())
continue; continue;
const bool assign = tok->isAssignmentOp();
ValueFlow::Value v(tok->astOperand2()->values().front()); ValueFlow::Value v(tok->astOperand2()->values().front());
if (assign)
v.errorPath.emplace_back(tok, tok->astOperand1()->expressionString() + " is assigned value " + MathLib::toString(v.intvalue)); v.errorPath.emplace_back(tok, tok->astOperand1()->expressionString() + " is assigned value " + MathLib::toString(v.intvalue));
else {
v.errorPath.emplace_back(tok, "Assuming that " + tok->astOperand1()->expressionString() + " has the value " + MathLib::toString(v.intvalue));
v.condition = tok;
}
FwdAnalysisAllPaths fwdAnalysis(tokenlist->isCPP(), settings->library); FwdAnalysisAllPaths fwdAnalysis(tokenlist->isCPP(), settings->library);
const Token *startToken = tok->findExpressionStartEndTokens().second->next(); const Token *startToken = tok->findExpressionStartEndTokens().second->next();
const Scope *functionScope = tok->scope(); const Scope *functionScope = tok->scope();
@ -4675,7 +4681,7 @@ static void valueFlowFwdAnalysis(const TokenList *tokenlist, const Settings *set
const Scope *s = tok2->scope(); const Scope *s = tok2->scope();
while (s && s != tok->scope()) while (s && s != tok->scope())
s = s->nestedIn; s = s->nestedIn;
v.valueKind = s ? ValueFlow::Value::ValueKind::Known : ValueFlow::Value::ValueKind::Possible; v.valueKind = assign && s ? ValueFlow::Value::ValueKind::Known : ValueFlow::Value::ValueKind::Possible;
setTokenValue(const_cast<Token *>(tok2), v, settings); setTokenValue(const_cast<Token *>(tok2), v, settings);
} }
} }

View File

@ -2369,6 +2369,16 @@ private:
ASSERT_EQUALS(true, values.front().isKnown()); ASSERT_EQUALS(true, values.front().isKnown());
ASSERT_EQUALS(true, values.front().isIntValue()); ASSERT_EQUALS(true, values.front().isIntValue());
ASSERT_EQUALS(1, values.front().intvalue); ASSERT_EQUALS(1, values.front().intvalue);
code = "void f(const Foo foo) {\n"
" if (foo.x == 2) {}\n"
" x = 0 + foo.x;\n" // <- foo.x might be 2
"}";
values = tokenValues(code, "+");
ASSERT_EQUALS(1U, values.size());
ASSERT_EQUALS(false, values.front().isKnown());
ASSERT_EQUALS(true, values.front().isIntValue());
ASSERT_EQUALS(2, values.front().intvalue);
} }
void valueFlowSwitchVariable() { void valueFlowSwitchVariable() {