Skip to content

Commit 90b6973

Browse files
firewavepfultz2
andcommitted
ValueFlow: avoid unnecessary ValuePtr and Value copies [skip ci]
Co-authored-by: Paul Fultz II <paul.fultz@amd.com>
1 parent 241cfcb commit 90b6973

4 files changed

Lines changed: 18 additions & 10 deletions

File tree

lib/forwardanalyzer.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@
4444
#include <vector>
4545

4646
namespace {
47-
struct ForwardTraversal {
47+
struct ForwardTraversal { // FIXME: invokes copy constructor
4848
enum class Progress : std::uint8_t { Continue, Break, Skip };
49-
ForwardTraversal(const ValuePtr<Analyzer>& analyzer, const TokenList& tokenList, ErrorLogger& errorLogger, const Settings& settings)
50-
: analyzer(analyzer), tokenList(tokenList), errorLogger(errorLogger), settings(settings)
49+
ForwardTraversal(ValuePtr<Analyzer> analyzer, const TokenList& tokenList, ErrorLogger& errorLogger, const Settings& settings)
50+
: analyzer(std::move(analyzer)), tokenList(tokenList), errorLogger(errorLogger), settings(settings)
5151
{}
5252
ValuePtr<Analyzer> analyzer;
5353
const TokenList& tokenList;

lib/reverseanalyzer.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@
3737

3838
namespace {
3939
struct ReverseTraversal {
40-
ReverseTraversal(const ValuePtr<Analyzer>& analyzer, const TokenList& tokenlist, ErrorLogger& errorLogger, const Settings& settings)
41-
: analyzer(analyzer), tokenlist(tokenlist), errorLogger(errorLogger), settings(settings)
40+
ReverseTraversal(ValuePtr<Analyzer> analyzer, const TokenList& tokenlist, ErrorLogger& errorLogger, const Settings& settings)
41+
: analyzer(std::move(analyzer)), tokenlist(tokenlist), errorLogger(errorLogger), settings(settings)
4242
{}
4343
ValuePtr<Analyzer> analyzer;
4444
const TokenList& tokenlist;
@@ -272,7 +272,7 @@ namespace {
272272
tokenlist,
273273
errorLogger,
274274
settings);
275-
valueFlowGenericReverse(assignTok->astOperand1()->previous(), end, a, tokenlist, errorLogger, settings);
275+
valueFlowGenericReverse(assignTok->astOperand1()->previous(), end, std::move(a), tokenlist, errorLogger, settings);
276276
}
277277
}
278278
}
@@ -406,10 +406,10 @@ namespace {
406406
};
407407
}
408408

409-
void valueFlowGenericReverse(Token* start, const Token* end, const ValuePtr<Analyzer>& a, const TokenList& tokenlist, ErrorLogger& errorLogger, const Settings& settings)
409+
void valueFlowGenericReverse(Token* start, const Token* end, ValuePtr<Analyzer> a, const TokenList& tokenlist, ErrorLogger& errorLogger, const Settings& settings)
410410
{
411411
if (a->invalid())
412412
return;
413-
ReverseTraversal rt{a, tokenlist, errorLogger, settings};
413+
ReverseTraversal rt{std::move(a), tokenlist, errorLogger, settings};
414414
rt.traverse(start, end);
415415
}

lib/reverseanalyzer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,6 @@ class TokenList;
2727
template<class T>
2828
class ValuePtr;
2929

30-
void valueFlowGenericReverse(Token* start, const Token* end, const ValuePtr<Analyzer>& a, const TokenList& tokenlist, ErrorLogger& errorLogger, const Settings& settings);
30+
void valueFlowGenericReverse(Token* start, const Token* end, ValuePtr<Analyzer> a, const TokenList& tokenlist, ErrorLogger& errorLogger, const Settings& settings);
3131

3232
#endif

lib/valueptr.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ class CPPCHECKLIB ValuePtr {
3232
static T* apply(const T* x) {
3333
return new U(*static_cast<const U*>(x));
3434
}
35+
static T* move(T* x) {
36+
return new U(std::move(*static_cast<U*>(x)));
37+
}
3538
};
3639

3740
public:
@@ -42,13 +45,18 @@ class CPPCHECKLIB ValuePtr {
4245

4346
ValuePtr() : mPtr(nullptr), mClone() {}
4447

45-
template<class U>
48+
template<class U, REQUIRES("Must not be ValuePtr", !std::is_base_of<ValuePtr, U>)>
4649
// cppcheck-suppress noExplicitConstructor
4750
// NOLINTNEXTLINE(google-explicit-constructor)
4851
ValuePtr(const U& value) : mPtr(cloner<U>::apply(&value)), mClone(&cloner<U>::apply)
4952
{}
5053

54+
template<class U, REQUIRES("Must be rvalue", !std::is_lvalue_reference<U>), REQUIRES("Must not be ValuePtr", !std::is_base_of<ValuePtr, U>)>
55+
explicit ValuePtr(U&& value) : mPtr(cloner<U>::move(&value)), mClone(&cloner<U>::apply)
56+
{}
57+
5158
ValuePtr(const ValuePtr& rhs) : mPtr(nullptr), mClone(rhs.mClone) {
59+
static_assert(false, "");
5260
if (rhs) {
5361
mPtr.reset(mClone(rhs.get()));
5462
}

0 commit comments

Comments
 (0)