diff --git a/lib/forwardanalyzer.cpp b/lib/forwardanalyzer.cpp index e883df33b46..e15c8b47995 100644 --- a/lib/forwardanalyzer.cpp +++ b/lib/forwardanalyzer.cpp @@ -47,8 +47,8 @@ namespace { struct ForwardTraversal { enum class Progress : std::uint8_t { Continue, Break, Skip }; - ForwardTraversal(const ValuePtr& analyzer, const TokenList& tokenList, ErrorLogger& errorLogger, const Settings& settings) - : analyzer(analyzer), tokenList(tokenList), errorLogger(errorLogger), settings(settings) + ForwardTraversal(ValuePtr analyzer, const TokenList& tokenList, ErrorLogger& errorLogger, const Settings& settings) + : analyzer(std::move(analyzer)), tokenList(tokenList), errorLogger(errorLogger), settings(settings) {} ValuePtr analyzer; const TokenList& tokenList; @@ -900,24 +900,24 @@ namespace { }; } -Analyzer::Result valueFlowGenericForward(Token* start, const Token* end, const ValuePtr& a, const TokenList& tokenList, ErrorLogger& errorLogger, const Settings& settings) +Analyzer::Result valueFlowGenericForward(Token* start, const Token* end, ValuePtr a, const TokenList& tokenList, ErrorLogger& errorLogger, const Settings& settings) { if (a->invalid()) return Analyzer::Result{Analyzer::Action::None, Analyzer::Terminate::Bail}; - ForwardTraversal ft{a, tokenList, errorLogger, settings}; + ForwardTraversal ft{std::move(a), tokenList, errorLogger, settings}; if (start) ft.analyzer->updateState(start); ft.updateRange(start, end); return Analyzer::Result{ ft.actions, ft.terminate }; } -Analyzer::Result valueFlowGenericForward(Token* start, const ValuePtr& a, const TokenList& tokenList, ErrorLogger& errorLogger, const Settings& settings) +Analyzer::Result valueFlowGenericForward(Token* start, ValuePtr a, const TokenList& tokenList, ErrorLogger& errorLogger, const Settings& settings) { if (Settings::terminated()) throw TerminateException(); if (a->invalid()) return Analyzer::Result{Analyzer::Action::None, Analyzer::Terminate::Bail}; - ForwardTraversal ft{a, tokenList, errorLogger, settings}; + ForwardTraversal ft{std::move(a), tokenList, errorLogger, settings}; (void)ft.updateRecursive(start); return Analyzer::Result{ ft.actions, ft.terminate }; } diff --git a/lib/forwardanalyzer.h b/lib/forwardanalyzer.h index 7b722f48c35..1de1fc26b39 100644 --- a/lib/forwardanalyzer.h +++ b/lib/forwardanalyzer.h @@ -20,20 +20,19 @@ #define forwardanalyzerH #include "analyzer.h" +#include "valueptr.h" class ErrorLogger; class Settings; class Token; class TokenList; -template class ValuePtr; Analyzer::Result valueFlowGenericForward(Token* start, - const Token* end, - const ValuePtr& a, + const Token* end,ValuePtr a, const TokenList& tokenList, ErrorLogger& errorLogger, const Settings& settings); -Analyzer::Result valueFlowGenericForward(Token* start, const ValuePtr& a, const TokenList& tokenList, ErrorLogger& errorLogger, const Settings& settings); +Analyzer::Result valueFlowGenericForward(Token* start, ValuePtr a, const TokenList& tokenList, ErrorLogger& errorLogger, const Settings& settings); #endif diff --git a/lib/reverseanalyzer.cpp b/lib/reverseanalyzer.cpp index 2d31241f200..2ab64616aa7 100644 --- a/lib/reverseanalyzer.cpp +++ b/lib/reverseanalyzer.cpp @@ -37,8 +37,8 @@ namespace { struct ReverseTraversal { - ReverseTraversal(const ValuePtr& analyzer, const TokenList& tokenlist, ErrorLogger& errorLogger, const Settings& settings) - : analyzer(analyzer), tokenlist(tokenlist), errorLogger(errorLogger), settings(settings) + ReverseTraversal(ValuePtr analyzer, const TokenList& tokenlist, ErrorLogger& errorLogger, const Settings& settings) + : analyzer(std::move(analyzer)), tokenlist(tokenlist), errorLogger(errorLogger), settings(settings) {} ValuePtr analyzer; const TokenList& tokenlist; @@ -251,7 +251,7 @@ namespace { if (a) { valueFlowGenericForward(nextAfterAstRightmostLeaf(assignTok->astOperand2()), assignTok->astOperand2()->scope()->bodyEnd, - a, + std::move(a), tokenlist, errorLogger, settings); @@ -265,11 +265,11 @@ namespace { if (a) { valueFlowGenericForward(nextAfterAstRightmostLeaf(assignTok->astOperand2()), assignTok->astOperand2()->scope()->bodyEnd, - a, + std::move(a), tokenlist, errorLogger, settings); - valueFlowGenericReverse(assignTok->astOperand1()->previous(), end, a, tokenlist, errorLogger, settings); + valueFlowGenericReverse(assignTok->astOperand1()->previous(), end, std::move(a), tokenlist, errorLogger, settings); } } } @@ -302,7 +302,7 @@ namespace { break; if (condAction.isModified()) break; - valueFlowGenericForward(condTok, analyzer, tokenlist, errorLogger, settings); + valueFlowGenericForward(condTok, std::move(analyzer), tokenlist, errorLogger, settings); } Token* thenEnd; const bool hasElse = Token::simpleMatch(tok->link()->tokAt(-2), "} else {"); @@ -331,7 +331,7 @@ namespace { break; if (!thenAction.isModified() && !elseAction.isModified()) - valueFlowGenericForward(condTok, analyzer, tokenlist, errorLogger, settings); + valueFlowGenericForward(condTok, std::move(analyzer), tokenlist, errorLogger, settings); else if (condAction.isRead()) break; // If the condition modifies the variable then bail @@ -350,7 +350,7 @@ namespace { } Token* condTok = getCondTokFromEnd(tok->link()); if (condTok) { - Analyzer::Result r = valueFlowGenericForward(condTok, analyzer, tokenlist, errorLogger, settings); + Analyzer::Result r = valueFlowGenericForward(condTok, std::move(analyzer), tokenlist, errorLogger, settings); if (r.action.isModified()) break; } @@ -403,10 +403,10 @@ namespace { }; } -void valueFlowGenericReverse(Token* start, const Token* end, const ValuePtr& a, const TokenList& tokenlist, ErrorLogger& errorLogger, const Settings& settings) +void valueFlowGenericReverse(Token* start, const Token* end, ValuePtr a, const TokenList& tokenlist, ErrorLogger& errorLogger, const Settings& settings) { if (a->invalid()) return; - ReverseTraversal rt{a, tokenlist, errorLogger, settings}; + ReverseTraversal rt{std::move(a), tokenlist, errorLogger, settings}; rt.traverse(start, end); } diff --git a/lib/reverseanalyzer.h b/lib/reverseanalyzer.h index 2a9877fb337..676e73f68aa 100644 --- a/lib/reverseanalyzer.h +++ b/lib/reverseanalyzer.h @@ -19,14 +19,14 @@ #ifndef reverseanalyzerH #define reverseanalyzerH +#include "valueptr.h" + struct Analyzer; class ErrorLogger; class Settings; class Token; class TokenList; -template -class ValuePtr; -void valueFlowGenericReverse(Token* start, const Token* end, const ValuePtr& a, const TokenList& tokenlist, ErrorLogger& errorLogger, const Settings& settings); +void valueFlowGenericReverse(Token* start, const Token* end, ValuePtr a, const TokenList& tokenlist, ErrorLogger& errorLogger, const Settings& settings); #endif diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 9f5254b02c7..6bf94c68c5c 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -3362,14 +3362,14 @@ static void valueFlowConditionExpressions(const TokenList& tokenlist, condTok2, makeConditionValue(1, condTok2, /*assume*/ true, !isBool, settings), settings); // don't set '1' for non-boolean expressions - valueFlowGenericForward(startTok, startTok->link(), a1, tokenlist, errorLogger, settings); + valueFlowGenericForward(startTok, startTok->link(), std::move(a1), tokenlist, errorLogger, settings); } auto a2 = makeOppositeExpressionAnalyzer(true, condTok2, makeConditionValue(0, condTok2, true, false, settings), settings); - valueFlowGenericForward(startTok, startTok->link(), a2, tokenlist, errorLogger, settings); + valueFlowGenericForward(startTok, startTok->link(), std::move(a2), tokenlist, errorLogger, settings); } } @@ -3384,7 +3384,7 @@ static void valueFlowConditionExpressions(const TokenList& tokenlist, auto a1 = makeSameExpressionAnalyzer(condTok2, makeConditionValue(0, condTok2, false, false, settings), settings); - valueFlowGenericForward(startTok, startTok->link(), a1, tokenlist, errorLogger, settings); + valueFlowGenericForward(startTok, startTok->link(), std::move(a1), tokenlist, errorLogger, settings); if (is1) { auto a2 = @@ -3392,7 +3392,7 @@ static void valueFlowConditionExpressions(const TokenList& tokenlist, condTok2, makeConditionValue(isOp, condTok2, false, false, settings), settings); - valueFlowGenericForward(startTok, startTok->link(), a2, tokenlist, errorLogger, settings); + valueFlowGenericForward(startTok, startTok->link(), std::move(a2), tokenlist, errorLogger, settings); } } } @@ -3410,7 +3410,7 @@ static void valueFlowConditionExpressions(const TokenList& tokenlist, auto a1 = makeSameExpressionAnalyzer(condTok2, makeConditionValue(0, condTok2, false, false, settings), settings); - valueFlowGenericForward(startTok->link()->next(), scope2->bodyEnd, a1, tokenlist, errorLogger, settings); + valueFlowGenericForward(startTok->link()->next(), scope2->bodyEnd, std::move(a1), tokenlist, errorLogger, settings); if (is1) { auto a2 = makeOppositeExpressionAnalyzer(true, @@ -3419,7 +3419,7 @@ static void valueFlowConditionExpressions(const TokenList& tokenlist, settings); valueFlowGenericForward(startTok->link()->next(), scope2->bodyEnd, - a2, + std::move(a2), tokenlist, errorLogger, settings); @@ -3711,11 +3711,11 @@ static void valueFlowSymbolicInfer(const SymbolDatabase& symboldatabase, const S std::vector values; { SymbolicInferModel leftModel{tok->astOperand1()}; - values = infer(leftModel, tok->str(), 0, tok->astOperand2()->values()); + values = infer(std::move(leftModel), tok->str(), 0, tok->astOperand2()->values()); } if (values.empty()) { SymbolicInferModel rightModel{tok->astOperand2()}; - values = infer(rightModel, tok->str(), tok->astOperand1()->values(), 0); + values = infer(std::move(rightModel), tok->str(), tok->astOperand1()->values(), 0); } for (ValueFlow::Value& value : values) { setTokenValue(tok, std::move(value), settings); @@ -5404,7 +5404,7 @@ static void valueFlowInjectParameter(const TokenList& tokenlist, auto a = makeMultiValueFlowAnalyzer(arg, settings); valueFlowGenericForward(const_cast(functionScope->bodyStart), functionScope->bodyEnd, - a, + std::move(a), tokenlist, errorLogger, settings); @@ -5932,7 +5932,7 @@ static void valueFlowUninit(TokenList& tokenlist, ErrorLogger& errorLogger, cons } auto partialReadsAnalyzer = std::make_shared(); auto analyzer = makeMemberExpressionAnalyzer(memVar.nameToken()->str(), tok, uninitValue, partialReadsAnalyzer, settings); - valueFlowGenericForward(start, tok->scope()->bodyEnd, analyzer, tokenlist, errorLogger, settings); + valueFlowGenericForward(start, tok->scope()->bodyEnd, std::move(analyzer), tokenlist, errorLogger, settings); for (auto&& p : *partialReadsAnalyzer) { Token* tok2 = p.first; diff --git a/lib/valueptr.h b/lib/valueptr.h index 5c2ce55bedf..48ef6229572 100644 --- a/lib/valueptr.h +++ b/lib/valueptr.h @@ -32,6 +32,9 @@ class CPPCHECKLIB ValuePtr { static T* apply(const T* x) { return new U(*static_cast(x)); } + static T* move(T* x) { + return new U(std::move(*static_cast(x))); + } }; public: @@ -47,6 +50,10 @@ class CPPCHECKLIB ValuePtr { ValuePtr(const U& value) : mPtr(cloner::apply(&value)), mClone(&cloner::apply) {} + template + ValuePtr(U&& value) : mPtr(cloner::move(&value)), mClone(&cloner::apply) + {} + ValuePtr(const ValuePtr& rhs) : mPtr(nullptr), mClone(rhs.mClone) { if (rhs) { mPtr.reset(mClone(rhs.get()));