MCPcopy Create free account
hub / github.com/cppcheck-opensource/cppcheck / valueFlowAfterMove

Function valueFlowAfterMove

lib/valueflow.cpp:3229–3316  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

3227}
3228
3229static void valueFlowAfterMove(const TokenList& tokenlist, const SymbolDatabase& symboldatabase, ErrorLogger& errorLogger, const Settings& settings)
3230{
3231 if (!tokenlist.isCPP() || settings.standards.cpp < Standards::CPP11)
3232 return;
3233 for (const Scope * scope : symboldatabase.functionScopes) {
3234 if (!scope)
3235 continue;
3236 const Token * start = scope->bodyStart;
3237 if (scope->function) {
3238 const Token * memberInitializationTok = scope->function->constructorMemberInitialization();
3239 if (memberInitializationTok)
3240 start = memberInitializationTok;
3241 }
3242
3243 for (auto* tok = const_cast<Token*>(start); tok != scope->bodyEnd; tok = tok->next()) {
3244 Token * varTok;
3245 if (Token::Match(tok, "%var% . reset|clear (") && tok->next()->originalName().empty()) {
3246 varTok = tok;
3247
3248 const Variable *var = tok->variable();
3249 if (!var || (!var->isLocal() && !var->isArgument()))
3250 continue;
3251
3252 ValueFlow::Value value;
3253 value.valueType = ValueFlow::Value::ValueType::MOVED;
3254 value.moveKind = ValueFlow::Value::MoveKind::NonMovedVariable;
3255 value.errorPath.emplace_back(tok, "Calling " + tok->next()->expressionString() + " makes " + tok->str() + " 'non-moved'");
3256 value.setKnown();
3257
3258 setTokenValue(tok, value, settings);
3259 if (var->scope()) {
3260 const Token* const endOfVarScope = var->scope()->bodyEnd;
3261 valueFlowForward(tok->next(), endOfVarScope, tok, std::move(value), tokenlist, errorLogger, settings);
3262 }
3263 continue;
3264 }
3265 ValueFlow::Value::MoveKind moveKind;
3266 if (!isStdMoveOrStdForwarded(tok, &moveKind, &varTok))
3267 continue;
3268 const nonneg int varId = varTok->varId();
3269 // x is not MOVED after assignment if code is: x = ... std::move(x) .. ;
3270 const Token *parent = tok->astParent();
3271 bool bail = false;
3272 while (parent && parent->str() != "=" && parent->str() != "return" &&
3273 !(parent->str() == "(" && isOpenParenthesisMemberFunctionCallOfVarId(parent, varId))) {
3274 if (isTryEmplace(parent)) {
3275 bail = true;
3276 break;
3277 }
3278 parent = parent->astParent();
3279 }
3280 if (bail)
3281 continue;
3282 if (parent &&
3283 (parent->str() == "return" || // MOVED in return statement
3284 parent->str() == "(")) // MOVED in self assignment, isOpenParenthesisMemberFunctionCallOfVarId == true
3285 continue;
3286 if (parent && parent->astOperand1() && parent->astOperand1()->varId() == varId)

Callers 1

setValuesMethod · 0.85

Calls 15

setTokenValueFunction · 0.85
valueFlowForwardFunction · 0.85
isStdMoveOrStdForwardedFunction · 0.85
isTryEmplaceFunction · 0.85
findOpenParentesisOfMoveFunction · 0.85
isCPPMethod · 0.80
nextMethod · 0.80
variableMethod · 0.80
scopeMethod · 0.80

Tested by

no test coverage detected