Skip to content

Commit 0f291e5

Browse files
[clang-tidy] Add flag to specify an alternative to std::move in cppcoreguidelines-rvalue-reference-param-not-moved (#138757)
Since std::move is nothing more than a cast, part of STL and not the language itself, it's easy to provide a custom implementation if one wishes not to include the entirety of <utility>. Added flag (MoveFunction) provides a way to continue using this essential check even with the custom implementation of moving. --------- Co-authored-by: EugeneZelenko <[email protected]>
1 parent 5f91b69 commit 0f291e5

File tree

5 files changed

+62
-3
lines changed

5 files changed

+62
-3
lines changed

clang-tools-extra/clang-tidy/cppcoreguidelines/RvalueReferenceParamNotMovedCheck.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@ void RvalueReferenceParamNotMovedCheck::registerMatchers(MatchFinder *Finder) {
4242
StatementMatcher MoveCallMatcher =
4343
callExpr(
4444
argumentCountIs(1),
45-
anyOf(callee(functionDecl(hasName("::std::move"))),
45+
anyOf(callee(functionDecl(hasName(MoveFunction))),
4646
callee(unresolvedLookupExpr(hasAnyDeclaration(
47-
namedDecl(hasUnderlyingDecl(hasName("::std::move"))))))),
47+
namedDecl(hasUnderlyingDecl(hasName(MoveFunction))))))),
4848
hasArgument(
4949
0, argumentOf(
5050
AllowPartialMove,
@@ -122,14 +122,16 @@ RvalueReferenceParamNotMovedCheck::RvalueReferenceParamNotMovedCheck(
122122
AllowPartialMove(Options.get("AllowPartialMove", false)),
123123
IgnoreUnnamedParams(Options.get("IgnoreUnnamedParams", false)),
124124
IgnoreNonDeducedTemplateTypes(
125-
Options.get("IgnoreNonDeducedTemplateTypes", false)) {}
125+
Options.get("IgnoreNonDeducedTemplateTypes", false)),
126+
MoveFunction(Options.get("MoveFunction", "::std::move")) {}
126127

127128
void RvalueReferenceParamNotMovedCheck::storeOptions(
128129
ClangTidyOptions::OptionMap &Opts) {
129130
Options.store(Opts, "AllowPartialMove", AllowPartialMove);
130131
Options.store(Opts, "IgnoreUnnamedParams", IgnoreUnnamedParams);
131132
Options.store(Opts, "IgnoreNonDeducedTemplateTypes",
132133
IgnoreNonDeducedTemplateTypes);
134+
Options.store(Opts, "MoveFunction", MoveFunction);
133135
}
134136

135137
} // namespace clang::tidy::cppcoreguidelines

clang-tools-extra/clang-tidy/cppcoreguidelines/RvalueReferenceParamNotMovedCheck.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class RvalueReferenceParamNotMovedCheck : public ClangTidyCheck {
3232
const bool AllowPartialMove;
3333
const bool IgnoreUnnamedParams;
3434
const bool IgnoreNonDeducedTemplateTypes;
35+
const StringRef MoveFunction;
3536
};
3637

3738
} // namespace clang::tidy::cppcoreguidelines

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,11 @@ Changes in existing checks
215215
- Improved :doc:`cppcoreguidelines-missing-std-forward
216216
<clang-tidy/checks/cppcoreguidelines/missing-std-forward>` check by adding a
217217
flag to specify the function used for forwarding instead of ``std::forward``.
218+
219+
- Improved :doc:`cppcoreguidelines-rvalue-reference-param-not-moved
220+
<clang-tidy/checks/cppcoreguidelines/rvalue-reference-param-not-moved>` check
221+
by adding a flag to specify the function used for moving instead of
222+
``std::move``.
218223

219224
- Improved :doc:`cppcoreguidelines-special-member-functions
220225
<clang-tidy/checks/cppcoreguidelines/special-member-functions>` check by

clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/rvalue-reference-param-not-moved.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ Options
7979
T other = std::forward<T>(t);
8080
}
8181

82+
.. option:: MoveFunction
83+
84+
Specify the function used for moving. Default is `::std::move`.
85+
8286
This check implements `F.18
8387
<http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#f18-for-will-move-from-parameters-pass-by-x-and-stdmove-the-parameter>`_
8488
from the C++ Core Guidelines.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// RUN: %check_clang_tidy -std=c++11 %s cppcoreguidelines-rvalue-reference-param-not-moved %t -- \
2+
// RUN: -config="{CheckOptions: {cppcoreguidelines-rvalue-reference-param-not-moved.AllowPartialMove: true, cppcoreguidelines-rvalue-reference-param-not-moved.IgnoreUnnamedParams: true, cppcoreguidelines-rvalue-reference-param-not-moved.IgnoreNonDeducedTemplateTypes: true, cppcoreguidelines-rvalue-reference-param-not-moved.MoveFunction: custom_move}}" -- -fno-delayed-template-parsing
3+
4+
// NOLINTBEGIN
5+
namespace std {
6+
template <typename>
7+
struct remove_reference;
8+
9+
template <typename _Tp> struct remove_reference { typedef _Tp type; };
10+
template <typename _Tp> struct remove_reference<_Tp&> { typedef _Tp type; };
11+
template <typename _Tp> struct remove_reference<_Tp&&> { typedef _Tp type; };
12+
13+
template <typename _Tp>
14+
constexpr typename std::remove_reference<_Tp>::type &&move(_Tp &&__t) noexcept;
15+
16+
template <typename _Tp>
17+
constexpr _Tp &&
18+
forward(typename remove_reference<_Tp>::type &__t) noexcept;
19+
20+
}
21+
// NOLINTEND
22+
23+
24+
struct Obj {
25+
Obj();
26+
Obj(const Obj&);
27+
Obj& operator=(const Obj&);
28+
Obj(Obj&&);
29+
Obj& operator=(Obj&&);
30+
void member() const;
31+
};
32+
33+
template<class T>
34+
constexpr typename std::remove_reference<T>::type&& custom_move(T&& x) noexcept
35+
{
36+
return static_cast<typename std::remove_reference<T>::type&&>(x);
37+
}
38+
39+
void move_with_std(Obj&& o) {
40+
// CHECK-MESSAGES: :[[@LINE-1]]:26: warning: rvalue reference parameter 'o' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
41+
Obj other{std::move(o)};
42+
}
43+
44+
void move_with_custom(Obj&& o) {
45+
Obj other{custom_move(o)};
46+
}
47+

0 commit comments

Comments
 (0)