Fixed #8187 (isVariableChangedByFunctionCall: Constructor reference argument)

This commit is contained in:
Daniel Marjamäki 2017-09-20 12:53:25 +02:00
parent 87c35cd60e
commit 4318521fc1
2 changed files with 41 additions and 2 deletions

View File

@ -411,8 +411,31 @@ bool isVariableChangedByFunctionCall(const Token *tok, const Settings *settings,
if (!Token::Match(tok, "%name% ("))
return false; // not a function => variable not changed
if (tok->varId())
return false; // Constructor call of tok => variable probably not changed by constructor call
// Constructor call
if (tok->variable() && tok->variable()->nameToken() == tok) {
// Find constructor..
unsigned int numberOfArguments = Token::simpleMatch(tok->next(), "( )") ? 0 : 1;
for (const Token *tok2 = tok->tokAt(2); tok2; tok2 = tok2->next()) {
if (tok2->str() == "(")
tok2 = tok2->link();
else if (tok2->str() == ",")
++numberOfArguments;
}
const ::Scope *typeScope = tok->variable()->typeScope();
if (typeScope) {
for (std::list<Function>::const_iterator it = typeScope->functionList.begin(); it != typeScope->functionList.end(); ++it) {
if (!it->isConstructor() || it->argCount() != numberOfArguments)
continue;
const Variable *arg = it->getArgumentVar(argnr);
if (arg && arg->isReference())
return true;
}
return false;
}
if (inconclusive)
*inconclusive = true;
return false;
}
if (!tok->function()) {
// if the library says 0 is invalid

View File

@ -78,6 +78,7 @@ private:
TEST_CASE(valueFlowAfterCondition);
TEST_CASE(valueFlowForwardCompoundAssign);
TEST_CASE(valueFlowForwardCorrelatedVariables);
TEST_CASE(valueFlowForwardFunction);
TEST_CASE(valueFlowForwardLambda);
TEST_CASE(valueFlowSwitchVariable);
@ -1798,6 +1799,21 @@ private:
ASSERT_EQUALS(false, testValueOfX(code, 4U, 0));
}
void valueFlowForwardFunction() {
const char *code;
code = "class C {\n"
"public:\n"
" C(int &i);\n"
"};\n"
"int f() {\n"
" int x=1;\n"
" C c(x);\n"
" return x;\n"
"}";
ASSERT_EQUALS(false, testValueOfX(code, 8U, 1));
}
void valueFlowForwardLambda() {
const char *code;