void MoveConstantArgumentCheck::registerMatchers(MatchFinder *Finder) {
if (!getLangOpts().CPlusPlus)
return;
- Finder->addMatcher(callExpr(unless(isInTemplateInstantiation()),
- callee(functionDecl(hasName("::std::move"))))
+ Finder->addMatcher(callExpr(callee(functionDecl(hasName("::std::move"))),
+ argumentCountIs(1),
+ unless(isInTemplateInstantiation()))
.bind("call-move"),
this);
}
void MoveConstantArgumentCheck::check(const MatchFinder::MatchResult &Result) {
const auto *CallMove = Result.Nodes.getNodeAs<CallExpr>("call-move");
- if (CallMove->getNumArgs() != 1)
- return;
const Expr *Arg = CallMove->getArg(0);
SourceManager &SM = Result.Context->getSourceManager();
if (!FileMoveRange.isValid())
return;
bool IsVariable = isa<DeclRefExpr>(Arg);
- auto Diag =
- diag(FileMoveRange.getBegin(), "std::move of the %select{|const }0"
- "%select{expression|variable}1 "
- "%select{|of trivially-copyable type }2"
- "has no effect; remove std::move()")
- << IsConstArg << IsVariable << IsTriviallyCopyable;
+ auto Diag = diag(FileMoveRange.getBegin(),
+ "std::move of the %select{|const }0"
+ "%select{expression|variable}1 "
+ "%select{|of a trivially-copyable type }2"
+ "has no effect; remove std::move()")
+ << IsConstArg << IsVariable << IsTriviallyCopyable;
auto BeforeArgumentsRange = Lexer::makeFileCharRange(
CharSourceRange::getCharRange(CallMove->getLocStart(),
misc-move-const-arg
===================
-The check warns if the result of ``std::move(x)`` is bound to a constant
-reference argument, e.g.:
+The check warns if ``std::move()`` is called with a constant argument or an
+argument of a trivially-copyable type, e.g.:
.. code:: c++
- void f(const string&);
- void g() {
- string s;
- F(std::move(s)); // Warning here. std::move() is not moving anything.
- }
+ const string s;
+ return std::move(s); // Warning: std::move of the const variable has no effect
+
+ int x;
+ return std::move(x); // Warning: std::move of the variable of a trivially-copyable type has no effect
-// RUN: %check_clang_tidy %s misc-move-const-arg %t -- -- -std=c++11
+// RUN: %check_clang_tidy %s misc-move-const-arg %t
namespace std {
template <typename> struct remove_reference;
int f1() {
return std::move(42);
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: std::move of the expression of trivially-copyable type has no effect; remove std::move() [misc-move-const-arg]
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: std::move of the expression of a trivially-copyable type has no effect; remove std::move() [misc-move-const-arg]
// CHECK-FIXES: return 42;
}
int f2(int x2) {
return std::move(x2);
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: std::move of the variable of trivially-copyable type
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: std::move of the variable of a trivially-copyable type
// CHECK-FIXES: return x2;
}
int *f3(int *x3) {
return std::move(x3);
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: std::move of the variable of trivially-copyable type
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: std::move of the variable of a trivially-copyable type
// CHECK-FIXES: return x3;
}