@@ -169,11 +169,13 @@ static void bailoutInternal(TokenList *tokenlist, ErrorLogger *errorLogger, cons
169169#define bailout (tokenlist, errorLogger, tok, what ) bailoutInternal(tokenlist, errorLogger, tok, what, __FILE__, __LINE__, " (valueFlow)" )
170170#endif
171171
172- static void changeKnownToPossible (std::list<ValueFlow::Value> &values)
172+ static void changeKnownToPossible (std::list<ValueFlow::Value> &values, int indirect=- 1 )
173173{
174- std::list<ValueFlow::Value>::iterator it;
175- for (it = values.begin (); it != values.end (); ++it)
176- it->changeKnownToPossible ();
174+ for (ValueFlow::Value& v: values) {
175+ if (indirect >= 0 && v.indirect != indirect)
176+ continue ;
177+ v.changeKnownToPossible ();
178+ }
177179}
178180
179181/* *
@@ -1690,7 +1692,7 @@ static void valueFlowReverse(TokenList *tokenlist,
16901692
16911693 // assigned by subfunction?
16921694 bool inconclusive = false ;
1693- if (isVariableChangedByFunctionCall (tok2, settings, &inconclusive)) {
1695+ if (isVariableChangedByFunctionCall (tok2, std::max (val. indirect , val2. indirect ), settings, &inconclusive)) {
16941696 if (settings->debugwarnings )
16951697 bailout (tokenlist, errorLogger, tok2, " possible assignment of " + tok2->str () + " by subfunction" );
16961698 break ;
@@ -2071,6 +2073,15 @@ static bool isAliasOf(const Variable * var, const Token *tok, nonneg int varid,
20712073 return false ;
20722074}
20732075
2076+ static std::set<int > getIndirections (const std::list<ValueFlow::Value>& values)
2077+ {
2078+ std::set<int > result;
2079+ std::transform (values.begin (), values.end (), std::inserter (result, result.end ()), [](const ValueFlow::Value& v) {
2080+ return std::max (0 , v.indirect );
2081+ });
2082+ return result;
2083+ }
2084+
20742085static bool valueFlowForward (Token * const startToken,
20752086 const Token * const endToken,
20762087 const Variable * const var,
@@ -2204,16 +2215,21 @@ static bool valueFlowForward(Token * const startToken,
22042215 // conditional block of code that assigns variable..
22052216 else if (!tok2->varId () && Token::Match (tok2, " %name% (" ) && Token::simpleMatch (tok2->linkAt (1 ), " ) {" )) {
22062217 // is variable changed in condition?
2207- Token* tokChanged = findVariableChanged (tok2->next (), tok2->next ()->link (), varid, var->isGlobal (), settings, tokenlist->isCPP ());
2208- if (tokChanged != nullptr ) {
2209- // Set the value before bailing
2210- if (tokChanged->varId () == varid) {
2211- for (const ValueFlow::Value &v : values) {
2212- if (!v.isNonValue ())
2213- continue ;
2214- setTokenValue (tokChanged, v, settings);
2218+ for (int i:getIndirections (values)) {
2219+ Token* tokChanged = findVariableChanged (tok2->next (), tok2->next ()->link (), i, varid, var->isGlobal (), settings, tokenlist->isCPP ());
2220+ if (tokChanged != nullptr ) {
2221+ // Set the value before bailing
2222+ if (tokChanged->varId () == varid) {
2223+ for (const ValueFlow::Value &v : values) {
2224+ if (!v.isNonValue ())
2225+ continue ;
2226+ setTokenValue (tokChanged, v, settings);
2227+ }
22152228 }
2229+ values.remove_if ([&](const ValueFlow::Value& v) { return v.indirect == i; });
22162230 }
2231+ }
2232+ if (values.empty ()) {
22172233 if (settings->debugwarnings )
22182234 bailout (tokenlist, errorLogger, tok2, " variable " + var->name () + " valueFlowForward, assignment in condition" );
22192235 return false ;
@@ -2534,8 +2550,10 @@ static bool valueFlowForward(Token * const startToken,
25342550 Token *expr = (condValue.intvalue != 0 ) ? op2->astOperand1 () : op2->astOperand2 ();
25352551 for (const ValueFlow::Value &v : values)
25362552 valueFlowAST (expr, varid, v, settings);
2537- if (isVariableChangedByFunctionCall (expr, varid, settings, nullptr ))
2538- changeKnownToPossible (values);
2553+ if (isVariableChangedByFunctionCall (expr, 0 , varid, settings, nullptr ))
2554+ changeKnownToPossible (values, 0 );
2555+ if (isVariableChangedByFunctionCall (expr, 1 , varid, settings, nullptr ))
2556+ changeKnownToPossible (values, 1 );
25392557 } else {
25402558 for (const ValueFlow::Value &v : values) {
25412559 const ProgramMemory programMemory (getProgramMemory (tok2, varid, v));
@@ -2730,16 +2748,24 @@ static bool valueFlowForward(Token * const startToken,
27302748 }
27312749
27322750 // assigned by subfunction?
2733- bool inconclusive = false ;
2734- if (isVariableChangedByFunctionCall (tok2, settings, &inconclusive)) {
2751+ for (int i:getIndirections (values)) {
2752+ bool inconclusive = false ;
2753+ if (isVariableChangedByFunctionCall (tok2, i, settings, &inconclusive)) {
2754+ values.remove_if ([&](const ValueFlow::Value& v) { return v.indirect <= i; });
2755+ }
2756+ if (inconclusive) {
2757+ for (ValueFlow::Value &v : values) {
2758+ if (v.indirect != i)
2759+ continue ;
2760+ v.setInconclusive ();
2761+ }
2762+ }
2763+ }
2764+ if (values.empty ()) {
27352765 if (settings->debugwarnings )
27362766 bailout (tokenlist, errorLogger, tok2, " possible assignment of " + tok2->str () + " by subfunction" );
27372767 return false ;
27382768 }
2739- if (inconclusive) {
2740- for (ValueFlow::Value &v : values)
2741- v.setInconclusive ();
2742- }
27432769 if (tok2->strAt (1 ) == " ." && tok2->next ()->originalName () != " ->" ) {
27442770 if (settings->inconclusive ) {
27452771 for (ValueFlow::Value &v : values)
@@ -2751,10 +2777,12 @@ static bool valueFlowForward(Token * const startToken,
27512777 }
27522778 }
27532779 // Variable changed
2754- if (isVariableChanged (tok2, settings, tokenlist->isCPP ())) {
2755- values.remove_if (std::mem_fn (&ValueFlow::Value::isUninitValue));
2756- }
2757- } else if (isAliasOf (var, tok2, varid, values) && isVariableChanged (tok2, settings, tokenlist->isCPP ())) {
2780+ for (int i:getIndirections (values)) {
2781+ // Remove unintialized values if modified
2782+ if (isVariableChanged (tok2, i, settings, tokenlist->isCPP ()))
2783+ values.remove_if ([&](const ValueFlow::Value& v) { return v.isUninitValue () && v.indirect <= i; });
2784+ }
2785+ } else if (isAliasOf (var, tok2, varid, values) && isVariableChanged (tok2, 0 , settings, tokenlist->isCPP ())) {
27582786 if (settings->debugwarnings )
27592787 bailout (tokenlist, errorLogger, tok2, " Alias variable was modified." );
27602788 // Bail at the end of the statement if its in an assignment
0 commit comments