1 | // RUN: %check_clang_tidy %s modernize-use-emplace %t -- \ |
---|---|
2 | // RUN: -config="{CheckOptions: \ |
3 | // RUN: {modernize-use-emplace.ContainersWithPushBack: \ |
4 | // RUN: '::std::vector; ::std::list; ::std::deque; llvm::LikeASmallVector', \ |
5 | // RUN: modernize-use-emplace.TupleTypes: \ |
6 | // RUN: '::std::pair; std::tuple; ::test::Single', \ |
7 | // RUN: modernize-use-emplace.TupleMakeFunctions: \ |
8 | // RUN: '::std::make_pair; ::std::make_tuple; ::test::MakeSingle'}}" |
9 | |
10 | namespace std { |
11 | template <typename E> |
12 | class initializer_list { |
13 | public: |
14 | const E *a, *b; |
15 | initializer_list() noexcept {} |
16 | }; |
17 | |
18 | template <typename T1, typename T2> |
19 | class pair { |
20 | public: |
21 | pair() = default; |
22 | pair(const pair &) = default; |
23 | pair(pair &&) = default; |
24 | |
25 | pair(const T1 &, const T2 &) {} |
26 | pair(T1 &&, T2 &&) {} |
27 | |
28 | template <typename U1, typename U2> |
29 | pair(const pair<U1, U2> &){}; |
30 | template <typename U1, typename U2> |
31 | pair(pair<U1, U2> &&){}; |
32 | }; |
33 | |
34 | template <typename T> |
35 | class vector { |
36 | public: |
37 | using value_type = T; |
38 | |
39 | class iterator {}; |
40 | class const_iterator {}; |
41 | const_iterator begin() { return const_iterator{}; } |
42 | |
43 | vector() = default; |
44 | vector(initializer_list<T>) {} |
45 | |
46 | void push_back(const T &) {} |
47 | void push_back(T &&) {} |
48 | |
49 | template <typename... Args> |
50 | void emplace_back(Args &&... args){}; |
51 | template <typename... Args> |
52 | iterator emplace(const_iterator pos, Args &&...args); |
53 | ~vector(); |
54 | }; |
55 | |
56 | template <typename T> |
57 | class list { |
58 | public: |
59 | using value_type = T; |
60 | |
61 | class iterator {}; |
62 | class const_iterator {}; |
63 | const_iterator begin() { return const_iterator{}; } |
64 | |
65 | void push_front(const T &) {} |
66 | void push_front(T &&) {} |
67 | |
68 | void push_back(const T &) {} |
69 | void push_back(T &&) {} |
70 | |
71 | template <typename... Args> |
72 | iterator emplace(const_iterator pos, Args &&...args); |
73 | template <typename... Args> |
74 | void emplace_back(Args &&... args){}; |
75 | template <typename... Args> |
76 | void emplace_front(Args &&...args){}; |
77 | ~list(); |
78 | }; |
79 | |
80 | template <typename T> |
81 | class deque { |
82 | public: |
83 | using value_type = T; |
84 | |
85 | class iterator {}; |
86 | class const_iterator {}; |
87 | const_iterator begin() { return const_iterator{}; } |
88 | |
89 | void push_back(const T &) {} |
90 | void push_back(T &&) {} |
91 | |
92 | void push_front(const T &) {} |
93 | void push_front(T &&) {} |
94 | |
95 | template <typename... Args> |
96 | iterator emplace(const_iterator pos, Args &&...args); |
97 | template <typename... Args> |
98 | void emplace_back(Args &&... args){}; |
99 | template <typename... Args> |
100 | void emplace_front(Args &&...args){}; |
101 | ~deque(); |
102 | }; |
103 | |
104 | template <typename T> |
105 | class forward_list { |
106 | public: |
107 | using value_type = T; |
108 | |
109 | class iterator {}; |
110 | class const_iterator {}; |
111 | const_iterator begin() { return const_iterator{}; } |
112 | |
113 | void push_front(const T &) {} |
114 | void push_front(T &&) {} |
115 | |
116 | template <typename... Args> |
117 | void emplace_front(Args &&...args){}; |
118 | template <typename... Args> |
119 | iterator emplace_after(const_iterator pos, Args &&...args); |
120 | }; |
121 | |
122 | template <typename T> |
123 | class set { |
124 | public: |
125 | using value_type = T; |
126 | |
127 | class iterator {}; |
128 | class const_iterator {}; |
129 | const_iterator begin() { return const_iterator{}; } |
130 | |
131 | template <typename... Args> |
132 | void emplace(Args &&...args){}; |
133 | template <typename... Args> |
134 | iterator emplace_hint(const_iterator pos, Args &&...args); |
135 | }; |
136 | |
137 | template <typename Key, typename T> |
138 | class map { |
139 | public: |
140 | using value_type = std::pair<Key, T>; |
141 | |
142 | class iterator {}; |
143 | class const_iterator {}; |
144 | const_iterator begin() { return const_iterator{}; } |
145 | |
146 | template <typename... Args> |
147 | void emplace(Args &&...args){}; |
148 | template <typename... Args> |
149 | iterator emplace_hint(const_iterator pos, Args &&...args); |
150 | }; |
151 | |
152 | template <typename T> |
153 | class multiset { |
154 | public: |
155 | using value_type = T; |
156 | |
157 | class iterator {}; |
158 | class const_iterator {}; |
159 | const_iterator begin() { return const_iterator{}; } |
160 | |
161 | template <typename... Args> |
162 | void emplace(Args &&...args){}; |
163 | template <typename... Args> |
164 | iterator emplace_hint(const_iterator pos, Args &&...args); |
165 | }; |
166 | |
167 | template <typename Key, typename T> |
168 | class multimap { |
169 | public: |
170 | using value_type = std::pair<Key, T>; |
171 | |
172 | class iterator {}; |
173 | class const_iterator {}; |
174 | const_iterator begin() { return const_iterator{}; } |
175 | |
176 | template <typename... Args> |
177 | void emplace(Args &&...args){}; |
178 | template <typename... Args> |
179 | iterator emplace_hint(const_iterator pos, Args &&...args); |
180 | }; |
181 | |
182 | template <typename T> |
183 | class unordered_set { |
184 | public: |
185 | using value_type = T; |
186 | |
187 | class iterator {}; |
188 | class const_iterator {}; |
189 | const_iterator begin() { return const_iterator{}; } |
190 | |
191 | template <typename... Args> |
192 | void emplace(Args &&...args){}; |
193 | template <typename... Args> |
194 | iterator emplace_hint(const_iterator pos, Args &&...args); |
195 | }; |
196 | |
197 | template <typename Key, typename T> |
198 | class unordered_map { |
199 | public: |
200 | using value_type = std::pair<Key, T>; |
201 | |
202 | class iterator {}; |
203 | class const_iterator {}; |
204 | const_iterator begin() { return const_iterator{}; } |
205 | |
206 | template <typename... Args> |
207 | void emplace(Args &&...args){}; |
208 | template <typename... Args> |
209 | iterator emplace_hint(const_iterator pos, Args &&...args); |
210 | }; |
211 | |
212 | template <typename T> |
213 | class unordered_multiset { |
214 | public: |
215 | using value_type = T; |
216 | |
217 | class iterator {}; |
218 | class const_iterator {}; |
219 | const_iterator begin() { return const_iterator{}; } |
220 | |
221 | template <typename... Args> |
222 | void emplace(Args &&...args){}; |
223 | template <typename... Args> |
224 | iterator emplace_hint(const_iterator pos, Args &&...args); |
225 | }; |
226 | |
227 | template <typename Key, typename T> |
228 | class unordered_multimap { |
229 | public: |
230 | using value_type = std::pair<Key, T>; |
231 | |
232 | class iterator {}; |
233 | class const_iterator {}; |
234 | const_iterator begin() { return const_iterator{}; } |
235 | |
236 | template <typename... Args> |
237 | void emplace(Args &&...args){}; |
238 | template <typename... Args> |
239 | iterator emplace_hint(const_iterator pos, Args &&...args); |
240 | }; |
241 | |
242 | template <typename T> |
243 | class stack { |
244 | public: |
245 | using value_type = T; |
246 | |
247 | void push(const T &) {} |
248 | void push(T &&) {} |
249 | |
250 | template <typename... Args> |
251 | void emplace(Args &&...args){}; |
252 | }; |
253 | |
254 | template <typename T> |
255 | class queue { |
256 | public: |
257 | using value_type = T; |
258 | |
259 | void push(const T &) {} |
260 | void push(T &&) {} |
261 | |
262 | template <typename... Args> |
263 | void emplace(Args &&...args){}; |
264 | }; |
265 | |
266 | template <typename T> |
267 | class priority_queue { |
268 | public: |
269 | using value_type = T; |
270 | |
271 | void push(const T &) {} |
272 | void push(T &&) {} |
273 | |
274 | template <typename... Args> |
275 | void emplace(Args &&...args){}; |
276 | }; |
277 | |
278 | template <typename T> |
279 | struct remove_reference { using type = T; }; |
280 | template <typename T> |
281 | struct remove_reference<T &> { using type = T; }; |
282 | template <typename T> |
283 | struct remove_reference<T &&> { using type = T; }; |
284 | |
285 | template <typename T1, typename T2> |
286 | pair<typename remove_reference<T1>::type, typename remove_reference<T2>::type> |
287 | make_pair(T1 &&, T2 &&) { |
288 | return {}; |
289 | }; |
290 | |
291 | template <typename... Ts> |
292 | class tuple { |
293 | public: |
294 | tuple() = default; |
295 | tuple(const tuple &) = default; |
296 | tuple(tuple &&) = default; |
297 | |
298 | tuple(const Ts &...) {} |
299 | tuple(Ts &&...) {} |
300 | |
301 | template <typename... Us> |
302 | tuple(const tuple<Us...> &){}; |
303 | template <typename... Us> |
304 | tuple(tuple<Us...> &&) {} |
305 | |
306 | template <typename U1, typename U2> |
307 | tuple(const pair<U1, U2> &) { |
308 | static_assert(sizeof...(Ts) == 2, "Wrong tuple size"); |
309 | }; |
310 | template <typename U1, typename U2> |
311 | tuple(pair<U1, U2> &&) { |
312 | static_assert(sizeof...(Ts) == 2, "Wrong tuple size"); |
313 | }; |
314 | }; |
315 | |
316 | template <typename... Ts> |
317 | tuple<typename remove_reference<Ts>::type...> make_tuple(Ts &&...) { |
318 | return {}; |
319 | } |
320 | |
321 | template <typename T> |
322 | class unique_ptr { |
323 | public: |
324 | explicit unique_ptr(T *) {} |
325 | ~unique_ptr(); |
326 | }; |
327 | } // namespace std |
328 | |
329 | namespace llvm { |
330 | template <typename T> |
331 | class LikeASmallVector { |
332 | public: |
333 | void push_back(const T &) {} |
334 | void push_back(T &&) {} |
335 | |
336 | template <typename... Args> |
337 | void emplace_back(Args &&... args){}; |
338 | }; |
339 | |
340 | } // namespace llvm |
341 | |
342 | void testInts() { |
343 | std::vector<int> v; |
344 | v.push_back(42); |
345 | v.push_back(int(42)); |
346 | v.push_back(int{42}); |
347 | v.push_back(42.0); |
348 | int z; |
349 | v.push_back(z); |
350 | } |
351 | |
352 | struct Something { |
353 | Something(int a, int b = 41) {} |
354 | Something() {} |
355 | void push_back(Something); |
356 | int getInt() { return 42; } |
357 | }; |
358 | |
359 | struct Convertable { |
360 | operator Something() { return Something{}; } |
361 | }; |
362 | |
363 | struct Zoz { |
364 | Zoz(Something, int = 42) {} |
365 | }; |
366 | |
367 | Zoz getZoz(Something s) { return Zoz(s); } |
368 | |
369 | void test_Something() { |
370 | std::vector<Something> v; |
371 | |
372 | v.push_back(Something(1, 2)); |
373 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back instead of push_back [modernize-use-emplace] |
374 | // CHECK-FIXES: v.emplace_back(1, 2); |
375 | |
376 | v.push_back(Something{1, 2}); |
377 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
378 | // CHECK-FIXES: v.emplace_back(1, 2); |
379 | |
380 | v.push_back(Something()); |
381 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
382 | // CHECK-FIXES: v.emplace_back(); |
383 | |
384 | v.push_back(Something{}); |
385 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
386 | // CHECK-FIXES: v.emplace_back(); |
387 | |
388 | Something Different; |
389 | v.push_back(Something(Different.getInt(), 42)); |
390 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
391 | // CHECK-FIXES: v.emplace_back(Different.getInt(), 42); |
392 | |
393 | v.push_back(Different.getInt()); |
394 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
395 | // CHECK-FIXES: v.emplace_back(Different.getInt()); |
396 | |
397 | v.push_back(42); |
398 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
399 | // CHECK-FIXES: v.emplace_back(42); |
400 | |
401 | Something temporary(42, 42); |
402 | temporary.push_back(temporary); |
403 | v.push_back(temporary); |
404 | |
405 | v.push_back(Convertable()); |
406 | v.push_back(Convertable{}); |
407 | Convertable s; |
408 | v.push_back(s); |
409 | } |
410 | |
411 | template <typename ElemType> |
412 | void dependOnElem() { |
413 | std::vector<ElemType> v; |
414 | v.push_back(ElemType(42)); |
415 | } |
416 | |
417 | template <typename ContainerType> |
418 | void dependOnContainer() { |
419 | ContainerType v; |
420 | v.push_back(Something(42)); |
421 | } |
422 | |
423 | void callDependent() { |
424 | dependOnElem<Something>(); |
425 | dependOnContainer<std::vector<Something>>(); |
426 | } |
427 | |
428 | void test2() { |
429 | std::vector<Zoz> v; |
430 | v.push_back(Zoz(Something(21, 37))); |
431 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
432 | // CHECK-FIXES: v.emplace_back(Something(21, 37)); |
433 | |
434 | v.push_back(Zoz(Something(21, 37), 42)); |
435 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
436 | // CHECK-FIXES: v.emplace_back(Something(21, 37), 42); |
437 | |
438 | v.push_back(getZoz(s: Something(1, 2))); |
439 | } |
440 | |
441 | struct GetPair { |
442 | std::pair<int, long> getPair(); |
443 | }; |
444 | void testPair() { |
445 | std::vector<std::pair<int, int>> v; |
446 | v.push_back(std::pair<int, int>(1, 2)); |
447 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
448 | // CHECK-FIXES: v.emplace_back(1, 2); |
449 | |
450 | GetPair g; |
451 | v.push_back(g.getPair()); |
452 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
453 | // CHECK-FIXES: v.emplace_back(g.getPair()); |
454 | |
455 | std::vector<std::pair<Something, Zoz>> v2; |
456 | v2.push_back(std::pair<Something, Zoz>(Something(42, 42), Zoz(Something(21, 37)))); |
457 | // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back |
458 | // CHECK-FIXES: v2.emplace_back(Something(42, 42), Zoz(Something(21, 37))); |
459 | } |
460 | |
461 | void testTuple() { |
462 | std::vector<std::tuple<bool, char, int>> v; |
463 | v.push_back(std::tuple<bool, char, int>(false, 'x', 1)); |
464 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
465 | // CHECK-FIXES: v.emplace_back(false, 'x', 1); |
466 | |
467 | v.push_back(std::tuple<bool, char, int>{false, 'y', 2}); |
468 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
469 | // CHECK-FIXES: v.emplace_back(false, 'y', 2); |
470 | |
471 | v.push_back({true, 'z', 3}); |
472 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
473 | // CHECK-FIXES: v.emplace_back(true, 'z', 3); |
474 | |
475 | std::vector<std::tuple<int, bool>> x; |
476 | x.push_back(std::make_pair(1, false)); |
477 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
478 | // CHECK-FIXES: x.emplace_back(1, false); |
479 | |
480 | x.push_back(std::make_pair(2LL, 1)); |
481 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
482 | // CHECK-FIXES: x.emplace_back(2LL, 1); |
483 | } |
484 | |
485 | struct Base { |
486 | Base(int, int *, int = 42); |
487 | }; |
488 | |
489 | struct Derived : Base { |
490 | Derived(int *, Something) : Base(42, nullptr) {} |
491 | }; |
492 | |
493 | void testDerived() { |
494 | std::vector<Base> v; |
495 | v.push_back(Derived(nullptr, Something{})); |
496 | } |
497 | |
498 | void testNewExpr() { |
499 | std::vector<Derived> v; |
500 | v.push_back(Derived(new int, Something{})); |
501 | } |
502 | |
503 | void testSpaces() { |
504 | std::vector<Something> v; |
505 | |
506 | // clang-format off |
507 | |
508 | v.push_back(Something(1, //arg1 |
509 | 2 // arg2 |
510 | ) // Something |
511 | ); |
512 | // CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use emplace_back |
513 | // CHECK-FIXES: v.emplace_back(1, //arg1 |
514 | // CHECK-FIXES: 2 // arg2 |
515 | // CHECK-FIXES: // Something |
516 | // CHECK-FIXES: ); |
517 | |
518 | v.push_back( Something (1, 2) ); |
519 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
520 | // CHECK-FIXES: v.emplace_back(1, 2 ); |
521 | |
522 | v.push_back( Something {1, 2} ); |
523 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
524 | // CHECK-FIXES: v.emplace_back(1, 2 ); |
525 | |
526 | v.push_back( Something {} ); |
527 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
528 | // CHECK-FIXES: v.emplace_back( ); |
529 | |
530 | v.push_back( |
531 | Something(1, 2) ); |
532 | // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use emplace_back |
533 | // CHECK-FIXES: v.emplace_back(1, 2 ); |
534 | |
535 | std::vector<Base> v2; |
536 | v2.push_back( |
537 | Base(42, nullptr)); |
538 | // CHECK-MESSAGES: :[[@LINE-2]]:6: warning: use emplace_back |
539 | // CHECK-FIXES: v2.emplace_back(42, nullptr); |
540 | |
541 | // clang-format on |
542 | } |
543 | |
544 | void testPointers() { |
545 | std::vector<int *> v; |
546 | v.push_back(new int(5)); |
547 | |
548 | std::vector<std::unique_ptr<int>> v2; |
549 | v2.push_back(std::unique_ptr<int>(new int(42))); |
550 | // This call can't be replaced with emplace_back. |
551 | // If emplacement will fail (not enough memory to add to vector) |
552 | // we will have leak of int because unique_ptr won't be constructed |
553 | // (and destructed) as in push_back case. |
554 | |
555 | auto *ptr = new int; |
556 | v2.push_back(std::unique_ptr<int>(ptr)); |
557 | // Same here |
558 | } |
559 | |
560 | void testMakePair() { |
561 | std::vector<std::pair<int, int>> v; |
562 | v.push_back(std::make_pair(1, 2)); |
563 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
564 | // CHECK-FIXES: v.emplace_back(1, 2); |
565 | |
566 | v.push_back(std::make_pair(42LL, 13)); |
567 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
568 | // CHECK-FIXES: v.emplace_back(42LL, 13); |
569 | |
570 | v.push_back(std::make_pair<char, char>(0, 3)); |
571 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
572 | // CHECK-FIXES: v.emplace_back(std::make_pair<char, char>(0, 3)); |
573 | // |
574 | // Even though the call above could be turned into v.emplace_back(0, 3), |
575 | // we don't eliminate the make_pair call here, because of the explicit |
576 | // template parameters provided. make_pair's arguments can be convertible |
577 | // to its explicitly provided template parameter, but not to the pair's |
578 | // element type. The examples below illustrate the problem. |
579 | struct D { |
580 | D(...) {} |
581 | operator char() const { return 0; } |
582 | }; |
583 | v.push_back(std::make_pair<D, int>(Something(), 2)); |
584 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
585 | // CHECK-FIXES: v.emplace_back(std::make_pair<D, int>(Something(), 2)); |
586 | |
587 | struct X { |
588 | X(std::pair<int, int>) {} |
589 | }; |
590 | std::vector<X> x; |
591 | x.push_back(std::make_pair(1, 2)); |
592 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
593 | // CHECK-FIXES: x.emplace_back(std::make_pair(1, 2)); |
594 | // make_pair cannot be removed here, as X is not constructible with two ints. |
595 | |
596 | struct Y { |
597 | Y(std::pair<int, int> &&) {} |
598 | }; |
599 | std::vector<Y> y; |
600 | y.push_back(std::make_pair(2, 3)); |
601 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
602 | // CHECK-FIXES: y.emplace_back(std::make_pair(2, 3)); |
603 | // make_pair cannot be removed here, as Y is not constructible with two ints. |
604 | } |
605 | |
606 | void testMakeTuple() { |
607 | std::vector<std::tuple<int, bool, char>> v; |
608 | v.push_back(std::make_tuple(1, true, 'v')); |
609 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
610 | // CHECK-FIXES: v.emplace_back(1, true, 'v'); |
611 | |
612 | v.push_back(std::make_tuple(2ULL, 1, 0)); |
613 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
614 | // CHECK-FIXES: v.emplace_back(2ULL, 1, 0); |
615 | |
616 | v.push_back(std::make_tuple<long long, int, int>(3LL, 1, 0)); |
617 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
618 | // CHECK-FIXES: v.emplace_back(std::make_tuple<long long, int, int>(3LL, 1, 0)); |
619 | // make_tuple is not removed when there are explicit template |
620 | // arguments provided. |
621 | } |
622 | |
623 | namespace test { |
624 | template <typename T> |
625 | struct Single { |
626 | Single() = default; |
627 | Single(const Single &) = default; |
628 | Single(Single &&) = default; |
629 | |
630 | Single(const T &) {} |
631 | Single(T &&) {} |
632 | |
633 | template <typename U> |
634 | Single(const Single<U> &) {} |
635 | template <typename U> |
636 | Single(Single<U> &&) {} |
637 | |
638 | template <typename U> |
639 | Single(const std::tuple<U> &) {} |
640 | template <typename U> |
641 | Single(std::tuple<U> &&) {} |
642 | }; |
643 | |
644 | template <typename T> |
645 | Single<typename std::remove_reference<T>::type> MakeSingle(T &&) { |
646 | return {}; |
647 | } |
648 | } // namespace test |
649 | |
650 | void testOtherTuples() { |
651 | std::vector<test::Single<int>> v; |
652 | v.push_back(test::Single<int>(1)); |
653 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
654 | // CHECK-FIXES: v.emplace_back(1); |
655 | |
656 | v.push_back({2}); |
657 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
658 | // CHECK-FIXES: v.emplace_back(2); |
659 | |
660 | v.push_back(test::MakeSingle(3)); |
661 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
662 | // CHECK-FIXES: v.emplace_back(3); |
663 | |
664 | v.push_back(test::MakeSingle<long long>(4)); |
665 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
666 | // CHECK-FIXES: v.emplace_back(test::MakeSingle<long long>(4)); |
667 | // We don't remove make functions with explicit template parameters. |
668 | |
669 | v.push_back(test::MakeSingle(5LL)); |
670 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
671 | // CHECK-FIXES: v.emplace_back(5LL); |
672 | |
673 | v.push_back(std::make_tuple(6)); |
674 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
675 | // CHECK-FIXES: v.emplace_back(6); |
676 | |
677 | v.push_back(std::make_tuple(7LL)); |
678 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
679 | // CHECK-FIXES: v.emplace_back(7LL); |
680 | } |
681 | |
682 | void testOtherContainers() { |
683 | std::list<Something> l; |
684 | l.push_back(Something(42, 41)); |
685 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
686 | // CHECK-FIXES: l.emplace_back(42, 41); |
687 | |
688 | l.push_front(Something(42, 41)); |
689 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_front |
690 | // CHECK-FIXES: l.emplace_front(42, 41); |
691 | |
692 | std::deque<Something> d; |
693 | d.push_back(Something(42)); |
694 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
695 | // CHECK-FIXES: d.emplace_back(42); |
696 | |
697 | d.push_front(Something(42)); |
698 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_front |
699 | // CHECK-FIXES: d.emplace_front(42); |
700 | |
701 | llvm::LikeASmallVector<Something> ls; |
702 | ls.push_back(Something(42)); |
703 | // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back |
704 | // CHECK-FIXES: ls.emplace_back(42); |
705 | |
706 | std::stack<Something> s; |
707 | s.push(Something(42, 41)); |
708 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace |
709 | // CHECK-FIXES: s.emplace(42, 41); |
710 | |
711 | std::queue<Something> q; |
712 | q.push(Something(42, 41)); |
713 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace |
714 | // CHECK-FIXES: q.emplace(42, 41); |
715 | |
716 | std::priority_queue<Something> pq; |
717 | pq.push(Something(42, 41)); |
718 | // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace |
719 | // CHECK-FIXES: pq.emplace(42, 41); |
720 | |
721 | std::forward_list<Something> fl; |
722 | fl.push_front(Something(42, 41)); |
723 | // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_front |
724 | // CHECK-FIXES: fl.emplace_front(42, 41); |
725 | } |
726 | |
727 | class IntWrapper { |
728 | public: |
729 | IntWrapper(int x) : value(x) {} |
730 | IntWrapper operator+(const IntWrapper other) const { |
731 | return IntWrapper(value + other.value); |
732 | } |
733 | |
734 | private: |
735 | int value; |
736 | }; |
737 | |
738 | void testMultipleOpsInPushBack() { |
739 | std::vector<IntWrapper> v; |
740 | v.push_back(IntWrapper(42) + IntWrapper(27)); |
741 | } |
742 | |
743 | // Macro tests. |
744 | #define PUSH_BACK_WHOLE(c, x) c.push_back(x) |
745 | #define PUSH_BACK_NAME push_back |
746 | #define PUSH_BACK_ARG(x) (x) |
747 | #define SOME_OBJ Something(10) |
748 | #define MILLION 3 |
749 | #define SOME_WEIRD_PUSH(v) v.push_back(Something( |
750 | #define OPEN ( |
751 | #define CLOSE ) |
752 | void macroTest() { |
753 | std::vector<Something> v; |
754 | Something s; |
755 | |
756 | PUSH_BACK_WHOLE(v, Something(5, 6)); |
757 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use emplace_back |
758 | |
759 | v.PUSH_BACK_NAME(Something(5)); |
760 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
761 | |
762 | v.push_back PUSH_BACK_ARG(Something(5, 6)); |
763 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
764 | |
765 | v.push_back(SOME_OBJ); |
766 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
767 | |
768 | v.push_back(Something(MILLION)); |
769 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
770 | // CHECK-FIXES: v.emplace_back(MILLION); |
771 | |
772 | // clang-format off |
773 | v.push_back( Something OPEN 3 CLOSE ); |
774 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
775 | // clang-format on |
776 | PUSH_BACK_WHOLE(s, Something(1)); |
777 | } |
778 | |
779 | struct A { |
780 | int value1, value2; |
781 | }; |
782 | |
783 | struct B { |
784 | B(A) {} |
785 | }; |
786 | |
787 | struct C { |
788 | int value1, value2, value3; |
789 | }; |
790 | |
791 | void testAggregation() { |
792 | // This should not be noticed or fixed; after the correction, the code won't |
793 | // compile. |
794 | |
795 | std::vector<A> v; |
796 | v.push_back(A({.value1: 1, .value2: 2})); |
797 | |
798 | std::vector<B> vb; |
799 | vb.push_back(B({.value1: 10, .value2: 42})); |
800 | } |
801 | |
802 | struct Bitfield { |
803 | unsigned bitfield : 1; |
804 | unsigned notBitfield; |
805 | }; |
806 | |
807 | void testBitfields() { |
808 | std::vector<Something> v; |
809 | Bitfield b; |
810 | v.push_back(Something(42, b.bitfield)); |
811 | v.push_back(Something(b.bitfield)); |
812 | |
813 | v.push_back(Something(42, b.notBitfield)); |
814 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
815 | // CHECK-FIXES: v.emplace_back(42, b.notBitfield); |
816 | int var; |
817 | v.push_back(Something(42, var)); |
818 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
819 | // CHECK-FIXES: v.emplace_back(42, var); |
820 | } |
821 | |
822 | class PrivateCtor { |
823 | PrivateCtor(int z); |
824 | |
825 | public: |
826 | void doStuff() { |
827 | std::vector<PrivateCtor> v; |
828 | // This should not change it because emplace back doesn't have permission. |
829 | // Check currently doesn't support friend declarations because pretty much |
830 | // nobody would want to be friend with std::vector :(. |
831 | v.push_back(PrivateCtor(42)); |
832 | } |
833 | }; |
834 | |
835 | struct WithDtor { |
836 | WithDtor(int) {} |
837 | ~WithDtor(); |
838 | }; |
839 | |
840 | void testWithDtor() { |
841 | std::vector<WithDtor> v; |
842 | |
843 | v.push_back(WithDtor(42)); |
844 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
845 | // CHECK-FIXES: v.emplace_back(42); |
846 | } |
847 | |
848 | void testInitializerList() { |
849 | std::vector<std::vector<int>> v; |
850 | v.push_back(std::vector<int>({1})); |
851 | // Test against the bug reported in PR32896. |
852 | |
853 | v.push_back({{2}}); |
854 | |
855 | using PairIntVector = std::pair<int, std::vector<int>>; |
856 | std::vector<PairIntVector> x; |
857 | x.push_back(PairIntVector(3, {4})); |
858 | x.push_back({5, {6}}); |
859 | } |
860 | |
861 | class Foo { |
862 | public: |
863 | Foo(){}; |
864 | Foo(int){}; |
865 | Foo(int, int){}; |
866 | Foo(std::pair<int, int>){}; |
867 | |
868 | protected: |
869 | Foo(char *) : Foo(){}; |
870 | }; |
871 | |
872 | void testSomeEmplaceCases() { |
873 | std::vector<std::pair<char *, char *>> v1; |
874 | std::vector<Foo> v2; |
875 | std::unordered_map<int, char *> m1; |
876 | |
877 | v1.emplace_back(args: std::make_pair("foo", "bar")); |
878 | // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back |
879 | // CHECK-FIXES: v1.emplace_back("foo", "bar"); |
880 | |
881 | char *foo = "bar"; |
882 | v1.emplace_back(args: std::make_pair(foo, "bar")); |
883 | // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back |
884 | // CHECK-FIXES: v1.emplace_back(foo, "bar"); |
885 | |
886 | v1.emplace(pos: v1.begin(), args: std::make_pair("foo", "bar")); |
887 | // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: unnecessary temporary object created while calling emplace |
888 | // CHECK-FIXES: v1.emplace(v1.begin(), "foo", "bar"); |
889 | |
890 | v2.emplace_back(args: Foo()); |
891 | // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back |
892 | // CHECK-FIXES: v2.emplace_back(); |
893 | |
894 | v2.emplace_back(args: Foo(13)); |
895 | // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back |
896 | // CHECK-FIXES: v2.emplace_back(13); |
897 | |
898 | v2.emplace_back(args: Foo{13}); |
899 | // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back |
900 | // CHECK-FIXES: v2.emplace_back(13); |
901 | |
902 | int a = 31; |
903 | v2.emplace_back(args: Foo(13, a)); |
904 | // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back |
905 | // CHECK-FIXES: v2.emplace_back(13, a); |
906 | |
907 | v2.emplace_back(args: std::make_pair(3, 3)); |
908 | |
909 | m1.emplace(args: std::make_pair(13, "foo")); |
910 | // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: unnecessary temporary object created while calling emplace |
911 | // CHECK-FIXES: m1.emplace(13, "foo"); |
912 | |
913 | std::vector<std::pair<int, int>> v3; |
914 | v3.emplace_back(args: std::pair<int, int>(13, 71)); |
915 | // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back |
916 | v3.emplace_back(args: std::make_pair(13, 71)); |
917 | // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back |
918 | |
919 | std::vector<std::tuple<int, int, int>> v4; |
920 | v4.emplace_back(args: std::tuple<int, int, int>(13, 31, 71)); |
921 | // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back |
922 | v4.emplace_back(args: std::make_tuple(13, 31, 71)); |
923 | // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back |
924 | |
925 | std::vector<test::Single<int>> v5; |
926 | v5.emplace_back(args: test::Single<int>(13)); |
927 | // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back |
928 | v5.emplace_back(args: test::MakeSingle(13)); |
929 | // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back |
930 | } |
931 | |
932 | void testAllSTLEmplacyFunctions() { |
933 | std::vector<Foo> vector; |
934 | std::deque<Foo> deque; |
935 | std::forward_list<Foo> forward_list; |
936 | std::list<Foo> list; |
937 | std::set<Foo> set; |
938 | std::map<int, Foo> map; |
939 | std::multiset<Foo> multiset; |
940 | std::multimap<int, Foo> multimap; |
941 | std::unordered_set<Foo> unordered_set; |
942 | std::unordered_map<int, Foo> unordered_map; |
943 | std::unordered_multiset<Foo> unordered_multiset; |
944 | std::unordered_multimap<int, Foo> unordered_multimap; |
945 | std::stack<Foo> stack; |
946 | std::queue<Foo> queue; |
947 | std::priority_queue<Foo> priority_queue; |
948 | |
949 | vector.emplace_back(args: Foo(13)); |
950 | // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: unnecessary temporary object created while calling emplace_back |
951 | // CHECK-FIXES: vector.emplace_back(13); |
952 | |
953 | vector.emplace(pos: vector.begin(), args: Foo(13)); |
954 | // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: unnecessary temporary object created while calling emplace |
955 | // CHECK-FIXES: vector.emplace(vector.begin(), 13); |
956 | |
957 | deque.emplace(pos: deque.begin(), args: Foo(13)); |
958 | // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: unnecessary temporary object created while calling emplace |
959 | // CHECK-FIXES: deque.emplace(deque.begin(), 13); |
960 | |
961 | deque.emplace_front(args: Foo(13)); |
962 | // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: unnecessary temporary object created while calling emplace_front |
963 | // CHECK-FIXES: deque.emplace_front(13); |
964 | |
965 | deque.emplace_back(args: Foo(13)); |
966 | // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: unnecessary temporary object created while calling emplace_back |
967 | // CHECK-FIXES: deque.emplace_back(13); |
968 | |
969 | forward_list.emplace_after(pos: forward_list.begin(), args: Foo(13)); |
970 | // CHECK-MESSAGES: :[[@LINE-1]]:52: warning: unnecessary temporary object created while calling emplace_after |
971 | // CHECK-FIXES: forward_list.emplace_after(forward_list.begin(), 13); |
972 | |
973 | forward_list.emplace_front(args: Foo(13)); |
974 | // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: unnecessary temporary object created while calling emplace_front |
975 | // CHECK-FIXES: forward_list.emplace_front(13); |
976 | |
977 | list.emplace(pos: list.begin(), args: Foo(13)); |
978 | // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: unnecessary temporary object created while calling emplace |
979 | // CHECK-FIXES: list.emplace(list.begin(), 13); |
980 | |
981 | list.emplace_back(args: Foo(13)); |
982 | // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: unnecessary temporary object created while calling emplace_back |
983 | // CHECK-FIXES: list.emplace_back(13); |
984 | |
985 | list.emplace_front(args: Foo(13)); |
986 | // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: unnecessary temporary object created while calling emplace_front |
987 | // CHECK-FIXES: list.emplace_front(13); |
988 | |
989 | set.emplace(args: Foo(13)); |
990 | // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: unnecessary temporary object created while calling emplace |
991 | // CHECK-FIXES: set.emplace(13); |
992 | |
993 | set.emplace_hint(pos: set.begin(), args: Foo(13)); |
994 | // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: unnecessary temporary object created while calling emplace_hint |
995 | // CHECK-FIXES: set.emplace_hint(set.begin(), 13); |
996 | |
997 | map.emplace(args: std::make_pair(13, Foo(13))); |
998 | // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: unnecessary temporary object created while calling emplace |
999 | // CHECK-FIXES: map.emplace(13, Foo(13)); |
1000 | |
1001 | map.emplace_hint(pos: map.begin(), args: std::make_pair(13, Foo(13))); |
1002 | // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: unnecessary temporary object created while calling emplace_hint |
1003 | // CHECK-FIXES: map.emplace_hint(map.begin(), 13, Foo(13)); |
1004 | |
1005 | multiset.emplace(args: Foo(13)); |
1006 | // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: unnecessary temporary object created while calling emplace |
1007 | // CHECK-FIXES: multiset.emplace(13); |
1008 | |
1009 | multiset.emplace_hint(pos: multiset.begin(), args: Foo(13)); |
1010 | // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: unnecessary temporary object created while calling emplace_hint |
1011 | // CHECK-FIXES: multiset.emplace_hint(multiset.begin(), 13); |
1012 | |
1013 | multimap.emplace(args: std::make_pair(13, Foo(13))); |
1014 | // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: unnecessary temporary object created while calling emplace |
1015 | // CHECK-FIXES: multimap.emplace(13, Foo(13)); |
1016 | |
1017 | multimap.emplace_hint(pos: multimap.begin(), args: std::make_pair(13, Foo(13))); |
1018 | // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: unnecessary temporary object created while calling emplace_hint |
1019 | // CHECK-FIXES: multimap.emplace_hint(multimap.begin(), 13, Foo(13)); |
1020 | |
1021 | unordered_set.emplace(args: Foo(13)); |
1022 | // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: unnecessary temporary object created while calling emplace |
1023 | // CHECK-FIXES: unordered_set.emplace(13); |
1024 | |
1025 | unordered_set.emplace_hint(pos: unordered_set.begin(), args: Foo(13)); |
1026 | // CHECK-MESSAGES: :[[@LINE-1]]:53: warning: unnecessary temporary object created while calling emplace_hint |
1027 | // CHECK-FIXES: unordered_set.emplace_hint(unordered_set.begin(), 13); |
1028 | |
1029 | unordered_map.emplace(args: std::make_pair(13, Foo(13))); |
1030 | // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: unnecessary temporary object created while calling emplace |
1031 | // CHECK-FIXES: unordered_map.emplace(13, Foo(13)); |
1032 | |
1033 | unordered_map.emplace_hint(pos: unordered_map.begin(), args: std::make_pair(13, Foo(13))); |
1034 | // CHECK-MESSAGES: :[[@LINE-1]]:53: warning: unnecessary temporary object created while calling emplace_hint |
1035 | // CHECK-FIXES: unordered_map.emplace_hint(unordered_map.begin(), 13, Foo(13)); |
1036 | |
1037 | unordered_multiset.emplace(args: Foo(13)); |
1038 | // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: unnecessary temporary object created while calling emplace |
1039 | // CHECK-FIXES: unordered_multiset.emplace(13); |
1040 | unordered_multiset.emplace_hint(pos: unordered_multiset.begin(), args: Foo(13)); |
1041 | // CHECK-MESSAGES: :[[@LINE-1]]:63: warning: unnecessary temporary object created while calling emplace_hint |
1042 | // CHECK-FIXES: unordered_multiset.emplace_hint(unordered_multiset.begin(), 13); |
1043 | |
1044 | unordered_multimap.emplace(args: std::make_pair(13, Foo(13))); |
1045 | // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: unnecessary temporary object created while calling emplace |
1046 | // CHECK-FIXES: unordered_multimap.emplace(13, Foo(13)); |
1047 | unordered_multimap.emplace_hint(pos: unordered_multimap.begin(), args: std::make_pair(13, Foo(13))); |
1048 | // CHECK-MESSAGES: :[[@LINE-1]]:63: warning: unnecessary temporary object created while calling emplace_hint |
1049 | // CHECK-FIXES: unordered_multimap.emplace_hint(unordered_multimap.begin(), 13, Foo(13)); |
1050 | |
1051 | stack.emplace(args: Foo(13)); |
1052 | // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: unnecessary temporary object created while calling emplace |
1053 | // CHECK-FIXES: stack.emplace(13); |
1054 | |
1055 | queue.emplace(args: Foo(13)); |
1056 | // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: unnecessary temporary object created while calling emplace |
1057 | // CHECK-FIXES: queue.emplace(13); |
1058 | |
1059 | priority_queue.emplace(args: Foo(13)); |
1060 | // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: unnecessary temporary object created while calling emplace |
1061 | // CHECK-FIXES: priority_queue.emplace(13); |
1062 | } |
1063 | |
1064 | void test_AliasEmplacyFunctions() { |
1065 | typedef std::list<Foo> L; |
1066 | using DQ = std::deque<Foo>; |
1067 | L l; |
1068 | l.emplace_back(args: Foo(3)); |
1069 | // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: unnecessary temporary object created while calling emplace_back |
1070 | // CHECK-FIXES: l.emplace_back(3); |
1071 | |
1072 | DQ dq; |
1073 | dq.emplace_back(args: Foo(3)); |
1074 | // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back |
1075 | // CHECK-FIXES: dq.emplace_back(3); |
1076 | |
1077 | typedef std::stack<Foo> STACK; |
1078 | using PQ = std::priority_queue<Foo>; |
1079 | STACK stack; |
1080 | stack.emplace(args: Foo(3)); |
1081 | // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: unnecessary temporary object created while calling emplace |
1082 | // CHECK-FIXES: stack.emplace(3); |
1083 | |
1084 | PQ pq; |
1085 | pq.emplace(args: Foo(3)); |
1086 | // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: unnecessary temporary object created while calling emplace |
1087 | // CHECK-FIXES: pq.emplace(3); |
1088 | |
1089 | typedef std::forward_list<Foo> FL; |
1090 | using DQ2 = std::deque<Foo>; |
1091 | FL fl; |
1092 | fl.emplace_front(args: Foo(3)); |
1093 | // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: unnecessary temporary object created while calling emplace_front |
1094 | // CHECK-FIXES: fl.emplace_front(3); |
1095 | |
1096 | DQ2 dq2; |
1097 | dq2.emplace_front(args: Foo(3)); |
1098 | // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: unnecessary temporary object created while calling emplace_front |
1099 | // CHECK-FIXES: dq2.emplace_front(3); |
1100 | } |
1101 | |
1102 | void test_Alias() { |
1103 | typedef std::list<Foo> L; |
1104 | using DQ = std::deque<Foo>; |
1105 | L l; |
1106 | l.push_back(Foo(3)); |
1107 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back instead of push_back [modernize-use-emplace] |
1108 | // CHECK-FIXES: l.emplace_back(3); |
1109 | |
1110 | DQ dq; |
1111 | dq.push_back(Foo(3)); |
1112 | // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back instead of push_back [modernize-use-emplace] |
1113 | // CHECK-FIXES: dq.emplace_back(3); |
1114 | |
1115 | typedef std::stack<Foo> STACK; |
1116 | using PQ = std::priority_queue<Foo>; |
1117 | STACK stack; |
1118 | stack.push(Foo(3)); |
1119 | // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use emplace instead of push [modernize-use-emplace] |
1120 | // CHECK-FIXES: stack.emplace(3); |
1121 | |
1122 | PQ pq; |
1123 | pq.push(Foo(3)); |
1124 | // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace instead of push [modernize-use-emplace] |
1125 | // CHECK-FIXES: pq.emplace(3); |
1126 | |
1127 | typedef std::forward_list<Foo> FL; |
1128 | using DQ2 = std::deque<Foo>; |
1129 | FL fl; |
1130 | fl.push_front(Foo(3)); |
1131 | // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_front instead of push_front [modernize-use-emplace] |
1132 | // CHECK-FIXES: fl.emplace_front(3); |
1133 | |
1134 | DQ2 dq2; |
1135 | dq2.push_front(Foo(3)); |
1136 | // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace_front instead of push_front [modernize-use-emplace] |
1137 | // CHECK-FIXES: dq2.emplace_front(3); |
1138 | } |
1139 | |
1140 | struct Bar { |
1141 | public: |
1142 | Bar(){}; |
1143 | void testWithPrivateAndProtectedCtor() { |
1144 | std::vector<Bar> vec; |
1145 | |
1146 | vec.emplace_back(args: Bar(13)); |
1147 | vec.emplace_back(args: Bar(13, 13)); |
1148 | } |
1149 | |
1150 | protected: |
1151 | Bar(int){}; |
1152 | |
1153 | private: |
1154 | Bar(int, int){}; |
1155 | }; |
1156 | |
1157 | void testPossibleFalsePositives() { |
1158 | struct Y { |
1159 | Y(std::pair<int, int> &&) {} |
1160 | }; |
1161 | std::vector<Y> y; |
1162 | y.emplace_back(args: std::make_pair(2, 3)); |
1163 | |
1164 | std::vector<std::pair<int, int>> v; |
1165 | v.emplace_back(args: std::make_pair<char, char>(0, 3)); |
1166 | |
1167 | struct D { |
1168 | D(...) {} |
1169 | operator char() const { return 0; } |
1170 | }; |
1171 | v.emplace_back(args: std::make_pair<D, int>(Something(), 2)); |
1172 | } |
1173 | |
1174 | struct InnerType { |
1175 | InnerType(); |
1176 | InnerType(char const*); |
1177 | }; |
1178 | |
1179 | struct NonTrivialNoCtor { |
1180 | InnerType it; |
1181 | }; |
1182 | |
1183 | struct NonTrivialWithVector { |
1184 | std::vector<int> it; |
1185 | }; |
1186 | |
1187 | struct NonTrivialWithIntAndVector { |
1188 | int x; |
1189 | std::vector<int> it; |
1190 | }; |
1191 | |
1192 | struct NonTrivialWithCtor { |
1193 | NonTrivialWithCtor(); |
1194 | NonTrivialWithCtor(std::vector<int> const&); |
1195 | }; |
1196 | |
1197 | void testBracedInitTemporaries() { |
1198 | std::vector<NonTrivialNoCtor> v1; |
1199 | |
1200 | v1.push_back(NonTrivialNoCtor()); |
1201 | // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back |
1202 | // CHECK-FIXES: v1.emplace_back(); |
1203 | v1.push_back(NonTrivialNoCtor{}); |
1204 | // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back |
1205 | // CHECK-FIXES: v1.emplace_back(); |
1206 | v1.push_back({}); |
1207 | // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back |
1208 | // CHECK-FIXES: v1.emplace_back(); |
1209 | v1.push_back(NonTrivialNoCtor{.it: InnerType{}}); |
1210 | // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back |
1211 | // CHECK-FIXES: v1.emplace_back(); |
1212 | v1.push_back({.it: InnerType{}}); |
1213 | // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back |
1214 | // CHECK-FIXES: v1.emplace_back(); |
1215 | v1.push_back(NonTrivialNoCtor{.it: InnerType()}); |
1216 | // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back |
1217 | // CHECK-FIXES: v1.emplace_back(); |
1218 | v1.push_back({.it: InnerType()}); |
1219 | // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back |
1220 | // CHECK-FIXES: v1.emplace_back(); |
1221 | v1.push_back({.it: {}}); |
1222 | // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back |
1223 | // CHECK-FIXES: v1.emplace_back(); |
1224 | |
1225 | v1.emplace_back(args: NonTrivialNoCtor()); |
1226 | // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back |
1227 | // CHECK-FIXES: v1.emplace_back(); |
1228 | v1.emplace_back(args: NonTrivialNoCtor{}); |
1229 | // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back |
1230 | // CHECK-FIXES: v1.emplace_back(); |
1231 | v1.emplace_back(args: NonTrivialNoCtor{.it: InnerType{}}); |
1232 | // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back |
1233 | // CHECK-FIXES: v1.emplace_back(); |
1234 | v1.emplace_back(args: NonTrivialNoCtor{.it: {}}); |
1235 | // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back |
1236 | // CHECK-FIXES: v1.emplace_back(); |
1237 | |
1238 | // These should not be noticed or fixed; after the correction, the code won't |
1239 | // compile. |
1240 | v1.push_back(NonTrivialNoCtor{.it: ""}); |
1241 | v1.push_back({.it: ""}); |
1242 | v1.push_back(NonTrivialNoCtor{.it: InnerType{""}}); |
1243 | v1.push_back({.it: InnerType{""}}); |
1244 | v1.emplace_back(args: NonTrivialNoCtor{.it: ""}); |
1245 | |
1246 | std::vector<NonTrivialWithVector> v2; |
1247 | |
1248 | v2.push_back(NonTrivialWithVector()); |
1249 | // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back |
1250 | // CHECK-FIXES: v2.emplace_back(); |
1251 | v2.push_back(NonTrivialWithVector{}); |
1252 | // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back |
1253 | // CHECK-FIXES: v2.emplace_back(); |
1254 | v2.push_back({}); |
1255 | // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back |
1256 | // CHECK-FIXES: v2.emplace_back(); |
1257 | v2.push_back(NonTrivialWithVector{.it: std::vector<int>{}}); |
1258 | // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back |
1259 | // CHECK-FIXES: v2.emplace_back(); |
1260 | v2.push_back({.it: std::vector<int>{}}); |
1261 | // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back |
1262 | // CHECK-FIXES: v2.emplace_back(); |
1263 | v2.push_back(NonTrivialWithVector{.it: std::vector<int>()}); |
1264 | // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back |
1265 | // CHECK-FIXES: v2.emplace_back(); |
1266 | v2.push_back({.it: std::vector<int>()}); |
1267 | // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back |
1268 | // CHECK-FIXES: v2.emplace_back(); |
1269 | v2.push_back({.it: {}}); |
1270 | // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back |
1271 | // CHECK-FIXES: v2.emplace_back(); |
1272 | |
1273 | v2.emplace_back(args: NonTrivialWithVector()); |
1274 | // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back |
1275 | // CHECK-FIXES: v2.emplace_back(); |
1276 | v2.emplace_back(args: NonTrivialWithVector{}); |
1277 | // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back |
1278 | // CHECK-FIXES: v2.emplace_back(); |
1279 | v2.emplace_back(args: NonTrivialWithVector{.it: std::vector<int>{}}); |
1280 | // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back |
1281 | // CHECK-FIXES: v2.emplace_back(); |
1282 | v2.emplace_back(args: NonTrivialWithVector{.it: {}}); |
1283 | // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back |
1284 | // CHECK-FIXES: v2.emplace_back(); |
1285 | |
1286 | |
1287 | // These should not be noticed or fixed; after the correction, the code won't |
1288 | // compile. |
1289 | v2.push_back(NonTrivialWithVector{.it: {0}}); |
1290 | v2.push_back({.it: {0}}); |
1291 | v2.push_back(NonTrivialWithVector{.it: std::vector<int>{0}}); |
1292 | v2.push_back({.it: std::vector<int>{0}}); |
1293 | v2.emplace_back(args: NonTrivialWithVector{.it: std::vector<int>{0}}); |
1294 | |
1295 | std::vector<NonTrivialWithCtor> v3; |
1296 | |
1297 | v3.push_back(NonTrivialWithCtor()); |
1298 | // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back |
1299 | // CHECK-FIXES: v3.emplace_back(); |
1300 | v3.push_back(NonTrivialWithCtor{}); |
1301 | // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back |
1302 | // CHECK-FIXES: v3.emplace_back(); |
1303 | v3.push_back({}); |
1304 | // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back |
1305 | // CHECK-FIXES: v3.emplace_back(); |
1306 | v3.push_back(NonTrivialWithCtor{std::vector<int>()}); |
1307 | // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back |
1308 | // CHECK-FIXES: v3.emplace_back(std::vector<int>()); |
1309 | v3.push_back(NonTrivialWithCtor{std::vector<int>{0}}); |
1310 | // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back |
1311 | // CHECK-FIXES: v3.emplace_back(std::vector<int>{0}); |
1312 | v3.push_back(NonTrivialWithCtor{std::vector<int>{}}); |
1313 | // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back |
1314 | // CHECK-FIXES: v3.emplace_back(std::vector<int>{}); |
1315 | v3.push_back({std::vector<int>{0}}); |
1316 | // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back |
1317 | // CHECK-FIXES: v3.emplace_back(std::vector<int>{0}); |
1318 | v3.push_back({std::vector<int>{}}); |
1319 | // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back |
1320 | // CHECK-FIXES: v3.emplace_back(std::vector<int>{}); |
1321 | |
1322 | v3.emplace_back(args: NonTrivialWithCtor()); |
1323 | // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back |
1324 | // CHECK-FIXES: v3.emplace_back(); |
1325 | v3.emplace_back(args: NonTrivialWithCtor{}); |
1326 | // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back |
1327 | // CHECK-FIXES: v3.emplace_back(); |
1328 | v3.emplace_back(args: NonTrivialWithCtor{std::vector<int>{}}); |
1329 | // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back |
1330 | // CHECK-FIXES: v3.emplace_back(std::vector<int>{}); |
1331 | v3.emplace_back(args: NonTrivialWithCtor{std::vector<int>{0}}); |
1332 | // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back |
1333 | // CHECK-FIXES: v3.emplace_back(std::vector<int>{0}); |
1334 | |
1335 | // These should not be noticed or fixed; after the correction, the code won't |
1336 | // compile. |
1337 | v3.push_back(NonTrivialWithCtor{{0}}); |
1338 | v3.push_back(NonTrivialWithCtor{{}}); |
1339 | v3.push_back({{0}}); |
1340 | v3.push_back({{}}); |
1341 | |
1342 | std::vector<NonTrivialWithIntAndVector> v4; |
1343 | |
1344 | // These should not be noticed or fixed; after the correction, the code won't |
1345 | // compile. |
1346 | v4.push_back(NonTrivialWithIntAndVector{.x: 1, .it: {}}); |
1347 | v4.push_back(NonTrivialWithIntAndVector{}); |
1348 | v4.push_back({}); |
1349 | } |
1350 | |
1351 | void testWithPointerTypes() { |
1352 | std::list<Something> l; |
1353 | std::list<Something>* lp = &l; |
1354 | std::stack<Something> s; |
1355 | std::stack<Something>* sp; |
1356 | |
1357 | lp->push_back(Something(1, 2)); |
1358 | // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace_back instead of push_back [modernize-use-emplace] |
1359 | // CHECK-FIXES: lp->emplace_back(1, 2); |
1360 | lp->push_front(Something(1, 2)); |
1361 | // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace_front instead of push_front [modernize-use-emplace] |
1362 | // CHECK-FIXES: lp->emplace_front(1, 2); |
1363 | sp->push(Something(1, 2)); |
1364 | // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace instead of push [modernize-use-emplace] |
1365 | // CHECK-FIXES: sp->emplace(1, 2); |
1366 | |
1367 | lp->push_back(Something{1, 2}); |
1368 | // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace_back instead of push_back [modernize-use-emplace] |
1369 | // CHECK-FIXES: lp->emplace_back(1, 2); |
1370 | lp->push_front(Something{1, 2}); |
1371 | // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace_front instead of push_front [modernize-use-emplace] |
1372 | // CHECK-FIXES: lp->emplace_front(1, 2); |
1373 | sp->push(Something{1, 2}); |
1374 | // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace instead of push [modernize-use-emplace] |
1375 | // CHECK-FIXES: sp->emplace(1, 2); |
1376 | |
1377 | lp->push_back(Something()); |
1378 | // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace_back instead of push_back [modernize-use-emplace] |
1379 | // CHECK-FIXES: lp->emplace_back(); |
1380 | lp->push_front(Something()); |
1381 | // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace_front instead of push_front [modernize-use-emplace] |
1382 | // CHECK-FIXES: lp->emplace_front(); |
1383 | sp->push(Something()); |
1384 | // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace instead of push [modernize-use-emplace] |
1385 | // CHECK-FIXES: sp->emplace(); |
1386 | |
1387 | lp->push_back(Something{}); |
1388 | // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace_back instead of push_back [modernize-use-emplace] |
1389 | // CHECK-FIXES: lp->emplace_back(); |
1390 | lp->push_front(Something{}); |
1391 | // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace_front instead of push_front [modernize-use-emplace] |
1392 | // CHECK-FIXES: lp->emplace_front(); |
1393 | sp->push(Something{}); |
1394 | // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace instead of push [modernize-use-emplace] |
1395 | // CHECK-FIXES: sp->emplace(); |
1396 | |
1397 | lp->emplace_back(args: Something(1, 2)); |
1398 | // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: unnecessary temporary object created while calling emplace_back |
1399 | // CHECK-FIXES: lp->emplace_back(1, 2); |
1400 | lp->emplace_front(args: Something(1, 2)); |
1401 | // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: unnecessary temporary object created while calling emplace_front |
1402 | // CHECK-FIXES: lp->emplace_front(1, 2); |
1403 | sp->emplace(args: Something(1, 2)); |
1404 | // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: unnecessary temporary object created while calling emplace |
1405 | // CHECK-FIXES: sp->emplace(1, 2); |
1406 | |
1407 | lp->emplace_back(args: Something{1, 2}); |
1408 | // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: unnecessary temporary object created while calling emplace_back |
1409 | // CHECK-FIXES: lp->emplace_back(1, 2); |
1410 | lp->emplace_front(args: Something{1, 2}); |
1411 | // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: unnecessary temporary object created while calling emplace_front |
1412 | // CHECK-FIXES: lp->emplace_front(1, 2); |
1413 | sp->emplace(args: Something{1, 2}); |
1414 | // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: unnecessary temporary object created while calling emplace |
1415 | // CHECK-FIXES: sp->emplace(1, 2); |
1416 | |
1417 | lp->emplace_back(args: Something()); |
1418 | // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: unnecessary temporary object created while calling emplace_back |
1419 | // CHECK-FIXES: lp->emplace_back(); |
1420 | lp->emplace_front(args: Something()); |
1421 | // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: unnecessary temporary object created while calling emplace_front |
1422 | // CHECK-FIXES: lp->emplace_front(); |
1423 | sp->emplace(args: Something()); |
1424 | // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: unnecessary temporary object created while calling emplace |
1425 | // CHECK-FIXES: sp->emplace(); |
1426 | |
1427 | lp->emplace_back(args: Something{}); |
1428 | // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: unnecessary temporary object created while calling emplace_back |
1429 | // CHECK-FIXES: lp->emplace_back(); |
1430 | lp->emplace_front(args: Something{}); |
1431 | // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: unnecessary temporary object created while calling emplace_front |
1432 | // CHECK-FIXES: lp->emplace_front(); |
1433 | sp->emplace(args: Something{}); |
1434 | // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: unnecessary temporary object created while calling emplace |
1435 | // CHECK-FIXES: sp->emplace(); |
1436 | } |
1437 |
Definitions
- initializer_list
- initializer_list
- pair
- pair
- pair
- pair
- pair
- pair
- pair
- pair
- vector
- iterator
- const_iterator
- begin
- vector
- vector
- push_back
- push_back
- emplace_back
- list
- iterator
- const_iterator
- begin
- push_front
- push_front
- push_back
- push_back
- emplace_back
- emplace_front
- deque
- iterator
- const_iterator
- begin
- push_back
- push_back
- push_front
- push_front
- emplace_back
- emplace_front
- forward_list
- iterator
- const_iterator
- begin
- push_front
- push_front
- emplace_front
- set
- iterator
- const_iterator
- begin
- emplace
- map
- iterator
- const_iterator
- begin
- emplace
- multiset
- iterator
- const_iterator
- begin
- emplace
- multimap
- iterator
- const_iterator
- begin
- emplace
- unordered_set
- iterator
- const_iterator
- begin
- emplace
- unordered_map
- iterator
- const_iterator
- begin
- emplace
- unordered_multiset
- iterator
- const_iterator
- begin
- emplace
- unordered_multimap
- iterator
- const_iterator
- begin
- emplace
- stack
- push
- push
- emplace
- queue
- push
- push
- emplace
- priority_queue
- push
- push
- emplace
- remove_reference
- remove_reference
- remove_reference
- make_pair
- tuple
- tuple
- tuple
- tuple
- tuple
- tuple
- tuple
- tuple
- tuple
- tuple
- make_tuple
- unique_ptr
- unique_ptr
- LikeASmallVector
- push_back
- push_back
- emplace_back
- testInts
- Something
- Something
- Something
- getInt
- Convertable
- operator Something
- Zoz
- Zoz
- getZoz
- test_Something
- dependOnElem
- dependOnContainer
- callDependent
- test2
- GetPair
- testPair
- testTuple
- Base
- Derived
- Derived
- testDerived
- testNewExpr
- testSpaces
- testPointers
- testMakePair
- testMakeTuple
- Single
- Single
- Single
- Single
- Single
- Single
- Single
- Single
- Single
- Single
- MakeSingle
- testOtherTuples
- testOtherContainers
- IntWrapper
- IntWrapper
- operator+
- testMultipleOpsInPushBack
- macroTest
- A
- B
- B
- C
- testAggregation
- Bitfield
- testBitfields
- PrivateCtor
- doStuff
- WithDtor
- WithDtor
- testWithDtor
- testInitializerList
- Foo
- Foo
- Foo
- Foo
- Foo
- Foo
- testSomeEmplaceCases
- testAllSTLEmplacyFunctions
- test_AliasEmplacyFunctions
- test_Alias
- Bar
- Bar
- testWithPrivateAndProtectedCtor
- Bar
- Bar
- testPossibleFalsePositives
- InnerType
- NonTrivialNoCtor
- NonTrivialWithVector
- NonTrivialWithIntAndVector
- NonTrivialWithCtor
- testBracedInitTemporaries
Learn to use CMake with our Intro Training
Find out more