diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 1dec196cb..bc78a9c83 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -2713,7 +2713,7 @@ void CheckOther::checkAccessOfMovedVariable() } for (const Token* tok = scopeStart->next(); tok != scope->classEnd; tok = tok->next()) { const ValueFlow::Value * movedValue = tok->getMovedValue(); - if (!movedValue) + if (!movedValue || movedValue->moveKind == ValueFlow::Value::NonMovedVariable) continue; if (movedValue->inconclusive && !reportInconclusive) continue; @@ -2766,6 +2766,8 @@ void CheckOther::accessMovedError(const Token *tok, const std::string &varname, errorId = "accessForwarded"; kindString = "forwarded"; break; + default: + return; } const std::string errmsg(std::string("Access of ") + kindString + " variable " + varname + "."); reportError(tok, Severity::warning, errorId, errmsg, CWE(0U), inconclusive); diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index b6a51ec79..888b9c53b 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -1760,6 +1760,24 @@ static void valueFlowAfterMove(TokenList *tokenlist, SymbolDatabase* symboldatab for (Token* tok = const_cast(start); tok != scope->classEnd; tok = tok->next()) { Token * varTok; + if (Token::Match(tok, "%var% . reset|clear (") && tok->next()->originalName() == emptyString) { + varTok = tok; + ValueFlow::Value value; + value.valueType = ValueFlow::Value::MOVED; + value.moveKind = ValueFlow::Value::NonMovedVariable; + value.setKnown(); + std::list values; + values.push_back(value); + + const Variable *var = varTok->variable(); + if (!var || (!var->isLocal() && !var->isArgument())) + continue; + const unsigned int varId = varTok->varId(); + const Token * const endOfVarScope = var->typeStartToken()->scope()->classEnd; + setTokenValue(varTok, value, settings); + valueFlowForward(varTok->next(), endOfVarScope, var, varId, values, false, tokenlist, errorLogger, settings); + continue; + } ValueFlow::Value::MoveKind moveKind; if (!isStdMoveOrStdForwarded(tok, &moveKind, &varTok)) continue; diff --git a/lib/valueflow.h b/lib/valueflow.h index ffffd3c48..6368e70be 100644 --- a/lib/valueflow.h +++ b/lib/valueflow.h @@ -92,7 +92,7 @@ namespace ValueFlow { double floatValue; /** kind of moved */ - enum MoveKind {MovedVariable, ForwardedVariable} moveKind; + enum MoveKind {NonMovedVariable, MovedVariable, ForwardedVariable} moveKind; /** For calculated values - variable value that calculated value depends on */ long long varvalue; @@ -114,6 +114,8 @@ namespace ValueFlow { static const char * toString(MoveKind moveKind) { switch (moveKind) { + case NonMovedVariable: + return "NonMovedVariable"; case MovedVariable: return "MovedVariable"; case ForwardedVariable: diff --git a/test/testother.cpp b/test/testother.cpp index 8257f8676..849b3c86d 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -6228,12 +6228,7 @@ private: " 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()); + "[test.cpp:8]: (warning) Access of moved variable a.\n", errout.str()); } void moveAndFunctionParameter() { @@ -6301,8 +6296,7 @@ private: " v.clear();\n" " if (v.empty()) {}\n" "}"); - ASSERT_EQUALS("[test.cpp:4]: (warning, inconclusive) Access of moved variable v.\n" - "[test.cpp:5]: (warning, inconclusive) Access of moved variable v.\n", errout.str()); + ASSERT_EQUALS("", errout.str()); } void movedPointer() {