| // RUN: %check_clang_tidy %s performance-move-const-arg %t \ |
| // RUN: -config='{CheckOptions: \ |
| // RUN: [{key: performance-move-const-arg.CheckTriviallyCopyableMove, value: 0}]}' \ |
| // RUN: -- -std=c++14 |
| |
| 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) { |
| return static_cast<typename std::remove_reference<_Tp>::type &&>(__t); |
| } |
| |
| template <typename _Tp> |
| constexpr _Tp && |
| forward(typename remove_reference<_Tp>::type &__t) noexcept { |
| return static_cast<_Tp &&>(__t); |
| } |
| |
| } // namespace std |
| |
| class NoMoveSemantics { |
| public: |
| NoMoveSemantics(); |
| NoMoveSemantics(const NoMoveSemantics &); |
| |
| NoMoveSemantics &operator=(const NoMoveSemantics &); |
| }; |
| |
| void callByConstRef(const NoMoveSemantics &); |
| void callByConstRef(int i, const NoMoveSemantics &); |
| |
| void moveToConstReferencePositives() { |
| NoMoveSemantics obj; |
| |
| // Basic case. It is here just to have a single "detected and fixed" case. |
| callByConstRef(std::move(obj)); |
| // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: passing result of std::move() as a const reference argument; no move will actually happen [performance-move-const-arg] |
| // CHECK-FIXES: callByConstRef(obj); |
| } |
| |
| struct TriviallyCopyable { |
| int i; |
| }; |
| |
| void f(TriviallyCopyable) {} |
| |
| void g() { |
| TriviallyCopyable obj; |
| f(std::move(obj)); |
| } |
| |
| class MoveSemantics { |
| public: |
| MoveSemantics(); |
| MoveSemantics(MoveSemantics &&); |
| |
| MoveSemantics &operator=(MoveSemantics &&); |
| }; |
| |
| void fmovable(MoveSemantics); |
| |
| void lambda1() { |
| auto f = [](MoveSemantics m) { |
| fmovable(std::move(m)); |
| }; |
| f(MoveSemantics()); |
| } |
| |
| template<class T> struct function {}; |
| |
| template<typename Result, typename... Args> |
| class function<Result(Args...)> { |
| public: |
| function() = default; |
| void operator()(Args... args) const { |
| fmovable(std::forward<Args>(args)...); |
| } |
| }; |
| |
| void functionInvocation() { |
| function<void(MoveSemantics)> callback; |
| MoveSemantics m; |
| callback(std::move(m)); |
| } |
| |
| void lambda2() { |
| function<void(MoveSemantics)> callback; |
| |
| auto f = [callback = std::move(callback)](MoveSemantics m) mutable { |
| callback(std::move(m)); |
| }; |
| f(MoveSemantics()); |
| } |