Improve Fix #6180 ("reset" and "clear" clears the move status)

This commit is contained in:
Frank Zingsheim 2016-12-12 14:29:27 +01:00 committed by Daniel Marjamäki
parent f4ab45f13b
commit 9a871d33f7
4 changed files with 26 additions and 10 deletions

View File

@ -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);

View File

@ -1760,6 +1760,24 @@ static void valueFlowAfterMove(TokenList *tokenlist, SymbolDatabase* symboldatab
for (Token* tok = const_cast<Token*>(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<ValueFlow::Value> 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;

View File

@ -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:

View File

@ -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() {