@@ -803,11 +803,11 @@ static void setTokenValue(Token* tok, ValueFlow::Value value, const Settings* se
803803 // increment
804804 else if (parent->str () == " ++" ) {
805805 for (const ValueFlow::Value &val : tok->values ()) {
806- if (!val.isIntValue () && !val.isFloatValue ())
806+ if (!val.isIntValue () && !val.isFloatValue () && !val. isSymbolicValue () )
807807 continue ;
808808 ValueFlow::Value v (val);
809809 if (parent == tok->previous ()) {
810- if (v.isIntValue ())
810+ if (v.isIntValue () || v. isSymbolicValue () )
811811 v.intvalue = v.intvalue + 1 ;
812812 else
813813 v.floatValue = v.floatValue + 1.0 ;
@@ -819,11 +819,11 @@ static void setTokenValue(Token* tok, ValueFlow::Value value, const Settings* se
819819 // decrement
820820 else if (parent->str () == " --" ) {
821821 for (const ValueFlow::Value &val : tok->values ()) {
822- if (!val.isIntValue () && !val.isFloatValue ())
822+ if (!val.isIntValue () && !val.isFloatValue () && !val. isSymbolicValue () )
823823 continue ;
824824 ValueFlow::Value v (val);
825825 if (parent == tok->previous ()) {
826- if (v.isIntValue ())
826+ if (v.isIntValue () || v. isSymbolicValue () )
827827 v.intvalue = v.intvalue - 1 ;
828828 else
829829 v.floatValue = v.floatValue - 1.0 ;
@@ -2080,7 +2080,7 @@ struct ValueFlowAnalyzer : Analyzer {
20802080 // Check if its assigned to the same value
20812081 if (value && !value->isImpossible () && Token::simpleMatch (tok->astParent (), " =" ) && astIsLHS (tok) &&
20822082 astIsIntegral (tok->astParent ()->astOperand2 (), false )) {
2083- std::vector<int > result = evaluate (Evaluate::Integral, tok->astParent ()->astOperand2 ());
2083+ std::vector<MathLib::bigint > result = evaluate (Evaluate::Integral, tok->astParent ()->astOperand2 ());
20842084 if (!result.empty () && value->equalTo (result.front ()))
20852085 return Action::Idempotent;
20862086 }
@@ -2188,22 +2188,48 @@ struct ValueFlowAnalyzer : Analyzer {
21882188 return true ;
21892189 }
21902190
2191- bool isSameSymbolicValue (const Token* tok, ErrorPath* errorPath = nullptr ) const
2191+ const Token* findMatch (const Token* tok) const
2192+ {
2193+ return findAstNode (tok, [&](const Token* child) {
2194+ return match (child);
2195+ });
2196+ }
2197+
2198+ bool isSameSymbolicValue (const Token* tok, ValueFlow::Value* value = nullptr ) const
21922199 {
21932200 if (!useSymbolicValues ())
21942201 return false ;
21952202 if (Token::Match (tok, " %assign%" ))
21962203 return false ;
2204+ const ValueFlow::Value* currValue = getValue (tok);
2205+ if (!currValue)
2206+ return false ;
2207+ const bool exact = !currValue->isIntValue () || currValue->isImpossible ();
21972208 for (const ValueFlow::Value& v : tok->values ()) {
21982209 if (!v.isSymbolicValue ())
21992210 continue ;
2200- if (!v.isKnown ())
2211+ const bool toImpossible = v.isImpossible () && currValue->isKnown ();
2212+ if (!v.isKnown () && !toImpossible)
22012213 continue ;
2202- if (v.intvalue != 0 )
2214+ if (exact && v.intvalue != 0 )
22032215 continue ;
2216+ std::vector<MathLib::bigint> r;
2217+ ValueFlow::Value::Bound bound = currValue->bound ;
22042218 if (match (v.tokvalue )) {
2205- if (errorPath)
2206- errorPath->insert (errorPath->end (), v.errorPath .begin (), v.errorPath .end ());
2219+ r = {currValue->intvalue };
2220+ } else if (!exact && findMatch (v.tokvalue )) {
2221+ r = evaluate (Evaluate::Integral, v.tokvalue , tok);
2222+ if (bound == ValueFlow::Value::Bound::Point)
2223+ bound = v.bound ;
2224+ }
2225+ if (!r.empty ()) {
2226+ if (value) {
2227+ value->errorPath .insert (value->errorPath .end (), v.errorPath .begin (), v.errorPath .end ());
2228+ value->intvalue = r.front () + v.intvalue ;
2229+ if (toImpossible)
2230+ value->setImpossible ();
2231+ value->bound = bound;
2232+ }
22072233 return true ;
22082234 }
22092235 }
@@ -2302,11 +2328,12 @@ struct ValueFlowAnalyzer : Analyzer {
23022328 return Action::None;
23032329 }
23042330
2305- virtual std::vector<int > evaluate (Evaluate e, const Token* tok, const Token* ctx = nullptr ) const OVERRIDE {
2331+ virtual std::vector<MathLib::bigint> evaluate (Evaluate e, const Token* tok, const Token* ctx = nullptr ) const OVERRIDE
2332+ {
23062333 if (e == Evaluate::Integral) {
23072334 if (tok->hasKnownIntValue ())
23082335 return {static_cast <int >(tok->values ().front ().intvalue )};
2309- std::vector<int > result;
2336+ std::vector<MathLib::bigint > result;
23102337 ProgramMemory pm = pms.get (tok, ctx, getProgramState ());
23112338 if (Token::Match (tok, " &&|%oror%" )) {
23122339 if (conditionIsTrue (tok, pm))
@@ -2384,7 +2411,7 @@ struct ValueFlowAnalyzer : Analyzer {
23842411 // Make a copy of the value to modify it
23852412 localValue = *value;
23862413 value = &localValue;
2387- isSameSymbolicValue (tok, &value-> errorPath );
2414+ isSameSymbolicValue (tok, &localValue );
23882415 }
23892416 // Read first when moving forward
23902417 if (d == Direction::Forward && a.isRead ())
0 commit comments