xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/modernize/use-emplace.cpp (revision 03ef103235752830da7b9ce5e825c0e3ddf7f45a)
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>
12 class initializer_list {
13 public:
14   initializer_list() noexcept {}
15 };
16 
17 template <typename T1, typename T2>
18 class pair {
19 public:
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 
33 template <typename T>
34 class vector {
35 public:
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 
55 template <typename T>
56 class list {
57 public:
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 
79 template <typename T>
80 class deque {
81 public:
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 
103 template <typename T>
104 class forward_list {
105 public:
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 
121 template <typename T>
122 class set {
123 public:
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 
136 template <typename Key, typename T>
137 class map {
138 public:
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 
151 template <typename T>
152 class multiset {
153 public:
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 
166 template <typename Key, typename T>
167 class multimap {
168 public:
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 
181 template <typename T>
182 class unordered_set {
183 public:
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 
196 template <typename Key, typename T>
197 class unordered_map {
198 public:
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 
211 template <typename T>
212 class unordered_multiset {
213 public:
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 
226 template <typename Key, typename T>
227 class unordered_multimap {
228 public:
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 
241 template <typename T>
242 class stack {
243 public:
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 
253 template <typename T>
254 class queue {
255 public:
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 
265 template <typename T>
266 class priority_queue {
267 public:
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 
277 template <typename T>
278 struct remove_reference { using type = T; };
279 template <typename T>
280 struct remove_reference<T &> { using type = T; };
281 template <typename T>
282 struct remove_reference<T &&> { using type = T; };
283 
284 template <typename T1, typename T2>
285 pair<typename remove_reference<T1>::type, typename remove_reference<T2>::type>
286 make_pair(T1 &&, T2 &&) {
287   return {};
288 };
289 
290 template <typename... Ts>
291 class tuple {
292 public:
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 
315 template <typename... Ts>
316 tuple<typename remove_reference<Ts>::type...> make_tuple(Ts &&...) {
317   return {};
318 }
319 
320 template <typename T>
321 class unique_ptr {
322 public:
323   explicit unique_ptr(T *) {}
324   ~unique_ptr();
325 };
326 } // namespace std
327 
328 namespace llvm {
329 template <typename T>
330 class LikeASmallVector {
331 public:
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 
341 void 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 
351 struct Something {
352   Something(int a, int b = 41) {}
353   Something() {}
354   void push_back(Something);
355   int getInt() { return 42; }
356 };
357 
358 struct Convertable {
359   operator Something() { return Something{}; }
360 };
361 
362 struct Zoz {
363   Zoz(Something, int = 42) {}
364 };
365 
366 Zoz getZoz(Something s) { return Zoz(s); }
367 
368 void 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 
410 template <typename ElemType>
411 void dependOnElem() {
412   std::vector<ElemType> v;
413   v.push_back(ElemType(42));
414 }
415 
416 template <typename ContainerType>
417 void dependOnContainer() {
418   ContainerType v;
419   v.push_back(Something(42));
420 }
421 
422 void callDependent() {
423   dependOnElem<Something>();
424   dependOnContainer<std::vector<Something>>();
425 }
426 
427 void 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(Something(1, 2)));
438 }
439 
440 struct GetPair {
441   std::pair<int, long> getPair();
442 };
443 void 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 
460 void 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 
484 struct Base {
485   Base(int, int *, int = 42);
486 };
487 
488 struct Derived : Base {
489   Derived(int *, Something) : Base(42, nullptr) {}
490 };
491 
492 void testDerived() {
493   std::vector<Base> v;
494   v.push_back(Derived(nullptr, Something{}));
495 }
496 
497 void testNewExpr() {
498   std::vector<Derived> v;
499   v.push_back(Derived(new int, Something{}));
500 }
501 
502 void 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 
543 void 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 
559 void 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 
605 void 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 
622 namespace test {
623 template <typename T>
624 struct 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 
643 template <typename T>
644 Single<typename std::remove_reference<T>::type> MakeSingle(T &&) {
645   return {};
646 }
647 } // namespace test
648 
649 void 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 
681 void 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 
726 class IntWrapper {
727 public:
728   IntWrapper(int x) : value(x) {}
729   IntWrapper operator+(const IntWrapper other) const {
730     return IntWrapper(value + other.value);
731   }
732 
733 private:
734   int value;
735 };
736 
737 void 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 )
751 void 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 
778 struct A {
779   int value1, value2;
780 };
781 
782 struct B {
783   B(A) {}
784 };
785 
786 struct C {
787   int value1, value2, value3;
788 };
789 
790 void 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({1, 2}));
796 
797   std::vector<B> vb;
798   vb.push_back(B({10, 42}));
799 }
800 
801 struct Bitfield {
802   unsigned bitfield : 1;
803   unsigned notBitfield;
804 };
805 
806 void 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 
821 class PrivateCtor {
822   PrivateCtor(int z);
823 
824 public:
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 
834 struct WithDtor {
835   WithDtor(int) {}
836   ~WithDtor();
837 };
838 
839 void 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 
847 void 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 
860 class Foo {
861 public:
862   Foo(){};
863   Foo(int){};
864   Foo(int, int){};
865   Foo(std::pair<int, int>){};
866 
867 protected:
868   Foo(char *) : Foo(){};
869 };
870 
871 void 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(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(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(v1.begin(), 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(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(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(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(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(std::make_pair(3, 3));
907 
908   m1.emplace(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(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(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(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(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(test::Single<int>(13));
926   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
927   v5.emplace_back(test::MakeSingle(13));
928   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
929 }
930 
931 void 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(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(vector.begin(), 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(deque.begin(), 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(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(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(forward_list.begin(), 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(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(list.begin(), 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(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(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(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(set.begin(), 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(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(map.begin(), 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(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(multiset.begin(), 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(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(multimap.begin(), 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(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(unordered_set.begin(), 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(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(unordered_map.begin(), 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(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(unordered_multiset.begin(), 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(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(unordered_multimap.begin(), 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(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(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(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 
1063 void test_AliasEmplacyFunctions() {
1064   typedef std::list<Foo> L;
1065   using DQ = std::deque<Foo>;
1066   L l;
1067   l.emplace_back(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(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(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(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(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(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 
1101 void 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 
1139 struct Bar {
1140 public:
1141   Bar(){};
1142   void testWithPrivateAndProtectedCtor() {
1143     std::vector<Bar> vec;
1144 
1145     vec.emplace_back(Bar(13));
1146     vec.emplace_back(Bar(13, 13));
1147   }
1148 
1149 protected:
1150   Bar(int){};
1151 
1152 private:
1153   Bar(int, int){};
1154 };
1155 
1156 void testPossibleFalsePositives() {
1157   struct Y {
1158     Y(std::pair<int, int> &&) {}
1159   };
1160   std::vector<Y> y;
1161   y.emplace_back(std::make_pair(2, 3));
1162 
1163   std::vector<std::pair<int, int>> v;
1164   v.emplace_back(std::make_pair<char, char>(0, 3));
1165 
1166   struct D {
1167     D(...) {}
1168     operator char() const { return 0; }
1169   };
1170   v.emplace_back(std::make_pair<D, int>(Something(), 2));
1171 }
1172 
1173 struct InnerType {
1174   InnerType();
1175   InnerType(char const*);
1176 };
1177 
1178 struct NonTrivialNoCtor {
1179   InnerType it;
1180 };
1181 
1182 struct NonTrivialWithVector {
1183   std::vector<int> it;
1184 };
1185 
1186 struct NonTrivialWithIntAndVector {
1187   int x;
1188   std::vector<int> it;
1189 };
1190 
1191 struct NonTrivialWithCtor {
1192   NonTrivialWithCtor();
1193   NonTrivialWithCtor(std::vector<int> const&);
1194 };
1195 
1196 void 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{InnerType{}});
1209   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1210   // CHECK-FIXES: v1.emplace_back();
1211   v1.push_back({InnerType{}});
1212   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1213   // CHECK-FIXES: v1.emplace_back();
1214   v1.push_back(NonTrivialNoCtor{InnerType()});
1215   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1216   // CHECK-FIXES: v1.emplace_back();
1217   v1.push_back({InnerType()});
1218   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1219   // CHECK-FIXES: v1.emplace_back();
1220   v1.push_back({{}});
1221   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1222   // CHECK-FIXES: v1.emplace_back();
1223 
1224   v1.emplace_back(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(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(NonTrivialNoCtor{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(NonTrivialNoCtor{{}});
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{""});
1240   v1.push_back({""});
1241   v1.push_back(NonTrivialNoCtor{InnerType{""}});
1242   v1.push_back({InnerType{""}});
1243   v1.emplace_back(NonTrivialNoCtor{""});
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{std::vector<int>{}});
1257   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1258   // CHECK-FIXES: v2.emplace_back();
1259   v2.push_back({std::vector<int>{}});
1260   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1261   // CHECK-FIXES: v2.emplace_back();
1262   v2.push_back(NonTrivialWithVector{std::vector<int>()});
1263   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1264   // CHECK-FIXES: v2.emplace_back();
1265   v2.push_back({std::vector<int>()});
1266   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1267   // CHECK-FIXES: v2.emplace_back();
1268   v2.push_back({{}});
1269   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1270   // CHECK-FIXES: v2.emplace_back();
1271 
1272   v2.emplace_back(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(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(NonTrivialWithVector{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(NonTrivialWithVector{{}});
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{{0}});
1289   v2.push_back({{0}});
1290   v2.push_back(NonTrivialWithVector{std::vector<int>{0}});
1291   v2.push_back({std::vector<int>{0}});
1292   v2.emplace_back(NonTrivialWithVector{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(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(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(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(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{1, {}});
1346   v4.push_back(NonTrivialWithIntAndVector{});
1347   v4.push_back({});
1348 }
1349 
1350 void 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(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(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(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(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(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(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(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(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(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(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(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(Something{});
1433   // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: unnecessary temporary object created while calling emplace
1434   // CHECK-FIXES: sp->emplace();
1435 }
1436