1 | // RUN: %check_clang_tidy %s performance-noexcept-move-constructor %t -- -- -fexceptions |
---|---|
2 | // RUN: %check_clang_tidy -std=c++17 -check-suffixes=,ERR %s performance-noexcept-move-constructor %t \ |
3 | // RUN: -- --fix-errors -- -fexceptions -DENABLE_ERROR |
4 | |
5 | namespace std |
6 | { |
7 | template <typename T> |
8 | struct is_nothrow_move_constructible |
9 | { |
10 | static constexpr bool value = __is_nothrow_constructible(T, __add_rvalue_reference(T)); |
11 | }; |
12 | } // namespace std |
13 | |
14 | struct Empty |
15 | {}; |
16 | |
17 | struct IntWrapper { |
18 | int value; |
19 | }; |
20 | |
21 | template <typename T> |
22 | struct FalseT { |
23 | static constexpr bool value = false; |
24 | }; |
25 | |
26 | template <typename T> |
27 | struct TrueT { |
28 | static constexpr bool value = true; |
29 | }; |
30 | |
31 | struct ThrowOnAnything { |
32 | ThrowOnAnything() noexcept(false); |
33 | ThrowOnAnything(ThrowOnAnything&&) noexcept(false); |
34 | ThrowOnAnything& operator=(ThrowOnAnything &&) noexcept(false); |
35 | ~ThrowOnAnything() noexcept(false); |
36 | }; |
37 | |
38 | class A { |
39 | A(A &&); |
40 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: move constructors should be marked noexcept [performance-noexcept-move-constructor] |
41 | // CHECK-FIXES: A(A &&) noexcept ; |
42 | A &operator=(A &&); |
43 | // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: move assignment operators should be marked noexcept [performance-noexcept-move-constructor] |
44 | // CHECK-FIXES: A &operator=(A &&) noexcept ; |
45 | }; |
46 | |
47 | struct B { |
48 | static constexpr bool kFalse = false; |
49 | B(B &&) noexcept(kFalse); |
50 | // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: noexcept specifier on the move constructor evaluates to 'false' [performance-noexcept-move-constructor] |
51 | B &operator=(B &&) noexcept(kFalse); |
52 | // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: noexcept specifier on the move assignment operator evaluates to 'false' [performance-noexcept-move-constructor] |
53 | }; |
54 | |
55 | template <typename> |
56 | struct C { |
57 | C(C &&); |
58 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: move constructors should be marked noexcept [performance-noexcept-move-constructor] |
59 | // CHECK-FIXES: C(C &&) noexcept ; |
60 | C& operator=(C &&); |
61 | // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: move assignment operators should be marked noexcept [performance-noexcept-move-constructor] |
62 | // CHECK-FIXES: C& operator=(C &&) noexcept ; |
63 | }; |
64 | |
65 | struct D { |
66 | static constexpr bool kFalse = false; |
67 | D(D &&) noexcept(kFalse) = default; |
68 | // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: noexcept specifier on the move constructor evaluates to 'false' [performance-noexcept-move-constructor] |
69 | D& operator=(D &&) noexcept(kFalse) = default; |
70 | // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: noexcept specifier on the move assignment operator evaluates to 'false' [performance-noexcept-move-constructor] |
71 | }; |
72 | |
73 | template <typename> |
74 | struct E { |
75 | static constexpr bool kFalse = false; |
76 | E(E &&) noexcept(kFalse); |
77 | // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: noexcept specifier on the move constructor evaluates to 'false' [performance-noexcept-move-constructor] |
78 | E& operator=(E &&) noexcept(kFalse); |
79 | // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: noexcept specifier on the move assignment operator evaluates to 'false' |
80 | }; |
81 | |
82 | template <typename> |
83 | struct F { |
84 | static constexpr bool kFalse = false; |
85 | F(F &&) noexcept(kFalse) = default; |
86 | // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: noexcept specifier on the move constructor evaluates to 'false' [performance-noexcept-move-constructor] |
87 | F& operator=(F &&) noexcept(kFalse) = default; |
88 | // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: noexcept specifier on the move assignment operator evaluates to 'false' [performance-noexcept-move-constructor] |
89 | }; |
90 | |
91 | struct G { |
92 | G(G &&) = default; |
93 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: move constructors should be marked noexcept [performance-noexcept-move-constructor] |
94 | // CHECK-FIXES: G(G &&) noexcept = default; |
95 | G& operator=(G &&) = default; |
96 | // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: move assignment operators should be marked noexcept [performance-noexcept-move-constructor] |
97 | // CHECK-FIXES: G& operator=(G &&) noexcept = default; |
98 | |
99 | ThrowOnAnything field; |
100 | }; |
101 | |
102 | void throwing_function() noexcept(false) {} |
103 | |
104 | struct H { |
105 | H(H &&) noexcept(noexcept(throwing_function())); |
106 | // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: noexcept specifier on the move constructor evaluates to 'false' [performance-noexcept-move-constructor] |
107 | H &operator=(H &&) noexcept(noexcept(throwing_function())); |
108 | // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: noexcept specifier on the move assignment operator evaluates to 'false' [performance-noexcept-move-constructor] |
109 | }; |
110 | |
111 | template <typename> |
112 | struct I { |
113 | I(I &&) noexcept(noexcept(throwing_function())); |
114 | // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: noexcept specifier on the move constructor evaluates to 'false' [performance-noexcept-move-constructor] |
115 | I &operator=(I &&) noexcept(noexcept(throwing_function())); |
116 | // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: noexcept specifier on the move assignment operator evaluates to 'false' [performance-noexcept-move-constructor] |
117 | }; |
118 | |
119 | template <typename T> struct TemplatedType { |
120 | static void f() {} |
121 | }; |
122 | |
123 | template <> struct TemplatedType<int> { |
124 | static void f() noexcept {} |
125 | }; |
126 | |
127 | struct J { |
128 | J(J &&) noexcept(noexcept(TemplatedType<double>::f())); |
129 | // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: noexcept specifier on the move constructor evaluates to 'false' [performance-noexcept-move-constructor] |
130 | J &operator=(J &&) noexcept(noexcept(TemplatedType<double>::f())); |
131 | // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: noexcept specifier on the move assignment operator evaluates to 'false' [performance-noexcept-move-constructor] |
132 | }; |
133 | |
134 | struct K : public ThrowOnAnything { |
135 | K(K &&) = default; |
136 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: move constructors should be marked noexcept [performance-noexcept-move-constructor] |
137 | // CHECK-FIXES: K(K &&) noexcept = default; |
138 | K &operator=(K &&) = default; |
139 | // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: move assignment operators should be marked noexcept [performance-noexcept-move-constructor] |
140 | // CHECK-FIXES: K &operator=(K &&) noexcept = default; |
141 | }; |
142 | |
143 | struct InheritFromThrowOnAnything : public ThrowOnAnything |
144 | {}; |
145 | |
146 | struct L { |
147 | L(L &&) = default; |
148 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: move constructors should be marked noexcept [performance-noexcept-move-constructor] |
149 | // CHECK-FIXES: L(L &&) noexcept = default; |
150 | L &operator=(L &&) = default; |
151 | // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: move assignment operators should be marked noexcept [performance-noexcept-move-constructor] |
152 | // CHECK-FIXES: L &operator=(L &&) noexcept = default; |
153 | |
154 | InheritFromThrowOnAnything IFF; |
155 | }; |
156 | |
157 | struct M : public InheritFromThrowOnAnything { |
158 | M(M &&) = default; |
159 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: move constructors should be marked noexcept [performance-noexcept-move-constructor] |
160 | // CHECK-FIXES: M(M &&) noexcept = default; |
161 | M &operator=(M &&) = default; |
162 | // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: move assignment operators should be marked noexcept [performance-noexcept-move-constructor] |
163 | // CHECK-FIXES: M &operator=(M &&) noexcept = default; |
164 | }; |
165 | |
166 | struct N : public IntWrapper, ThrowOnAnything { |
167 | N(N &&) = default; |
168 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: move constructors should be marked noexcept [performance-noexcept-move-constructor] |
169 | // CHECK-FIXES: N(N &&) noexcept = default; |
170 | N &operator=(N &&) = default; |
171 | // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: move assignment operators should be marked noexcept [performance-noexcept-move-constructor] |
172 | // CHECK-FIXES: N &operator=(N &&) noexcept = default; |
173 | }; |
174 | |
175 | struct O : virtual IntWrapper, ThrowOnAnything { |
176 | O(O &&) = default; |
177 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: move constructors should be marked noexcept [performance-noexcept-move-constructor] |
178 | // CHECK-FIXES: O(O &&) noexcept = default; |
179 | O &operator=(O &&) = default; |
180 | // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: move assignment operators should be marked noexcept [performance-noexcept-move-constructor] |
181 | // CHECK-FIXES: O &operator=(O &&) noexcept = default; |
182 | }; |
183 | |
184 | class OK {}; |
185 | |
186 | void f() { |
187 | OK a; |
188 | a = OK(); |
189 | } |
190 | |
191 | struct OK1 { |
192 | OK1(const OK1 &); |
193 | OK1(OK1 &&) noexcept; |
194 | OK1 &operator=(OK1 &&) noexcept; |
195 | void f(); |
196 | void g() noexcept; |
197 | }; |
198 | |
199 | struct OK2 { |
200 | static constexpr bool kTrue = true; |
201 | |
202 | OK2(OK2 &&) noexcept(true) {} |
203 | OK2 &operator=(OK2 &&) noexcept(kTrue) { return *this; } |
204 | }; |
205 | |
206 | struct OK4 { |
207 | OK4(OK4 &&) noexcept(false) {} |
208 | OK4 &operator=(OK4 &&) = delete; |
209 | }; |
210 | |
211 | struct OK3 { |
212 | OK3(OK3 &&) noexcept = default; |
213 | OK3 &operator=(OK3 &&) noexcept = default; |
214 | }; |
215 | |
216 | struct OK5 { |
217 | OK5(OK5 &&) noexcept(true) = default; |
218 | OK5 &operator=(OK5 &&) noexcept(true) = default; |
219 | }; |
220 | |
221 | struct OK6 { |
222 | OK6(OK6 &&) = default; |
223 | OK6& operator=(OK6 &&) = default; |
224 | }; |
225 | |
226 | template <typename> |
227 | struct OK7 { |
228 | OK7(OK7 &&) = default; |
229 | OK7& operator=(OK7 &&) = default; |
230 | }; |
231 | |
232 | template <typename> |
233 | struct OK8 { |
234 | OK8(OK8 &&) noexcept = default; |
235 | OK8& operator=(OK8 &&) noexcept = default; |
236 | }; |
237 | |
238 | template <typename> |
239 | struct OK9 { |
240 | OK9(OK9 &&) noexcept(true) = default; |
241 | OK9& operator=(OK9 &&) noexcept(true) = default; |
242 | }; |
243 | |
244 | template <typename> |
245 | struct OK10 { |
246 | OK10(OK10 &&) noexcept(false) = default; |
247 | OK10& operator=(OK10 &&) noexcept(false) = default; |
248 | }; |
249 | |
250 | template <typename> |
251 | struct OK11 { |
252 | OK11(OK11 &&) = delete; |
253 | OK11& operator=(OK11 &&) = delete; |
254 | }; |
255 | |
256 | void noexcept_function() noexcept {} |
257 | |
258 | struct OK12 { |
259 | OK12(OK12 &&) noexcept(noexcept(noexcept_function())); |
260 | OK12 &operator=(OK12 &&) noexcept(noexcept(noexcept_function)); |
261 | }; |
262 | |
263 | struct OK13 { |
264 | OK13(OK13 &&) noexcept(noexcept(noexcept_function)) = default; |
265 | OK13 &operator=(OK13 &&) noexcept(noexcept(noexcept_function)) = default; |
266 | }; |
267 | |
268 | template <typename> |
269 | struct OK14 { |
270 | OK14(OK14 &&) noexcept(noexcept(TemplatedType<int>::f())); |
271 | OK14 &operator=(OK14 &&) noexcept(noexcept(TemplatedType<int>::f())); |
272 | }; |
273 | |
274 | struct OK15 { |
275 | OK15(OK15 &&) = default; |
276 | OK15 &operator=(OK15 &&) = default; |
277 | |
278 | int member; |
279 | }; |
280 | |
281 | template <typename> |
282 | struct OK16 { |
283 | OK16(OK16 &&) = default; |
284 | OK16 &operator=(OK16 &&) = default; |
285 | |
286 | int member; |
287 | }; |
288 | |
289 | struct OK17 { |
290 | OK17(OK17 &&) = default; |
291 | OK17 &operator=(OK17 &&) = default; |
292 | |
293 | OK empty_field; |
294 | }; |
295 | |
296 | template <typename> |
297 | struct OK18 { |
298 | OK18(OK18 &&) = default; |
299 | OK18 &operator=(OK18 &&) = default; |
300 | |
301 | OK empty_field; |
302 | }; |
303 | |
304 | struct OK19 : public OK { |
305 | OK19(OK19 &&) = default; |
306 | OK19 &operator=(OK19 &&) = default; |
307 | }; |
308 | |
309 | struct OK20 : virtual OK { |
310 | OK20(OK20 &&) = default; |
311 | OK20 &operator=(OK20 &&) = default; |
312 | }; |
313 | |
314 | template <typename T> |
315 | struct OK21 : public T { |
316 | OK21() = default; |
317 | OK21(OK21 &&) = default; |
318 | OK21 &operator=(OK21 &&) = default; |
319 | }; |
320 | |
321 | template <typename T> |
322 | struct OK22 : virtual T { |
323 | OK22() = default; |
324 | OK22(OK22 &&) = default; |
325 | OK22 &operator=(OK22 &&) = default; |
326 | }; |
327 | |
328 | template <typename T> |
329 | struct OK23 { |
330 | OK23() = default; |
331 | OK23(OK23 &&) = default; |
332 | OK23 &operator=(OK23 &&) = default; |
333 | |
334 | T member; |
335 | }; |
336 | |
337 | void testTemplates() { |
338 | OK21<Empty> value(OK21<Empty>{}); |
339 | value = OK21<Empty>{}; |
340 | |
341 | OK22<Empty> value2{OK22<Empty>{}}; |
342 | value2 = OK22<Empty>{}; |
343 | |
344 | OK23<Empty> value3{OK23<Empty>{}}; |
345 | value3 =OK23<Empty>{}; |
346 | } |
347 | |
348 | struct OK24 : public Empty, OK1 { |
349 | OK24(OK24 &&) = default; |
350 | OK24 &operator=(OK24 &&) = default; |
351 | }; |
352 | |
353 | struct OK25 : virtual Empty, OK1 { |
354 | OK25(OK25 &&) = default; |
355 | OK25 &operator=(OK25 &&) = default; |
356 | }; |
357 | |
358 | struct OK26 : public Empty, IntWrapper { |
359 | OK26(OK26 &&) = default; |
360 | OK26 &operator=(OK26 &&) = default; |
361 | }; |
362 | |
363 | template <typename T> |
364 | struct OK27 : public T { |
365 | OK27(OK27 &&) = default; |
366 | OK27 &operator=(OK27 &&) = default; |
367 | }; |
368 | |
369 | template <typename T> |
370 | struct OK28 : virtual T { |
371 | OK28(OK28 &&) = default; |
372 | OK28 &operator=(OK28 &&) = default; |
373 | }; |
374 | |
375 | template <typename T> |
376 | struct OK29 { |
377 | OK29(OK29 &&) = default; |
378 | OK29 &operator=(OK29 &&) = default; |
379 | |
380 | T member; |
381 | }; |
382 | |
383 | struct OK30 { |
384 | OK30(OK30 &&) noexcept(TrueT<OK30>::value) = default; |
385 | OK30& operator=(OK30 &&) noexcept(TrueT<OK30>::value) = default; |
386 | }; |
387 | |
388 | template <typename> |
389 | struct OK31 { |
390 | OK31(OK31 &&) noexcept(TrueT<int>::value) = default; |
391 | OK31& operator=(OK31 &&) noexcept(TrueT<int>::value) = default; |
392 | }; |
393 | |
394 | namespace gh68101 |
395 | { |
396 | template <typename T> |
397 | class Container { |
398 | public: |
399 | Container(Container&&) noexcept(std::is_nothrow_move_constructible<T>::value); |
400 | }; |
401 | } // namespace gh68101 |
402 | |
403 | namespace gh111436 |
404 | { |
405 | |
406 | template <typename value_type> class set { |
407 | set(set &&) = default; |
408 | |
409 | #ifdef ENABLE_ERROR |
410 | set(initializer_list<value_type> __l) {}; |
411 | // CHECK-MESSAGES-ERR: :[[@LINE-1]]:7: error: member 'initializer_list' cannot have template arguments [clang-diagnostic-error] |
412 | // CHECK-MESSAGES-ERR: :[[@LINE-2]]:36: error: expected ')' [clang-diagnostic-error] |
413 | #endif |
414 | }; |
415 | |
416 | } // namespace gh111436 |
417 |
Definitions
- is_nothrow_move_constructible
- value
- Empty
- IntWrapper
- FalseT
- value
- TrueT
- value
- ThrowOnAnything
- A
- B
- kFalse
- C
- D
- kFalse
- D
- operator=
- E
- kFalse
- F
- kFalse
- F
- operator=
- G
- G
- operator=
- throwing_function
- H
- I
- TemplatedType
- f
- TemplatedType
- f
- J
- K
- K
- operator=
- InheritFromThrowOnAnything
- L
- L
- operator=
- M
- M
- operator=
- N
- N
- operator=
- O
- O
- operator=
- OK
- f
- OK1
- OK2
- kTrue
- OK2
- operator=
- OK4
- OK4
- operator=
- OK3
- OK3
- operator=
- OK5
- OK5
- operator=
- OK6
- OK6
- operator=
- OK7
- OK7
- operator=
- OK8
- OK8
- operator=
- OK9
- OK9
- operator=
- OK10
- OK10
- operator=
- OK11
- OK11
- operator=
- noexcept_function
- OK12
- OK13
- OK13
- operator=
- OK14
- OK15
- OK15
- operator=
- OK16
- OK16
- operator=
- OK17
- OK17
- operator=
- OK18
- OK18
- operator=
- OK19
- OK19
- operator=
- OK20
- OK20
- operator=
- OK21
- OK21
- OK21
- operator=
- OK22
- OK22
- OK22
- operator=
- OK23
- OK23
- OK23
- operator=
- testTemplates
- OK24
- OK24
- operator=
- OK25
- OK25
- operator=
- OK26
- OK26
- operator=
- OK27
- OK27
- operator=
- OK28
- OK28
- operator=
- OK29
- OK29
- operator=
- OK30
- OK30
- operator=
- OK31
- OK31
- operator=
- Container
- set
Learn to use CMake with our Intro Training
Find out more