diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index fb387c847..85b32c69d 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -4657,14 +4657,20 @@ static void valueFlowContainerAfterCondition(TokenList *tokenlist, static void valueFlowFwdAnalysis(const TokenList *tokenlist, const Settings *settings) { 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; if (!tok->scope()->isExecutable()) continue; if (!tok->astOperand2()->hasKnownIntValue()) continue; + const bool assign = tok->isAssignmentOp(); ValueFlow::Value v(tok->astOperand2()->values().front()); - v.errorPath.emplace_back(tok, tok->astOperand1()->expressionString() + " is assigned value " + MathLib::toString(v.intvalue)); + if (assign) + 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); const Token *startToken = tok->findExpressionStartEndTokens().second->next(); const Scope *functionScope = tok->scope(); @@ -4675,7 +4681,7 @@ static void valueFlowFwdAnalysis(const TokenList *tokenlist, const Settings *set const Scope *s = tok2->scope(); while (s && s != tok->scope()) 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(tok2), v, settings); } } diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index ef6308a98..be9691f1a 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -2369,6 +2369,16 @@ private: ASSERT_EQUALS(true, values.front().isKnown()); ASSERT_EQUALS(true, values.front().isIntValue()); 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() {