Improve Fix #6180 (Do not warn about move if it is part of a reassignment of the variable)
This commit is contained in:
parent
f8cfa72159
commit
f4ab45f13b
|
@ -1736,6 +1736,12 @@ static bool isStdMoveOrStdForwarded(Token * tok, ValueFlow::Value::MoveKind * mo
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool isOpenParenthesisMemberFunctionCallOfVarId(const Token * openParenthesisToken, unsigned int varId)
|
||||
{
|
||||
return Token::Match(openParenthesisToken->tokAt(-3),"%varid% . %name% (", varId) &&
|
||||
openParenthesisToken->tokAt(-2)->originalName() == emptyString;
|
||||
}
|
||||
|
||||
static void valueFlowAfterMove(TokenList *tokenlist, SymbolDatabase* symboldatabase, ErrorLogger *errorLogger, const Settings *settings)
|
||||
{
|
||||
if (!tokenlist->isCPP() || settings->standards.cpp < Standards::CPP11)
|
||||
|
@ -1757,15 +1763,18 @@ static void valueFlowAfterMove(TokenList *tokenlist, SymbolDatabase* symboldatab
|
|||
ValueFlow::Value::MoveKind moveKind;
|
||||
if (!isStdMoveOrStdForwarded(tok, &moveKind, &varTok))
|
||||
continue;
|
||||
const unsigned int varId = varTok->varId();
|
||||
// x is not MOVED after assignment if code is: x = ... std::move(x) .. ;
|
||||
const Token *parent = tok->astParent();
|
||||
while (parent && parent->str() != "=" && parent->str() != "return")
|
||||
while (parent && parent->str() != "=" && parent->str() != "return" &&
|
||||
!(parent->str() == "(" && isOpenParenthesisMemberFunctionCallOfVarId(parent, varId)))
|
||||
parent = parent->astParent();
|
||||
if (parent && parent->str() == "return") // MOVED in return statement
|
||||
if (parent &&
|
||||
(parent->str() == "return" || // MOVED in return statement
|
||||
parent->str() == "(")) // MOVED in self assignment, isOpenParenthesisMemberFunctionCallOfVarId == true
|
||||
continue;
|
||||
if (parent && parent->astOperand1()->str() == varTok->str())
|
||||
if (parent && parent->astOperand1()->varId() == varId)
|
||||
continue;
|
||||
const unsigned int varid = varTok->varId();
|
||||
const Variable *var = varTok->variable();
|
||||
if (!var)
|
||||
continue;
|
||||
|
@ -1778,7 +1787,7 @@ static void valueFlowAfterMove(TokenList *tokenlist, SymbolDatabase* symboldatab
|
|||
std::list<ValueFlow::Value> values;
|
||||
values.push_back(value);
|
||||
|
||||
valueFlowForward(varTok->next(), endOfVarScope, var, varid, values, false, tokenlist, errorLogger, settings);
|
||||
valueFlowForward(varTok->next(), endOfVarScope, var, varId, values, false, tokenlist, errorLogger, settings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -179,6 +179,9 @@ private:
|
|||
TEST_CASE(moveAndAssign1);
|
||||
TEST_CASE(moveAndAssign2);
|
||||
TEST_CASE(moveAssignMoveAssign);
|
||||
TEST_CASE(moveAndReset1);
|
||||
TEST_CASE(moveAndReset2);
|
||||
TEST_CASE(moveResetMoveReset);
|
||||
TEST_CASE(moveAndFunctionParameter);
|
||||
TEST_CASE(moveAndFunctionParameterReference);
|
||||
TEST_CASE(moveAndFunctionParameterConstReference);
|
||||
|
@ -6189,6 +6192,50 @@ private:
|
|||
"[test.cpp:8]: (warning) Access of moved variable a.\n", errout.str());
|
||||
}
|
||||
|
||||
void moveAndReset1() {
|
||||
check("A g(A a);\n"
|
||||
"void f() {\n"
|
||||
" A a;\n"
|
||||
" a.reset(g(std::move(a)));\n"
|
||||
" a.reset(g(std::move(a)));\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void moveAndReset2() {
|
||||
check("A g(A a);\n"
|
||||
"void f() {\n"
|
||||
" A a;\n"
|
||||
" A b;\n"
|
||||
" A c;\n"
|
||||
" b.reset(g(std::move(a)));\n"
|
||||
" c.reset(g(std::move(a)));\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:7]: (warning) Access of moved variable a.\n", errout.str());
|
||||
}
|
||||
|
||||
void moveResetMoveReset() {
|
||||
check("void h(A a);\n"
|
||||
"void f() {"
|
||||
" A a;\n"
|
||||
" g(std::move(a));\n"
|
||||
" h(a);\n"
|
||||
" a.reset(b);\n"
|
||||
" h(a);\n"
|
||||
" g(std::move(a));\n"
|
||||
" h(a);\n"
|
||||
" a.reset(b);\n"
|
||||
" h(a);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (warning) Access of moved variable a.\n"
|
||||
"[test.cpp:5]: (warning, inconclusive) Access of moved variable a.\n"
|
||||
"[test.cpp:6]: (warning, inconclusive) Access of moved variable a.\n"
|
||||
"[test.cpp:7]: (warning, inconclusive) Access of moved variable a.\n"
|
||||
"[test.cpp:8]: (warning) Access of moved variable a.\n"
|
||||
"[test.cpp:9]: (warning, inconclusive) Access of moved variable a.\n"
|
||||
"[test.cpp:10]: (warning, inconclusive) Access of moved variable a.\n", errout.str());
|
||||
}
|
||||
|
||||
void moveAndFunctionParameter() {
|
||||
check("void g(A a);\n"
|
||||
"void f() {\n"
|
||||
|
|
Loading…
Reference in New Issue