ValueFlow: Value of expression after condition
This commit is contained in:
parent
9dc8faa3b6
commit
4918a18bfb
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
Loading…
Reference in New Issue