Index: clang-tidy/misc/MoveConstantArgumentCheck.cpp =================================================================== --- clang-tidy/misc/MoveConstantArgumentCheck.cpp +++ clang-tidy/misc/MoveConstantArgumentCheck.cpp @@ -85,6 +85,10 @@ return; } } + + if (!IsConstArg && IsTriviallyCopyable) + return; + bool IsVariable = isa(Arg); const auto *Var = IsVariable ? dyn_cast(Arg)->getDecl() : nullptr; Index: test/clang-tidy/misc-move-const-arg.cpp =================================================================== --- test/clang-tidy/misc-move-const-arg.cpp +++ test/clang-tidy/misc-move-const-arg.cpp @@ -14,6 +14,12 @@ return static_cast::type &&>(__t); } +template +constexpr _Tp && +forward(typename remove_reference<_Tp>::type &__t) noexcept { + return static_cast<_Tp &&>(__t); +} + } // namespace std class A { @@ -23,22 +29,18 @@ A(A &&rhs) {} }; -int f1() { - return std::move(42); - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: std::move of the expression of the trivially-copyable type 'int' has no effect; remove std::move() [misc-move-const-arg] - // CHECK-FIXES: return 42; -} +struct TriviallyCopyable { + int i; +}; -int f2(int x2) { - return std::move(x2); - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: std::move of the variable 'x2' of the trivially-copyable type 'int' - // CHECK-FIXES: return x2; -} +void f(TriviallyCopyable) {} + +void g() { + TriviallyCopyable obj; + f(std::move(obj)); -int *f3(int *x3) { - return std::move(x3); - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: std::move of the variable 'x3' of the trivially-copyable type 'int *' - // CHECK-FIXES: return x3; + // xCHECK-MESSAGES: :[[@LINE-1]]:10: warning: std::move of the expression of the trivially-copyable type 'int' has no effect; remove std::move() [misc-move-const-arg] + // xCHECK-FIXES: return 42; } A f4(A x4) { return std::move(x4); } @@ -176,3 +178,38 @@ void moveOnlyNegatives(MoveOnly val) { Q(std::move(val)); } + +void fmovable(MoveSemantics); + +void lambda1() { + auto f = [](MoveSemantics m) { + fmovable(std::move(m)); + }; + f(MoveSemantics()); +} + +template struct function {}; + +template +class function { +public: + function() = default; + void operator()(Args... args) const { + fmovable(std::forward(args)...); + } +}; + +void functionInvocation() { + function callback; + MoveSemantics m; + callback(std::move(m)); +} + +void lambda2() { + function callback; + + auto f = [callback = std::move(callback)](MoveSemantics m) mutable { + callback(std::move(m)); + }; + f(MoveSemantics()); +}