Improved isVariableChangedByFunctionCall, better logic when parameter might be passed by reference
This commit is contained in:
parent
857681a049
commit
14a0031e88
|
@ -811,6 +811,8 @@ bool isVariableChangedByFunctionCall(const Token *tok, const Settings *settings,
|
||||||
if (!tok)
|
if (!tok)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
const Token * const tok1 = tok;
|
||||||
|
|
||||||
// address of variable
|
// address of variable
|
||||||
const bool addressOf = tok->astParent() && tok->astParent()->isUnaryOp("&");
|
const bool addressOf = tok->astParent() && tok->astParent()->isUnaryOp("&");
|
||||||
|
|
||||||
|
@ -844,10 +846,13 @@ bool isVariableChangedByFunctionCall(const Token *tok, const Settings *settings,
|
||||||
tok = tok->link();
|
tok = tok->link();
|
||||||
else if (Token::Match(tok->previous(), "%name% ("))
|
else if (Token::Match(tok->previous(), "%name% ("))
|
||||||
break;
|
break;
|
||||||
|
else if (Token::simpleMatch(tok->previous(), "> (") && tok->previous()->link())
|
||||||
|
break;
|
||||||
tok = tok->previous();
|
tok = tok->previous();
|
||||||
}
|
}
|
||||||
if (!tok || tok->str() != "(")
|
if (!tok || tok->str() != "(")
|
||||||
return false;
|
return false;
|
||||||
|
const bool possiblyPassedByReference = (tok->next() == tok1 || Token::simpleMatch(tok->previous(), ", %name% [,)]"));
|
||||||
tok = tok->previous();
|
tok = tok->previous();
|
||||||
if (tok && tok->link() && tok->str() == ">")
|
if (tok && tok->link() && tok->str() == ">")
|
||||||
tok = tok->link()->previous();
|
tok = tok->link()->previous();
|
||||||
|
@ -879,12 +884,13 @@ bool isVariableChangedByFunctionCall(const Token *tok, const Settings *settings,
|
||||||
// => it is assumed that parameter is an in parameter (TODO: this is a bad heuristic)
|
// => it is assumed that parameter is an in parameter (TODO: this is a bad heuristic)
|
||||||
if (!addressOf && settings && settings->library.isnullargbad(tok, 1+argnr))
|
if (!addressOf && settings && settings->library.isnullargbad(tok, 1+argnr))
|
||||||
return false;
|
return false;
|
||||||
// addressOf => inconclusive
|
// possible pass-by-reference => inconclusive
|
||||||
if (!addressOf) {
|
if (possiblyPassedByReference) {
|
||||||
if (inconclusive != nullptr)
|
if (inconclusive != nullptr)
|
||||||
*inconclusive = true;
|
*inconclusive = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
// Safe guess: Assume that parameter is changed by function call
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -135,7 +135,7 @@ private:
|
||||||
"}";
|
"}";
|
||||||
inconclusive = false;
|
inconclusive = false;
|
||||||
ASSERT_EQUALS(false, isVariableChangedByFunctionCall(code, "x ) ;", &inconclusive));
|
ASSERT_EQUALS(false, isVariableChangedByFunctionCall(code, "x ) ;", &inconclusive));
|
||||||
// FIXME : ASSERT_EQUALS(true, inconclusive);
|
ASSERT_EQUALS(true, inconclusive);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nextAfterAstRightmostLeaf(const char code[], const char parentPattern[], const char rightPattern[]) {
|
bool nextAfterAstRightmostLeaf(const char code[], const char parentPattern[], const char rightPattern[]) {
|
||||||
|
|
Loading…
Reference in New Issue