1 | // RUN: %check_clang_tidy %s modernize-use-equals-default %t -- -- -fno-delayed-template-parsing -fexceptions |
2 | |
3 | // Out of line definition. |
4 | class OL { |
5 | public: |
6 | OL(); |
7 | ~OL(); |
8 | }; |
9 | |
10 | OL::OL() {}; |
11 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use '= default' to define a trivial default constructor [modernize-use-equals-default] |
12 | // CHECK-FIXES: OL::OL() = default; |
13 | OL::~OL() {} |
14 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use '= default' to define a trivial destructor [modernize-use-equals-default] |
15 | // CHECK-FIXES: OL::~OL() = default; |
16 | |
17 | // Inline definitions. |
18 | class IL { |
19 | public: |
20 | IL() {} ; // Note embedded tab on this line |
21 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default' |
22 | // CHECK-FIXES: IL() = default ; // Note embedded tab on this line |
23 | ~IL() {} |
24 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default' |
25 | // CHECK-FIXES: ~IL() = default; |
26 | }; |
27 | |
28 | // Non-empty body. |
29 | void f(); |
30 | class NE { |
31 | public: |
32 | NE() { f(); } |
33 | ~NE() { f(); } |
34 | }; |
35 | |
36 | // Skip unions. |
37 | union NU { |
38 | NU() {} |
39 | // CHECK-FIXES: NU() {} |
40 | ~NU() {} |
41 | // CHECK-FIXES: ~NU() {} |
42 | NE Field; |
43 | }; |
44 | |
45 | // Skip unions with out-of-line constructor/destructor. |
46 | union NUO { |
47 | NUO(); |
48 | ~NUO(); |
49 | NE Field; |
50 | }; |
51 | |
52 | NUO::NUO() {} |
53 | // CHECK-FIXES: NUO::NUO() {} |
54 | NUO::~NUO() {} |
55 | // CHECK-FIXES: NUO::~NUO() {} |
56 | |
57 | // Skip structs/classes containing anonymous unions. |
58 | struct SU { |
59 | SU() {} |
60 | // CHECK-FIXES: SU() {} |
61 | ~SU() {} |
62 | // CHECK-FIXES: ~SU() {} |
63 | union { |
64 | NE Field; |
65 | }; |
66 | }; |
67 | |
68 | // Skip variadic constructors. |
69 | struct VA { |
70 | VA(...) {} |
71 | }; |
72 | |
73 | // Skip template constructors. |
74 | struct TC { |
75 | template <unsigned U> |
76 | TC() {} |
77 | |
78 | template <unsigned U> |
79 | TC(const TC &) {} |
80 | |
81 | template <unsigned U> |
82 | TC& operator = (const TC &) { return *this; } |
83 | }; |
84 | |
85 | // Initializer or arguments. |
86 | class IA { |
87 | public: |
88 | // Constructor with initializer. |
89 | IA() : Field(5) {} |
90 | // Constructor with arguments. |
91 | IA(int Arg1, int Arg2) {} |
92 | int Field; |
93 | }; |
94 | |
95 | // Default member initializer |
96 | class DMI { |
97 | public: |
98 | DMI() {} // Comment before semi-colon on next line |
99 | ; |
100 | // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use '= default' |
101 | // CHECK-FIXES: DMI() = default // Comment before semi-colon on next line |
102 | // CHECK-FIXES-NEXT: ; |
103 | int Field = 5; |
104 | }; |
105 | |
106 | // Class member |
107 | class CM { |
108 | public: |
109 | CM() {} /* Comments */ /* before */ /* semicolon */; |
110 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default' |
111 | // CHECK-FIXES: CM() = default /* Comments */ /* before */ /* semicolon */; |
112 | OL o; |
113 | }; |
114 | |
115 | // Private constructor/destructor. |
116 | class Priv { |
117 | Priv(); |
118 | ~Priv() {} |
119 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default' |
120 | // CHECK-FIXES: ~Priv() = default; |
121 | }; |
122 | |
123 | Priv::Priv() {} |
124 | // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use '= default' |
125 | // CHECK-FIXES: Priv::Priv() = default; |
126 | |
127 | struct SemiColon { |
128 | SemiColon() {}; |
129 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default' |
130 | // CHECK-FIXES: SemiColon() = default;{{$}} |
131 | }; |
132 | |
133 | struct SemiColonOutOfLine { |
134 | SemiColonOutOfLine(); |
135 | }; |
136 | |
137 | SemiColonOutOfLine::SemiColonOutOfLine() {}; |
138 | // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use '= default' |
139 | // CHECK-FIXES: SemiColonOutOfLine::SemiColonOutOfLine() = default;{{$}} |
140 | |
141 | // struct. |
142 | struct ST { |
143 | ST() {} |
144 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default' |
145 | // CHECK-FIXES: ST() = default;{{$}} |
146 | ~ST() {} |
147 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default' |
148 | // CHECK-FIXES: ST() = default;{{$}} |
149 | }; |
150 | |
151 | // Deleted constructor/destructor. |
152 | class Del { |
153 | public: |
154 | Del() = delete; |
155 | ~Del() = delete; |
156 | }; |
157 | |
158 | // Do not remove other keywords. |
159 | class KW { |
160 | public: |
161 | explicit KW() {} |
162 | // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use '= default' |
163 | // CHECK-FIXES: explicit KW() = default; |
164 | virtual ~KW() {} |
165 | // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use '= default' |
166 | // CHECK-FIXES: virtual ~KW() = default; |
167 | }; |
168 | |
169 | // Nested class. |
170 | struct N { |
171 | struct NN { |
172 | NN() {} |
173 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use '= default' |
174 | // CHECK-FIXES: NN() = default; |
175 | ~NN() {} |
176 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use '= default' |
177 | // CHECK-FIXES: ~NN() = default; |
178 | }; |
179 | int Int; |
180 | }; |
181 | |
182 | // Class template. |
183 | template <class T> |
184 | class Temp { |
185 | public: |
186 | Temp() {} |
187 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default' |
188 | // CHECK-FIXES: Temp() = default; |
189 | ~Temp() {} |
190 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default' |
191 | // CHECK-FIXES: ~Temp() = default; |
192 | }; |
193 | |
194 | // Class template out of line with explicit instantiation. |
195 | template <class T> |
196 | class TempODef { |
197 | public: |
198 | TempODef(); |
199 | ~TempODef(); |
200 | }; |
201 | |
202 | template <class T> |
203 | TempODef<T>::TempODef() {} |
204 | // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use '= default' |
205 | // CHECK-FIXES: TempODef<T>::TempODef() = default; |
206 | template <class T> |
207 | TempODef<T>::~TempODef() {} |
208 | // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use '= default' |
209 | // CHECK-FIXES: TempODef<T>::~TempODef() = default; |
210 | |
211 | template class TempODef<int>; |
212 | template class TempODef<double>; |
213 | |
214 | // Non user-provided constructor/destructor. |
215 | struct Imp { |
216 | int Int; |
217 | }; |
218 | void g() { |
219 | Imp *PtrImp = new Imp(); |
220 | PtrImp->~Imp(); |
221 | delete PtrImp; |
222 | } |
223 | |
224 | // Already using default. |
225 | struct IDef { |
226 | IDef() = default; |
227 | ~IDef() = default; |
228 | }; |
229 | struct ODef { |
230 | ODef(); |
231 | ~ODef(); |
232 | }; |
233 | ODef::ODef() = default; |
234 | ODef::~ODef() = default; |
235 | |
236 | // Delegating constructor and overriden destructor. |
237 | struct DC : KW { |
238 | DC() : KW() {} |
239 | ~DC() override {} |
240 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default' |
241 | // CHECK-FIXES: ~DC() override = default;{{$}} |
242 | }; |
243 | |
244 | struct OverrideWithSemiColon : KW { |
245 | ~OverrideWithSemiColon() override {}; |
246 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default' |
247 | // CHECK-FIXES: ~OverrideWithSemiColon() override = default;{{$}} |
248 | }; |
249 | |
250 | struct { |
251 | () { |
252 | // Don't erase comments inside the body. |
253 | } |
254 | // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use '= default' |
255 | () { |
256 | // Don't erase comments inside the body. |
257 | } |
258 | // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use '= default' |
259 | }; |
260 | |
261 | // Try-catch. |
262 | struct ITC { |
263 | ITC() try {} catch(...) {} |
264 | ~ITC() try {} catch(...) {} |
265 | }; |
266 | |
267 | struct OTC { |
268 | OTC(); |
269 | ~OTC(); |
270 | }; |
271 | OTC::OTC() try {} catch(...) {} |
272 | OTC::~OTC() try {} catch(...) {} |
273 | |
274 | #define STRUCT_WITH_DEFAULT(_base, _type) \ |
275 | struct _type { \ |
276 | _type() {} \ |
277 | _base value; \ |
278 | }; |
279 | |
280 | STRUCT_WITH_DEFAULT(unsigned char, InMacro) |
281 | |
282 | #define ZERO_VALUE 0 |
283 | struct PreprocesorDependentTest |
284 | { |
285 | void something(); |
286 | |
287 | PreprocesorDependentTest() { |
288 | #if ZERO_VALUE |
289 | something(); |
290 | #endif |
291 | } |
292 | |
293 | ~PreprocesorDependentTest() { |
294 | #if ZERO_VALUE |
295 | something(); |
296 | #endif |
297 | } |
298 | }; |
299 | |