diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index 9882cba2a3c..684265e3fac 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -59,7 +59,7 @@ std::size_t ExprIdToken::Hash::operator()(ExprIdToken etok) const void ProgramMemory::setValue(const Token* expr, const ValueFlow::Value& value) { copyOnWrite(); - (*mValues)[expr] = value; + (*mValues)[expr] = value; // copy ValueFlow::Value subvalue = value; const Token* subexpr = solveExprValue( expr, @@ -327,11 +327,13 @@ static void programMemoryParseCondition(ProgramMemory& pm, const Token* tok, con if (endTok && findExpressionChanged(vartok, tok->next(), endTok, settings)) return; const bool impossible = (tok->str() == "==" && !then) || (tok->str() == "!=" && then); - const ValueFlow::Value& v = then ? truevalue : falsevalue; - pm.setValue(vartok, impossible ? asImpossible(v) : v); + ValueFlow::Value& v = then ? truevalue : falsevalue; + const auto iv = v.intvalue; + // cppcheck-suppress accessMoved - FP #13628 + pm.setValue(vartok, impossible ? asImpossible(std::move(v)) : v); const Token* containerTok = settings.library.getContainerFromYield(vartok, Library::Container::Yield::SIZE); if (containerTok) - pm.setContainerSizeValue(containerTok, v.intvalue, !impossible); + pm.setContainerSizeValue(containerTok, iv, !impossible); } else if (Token::simpleMatch(tok, "!")) { programMemoryParseCondition(pm, tok->astOperand1(), endTok, settings, !then); } else if (then && Token::simpleMatch(tok, "&&")) { diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 81e65c8347f..c8d1553a6e6 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -1684,7 +1684,7 @@ ValueFlow::Value ValueFlow::getLifetimeObjValue(const Token *tok, bool inconclus // There should only be one lifetime if (values.size() != 1) return ValueFlow::Value{}; - return values.front(); + return std::move(values.front()); } template @@ -3155,10 +3155,10 @@ static void valueFlowLifetime(TokenList &tokenlist, ErrorLogger &errorLogger, co else if (tok->isUnaryOp("&")) { if (Token::simpleMatch(tok->astParent(), "*")) continue; - for (const ValueFlow::LifetimeToken& lt : ValueFlow::getLifetimeTokens(tok->astOperand1(), settings)) { + for (ValueFlow::LifetimeToken& lt : ValueFlow::getLifetimeTokens(tok->astOperand1(), settings)) { if (!settings.certainty.isEnabled(Certainty::inconclusive) && lt.inconclusive) continue; - ErrorPath errorPath = lt.errorPath; + ErrorPath& errorPath = lt.errorPath; errorPath.emplace_back(tok, "Address of variable taken here."); ValueFlow::Value value; @@ -3801,7 +3801,7 @@ static void valueFlowSymbolicOperators(const SymbolDatabase& symboldatabase, con continue; ValueFlow::Value v = makeSymbolic(arg); - v.errorPath = c.errorPath; + v.errorPath = std::move(c.errorPath); v.errorPath.emplace_back(tok, "Passed to " + tok->str()); if (c.intvalue == 0) v.setImpossible(); @@ -4355,7 +4355,7 @@ static void valueFlowAfterAssign(TokenList &tokenlist, continue; ids.insert(value.tokvalue->exprId()); } - for (ValueFlow::Value value : values) { + for (ValueFlow::Value& value : values) { if (!value.isSymbolicValue()) continue; const Token* expr = value.tokvalue; @@ -5198,7 +5198,7 @@ static void valueFlowInferCondition(TokenList& tokenlist, const Settings& settin for (const ValuePtr& model : iteratorModels) { std::vector result = infer(model, tok->str(), tok->astOperand1()->values(), tok->astOperand2()->values()); - for (ValueFlow::Value value : result) { + for (ValueFlow::Value& value : result) { value.valueType = ValueFlow::Value::ValueType::INT; setTokenValue(tok, std::move(value), settings); } @@ -5216,8 +5216,7 @@ static void valueFlowInferCondition(TokenList& tokenlist, const Settings& settin std::vector result = infer(makeIntegralInferModel(), "!=", tok->values(), 0); if (result.size() != 1) continue; - ValueFlow::Value value = result.front(); - setTokenValue(tok, std::move(value), settings); + setTokenValue(tok, std::move(result.front()), settings); } } } @@ -5636,7 +5635,7 @@ static void valueFlowInjectParameter(const TokenList& tokenlist, const Settings& settings, const Variable* arg, const Scope* functionScope, - const std::list& argvalues) + std::list argvalues) { // Is argument passed by value or const reference, and is it a known non-class type? if (arg->isReference() && !arg->isConst() && !arg->isClass()) @@ -5650,7 +5649,7 @@ static void valueFlowInjectParameter(const TokenList& tokenlist, valueFlowForward(const_cast(functionScope->bodyStart->next()), functionScope->bodyEnd, arg->nameToken(), - argvalues, + std::move(argvalues), tokenlist, errorLogger, settings); @@ -5876,7 +5875,7 @@ static void valueFlowFunctionDefaultParameter(const TokenList& tokenlist, const argvalues.push_back(std::move(v)); } if (!argvalues.empty()) - valueFlowInjectParameter(tokenlist, errorLogger, settings, var, scope, argvalues); + valueFlowInjectParameter(tokenlist, errorLogger, settings, var, scope, std::move(argvalues)); } } } @@ -5961,10 +5960,10 @@ static void valueFlowFunctionReturn(TokenList& tokenlist, ErrorLogger& errorLogg bool hasKnownValue = false; - for (const ValueFlow::Value& v : getCommonValuesFromTokens(returns)) { - setFunctionReturnValue(function, tok, v, settings, false); + for (ValueFlow::Value& v : getCommonValuesFromTokens(returns)) { if (v.isKnown()) hasKnownValue = true; + setFunctionReturnValue(function, tok, std::move(v), settings, false); } if (hasKnownValue) @@ -5990,10 +5989,10 @@ static void valueFlowFunctionReturn(TokenList& tokenlist, ErrorLogger& errorLogg if (programMemory.empty() && !arguments.empty()) continue; std::vector values = execute(function->functionScope, programMemory, settings); - for (const ValueFlow::Value& v : values) { + for (ValueFlow::Value& v : values) { if (v.isUninitValue()) continue; - setFunctionReturnValue(function, tok, v, settings); + setFunctionReturnValue(function, tok, std::move(v), settings); } } } @@ -6799,8 +6798,8 @@ static void valueFlowContainerSize(const TokenList& tokenlist, continue; } - for (const ValueFlow::Value& value : values) { - valueFlowForward(nameToken->next(), var->nameToken(), value, tokenlist, errorLogger, settings); + for (ValueFlow::Value& value : values) { + valueFlowForward(nameToken->next(), var->nameToken(), std::move(value), tokenlist, errorLogger, settings); } } @@ -6846,8 +6845,8 @@ static void valueFlowContainerSize(const TokenList& tokenlist, const Token* constructorArgs = tok; values = getContainerSizeFromConstructor(constructorArgs, tok->valueType(), settings, true); } - for (const ValueFlow::Value& value : values) - setTokenValue(tok, value, settings); + for (ValueFlow::Value& value : values) + setTokenValue(tok, std::move(value), settings); } else if (Token::Match(tok, ";|{|} %var% =") && Token::Match(tok->tokAt(2)->astOperand2(), "[({]") && // init list ((tok->tokAt(2) == tok->tokAt(2)->astOperand2()->astParent() && !tok->tokAt(2)->astOperand2()->astOperand2() && tok->tokAt(2)->astOperand2()->str() == "{") || @@ -6860,8 +6859,8 @@ static void valueFlowContainerSize(const TokenList& tokenlist, Token* rhs = tok->tokAt(2)->astOperand2(); std::vector values = getInitListSize(rhs, containerTok->valueType(), settings); valueFlowContainerSetTokValue(tokenlist, errorLogger, settings, containerTok, rhs); - for (const ValueFlow::Value& value : values) - valueFlowForward(containerTok->next(), containerTok, value, tokenlist, errorLogger, settings); + for (ValueFlow::Value& value : values) + valueFlowForward(containerTok->next(), containerTok, std::move(value), tokenlist, errorLogger, settings); } } else if (Token::Match(tok, ". %name% (") && tok->astOperand1() && tok->astOperand1()->valueType() && tok->astOperand1()->valueType()->container) { @@ -7125,8 +7124,8 @@ static void valueFlowSafeFunctions(const TokenList& tokenlist, const SymbolDatab argValues.back().valueType = ValueFlow::Value::ValueType::CONTAINER_SIZE; argValues.back().errorPath.emplace_back(arg.nameToken(), "Assuming " + arg.name() + " size is 1000000"); argValues.back().safe = true; - for (const ValueFlow::Value &value : argValues) - valueFlowForward(const_cast(functionScope->bodyStart), arg.nameToken(), value, tokenlist, errorLogger, settings); + for (ValueFlow::Value &value : argValues) + valueFlowForward(const_cast(functionScope->bodyStart), arg.nameToken(), std::move(value), tokenlist, errorLogger, settings); continue; } diff --git a/lib/vf_settokenvalue.cpp b/lib/vf_settokenvalue.cpp index 1fcf7d28a3a..414a22ae5ac 100644 --- a/lib/vf_settokenvalue.cpp +++ b/lib/vf_settokenvalue.cpp @@ -126,32 +126,31 @@ namespace ValueFlow return value.isIntValue() || value.isFloatValue(); } - static void setTokenValueCast(Token *parent, const ValueType &valueType, const Value &value, const Settings &settings) + static void setTokenValueCast(Token *parent, const ValueType &valueType, Value value, const Settings &settings) { if (valueType.pointer || value.isImpossible()) - setTokenValue(parent,value,settings); + setTokenValue(parent,std::move(value),settings); else if (valueType.type == ValueType::Type::CHAR) - setTokenValue(parent, castValue(value, valueType.sign, settings.platform.char_bit), settings); + setTokenValue(parent, castValue(std::move(value), valueType.sign, settings.platform.char_bit), settings); else if (valueType.type == ValueType::Type::SHORT) - setTokenValue(parent, castValue(value, valueType.sign, settings.platform.short_bit), settings); + setTokenValue(parent, castValue(std::move(value), valueType.sign, settings.platform.short_bit), settings); else if (valueType.type == ValueType::Type::INT) - setTokenValue(parent, castValue(value, valueType.sign, settings.platform.int_bit), settings); + setTokenValue(parent, castValue(std::move(value), valueType.sign, settings.platform.int_bit), settings); else if (valueType.type == ValueType::Type::LONG) - setTokenValue(parent, castValue(value, valueType.sign, settings.platform.long_bit), settings); + setTokenValue(parent, castValue(std::move(value), valueType.sign, settings.platform.long_bit), settings); else if (valueType.type == ValueType::Type::LONGLONG) - setTokenValue(parent, castValue(value, valueType.sign, settings.platform.long_long_bit), settings); + setTokenValue(parent, castValue(std::move(value), valueType.sign, settings.platform.long_long_bit), settings); else if (valueType.isFloat() && isNumeric(value)) { - Value floatValue = value; - floatValue.valueType = Value::ValueType::FLOAT; if (value.isIntValue()) - floatValue.floatValue = static_cast(value.intvalue); - setTokenValue(parent, std::move(floatValue), settings); + value.floatValue = static_cast(value.intvalue); + value.valueType = Value::ValueType::FLOAT; + setTokenValue(parent, std::move(value), settings); } else if (value.isIntValue()) { const long long charMax = settings.platform.signedCharMax(); const long long charMin = settings.platform.signedCharMin(); if (charMin <= value.intvalue && value.intvalue <= charMax) { // unknown type, but value is small so there should be no truncation etc - setTokenValue(parent,value,settings); + setTokenValue(parent,std::move(value),settings); } } } @@ -307,22 +306,23 @@ namespace ValueFlow value.valueType = Value::ValueType::INT; setTokenValue(next, std::move(value), settings); } else if (yields == Library::Container::Yield::EMPTY) { - Value v(value); - v.valueType = Value::ValueType::INT; - v.bound = Value::Bound::Point; + const Value::Bound bound = value.bound; + const long long intvalue = value.intvalue; + value.valueType = Value::ValueType::INT; + value.bound = Value::Bound::Point; if (value.isImpossible()) { - if (value.intvalue == 0) - v.setKnown(); - else if ((value.bound == Value::Bound::Upper && value.intvalue > 0) || - (value.bound == Value::Bound::Lower && value.intvalue < 0)) { - v.intvalue = 0; - v.setKnown(); + if (intvalue == 0) + value.setKnown(); + else if ((bound == Value::Bound::Upper && intvalue > 0) || + (bound == Value::Bound::Lower && intvalue < 0)) { + value.intvalue = 0; + value.setKnown(); } else - v.setPossible(); + value.setPossible(); } else { - v.intvalue = !v.intvalue; + value.intvalue = !value.intvalue; } - setTokenValue(next, std::move(v), settings); + setTokenValue(next, std::move(value), settings); } return; } @@ -346,27 +346,26 @@ namespace ValueFlow setTokenValue(parent, std::move(value), settings); return; } - Value pvalue = value; if (!value.subexpressions.empty() && Token::Match(parent, ". %var%")) { if (contains(value.subexpressions, parent->strAt(1))) - pvalue.subexpressions.clear(); + value.subexpressions.clear(); else return; } if (parent->isUnaryOp("&")) { - pvalue.indirect++; - setTokenValue(parent, std::move(pvalue), settings); + value.indirect++; + setTokenValue(parent, std::move(value), settings); } else if (Token::Match(parent, ". %var%") && parent->astOperand1() == tok && parent->astOperand2()) { - if (parent->originalName() == "->" && pvalue.indirect > 0) - pvalue.indirect--; - setTokenValue(parent->astOperand2(), std::move(pvalue), settings); + if (parent->originalName() == "->" && value.indirect > 0) + value.indirect--; + setTokenValue(parent->astOperand2(), std::move(value), settings); } else if (Token::Match(parent->astParent(), ". %var%") && parent->astParent()->astOperand1() == parent) { - if (parent->astParent()->originalName() == "->" && pvalue.indirect > 0) - pvalue.indirect--; - setTokenValue(parent->astParent()->astOperand2(), std::move(pvalue), settings); - } else if (parent->isUnaryOp("*") && pvalue.indirect > 0) { - pvalue.indirect--; - setTokenValue(parent, std::move(pvalue), settings); + if (parent->astParent()->originalName() == "->" && value.indirect > 0) + value.indirect--; + setTokenValue(parent->astParent()->astOperand2(), std::move(value), settings); + } else if (parent->isUnaryOp("*") && value.indirect > 0) { + value.indirect--; + setTokenValue(parent, std::move(value), settings); } return; } @@ -382,7 +381,7 @@ namespace ValueFlow && getSizeOf(*tok->valueType(), settings, ValueFlow::Accuracy::ExactOrZero) >= getSizeOf(valueType, settings, ValueFlow::Accuracy::ExactOrZero)) return; - setTokenValueCast(parent, valueType, value, settings); + setTokenValueCast(parent, valueType, std::move(value), settings); } else if (parent->str() == ":") { @@ -422,11 +421,10 @@ namespace ValueFlow if (ret) return; - Value v(std::move(value)); - v.conditional = true; - v.changeKnownToPossible(); + value.conditional = true; + value.changeKnownToPossible(); - setTokenValue(parent, std::move(v), settings); + setTokenValue(parent, std::move(value), settings); } } @@ -718,15 +716,13 @@ namespace ValueFlow std::vector args = getArguments(value.tokvalue); if (const Library::Function* f = settings.library.getFunction(parent->previous())) { if (f->containerYield == Library::Container::Yield::SIZE) { - Value v(std::move(value)); - v.valueType = Value::ValueType::INT; - v.intvalue = args.size(); - setTokenValue(parent, std::move(v), settings); + value.valueType = Value::ValueType::INT; + value.intvalue = args.size(); + setTokenValue(parent, std::move(value), settings); } else if (f->containerYield == Library::Container::Yield::EMPTY) { - Value v(std::move(value)); - v.intvalue = args.empty(); - v.valueType = Value::ValueType::INT; - setTokenValue(parent, std::move(v), settings); + value.intvalue = args.empty(); + value.valueType = Value::ValueType::INT; + setTokenValue(parent, std::move(value), settings); } } }