@@ -108,6 +108,34 @@ static void bailoutInternal(TokenList *tokenlist, ErrorLogger *errorLogger, cons
108108#define bailout (tokenlist, errorLogger, tok, what ) bailoutInternal(tokenlist, errorLogger, tok, what, __FILE__, __LINE__, " (valueFlow)" )
109109#endif
110110
111+ static void changeKnownToPossible (std::list<ValueFlow::Value> &values)
112+ {
113+ std::list<ValueFlow::Value>::iterator it;
114+ for (it = values.begin (); it != values.end (); ++it)
115+ it->changeKnownToPossible ();
116+ }
117+
118+ static bool mightBeNonConstPointerFunctionArg (const Token *tok)
119+ {
120+ // TODO: check if argument might be non-const pointer
121+ const Token *parent = tok->astParent ();
122+ while (parent && parent->str () == " ," )
123+ parent = parent->astParent ();
124+ return (parent && Token::Match (parent->previous (), " %name% (" ));
125+ }
126+
127+ static const Token *findVariableInAST (const Token *tok, unsigned int varid)
128+ {
129+ if (!tok)
130+ return nullptr ;
131+ if (tok->varId () == varid)
132+ return tok;
133+ const Token *ret1 = findVariableInAST (tok->astOperand1 (), varid);
134+ if (ret1)
135+ return ret1;
136+ return findVariableInAST (tok->astOperand2 (), varid);
137+ }
138+
111139/* *
112140 * Is condition always false when variable has given value?
113141 * \param condition top ast token in condition
@@ -1465,9 +1493,7 @@ static bool valueFlowForward(Token * const startToken,
14651493 Token::simpleMatch (tok2->link ()->previous (), " else {" ) &&
14661494 !isReturnScope (tok2->link ()->tokAt (-2 )) &&
14671495 isVariableChanged (tok2->link (), tok2, varid, var->isGlobal (), settings)) {
1468- std::list<ValueFlow::Value>::iterator it;
1469- for (it = values.begin (); it != values.end (); ++it)
1470- it->changeKnownToPossible ();
1496+ changeKnownToPossible (values);
14711497 }
14721498 }
14731499
@@ -1482,8 +1508,7 @@ static bool valueFlowForward(Token * const startToken,
14821508 }
14831509
14841510 if (Token::Match (tok2, " [;{}] %name% :" ) || tok2->str () == " case" ) {
1485- for (std::list<ValueFlow::Value>::iterator it = values.begin (); it != values.end (); ++it)
1486- it->changeKnownToPossible ();
1511+ changeKnownToPossible (values);
14871512 tok2 = tok2->tokAt (2 );
14881513 continue ;
14891514 }
@@ -1597,10 +1622,7 @@ static bool valueFlowForward(Token * const startToken,
15971622
15981623 if (!condAlwaysFalse && isVariableChanged (startToken1, startToken1->link (), varid, var->isGlobal (), settings)) {
15991624 removeValues (values, truevalues);
1600-
1601- std::list<ValueFlow::Value>::iterator it;
1602- for (it = values.begin (); it != values.end (); ++it)
1603- it->changeKnownToPossible ();
1625+ changeKnownToPossible (values);
16041626 }
16051627
16061628 // goto '}'
@@ -1628,10 +1650,7 @@ static bool valueFlowForward(Token * const startToken,
16281650
16291651 if (!condAlwaysTrue && isVariableChanged (startTokenElse, startTokenElse->link (), varid, var->isGlobal (), settings)) {
16301652 removeValues (values, falsevalues);
1631-
1632- std::list<ValueFlow::Value>::iterator it;
1633- for (it = values.begin (); it != values.end (); ++it)
1634- it->changeKnownToPossible ();
1653+ changeKnownToPossible (values);
16351654 }
16361655
16371656 // goto '}'
@@ -1811,9 +1830,7 @@ static bool valueFlowForward(Token * const startToken,
18111830 if (tok2 == endToken)
18121831 break ;
18131832 --indentlevel;
1814- for (std::list<ValueFlow::Value>::iterator it = values.begin (); it != values.end (); ++it) {
1815- it->changeKnownToPossible ();
1816- }
1833+ changeKnownToPossible (values);
18171834 continue ;
18181835 }
18191836 }
@@ -1841,6 +1858,8 @@ static bool valueFlowForward(Token * const startToken,
18411858 std::list<ValueFlow::Value>::const_iterator it;
18421859 for (it = values.begin (); it != values.end (); ++it)
18431860 valueFlowAST (const_cast <Token*>(expr), varid, *it, settings);
1861+ if ((expr->valueType () && expr->valueType ()->pointer ) && mightBeNonConstPointerFunctionArg (tok2) && findVariableInAST (expr,varid))
1862+ changeKnownToPossible (values);
18441863 } else {
18451864 std::list<ValueFlow::Value>::const_iterator it;
18461865 for (it = values.begin (); it != values.end (); ++it) {
@@ -1852,6 +1871,9 @@ static bool valueFlowForward(Token * const startToken,
18521871 else
18531872 valueFlowAST (const_cast <Token*>(op2), varid, *it, settings);
18541873 }
1874+
1875+ if (mightBeNonConstPointerFunctionArg (tok2) && findVariableInAST (op2,varid))
1876+ changeKnownToPossible (values);
18551877 }
18561878
18571879 // Skip conditional expressions..
@@ -2245,11 +2267,8 @@ static void valueFlowAfterAssign(TokenList *tokenlist, SymbolDatabase* symboldat
22452267 }
22462268
22472269 // Static variable initialisation?
2248- if (var->isStatic () && var->nameToken () == tok->astOperand1 ()) {
2249- for (std::list<ValueFlow::Value>::iterator it = values.begin (); it != values.end (); ++it) {
2250- it->changeKnownToPossible ();
2251- }
2252- }
2270+ if (var->isStatic () && var->nameToken () == tok->astOperand1 ())
2271+ changeKnownToPossible (values);
22532272
22542273 // Skip RHS
22552274 const Token * nextExpression = nextAfterAstRightmostLeaf (tok);
@@ -3057,9 +3076,7 @@ static void valueFlowSubFunction(TokenList *tokenlist, ErrorLogger *errorLogger,
30573076 }
30583077
30593078 // passed values are not "known"..
3060- for (std::list<ValueFlow::Value>::iterator it = argvalues.begin (); it != argvalues.end (); ++it) {
3061- it->changeKnownToPossible ();
3062- }
3079+ changeKnownToPossible (argvalues);
30633080
30643081 valueFlowInjectParameter (tokenlist, errorLogger, settings, argvar, calledFunctionScope, argvalues);
30653082 }
0 commit comments