@@ -429,22 +429,12 @@ static void fillProgramMemoryFromAssignments(ProgramMemory& pm, const Token* tok
429429 for (const Token *tok2 = tok; tok2; tok2 = tok2->previous ()) {
430430 if ((Token::simpleMatch (tok2, " =" ) || Token::Match (tok2->previous (), " %var% (|{" )) && tok2->astOperand1 () &&
431431 tok2->astOperand2 ()) {
432- bool setvar = false ;
433432 const Token* vartok = tok2->astOperand1 ();
434- for (const auto & p:vars) {
435- if (p.first .getExpressionId () != vartok->exprId ())
436- continue ;
437- if (vartok == tok)
438- continue ;
439- pm.setValue (vartok, p.second );
440- setvar = true ;
441- }
442- if (!setvar) {
443- if (!pm.hasValue (vartok->exprId ())) {
444- const Token* valuetok = tok2->astOperand2 ();
445- ProgramMemory local = state;
446- pm.setValue (vartok, execute (valuetok, local, settings, vars));
447- }
433+ if (!pm.hasValue (vartok->exprId ())) {
434+ const Token* valuetok = tok2->astOperand2 ();
435+ ProgramMemory local = state;
436+ // Tracked values are substituted by execute() when the expression is evaluated.
437+ pm.setValue (vartok, execute (valuetok, local, settings, vars));
448438 }
449439 } else if (Token::simpleMatch (tok2, " )" ) && tok2->link () &&
450440 Token::Match (tok2->link ()->previous (), " assert|ASSERT ( !!)" )) {
@@ -1647,9 +1637,14 @@ namespace {
16471637 }
16481638 return execute (expr->astOperand1 ());
16491639 }
1650- // A tracked value is the authoritative current value of its expression.
1651- if (const ValueFlow::Value* tracked = getTrackedValue (expr))
1640+ // A tracked value is the authoritative current value of its expression. Write it back
1641+ // into the program memory when it differs from what is stored, so that later reads see
1642+ // the same value (matching the substitution done by fillProgramMemoryFromAssignments).
1643+ if (const ValueFlow::Value* tracked = getTrackedValue (expr)) {
1644+ if (!pm->hasValue (expr->exprId ()) || utils::as_const (*pm).at (expr->exprId ()) != *tracked)
1645+ pm->setValue (expr, *tracked);
16521646 return *tracked;
1647+ }
16531648 if (expr->exprId () > 0 && pm->hasValue (expr->exprId ()) && !dependsOnTrackedValue (expr)) {
16541649 ValueFlow::Value result = utils::as_const (*pm).at (expr->exprId ());
16551650 if (result.isImpossible () && result.isIntValue () && result.intvalue == 0 && isUsedAsBool (expr, settings)) {
0 commit comments