[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 <eugene.zelenko@gmail.com>
This commit is contained in:
committed by
GitHub
parent
5f91b697bc
commit
0f291e5787
@@ -42,9 +42,9 @@ void RvalueReferenceParamNotMovedCheck::registerMatchers(MatchFinder *Finder) {
|
||||
StatementMatcher MoveCallMatcher =
|
||||
callExpr(
|
||||
argumentCountIs(1),
|
||||
anyOf(callee(functionDecl(hasName("::std::move"))),
|
||||
anyOf(callee(functionDecl(hasName(MoveFunction))),
|
||||
callee(unresolvedLookupExpr(hasAnyDeclaration(
|
||||
namedDecl(hasUnderlyingDecl(hasName("::std::move"))))))),
|
||||
namedDecl(hasUnderlyingDecl(hasName(MoveFunction))))))),
|
||||
hasArgument(
|
||||
0, argumentOf(
|
||||
AllowPartialMove,
|
||||
@@ -122,7 +122,8 @@ RvalueReferenceParamNotMovedCheck::RvalueReferenceParamNotMovedCheck(
|
||||
AllowPartialMove(Options.get("AllowPartialMove", false)),
|
||||
IgnoreUnnamedParams(Options.get("IgnoreUnnamedParams", false)),
|
||||
IgnoreNonDeducedTemplateTypes(
|
||||
Options.get("IgnoreNonDeducedTemplateTypes", false)) {}
|
||||
Options.get("IgnoreNonDeducedTemplateTypes", false)),
|
||||
MoveFunction(Options.get("MoveFunction", "::std::move")) {}
|
||||
|
||||
void RvalueReferenceParamNotMovedCheck::storeOptions(
|
||||
ClangTidyOptions::OptionMap &Opts) {
|
||||
@@ -130,6 +131,7 @@ void RvalueReferenceParamNotMovedCheck::storeOptions(
|
||||
Options.store(Opts, "IgnoreUnnamedParams", IgnoreUnnamedParams);
|
||||
Options.store(Opts, "IgnoreNonDeducedTemplateTypes",
|
||||
IgnoreNonDeducedTemplateTypes);
|
||||
Options.store(Opts, "MoveFunction", MoveFunction);
|
||||
}
|
||||
|
||||
} // namespace clang::tidy::cppcoreguidelines
|
||||
|
||||
@@ -32,6 +32,7 @@ private:
|
||||
const bool AllowPartialMove;
|
||||
const bool IgnoreUnnamedParams;
|
||||
const bool IgnoreNonDeducedTemplateTypes;
|
||||
const StringRef MoveFunction;
|
||||
};
|
||||
|
||||
} // namespace clang::tidy::cppcoreguidelines
|
||||
|
||||
@@ -215,6 +215,11 @@ Changes in existing checks
|
||||
- Improved :doc:`cppcoreguidelines-missing-std-forward
|
||||
<clang-tidy/checks/cppcoreguidelines/missing-std-forward>` check by adding a
|
||||
flag to specify the function used for forwarding instead of ``std::forward``.
|
||||
|
||||
- Improved :doc:`cppcoreguidelines-rvalue-reference-param-not-moved
|
||||
<clang-tidy/checks/cppcoreguidelines/rvalue-reference-param-not-moved>` check
|
||||
by adding a flag to specify the function used for moving instead of
|
||||
``std::move``.
|
||||
|
||||
- Improved :doc:`cppcoreguidelines-special-member-functions
|
||||
<clang-tidy/checks/cppcoreguidelines/special-member-functions>` check by
|
||||
|
||||
@@ -79,6 +79,10 @@ Options
|
||||
T other = std::forward<T>(t);
|
||||
}
|
||||
|
||||
.. option:: MoveFunction
|
||||
|
||||
Specify the function used for moving. Default is `::std::move`.
|
||||
|
||||
This check implements `F.18
|
||||
<http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#f18-for-will-move-from-parameters-pass-by-x-and-stdmove-the-parameter>`_
|
||||
from the C++ Core Guidelines.
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
// RUN: %check_clang_tidy -std=c++11 %s cppcoreguidelines-rvalue-reference-param-not-moved %t -- \
|
||||
// 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
|
||||
|
||||
// NOLINTBEGIN
|
||||
namespace std {
|
||||
template <typename>
|
||||
struct remove_reference;
|
||||
|
||||
template <typename _Tp> struct remove_reference { typedef _Tp type; };
|
||||
template <typename _Tp> struct remove_reference<_Tp&> { typedef _Tp type; };
|
||||
template <typename _Tp> struct remove_reference<_Tp&&> { typedef _Tp type; };
|
||||
|
||||
template <typename _Tp>
|
||||
constexpr typename std::remove_reference<_Tp>::type &&move(_Tp &&__t) noexcept;
|
||||
|
||||
template <typename _Tp>
|
||||
constexpr _Tp &&
|
||||
forward(typename remove_reference<_Tp>::type &__t) noexcept;
|
||||
|
||||
}
|
||||
// NOLINTEND
|
||||
|
||||
|
||||
struct Obj {
|
||||
Obj();
|
||||
Obj(const Obj&);
|
||||
Obj& operator=(const Obj&);
|
||||
Obj(Obj&&);
|
||||
Obj& operator=(Obj&&);
|
||||
void member() const;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
constexpr typename std::remove_reference<T>::type&& custom_move(T&& x) noexcept
|
||||
{
|
||||
return static_cast<typename std::remove_reference<T>::type&&>(x);
|
||||
}
|
||||
|
||||
void move_with_std(Obj&& o) {
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:26: warning: rvalue reference parameter 'o' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
|
||||
Obj other{std::move(o)};
|
||||
}
|
||||
|
||||
void move_with_custom(Obj&& o) {
|
||||
Obj other{custom_move(o)};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user