diff options
Diffstat (limited to 'clang-tools-extra/test/clang-tidy/performance-move-constructor-init.cpp')
-rw-r--r-- | clang-tools-extra/test/clang-tidy/performance-move-constructor-init.cpp | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/clang-tools-extra/test/clang-tidy/performance-move-constructor-init.cpp b/clang-tools-extra/test/clang-tidy/performance-move-constructor-init.cpp new file mode 100644 index 00000000000..c9ed3469894 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/performance-move-constructor-init.cpp @@ -0,0 +1,154 @@ +// RUN: %check_clang_tidy %s performance-move-constructor-init,modernize-pass-by-value %t -- \ +// RUN: -config='{CheckOptions: \ +// RUN: [{key: modernize-pass-by-value.ValuesOnly, value: 1}]}' \ +// RUN: -- -std=c++11 -isystem %S/Inputs/Headers + +#include <s.h> + +// CHECK-FIXES: #include <utility> + +template <class T> struct remove_reference {typedef T type;}; +template <class T> struct remove_reference<T&> {typedef T type;}; +template <class T> struct remove_reference<T&&> {typedef T type;}; + +template <typename T> +typename remove_reference<T>::type&& move(T&& arg) { + return static_cast<typename remove_reference<T>::type&&>(arg); +} + +struct C { + C() = default; + C(const C&) = default; +}; + +struct B { + B() {} + B(const B&) {} + B(B &&) {} +}; + +struct D : B { + D() : B() {} + D(const D &RHS) : B(RHS) {} + // CHECK-MESSAGES: :[[@LINE+3]]:16: warning: move constructor initializes base class by calling a copy constructor [performance-move-constructor-init] + // CHECK-MESSAGES: 26:3: note: copy constructor being called + // CHECK-MESSAGES: 27:3: note: candidate move constructor here + D(D &&RHS) : B(RHS) {} +}; + +struct E : B { + E() : B() {} + E(const E &RHS) : B(RHS) {} + E(E &&RHS) : B(move(RHS)) {} // ok +}; + +struct F { + C M; + + F(F &&) : M(C()) {} // ok +}; + +struct G { + G() = default; + G(const G&) = default; + G(G&&) = delete; +}; + +struct H : G { + H() = default; + H(const H&) = default; + H(H &&RHS) : G(RHS) {} // ok +}; + +struct I { + I(const I &) = default; // suppresses move constructor creation +}; + +struct J : I { + J(J &&RHS) : I(RHS) {} // ok +}; + +struct K {}; // Has implicit copy and move constructors, is trivially copyable +struct L : K { + L(L &&RHS) : K(RHS) {} // ok +}; + +struct M { + B Mem; + // CHECK-MESSAGES: :[[@LINE+1]]:16: warning: move constructor initializes class member by calling a copy constructor [performance-move-constructor-init] + M(M &&RHS) : Mem(RHS.Mem) {} +}; + +struct N { + B Mem; + N(N &&RHS) : Mem(move(RHS.Mem)) {} +}; + +struct O { + O(O&& other) : b(other.b) {} // ok + const B b; +}; + +struct P { + P(O&& other) : b(other.b) {} // ok + B b; +}; + +struct Movable { + Movable(Movable &&) = default; + Movable(const Movable &) = default; + Movable &operator=(const Movable &) = default; + ~Movable() {} +}; + +struct TriviallyCopyable { + TriviallyCopyable() = default; + TriviallyCopyable(TriviallyCopyable &&) = default; + TriviallyCopyable(const TriviallyCopyable &) = default; +}; + +struct Positive { + Positive(Movable M) : M_(M) {} + // CHECK-MESSAGES: [[@LINE-1]]:12: warning: pass by value and use std::move [modernize-pass-by-value] + // CHECK-FIXES: Positive(Movable M) : M_(std::move(M)) {} + Movable M_; +}; + +struct NegativeMultipleInitializerReferences { + NegativeMultipleInitializerReferences(Movable M) : M_(M), n_(M) {} + Movable M_; + Movable n_; +}; + +struct NegativeReferencedInConstructorBody { + NegativeReferencedInConstructorBody(Movable M) : M_(M) { M_ = M; } + Movable M_; +}; + +struct NegativeParamTriviallyCopyable { + NegativeParamTriviallyCopyable(TriviallyCopyable T) : T_(T) {} + NegativeParamTriviallyCopyable(int I) : I_(I) {} + + TriviallyCopyable T_; + int I_; +}; + +struct NegativeNotPassedByValue { + // This const ref constructor isn't warned about because the ValuesOnly option is set. + NegativeNotPassedByValue(const Movable &M) : M_(M) {} + NegativeNotPassedByValue(const Movable M) : M_(M) {} + NegativeNotPassedByValue(Movable &M) : M_(M) {} + NegativeNotPassedByValue(Movable *M) : M_(*M) {} + NegativeNotPassedByValue(const Movable *M) : M_(*M) {} + Movable M_; +}; + +struct Immovable { + Immovable(const Immovable &) = default; + Immovable(Immovable &&) = delete; +}; + +struct NegativeImmovableParameter { + NegativeImmovableParameter(Immovable I) : I_(I) {} + Immovable I_; +}; |