Skip to content

Commit 8fe4852

Browse files
committed
Refactoring, reuse and improve isVariableChangedByFunction()
1 parent 9191e6f commit 8fe4852

3 files changed

Lines changed: 34 additions & 25 deletions

File tree

lib/astutils.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,16 @@ bool isReturnScope(const Token * const endToken)
398398
return false;
399399
}
400400

401+
bool isVariableChangedByFunctionCall(const Token *tok, unsigned int varid, const Settings *settings, bool *inconclusive)
402+
{
403+
if (!tok)
404+
return false;
405+
if (tok->varId() == varid)
406+
return isVariableChangedByFunctionCall(tok, settings, inconclusive);
407+
return isVariableChangedByFunctionCall(tok->astOperand1(), varid, settings, inconclusive) ||
408+
isVariableChangedByFunctionCall(tok->astOperand2(), varid, settings, inconclusive);
409+
}
410+
401411
bool isVariableChangedByFunctionCall(const Token *tok, const Settings *settings, bool *inconclusive)
402412
{
403413
if (!tok)
@@ -411,7 +421,17 @@ bool isVariableChangedByFunctionCall(const Token *tok, const Settings *settings,
411421
;
412422
else if (Token::Match(tok->tokAt(addressOf?-2:-1), "[(,] &| %name% [,)]"))
413423
;
414-
else
424+
else if (Token::Match(tok->tokAt(addressOf?-2:-1), "[?:] &| %name% [:,)]")) {
425+
const Token *parent = tok->astParent();
426+
if (parent == tok->previous() && parent->str() == "&")
427+
parent = parent->astParent();
428+
while (Token::Match(parent, "[?:]"))
429+
parent = parent->astParent();
430+
while (Token::simpleMatch(parent, ","))
431+
parent = parent->astParent();
432+
if (!parent || parent->str() != "(")
433+
return false;
434+
} else
415435
return false;
416436

417437
// reinterpret_cast etc..

lib/astutils.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,17 @@ bool isWithoutSideEffects(bool cpp, const Token* tok);
7474
/** Is scope a return scope (scope will unconditionally return) */
7575
bool isReturnScope(const Token *endToken);
7676

77+
/** Is variable changed by function call?
78+
* In case the answer of the question is inconclusive, e.g. because the function declaration is not known
79+
* the return value is false and the output parameter inconclusive is set to true
80+
*
81+
* @param tok ast tree
82+
* @param varid Variable Id
83+
* @param settings program settings
84+
* @param inconclusive pointer to output variable which indicates that the answer of the question is inconclusive
85+
*/
86+
bool isVariableChangedByFunctionCall(const Token *tok, unsigned int varid, const Settings *settings, bool *inconclusive);
87+
7788
/** Is variable changed by function call?
7889
* In case the answer of the question is inconclusive, e.g. because the function declaration is not known
7990
* the return value is false and the output parameter inconclusive is set to true

lib/valueflow.cpp

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -115,27 +115,6 @@ static void changeKnownToPossible(std::list<ValueFlow::Value> &values)
115115
it->changeKnownToPossible();
116116
}
117117

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-
139118
/**
140119
* Is condition always false when variable has given value?
141120
* \param condition top ast token in condition
@@ -1858,7 +1837,7 @@ static bool valueFlowForward(Token * const startToken,
18581837
std::list<ValueFlow::Value>::const_iterator it;
18591838
for (it = values.begin(); it != values.end(); ++it)
18601839
valueFlowAST(const_cast<Token*>(expr), varid, *it, settings);
1861-
if ((expr->valueType() && expr->valueType()->pointer) && mightBeNonConstPointerFunctionArg(tok2) && findVariableInAST(expr,varid))
1840+
if (isVariableChangedByFunctionCall(expr, varid, settings, nullptr))
18621841
changeKnownToPossible(values);
18631842
} else {
18641843
std::list<ValueFlow::Value>::const_iterator it;
@@ -1871,8 +1850,7 @@ static bool valueFlowForward(Token * const startToken,
18711850
else
18721851
valueFlowAST(const_cast<Token*>(op2), varid, *it, settings);
18731852
}
1874-
1875-
if (mightBeNonConstPointerFunctionArg(tok2) && findVariableInAST(op2,varid))
1853+
if (isVariableChangedByFunctionCall(op2, varid, settings, nullptr))
18761854
changeKnownToPossible(values);
18771855
}
18781856

0 commit comments

Comments
 (0)