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

source code of clang-tools-extra/test/clang-tidy/checkers/modernize/use-emplace.cpp