Refactoring, reuse and improve isVariableChangedByFunction()
This commit is contained in:
parent
9191e6f112
commit
8fe4852b98
|
@ -398,6 +398,16 @@ bool isReturnScope(const Token * const endToken)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isVariableChangedByFunctionCall(const Token *tok, unsigned int varid, const Settings *settings, bool *inconclusive)
|
||||||
|
{
|
||||||
|
if (!tok)
|
||||||
|
return false;
|
||||||
|
if (tok->varId() == varid)
|
||||||
|
return isVariableChangedByFunctionCall(tok, settings, inconclusive);
|
||||||
|
return isVariableChangedByFunctionCall(tok->astOperand1(), varid, settings, inconclusive) ||
|
||||||
|
isVariableChangedByFunctionCall(tok->astOperand2(), varid, settings, inconclusive);
|
||||||
|
}
|
||||||
|
|
||||||
bool isVariableChangedByFunctionCall(const Token *tok, const Settings *settings, bool *inconclusive)
|
bool isVariableChangedByFunctionCall(const Token *tok, const Settings *settings, bool *inconclusive)
|
||||||
{
|
{
|
||||||
if (!tok)
|
if (!tok)
|
||||||
|
@ -411,7 +421,17 @@ bool isVariableChangedByFunctionCall(const Token *tok, const Settings *settings,
|
||||||
;
|
;
|
||||||
else if (Token::Match(tok->tokAt(addressOf?-2:-1), "[(,] &| %name% [,)]"))
|
else if (Token::Match(tok->tokAt(addressOf?-2:-1), "[(,] &| %name% [,)]"))
|
||||||
;
|
;
|
||||||
else
|
else if (Token::Match(tok->tokAt(addressOf?-2:-1), "[?:] &| %name% [:,)]")) {
|
||||||
|
const Token *parent = tok->astParent();
|
||||||
|
if (parent == tok->previous() && parent->str() == "&")
|
||||||
|
parent = parent->astParent();
|
||||||
|
while (Token::Match(parent, "[?:]"))
|
||||||
|
parent = parent->astParent();
|
||||||
|
while (Token::simpleMatch(parent, ","))
|
||||||
|
parent = parent->astParent();
|
||||||
|
if (!parent || parent->str() != "(")
|
||||||
|
return false;
|
||||||
|
} else
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// reinterpret_cast etc..
|
// reinterpret_cast etc..
|
||||||
|
|
|
@ -74,6 +74,17 @@ bool isWithoutSideEffects(bool cpp, const Token* tok);
|
||||||
/** Is scope a return scope (scope will unconditionally return) */
|
/** Is scope a return scope (scope will unconditionally return) */
|
||||||
bool isReturnScope(const Token *endToken);
|
bool isReturnScope(const Token *endToken);
|
||||||
|
|
||||||
|
/** Is variable changed by function call?
|
||||||
|
* In case the answer of the question is inconclusive, e.g. because the function declaration is not known
|
||||||
|
* the return value is false and the output parameter inconclusive is set to true
|
||||||
|
*
|
||||||
|
* @param tok ast tree
|
||||||
|
* @param varid Variable Id
|
||||||
|
* @param settings program settings
|
||||||
|
* @param inconclusive pointer to output variable which indicates that the answer of the question is inconclusive
|
||||||
|
*/
|
||||||
|
bool isVariableChangedByFunctionCall(const Token *tok, unsigned int varid, const Settings *settings, bool *inconclusive);
|
||||||
|
|
||||||
/** Is variable changed by function call?
|
/** Is variable changed by function call?
|
||||||
* In case the answer of the question is inconclusive, e.g. because the function declaration is not known
|
* In case the answer of the question is inconclusive, e.g. because the function declaration is not known
|
||||||
* the return value is false and the output parameter inconclusive is set to true
|
* the return value is false and the output parameter inconclusive is set to true
|
||||||
|
|
|
@ -115,27 +115,6 @@ static void changeKnownToPossible(std::list<ValueFlow::Value> &values)
|
||||||
it->changeKnownToPossible();
|
it->changeKnownToPossible();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool mightBeNonConstPointerFunctionArg(const Token *tok)
|
|
||||||
{
|
|
||||||
// TODO: check if argument might be non-const pointer
|
|
||||||
const Token *parent = tok->astParent();
|
|
||||||
while (parent && parent->str() == ",")
|
|
||||||
parent = parent->astParent();
|
|
||||||
return (parent && Token::Match(parent->previous(), "%name% ("));
|
|
||||||
}
|
|
||||||
|
|
||||||
static const Token *findVariableInAST(const Token *tok, unsigned int varid)
|
|
||||||
{
|
|
||||||
if (!tok)
|
|
||||||
return nullptr;
|
|
||||||
if (tok->varId() == varid)
|
|
||||||
return tok;
|
|
||||||
const Token *ret1 = findVariableInAST(tok->astOperand1(), varid);
|
|
||||||
if (ret1)
|
|
||||||
return ret1;
|
|
||||||
return findVariableInAST(tok->astOperand2(), varid);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is condition always false when variable has given value?
|
* Is condition always false when variable has given value?
|
||||||
* \param condition top ast token in condition
|
* \param condition top ast token in condition
|
||||||
|
@ -1858,7 +1837,7 @@ static bool valueFlowForward(Token * const startToken,
|
||||||
std::list<ValueFlow::Value>::const_iterator it;
|
std::list<ValueFlow::Value>::const_iterator it;
|
||||||
for (it = values.begin(); it != values.end(); ++it)
|
for (it = values.begin(); it != values.end(); ++it)
|
||||||
valueFlowAST(const_cast<Token*>(expr), varid, *it, settings);
|
valueFlowAST(const_cast<Token*>(expr), varid, *it, settings);
|
||||||
if ((expr->valueType() && expr->valueType()->pointer) && mightBeNonConstPointerFunctionArg(tok2) && findVariableInAST(expr,varid))
|
if (isVariableChangedByFunctionCall(expr, varid, settings, nullptr))
|
||||||
changeKnownToPossible(values);
|
changeKnownToPossible(values);
|
||||||
} else {
|
} else {
|
||||||
std::list<ValueFlow::Value>::const_iterator it;
|
std::list<ValueFlow::Value>::const_iterator it;
|
||||||
|
@ -1871,8 +1850,7 @@ static bool valueFlowForward(Token * const startToken,
|
||||||
else
|
else
|
||||||
valueFlowAST(const_cast<Token*>(op2), varid, *it, settings);
|
valueFlowAST(const_cast<Token*>(op2), varid, *it, settings);
|
||||||
}
|
}
|
||||||
|
if (isVariableChangedByFunctionCall(op2, varid, settings, nullptr))
|
||||||
if (mightBeNonConstPointerFunctionArg(tok2) && findVariableInAST(op2,varid))
|
|
||||||
changeKnownToPossible(values);
|
changeKnownToPossible(values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue