Skip to content

Commit f4ab45f

Browse files
zingsheimdanmar
authored andcommitted
Improve Fix #6180 (Do not warn about move if it is part of a reassignment of the variable)
1 parent f8cfa72 commit f4ab45f

2 files changed

Lines changed: 61 additions & 5 deletions

File tree

lib/valueflow.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1736,6 +1736,12 @@ static bool isStdMoveOrStdForwarded(Token * tok, ValueFlow::Value::MoveKind * mo
17361736
return true;
17371737
}
17381738

1739+
static bool isOpenParenthesisMemberFunctionCallOfVarId(const Token * openParenthesisToken, unsigned int varId)
1740+
{
1741+
return Token::Match(openParenthesisToken->tokAt(-3),"%varid% . %name% (", varId) &&
1742+
openParenthesisToken->tokAt(-2)->originalName() == emptyString;
1743+
}
1744+
17391745
static void valueFlowAfterMove(TokenList *tokenlist, SymbolDatabase* symboldatabase, ErrorLogger *errorLogger, const Settings *settings)
17401746
{
17411747
if (!tokenlist->isCPP() || settings->standards.cpp < Standards::CPP11)
@@ -1757,15 +1763,18 @@ static void valueFlowAfterMove(TokenList *tokenlist, SymbolDatabase* symboldatab
17571763
ValueFlow::Value::MoveKind moveKind;
17581764
if (!isStdMoveOrStdForwarded(tok, &moveKind, &varTok))
17591765
continue;
1766+
const unsigned int varId = varTok->varId();
17601767
// x is not MOVED after assignment if code is: x = ... std::move(x) .. ;
17611768
const Token *parent = tok->astParent();
1762-
while (parent && parent->str() != "=" && parent->str() != "return")
1769+
while (parent && parent->str() != "=" && parent->str() != "return" &&
1770+
!(parent->str() == "(" && isOpenParenthesisMemberFunctionCallOfVarId(parent, varId)))
17631771
parent = parent->astParent();
1764-
if (parent && parent->str() == "return") // MOVED in return statement
1772+
if (parent &&
1773+
(parent->str() == "return" || // MOVED in return statement
1774+
parent->str() == "(")) // MOVED in self assignment, isOpenParenthesisMemberFunctionCallOfVarId == true
17651775
continue;
1766-
if (parent && parent->astOperand1()->str() == varTok->str())
1776+
if (parent && parent->astOperand1()->varId() == varId)
17671777
continue;
1768-
const unsigned int varid = varTok->varId();
17691778
const Variable *var = varTok->variable();
17701779
if (!var)
17711780
continue;
@@ -1778,7 +1787,7 @@ static void valueFlowAfterMove(TokenList *tokenlist, SymbolDatabase* symboldatab
17781787
std::list<ValueFlow::Value> values;
17791788
values.push_back(value);
17801789

1781-
valueFlowForward(varTok->next(), endOfVarScope, var, varid, values, false, tokenlist, errorLogger, settings);
1790+
valueFlowForward(varTok->next(), endOfVarScope, var, varId, values, false, tokenlist, errorLogger, settings);
17821791
}
17831792
}
17841793
}

test/testother.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,9 @@ class TestOther : public TestFixture {
179179
TEST_CASE(moveAndAssign1);
180180
TEST_CASE(moveAndAssign2);
181181
TEST_CASE(moveAssignMoveAssign);
182+
TEST_CASE(moveAndReset1);
183+
TEST_CASE(moveAndReset2);
184+
TEST_CASE(moveResetMoveReset);
182185
TEST_CASE(moveAndFunctionParameter);
183186
TEST_CASE(moveAndFunctionParameterReference);
184187
TEST_CASE(moveAndFunctionParameterConstReference);
@@ -6189,6 +6192,50 @@ class TestOther : public TestFixture {
61896192
"[test.cpp:8]: (warning) Access of moved variable a.\n", errout.str());
61906193
}
61916194

6195+
void moveAndReset1() {
6196+
check("A g(A a);\n"
6197+
"void f() {\n"
6198+
" A a;\n"
6199+
" a.reset(g(std::move(a)));\n"
6200+
" a.reset(g(std::move(a)));\n"
6201+
"}");
6202+
ASSERT_EQUALS("", errout.str());
6203+
}
6204+
6205+
void moveAndReset2() {
6206+
check("A g(A a);\n"
6207+
"void f() {\n"
6208+
" A a;\n"
6209+
" A b;\n"
6210+
" A c;\n"
6211+
" b.reset(g(std::move(a)));\n"
6212+
" c.reset(g(std::move(a)));\n"
6213+
"}");
6214+
ASSERT_EQUALS("[test.cpp:7]: (warning) Access of moved variable a.\n", errout.str());
6215+
}
6216+
6217+
void moveResetMoveReset() {
6218+
check("void h(A a);\n"
6219+
"void f() {"
6220+
" A a;\n"
6221+
" g(std::move(a));\n"
6222+
" h(a);\n"
6223+
" a.reset(b);\n"
6224+
" h(a);\n"
6225+
" g(std::move(a));\n"
6226+
" h(a);\n"
6227+
" a.reset(b);\n"
6228+
" h(a);\n"
6229+
"}");
6230+
ASSERT_EQUALS("[test.cpp:4]: (warning) Access of moved variable a.\n"
6231+
"[test.cpp:5]: (warning, inconclusive) Access of moved variable a.\n"
6232+
"[test.cpp:6]: (warning, inconclusive) Access of moved variable a.\n"
6233+
"[test.cpp:7]: (warning, inconclusive) Access of moved variable a.\n"
6234+
"[test.cpp:8]: (warning) Access of moved variable a.\n"
6235+
"[test.cpp:9]: (warning, inconclusive) Access of moved variable a.\n"
6236+
"[test.cpp:10]: (warning, inconclusive) Access of moved variable a.\n", errout.str());
6237+
}
6238+
61926239
void moveAndFunctionParameter() {
61936240
check("void g(A a);\n"
61946241
"void f() {\n"

0 commit comments

Comments
 (0)