1// RUN: %check_clang_tidy %s performance-move-constructor-init,modernize-pass-by-value %t -- \
2// RUN: -config='{CheckOptions: \
3// RUN: {modernize-pass-by-value.ValuesOnly: true}}' \
4// RUN: -- -isystem %clang_tidy_headers
5
6#include <s.h>
7
8// CHECK-FIXES: #include <utility>
9
10template <class T> struct remove_reference {typedef T type;};
11template <class T> struct remove_reference<T&> {typedef T type;};
12template <class T> struct remove_reference<T&&> {typedef T type;};
13
14template <typename T>
15typename remove_reference<T>::type&& move(T&& arg) {
16 return static_cast<typename remove_reference<T>::type&&>(arg);
17}
18
19struct C {
20 C() = default;
21 C(const C&) = default;
22};
23
24struct B {
25 B() {}
26 B(const B&) {}
27 B(B &&) {}
28};
29
30struct D : B {
31 D() : B() {}
32 D(const D &RHS) : B(RHS) {}
33 // CHECK-NOTES: :[[@LINE+3]]:16: warning: move constructor initializes base class by calling a copy constructor [performance-move-constructor-init]
34 // CHECK-NOTES: 26:3: note: copy constructor being called
35 // CHECK-NOTES: 27:3: note: candidate move constructor here
36 D(D &&RHS) : B(RHS) {}
37};
38
39struct E : B {
40 E() : B() {}
41 E(const E &RHS) : B(RHS) {}
42 E(E &&RHS) : B(move(arg&: RHS)) {} // ok
43};
44
45struct F {
46 C M;
47
48 F(F &&) : M(C()) {} // ok
49};
50
51struct G {
52 G() = default;
53 G(const G&) = default;
54 G(G&&) = delete;
55};
56
57struct H : G {
58 H() = default;
59 H(const H&) = default;
60 H(H &&RHS) : G(RHS) {} // ok
61};
62
63struct I {
64 I(const I &) = default; // suppresses move constructor creation
65};
66
67struct J : I {
68 J(J &&RHS) : I(RHS) {} // ok
69};
70
71struct K {}; // Has implicit copy and move constructors, is trivially copyable
72struct L : K {
73 L(L &&RHS) : K(RHS) {} // ok
74};
75
76struct M {
77 B Mem;
78 // CHECK-NOTES: :[[@LINE+1]]:16: warning: move constructor initializes class member by calling a copy constructor [performance-move-constructor-init]
79 M(M &&RHS) : Mem(RHS.Mem) {}
80 // CHECK-NOTES: 26:3: note: copy constructor being called
81 // CHECK-NOTES: 27:3: note: candidate move constructor here
82};
83
84struct N {
85 B Mem;
86 N(N &&RHS) : Mem(move(arg&: RHS.Mem)) {}
87};
88
89struct O {
90 O(O&& other) : b(other.b) {} // ok
91 const B b;
92};
93
94struct P {
95 P(O&& other) : b(other.b) {} // ok
96 B b;
97};
98
99struct Movable {
100 Movable(Movable &&) = default;
101 Movable(const Movable &) = default;
102 Movable &operator=(const Movable &) = default;
103 ~Movable() {}
104};
105
106struct TriviallyCopyable {
107 TriviallyCopyable() = default;
108 TriviallyCopyable(TriviallyCopyable &&) = default;
109 TriviallyCopyable(const TriviallyCopyable &) = default;
110};
111
112struct Positive {
113 Positive(Movable M) : M_(M) {}
114 // CHECK-NOTES: [[@LINE-1]]:12: warning: pass by value and use std::move [modernize-pass-by-value]
115 // CHECK-FIXES: Positive(Movable M) : M_(std::move(M)) {}
116 Movable M_;
117};
118
119struct NegativeMultipleInitializerReferences {
120 NegativeMultipleInitializerReferences(Movable M) : M_(M), n_(M) {}
121 Movable M_;
122 Movable n_;
123};
124
125struct NegativeReferencedInConstructorBody {
126 NegativeReferencedInConstructorBody(Movable M) : M_(M) { M_ = M; }
127 Movable M_;
128};
129
130struct NegativeParamTriviallyCopyable {
131 NegativeParamTriviallyCopyable(TriviallyCopyable T) : T_(T) {}
132 NegativeParamTriviallyCopyable(int I) : I_(I) {}
133
134 TriviallyCopyable T_;
135 int I_;
136};
137
138struct NegativeNotPassedByValue {
139 // This const ref constructor isn't warned about because the ValuesOnly option is set.
140 NegativeNotPassedByValue(const Movable &M) : M_(M) {}
141 NegativeNotPassedByValue(const Movable M) : M_(M) {}
142 NegativeNotPassedByValue(Movable &M) : M_(M) {}
143 NegativeNotPassedByValue(Movable *M) : M_(*M) {}
144 NegativeNotPassedByValue(const Movable *M) : M_(*M) {}
145 Movable M_;
146};
147
148struct Immovable {
149 Immovable(const Immovable &) = default;
150 Immovable(Immovable &&) = delete;
151};
152
153struct NegativeImmovableParameter {
154 NegativeImmovableParameter(Immovable I) : I_(I) {}
155 Immovable I_;
156};
157

source code of clang-tools-extra/test/clang-tidy/checkers/performance/move-constructor-init.cpp