Skip to content

Commit 46fcb75

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 46fcb75

4 files changed

Lines changed: 21 additions & 13 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: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,15 @@
2626
#include <memory>
2727

2828
template<class T>
29-
class CPPCHECKLIB ValuePtr {
29+
class ValuePtr {
3030
template<class U>
3131
struct cloner {
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
}
@@ -62,10 +70,10 @@ class CPPCHECKLIB ValuePtr {
6270
return mPtr.get();
6371
}
6472

65-
T& operator*() {
73+
T& operator*() NOEXCEPT {
6674
return *get();
6775
}
68-
const T& operator*() const {
76+
const T& operator*() const NOEXCEPT {
6977
return *get();
7078
}
7179

0 commit comments

Comments
 (0)