xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/modernize/use-emplace.cpp (revision b8655f7ff286b9ebcd97cdd24b9c8eb5b89b9651)
1 // RUN: %check_clang_tidy %s modernize-use-emplace %t -- \
2 // RUN:   -config="{CheckOptions: \
3 // RUN:             [{key: modernize-use-emplace.ContainersWithPushBack, \
4 // RUN:               value: '::std::vector; ::std::list; ::std::deque; llvm::LikeASmallVector'}, \
5 // RUN:              {key: modernize-use-emplace.TupleTypes, \
6 // RUN:               value: '::std::pair; std::tuple; ::test::Single'}, \
7 // RUN:              {key: modernize-use-emplace.TupleMakeFunctions, \
8 // RUN:               value: '::std::make_pair; ::std::make_tuple; ::test::MakeSingle'}] \
9 // RUN:             }"
10 
11 namespace std {
12 template <typename>
13 class initializer_list {
14 public:
15   initializer_list() noexcept {}
16 };
17 
18 template <typename T1, typename T2>
19 class pair {
20 public:
21   pair() = default;
22   pair(const pair &) = default;
23   pair(pair &&) = default;
24 
25   pair(const T1 &, const T2 &) {}
26   pair(T1 &&, T2 &&) {}
27 
28   template <typename U1, typename U2>
29   pair(const pair<U1, U2> &){};
30   template <typename U1, typename U2>
31   pair(pair<U1, U2> &&){};
32 };
33 
34 template <typename T>
35 class vector {
36 public:
37   using value_type = T;
38 
39   class iterator {};
40   class const_iterator {};
41   const_iterator begin() { return const_iterator{}; }
42 
43   vector() = default;
44   vector(initializer_list<T>) {}
45 
46   void push_back(const T &) {}
47   void push_back(T &&) {}
48 
49   template <typename... Args>
50   void emplace_back(Args &&... args){};
51   template <typename... Args>
52   iterator emplace(const_iterator pos, Args &&...args){};
53   ~vector();
54 };
55 
56 template <typename T>
57 class list {
58 public:
59   using value_type = T;
60 
61   class iterator {};
62   class const_iterator {};
63   const_iterator begin() { return const_iterator{}; }
64 
65   void push_front(const T &) {}
66   void push_front(T &&) {}
67 
68   void push_back(const T &) {}
69   void push_back(T &&) {}
70 
71   template <typename... Args>
72   iterator emplace(const_iterator pos, Args &&...args){};
73   template <typename... Args>
74   void emplace_back(Args &&... args){};
75   template <typename... Args>
76   void emplace_front(Args &&...args){};
77   ~list();
78 };
79 
80 template <typename T>
81 class deque {
82 public:
83   using value_type = T;
84 
85   class iterator {};
86   class const_iterator {};
87   const_iterator begin() { return const_iterator{}; }
88 
89   void push_back(const T &) {}
90   void push_back(T &&) {}
91 
92   void push_front(const T &) {}
93   void push_front(T &&) {}
94 
95   template <typename... Args>
96   iterator emplace(const_iterator pos, Args &&...args){};
97   template <typename... Args>
98   void emplace_back(Args &&... args){};
99   template <typename... Args>
100   void emplace_front(Args &&...args){};
101   ~deque();
102 };
103 
104 template <typename T>
105 class forward_list {
106 public:
107   using value_type = T;
108 
109   class iterator {};
110   class const_iterator {};
111   const_iterator begin() { return const_iterator{}; }
112 
113   void push_front(const T &) {}
114   void push_front(T &&) {}
115 
116   template <typename... Args>
117   void emplace_front(Args &&...args){};
118   template <typename... Args>
119   iterator emplace_after(const_iterator pos, Args &&...args){};
120 };
121 
122 template <typename T>
123 class set {
124 public:
125   using value_type = T;
126 
127   class iterator {};
128   class const_iterator {};
129   const_iterator begin() { return const_iterator{}; }
130 
131   template <typename... Args>
132   void emplace(Args &&...args){};
133   template <typename... Args>
134   iterator emplace_hint(const_iterator pos, Args &&...args){};
135 };
136 
137 template <typename Key, typename T>
138 class map {
139 public:
140   using value_type = std::pair<Key, T>;
141 
142   class iterator {};
143   class const_iterator {};
144   const_iterator begin() { return const_iterator{}; }
145 
146   template <typename... Args>
147   void emplace(Args &&...args){};
148   template <typename... Args>
149   iterator emplace_hint(const_iterator pos, Args &&...args){};
150 };
151 
152 template <typename T>
153 class multiset {
154 public:
155   using value_type = T;
156 
157   class iterator {};
158   class const_iterator {};
159   const_iterator begin() { return const_iterator{}; }
160 
161   template <typename... Args>
162   void emplace(Args &&...args){};
163   template <typename... Args>
164   iterator emplace_hint(const_iterator pos, Args &&...args){};
165 };
166 
167 template <typename Key, typename T>
168 class multimap {
169 public:
170   using value_type = std::pair<Key, T>;
171 
172   class iterator {};
173   class const_iterator {};
174   const_iterator begin() { return const_iterator{}; }
175 
176   template <typename... Args>
177   void emplace(Args &&...args){};
178   template <typename... Args>
179   iterator emplace_hint(const_iterator pos, Args &&...args){};
180 };
181 
182 template <typename T>
183 class unordered_set {
184 public:
185   using value_type = T;
186 
187   class iterator {};
188   class const_iterator {};
189   const_iterator begin() { return const_iterator{}; }
190 
191   template <typename... Args>
192   void emplace(Args &&...args){};
193   template <typename... Args>
194   iterator emplace_hint(const_iterator pos, Args &&...args){};
195 };
196 
197 template <typename Key, typename T>
198 class unordered_map {
199 public:
200   using value_type = std::pair<Key, T>;
201 
202   class iterator {};
203   class const_iterator {};
204   const_iterator begin() { return const_iterator{}; }
205 
206   template <typename... Args>
207   void emplace(Args &&...args){};
208   template <typename... Args>
209   iterator emplace_hint(const_iterator pos, Args &&...args){};
210 };
211 
212 template <typename T>
213 class unordered_multiset {
214 public:
215   using value_type = T;
216 
217   class iterator {};
218   class const_iterator {};
219   const_iterator begin() { return const_iterator{}; }
220 
221   template <typename... Args>
222   void emplace(Args &&...args){};
223   template <typename... Args>
224   iterator emplace_hint(const_iterator pos, Args &&...args){};
225 };
226 
227 template <typename Key, typename T>
228 class unordered_multimap {
229 public:
230   using value_type = std::pair<Key, T>;
231 
232   class iterator {};
233   class const_iterator {};
234   const_iterator begin() { return const_iterator{}; }
235 
236   template <typename... Args>
237   void emplace(Args &&...args){};
238   template <typename... Args>
239   iterator emplace_hint(const_iterator pos, Args &&...args){};
240 };
241 
242 template <typename T>
243 class stack {
244 public:
245   using value_type = T;
246 
247   void push(const T &) {}
248   void push(T &&) {}
249 
250   template <typename... Args>
251   void emplace(Args &&...args){};
252 };
253 
254 template <typename T>
255 class queue {
256 public:
257   using value_type = T;
258 
259   void push(const T &) {}
260   void push(T &&) {}
261 
262   template <typename... Args>
263   void emplace(Args &&...args){};
264 };
265 
266 template <typename T>
267 class priority_queue {
268 public:
269   using value_type = T;
270 
271   void push(const T &) {}
272   void push(T &&) {}
273 
274   template <typename... Args>
275   void emplace(Args &&...args){};
276 };
277 
278 template <typename T>
279 struct remove_reference { using type = T; };
280 template <typename T>
281 struct remove_reference<T &> { using type = T; };
282 template <typename T>
283 struct remove_reference<T &&> { using type = T; };
284 
285 template <typename T1, typename T2>
286 pair<typename remove_reference<T1>::type, typename remove_reference<T2>::type>
287 make_pair(T1 &&, T2 &&) {
288   return {};
289 };
290 
291 template <typename... Ts>
292 class tuple {
293 public:
294   tuple() = default;
295   tuple(const tuple &) = default;
296   tuple(tuple &&) = default;
297 
298   tuple(const Ts &...) {}
299   tuple(Ts &&...) {}
300 
301   template <typename... Us>
302   tuple(const tuple<Us...> &){};
303   template <typename... Us>
304   tuple(tuple<Us...> &&) {}
305 
306   template <typename U1, typename U2>
307   tuple(const pair<U1, U2> &) {
308     static_assert(sizeof...(Ts) == 2, "Wrong tuple size");
309   };
310   template <typename U1, typename U2>
311   tuple(pair<U1, U2> &&) {
312     static_assert(sizeof...(Ts) == 2, "Wrong tuple size");
313   };
314 };
315 
316 template <typename... Ts>
317 tuple<typename remove_reference<Ts>::type...> make_tuple(Ts &&...) {
318   return {};
319 }
320 
321 template <typename T>
322 class unique_ptr {
323 public:
324   explicit unique_ptr(T *) {}
325   ~unique_ptr();
326 };
327 } // namespace std
328 
329 namespace llvm {
330 template <typename T>
331 class LikeASmallVector {
332 public:
333   void push_back(const T &) {}
334   void push_back(T &&) {}
335 
336   template <typename... Args>
337   void emplace_back(Args &&... args){};
338 };
339 
340 } // namespace llvm
341 
342 void testInts() {
343   std::vector<int> v;
344   v.push_back(42);
345   v.push_back(int(42));
346   v.push_back(int{42});
347   v.push_back(42.0);
348   int z;
349   v.push_back(z);
350 }
351 
352 struct Something {
353   Something(int a, int b = 41) {}
354   Something() {}
355   void push_back(Something);
356   int getInt() { return 42; }
357 };
358 
359 struct Convertable {
360   operator Something() { return Something{}; }
361 };
362 
363 struct Zoz {
364   Zoz(Something, int = 42) {}
365 };
366 
367 Zoz getZoz(Something s) { return Zoz(s); }
368 
369 void test_Something() {
370   std::vector<Something> v;
371 
372   v.push_back(Something(1, 2));
373   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back instead of push_back [modernize-use-emplace]
374   // CHECK-FIXES: v.emplace_back(1, 2);
375 
376   v.push_back(Something{1, 2});
377   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
378   // CHECK-FIXES: v.emplace_back(1, 2);
379 
380   v.push_back(Something());
381   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
382   // CHECK-FIXES: v.emplace_back();
383 
384   v.push_back(Something{});
385   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
386   // CHECK-FIXES: v.emplace_back();
387 
388   Something Different;
389   v.push_back(Something(Different.getInt(), 42));
390   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
391   // CHECK-FIXES: v.emplace_back(Different.getInt(), 42);
392 
393   v.push_back(Different.getInt());
394   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
395   // CHECK-FIXES: v.emplace_back(Different.getInt());
396 
397   v.push_back(42);
398   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
399   // CHECK-FIXES: v.emplace_back(42);
400 
401   Something temporary(42, 42);
402   temporary.push_back(temporary);
403   v.push_back(temporary);
404 
405   v.push_back(Convertable());
406   v.push_back(Convertable{});
407   Convertable s;
408   v.push_back(s);
409 }
410 
411 template <typename ElemType>
412 void dependOnElem() {
413   std::vector<ElemType> v;
414   v.push_back(ElemType(42));
415 }
416 
417 template <typename ContainerType>
418 void dependOnContainer() {
419   ContainerType v;
420   v.push_back(Something(42));
421 }
422 
423 void callDependent() {
424   dependOnElem<Something>();
425   dependOnContainer<std::vector<Something>>();
426 }
427 
428 void test2() {
429   std::vector<Zoz> v;
430   v.push_back(Zoz(Something(21, 37)));
431   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
432   // CHECK-FIXES: v.emplace_back(Something(21, 37));
433 
434   v.push_back(Zoz(Something(21, 37), 42));
435   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
436   // CHECK-FIXES: v.emplace_back(Something(21, 37), 42);
437 
438   v.push_back(getZoz(Something(1, 2)));
439 }
440 
441 struct GetPair {
442   std::pair<int, long> getPair();
443 };
444 void testPair() {
445   std::vector<std::pair<int, int>> v;
446   v.push_back(std::pair<int, int>(1, 2));
447   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
448   // CHECK-FIXES: v.emplace_back(1, 2);
449 
450   GetPair g;
451   v.push_back(g.getPair());
452   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
453   // CHECK-FIXES: v.emplace_back(g.getPair());
454 
455   std::vector<std::pair<Something, Zoz>> v2;
456   v2.push_back(std::pair<Something, Zoz>(Something(42, 42), Zoz(Something(21, 37))));
457   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
458   // CHECK-FIXES: v2.emplace_back(Something(42, 42), Zoz(Something(21, 37)));
459 }
460 
461 void testTuple() {
462   std::vector<std::tuple<bool, char, int>> v;
463   v.push_back(std::tuple<bool, char, int>(false, 'x', 1));
464   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
465   // CHECK-FIXES: v.emplace_back(false, 'x', 1);
466 
467   v.push_back(std::tuple<bool, char, int>{false, 'y', 2});
468   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
469   // CHECK-FIXES: v.emplace_back(false, 'y', 2);
470 
471   v.push_back({true, 'z', 3});
472   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
473   // CHECK-FIXES: v.emplace_back(true, 'z', 3);
474 
475   std::vector<std::tuple<int, bool>> x;
476   x.push_back(std::make_pair(1, false));
477   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
478   // CHECK-FIXES: x.emplace_back(1, false);
479 
480   x.push_back(std::make_pair(2LL, 1));
481   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
482   // CHECK-FIXES: x.emplace_back(2LL, 1);
483 }
484 
485 struct Base {
486   Base(int, int *, int = 42);
487 };
488 
489 struct Derived : Base {
490   Derived(int *, Something) : Base(42, nullptr) {}
491 };
492 
493 void testDerived() {
494   std::vector<Base> v;
495   v.push_back(Derived(nullptr, Something{}));
496 }
497 
498 void testNewExpr() {
499   std::vector<Derived> v;
500   v.push_back(Derived(new int, Something{}));
501 }
502 
503 void testSpaces() {
504   std::vector<Something> v;
505 
506   // clang-format off
507 
508   v.push_back(Something(1, //arg1
509                 2 // arg2
510                ) // Something
511               );
512   // CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use emplace_back
513   // CHECK-FIXES: v.emplace_back(1, //arg1
514   // CHECK-FIXES:                2 // arg2
515   // CHECK-FIXES:                  // Something
516   // CHECK-FIXES:                );
517 
518   v.push_back(    Something   (1, 2)    );
519   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
520   // CHECK-FIXES: v.emplace_back(1, 2   );
521 
522   v.push_back(    Something   {1, 2}    );
523   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
524   // CHECK-FIXES: v.emplace_back(1, 2   );
525 
526   v.push_back(  Something {}    );
527   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
528   // CHECK-FIXES: v.emplace_back(   );
529 
530   v.push_back(
531              Something(1, 2)    );
532   // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use emplace_back
533   // CHECK-FIXES: v.emplace_back(1, 2   );
534 
535   std::vector<Base> v2;
536   v2.push_back(
537     Base(42, nullptr));
538   // CHECK-MESSAGES: :[[@LINE-2]]:6: warning: use emplace_back
539   // CHECK-FIXES: v2.emplace_back(42, nullptr);
540 
541   // clang-format on
542 }
543 
544 void testPointers() {
545   std::vector<int *> v;
546   v.push_back(new int(5));
547 
548   std::vector<std::unique_ptr<int>> v2;
549   v2.push_back(std::unique_ptr<int>(new int(42)));
550   // This call can't be replaced with emplace_back.
551   // If emplacement will fail (not enough memory to add to vector)
552   // we will have leak of int because unique_ptr won't be constructed
553   // (and destructed) as in push_back case.
554 
555   auto *ptr = new int;
556   v2.push_back(std::unique_ptr<int>(ptr));
557   // Same here
558 }
559 
560 void testMakePair() {
561   std::vector<std::pair<int, int>> v;
562   v.push_back(std::make_pair(1, 2));
563   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
564   // CHECK-FIXES: v.emplace_back(1, 2);
565 
566   v.push_back(std::make_pair(42LL, 13));
567   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
568   // CHECK-FIXES: v.emplace_back(42LL, 13);
569 
570   v.push_back(std::make_pair<char, char>(0, 3));
571   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
572   // CHECK-FIXES: v.emplace_back(std::make_pair<char, char>(0, 3));
573   //
574   // Even though the call above could be turned into v.emplace_back(0, 3),
575   // we don't eliminate the make_pair call here, because of the explicit
576   // template parameters provided. make_pair's arguments can be convertible
577   // to its explicitly provided template parameter, but not to the pair's
578   // element type. The examples below illustrate the problem.
579   struct D {
580     D(...) {}
581     operator char() const { return 0; }
582   };
583   v.push_back(std::make_pair<D, int>(Something(), 2));
584   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
585   // CHECK-FIXES: v.emplace_back(std::make_pair<D, int>(Something(), 2));
586 
587   struct X {
588     X(std::pair<int, int>) {}
589   };
590   std::vector<X> x;
591   x.push_back(std::make_pair(1, 2));
592   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
593   // CHECK-FIXES: x.emplace_back(std::make_pair(1, 2));
594   // make_pair cannot be removed here, as X is not constructible with two ints.
595 
596   struct Y {
597     Y(std::pair<int, int> &&) {}
598   };
599   std::vector<Y> y;
600   y.push_back(std::make_pair(2, 3));
601   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
602   // CHECK-FIXES: y.emplace_back(std::make_pair(2, 3));
603   // make_pair cannot be removed here, as Y is not constructible with two ints.
604 }
605 
606 void testMakeTuple() {
607   std::vector<std::tuple<int, bool, char>> v;
608   v.push_back(std::make_tuple(1, true, 'v'));
609   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
610   // CHECK-FIXES: v.emplace_back(1, true, 'v');
611 
612   v.push_back(std::make_tuple(2ULL, 1, 0));
613   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
614   // CHECK-FIXES: v.emplace_back(2ULL, 1, 0);
615 
616   v.push_back(std::make_tuple<long long, int, int>(3LL, 1, 0));
617   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
618   // CHECK-FIXES: v.emplace_back(std::make_tuple<long long, int, int>(3LL, 1, 0));
619   // make_tuple is not removed when there are explicit template
620   // arguments provided.
621 }
622 
623 namespace test {
624 template <typename T>
625 struct Single {
626   Single() = default;
627   Single(const Single &) = default;
628   Single(Single &&) = default;
629 
630   Single(const T &) {}
631   Single(T &&) {}
632 
633   template <typename U>
634   Single(const Single<U> &) {}
635   template <typename U>
636   Single(Single<U> &&) {}
637 
638   template <typename U>
639   Single(const std::tuple<U> &) {}
640   template <typename U>
641   Single(std::tuple<U> &&) {}
642 };
643 
644 template <typename T>
645 Single<typename std::remove_reference<T>::type> MakeSingle(T &&) {
646   return {};
647 }
648 } // namespace test
649 
650 void testOtherTuples() {
651   std::vector<test::Single<int>> v;
652   v.push_back(test::Single<int>(1));
653   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
654   // CHECK-FIXES: v.emplace_back(1);
655 
656   v.push_back({2});
657   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
658   // CHECK-FIXES: v.emplace_back(2);
659 
660   v.push_back(test::MakeSingle(3));
661   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
662   // CHECK-FIXES: v.emplace_back(3);
663 
664   v.push_back(test::MakeSingle<long long>(4));
665   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
666   // CHECK-FIXES: v.emplace_back(test::MakeSingle<long long>(4));
667   // We don't remove make functions with explicit template parameters.
668 
669   v.push_back(test::MakeSingle(5LL));
670   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
671   // CHECK-FIXES: v.emplace_back(5LL);
672 
673   v.push_back(std::make_tuple(6));
674   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
675   // CHECK-FIXES: v.emplace_back(6);
676 
677   v.push_back(std::make_tuple(7LL));
678   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
679   // CHECK-FIXES: v.emplace_back(7LL);
680 }
681 
682 void testOtherContainers() {
683   std::list<Something> l;
684   l.push_back(Something(42, 41));
685   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
686   // CHECK-FIXES: l.emplace_back(42, 41);
687 
688   l.push_front(Something(42, 41));
689   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_front
690   // CHECK-FIXES: l.emplace_front(42, 41);
691 
692   std::deque<Something> d;
693   d.push_back(Something(42));
694   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
695   // CHECK-FIXES: d.emplace_back(42);
696 
697   d.push_front(Something(42));
698   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_front
699   // CHECK-FIXES: d.emplace_front(42);
700 
701   llvm::LikeASmallVector<Something> ls;
702   ls.push_back(Something(42));
703   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
704   // CHECK-FIXES: ls.emplace_back(42);
705 
706   std::stack<Something> s;
707   s.push(Something(42, 41));
708   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace
709   // CHECK-FIXES: s.emplace(42, 41);
710 
711   std::queue<Something> q;
712   q.push(Something(42, 41));
713   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace
714   // CHECK-FIXES: q.emplace(42, 41);
715 
716   std::priority_queue<Something> pq;
717   pq.push(Something(42, 41));
718   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace
719   // CHECK-FIXES: pq.emplace(42, 41);
720 
721   std::forward_list<Something> fl;
722   fl.push_front(Something(42, 41));
723   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_front
724   // CHECK-FIXES: fl.emplace_front(42, 41);
725 }
726 
727 class IntWrapper {
728 public:
729   IntWrapper(int x) : value(x) {}
730   IntWrapper operator+(const IntWrapper other) const {
731     return IntWrapper(value + other.value);
732   }
733 
734 private:
735   int value;
736 };
737 
738 void testMultipleOpsInPushBack() {
739   std::vector<IntWrapper> v;
740   v.push_back(IntWrapper(42) + IntWrapper(27));
741 }
742 
743 // Macro tests.
744 #define PUSH_BACK_WHOLE(c, x) c.push_back(x)
745 #define PUSH_BACK_NAME push_back
746 #define PUSH_BACK_ARG(x) (x)
747 #define SOME_OBJ Something(10)
748 #define MILLION 3
749 #define SOME_WEIRD_PUSH(v) v.push_back(Something(
750 #define OPEN (
751 #define CLOSE )
752 void macroTest() {
753   std::vector<Something> v;
754   Something s;
755 
756   PUSH_BACK_WHOLE(v, Something(5, 6));
757   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use emplace_back
758 
759   v.PUSH_BACK_NAME(Something(5));
760   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
761 
762   v.push_back PUSH_BACK_ARG(Something(5, 6));
763   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
764 
765   v.push_back(SOME_OBJ);
766   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
767 
768   v.push_back(Something(MILLION));
769   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
770   // CHECK-FIXES: v.emplace_back(MILLION);
771 
772   // clang-format off
773   v.push_back(  Something OPEN 3 CLOSE  );
774   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
775   // clang-format on
776   PUSH_BACK_WHOLE(s, Something(1));
777 }
778 
779 struct A {
780   int value1, value2;
781 };
782 
783 struct B {
784   B(A) {}
785 };
786 
787 struct C {
788   int value1, value2, value3;
789 };
790 
791 void testAggregation() {
792   // This should not be noticed or fixed; after the correction, the code won't
793   // compile.
794 
795   std::vector<A> v;
796   v.push_back(A({1, 2}));
797 
798   std::vector<B> vb;
799   vb.push_back(B({10, 42}));
800 }
801 
802 struct Bitfield {
803   unsigned bitfield : 1;
804   unsigned notBitfield;
805 };
806 
807 void testBitfields() {
808   std::vector<Something> v;
809   Bitfield b;
810   v.push_back(Something(42, b.bitfield));
811   v.push_back(Something(b.bitfield));
812 
813   v.push_back(Something(42, b.notBitfield));
814   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
815   // CHECK-FIXES: v.emplace_back(42, b.notBitfield);
816   int var;
817   v.push_back(Something(42, var));
818   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
819   // CHECK-FIXES: v.emplace_back(42, var);
820 }
821 
822 class PrivateCtor {
823   PrivateCtor(int z);
824 
825 public:
826   void doStuff() {
827     std::vector<PrivateCtor> v;
828     // This should not change it because emplace back doesn't have permission.
829     // Check currently doesn't support friend declarations because pretty much
830     // nobody would want to be friend with std::vector :(.
831     v.push_back(PrivateCtor(42));
832   }
833 };
834 
835 struct WithDtor {
836   WithDtor(int) {}
837   ~WithDtor();
838 };
839 
840 void testWithDtor() {
841   std::vector<WithDtor> v;
842 
843   v.push_back(WithDtor(42));
844   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
845   // CHECK-FIXES: v.emplace_back(42);
846 }
847 
848 void testInitializerList() {
849   std::vector<std::vector<int>> v;
850   v.push_back(std::vector<int>({1}));
851   // Test against the bug reported in PR32896.
852 
853   v.push_back({{2}});
854 
855   using PairIntVector = std::pair<int, std::vector<int>>;
856   std::vector<PairIntVector> x;
857   x.push_back(PairIntVector(3, {4}));
858   x.push_back({5, {6}});
859 }
860 
861 class Foo {
862 public:
863   Foo(){};
864   Foo(int){};
865   Foo(int, int){};
866   Foo(std::pair<int, int>){};
867 
868 protected:
869   Foo(char *) : Foo(){};
870 };
871 
872 void testSomeEmplaceCases() {
873   std::vector<std::pair<char *, char *>> v1;
874   std::vector<Foo> v2;
875   std::unordered_map<int, char *> m1;
876 
877   v1.emplace_back(std::make_pair("foo", "bar"));
878   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
879   // CHECK-FIXES: v1.emplace_back("foo", "bar");
880 
881   char *foo = "bar";
882   v1.emplace_back(std::make_pair(foo, "bar"));
883   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
884   // CHECK-FIXES: v1.emplace_back(foo, "bar");
885 
886   v1.emplace(v1.begin(), std::make_pair("foo", "bar"));
887   // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: unnecessary temporary object created while calling emplace
888   // CHECK-FIXES: v1.emplace(v1.begin(), "foo", "bar");
889 
890   v2.emplace_back(Foo());
891   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
892   // CHECK-FIXES: v2.emplace_back();
893 
894   v2.emplace_back(Foo(13));
895   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
896   // CHECK-FIXES: v2.emplace_back(13);
897 
898   v2.emplace_back(Foo{13});
899   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
900   // CHECK-FIXES: v2.emplace_back(13);
901 
902   int a = 31;
903   v2.emplace_back(Foo(13, a));
904   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
905   // CHECK-FIXES: v2.emplace_back(13, a);
906 
907   v2.emplace_back(std::make_pair(3, 3));
908 
909   m1.emplace(std::make_pair(13, "foo"));
910   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: unnecessary temporary object created while calling emplace
911   // CHECK-FIXES: m1.emplace(13, "foo");
912 
913   std::vector<std::pair<int, int>> v3;
914   v3.emplace_back(std::pair<int, int>(13, 71));
915   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
916   v3.emplace_back(std::make_pair(13, 71));
917   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
918 
919   std::vector<std::tuple<int, int, int>> v4;
920   v4.emplace_back(std::tuple<int, int, int>(13, 31, 71));
921   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
922   v4.emplace_back(std::make_tuple(13, 31, 71));
923   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
924 
925   std::vector<test::Single<int>> v5;
926   v5.emplace_back(test::Single<int>(13));
927   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
928   v5.emplace_back(test::MakeSingle(13));
929   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
930 }
931 
932 void testAllSTLEmplacyFunctions() {
933   std::vector<Foo> vector;
934   std::deque<Foo> deque;
935   std::forward_list<Foo> forward_list;
936   std::list<Foo> list;
937   std::set<Foo> set;
938   std::map<int, Foo> map;
939   std::multiset<Foo> multiset;
940   std::multimap<int, Foo> multimap;
941   std::unordered_set<Foo> unordered_set;
942   std::unordered_map<int, Foo> unordered_map;
943   std::unordered_multiset<Foo> unordered_multiset;
944   std::unordered_multimap<int, Foo> unordered_multimap;
945   std::stack<Foo> stack;
946   std::queue<Foo> queue;
947   std::priority_queue<Foo> priority_queue;
948 
949   vector.emplace_back(Foo(13));
950   // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: unnecessary temporary object created while calling emplace_back
951   // CHECK-FIXES: vector.emplace_back(13);
952 
953   vector.emplace(vector.begin(), Foo(13));
954   // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: unnecessary temporary object created while calling emplace
955   // CHECK-FIXES: vector.emplace(vector.begin(), 13);
956 
957   deque.emplace(deque.begin(), Foo(13));
958   // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: unnecessary temporary object created while calling emplace
959   // CHECK-FIXES: deque.emplace(deque.begin(), 13);
960 
961   deque.emplace_front(Foo(13));
962   // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: unnecessary temporary object created while calling emplace_front
963   // CHECK-FIXES: deque.emplace_front(13);
964 
965   deque.emplace_back(Foo(13));
966   // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: unnecessary temporary object created while calling emplace_back
967   // CHECK-FIXES: deque.emplace_back(13);
968 
969   forward_list.emplace_after(forward_list.begin(), Foo(13));
970   // CHECK-MESSAGES: :[[@LINE-1]]:52: warning: unnecessary temporary object created while calling emplace_after
971   // CHECK-FIXES: forward_list.emplace_after(forward_list.begin(), 13);
972 
973   forward_list.emplace_front(Foo(13));
974   // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: unnecessary temporary object created while calling emplace_front
975   // CHECK-FIXES: forward_list.emplace_front(13);
976 
977   list.emplace(list.begin(), Foo(13));
978   // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: unnecessary temporary object created while calling emplace
979   // CHECK-FIXES: list.emplace(list.begin(), 13);
980 
981   list.emplace_back(Foo(13));
982   // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: unnecessary temporary object created while calling emplace_back
983   // CHECK-FIXES: list.emplace_back(13);
984 
985   list.emplace_front(Foo(13));
986   // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: unnecessary temporary object created while calling emplace_front
987   // CHECK-FIXES: list.emplace_front(13);
988 
989   set.emplace(Foo(13));
990   // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: unnecessary temporary object created while calling emplace
991   // CHECK-FIXES: set.emplace(13);
992 
993   set.emplace_hint(set.begin(), Foo(13));
994   // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: unnecessary temporary object created while calling emplace_hint
995   // CHECK-FIXES: set.emplace_hint(set.begin(), 13);
996 
997   map.emplace(std::make_pair(13, Foo(13)));
998   // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: unnecessary temporary object created while calling emplace
999   // CHECK-FIXES: map.emplace(13, Foo(13));
1000 
1001   map.emplace_hint(map.begin(), std::make_pair(13, Foo(13)));
1002   // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: unnecessary temporary object created while calling emplace_hint
1003   // CHECK-FIXES: map.emplace_hint(map.begin(), 13, Foo(13));
1004 
1005   multiset.emplace(Foo(13));
1006   // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: unnecessary temporary object created while calling emplace
1007   // CHECK-FIXES: multiset.emplace(13);
1008 
1009   multiset.emplace_hint(multiset.begin(), Foo(13));
1010   // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: unnecessary temporary object created while calling emplace_hint
1011   // CHECK-FIXES: multiset.emplace_hint(multiset.begin(), 13);
1012 
1013   multimap.emplace(std::make_pair(13, Foo(13)));
1014   // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: unnecessary temporary object created while calling emplace
1015   // CHECK-FIXES: multimap.emplace(13, Foo(13));
1016 
1017   multimap.emplace_hint(multimap.begin(), std::make_pair(13, Foo(13)));
1018   // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: unnecessary temporary object created while calling emplace_hint
1019   // CHECK-FIXES: multimap.emplace_hint(multimap.begin(), 13, Foo(13));
1020 
1021   unordered_set.emplace(Foo(13));
1022   // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: unnecessary temporary object created while calling emplace
1023   // CHECK-FIXES: unordered_set.emplace(13);
1024 
1025   unordered_set.emplace_hint(unordered_set.begin(), Foo(13));
1026   // CHECK-MESSAGES: :[[@LINE-1]]:53: warning: unnecessary temporary object created while calling emplace_hint
1027   // CHECK-FIXES: unordered_set.emplace_hint(unordered_set.begin(), 13);
1028 
1029   unordered_map.emplace(std::make_pair(13, Foo(13)));
1030   // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: unnecessary temporary object created while calling emplace
1031   // CHECK-FIXES: unordered_map.emplace(13, Foo(13));
1032 
1033   unordered_map.emplace_hint(unordered_map.begin(), std::make_pair(13, Foo(13)));
1034   // CHECK-MESSAGES: :[[@LINE-1]]:53: warning: unnecessary temporary object created while calling emplace_hint
1035   // CHECK-FIXES: unordered_map.emplace_hint(unordered_map.begin(), 13, Foo(13));
1036 
1037   unordered_multiset.emplace(Foo(13));
1038   // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: unnecessary temporary object created while calling emplace
1039   // CHECK-FIXES: unordered_multiset.emplace(13);
1040   unordered_multiset.emplace_hint(unordered_multiset.begin(), Foo(13));
1041   // CHECK-MESSAGES: :[[@LINE-1]]:63: warning: unnecessary temporary object created while calling emplace_hint
1042   // CHECK-FIXES: unordered_multiset.emplace_hint(unordered_multiset.begin(), 13);
1043 
1044   unordered_multimap.emplace(std::make_pair(13, Foo(13)));
1045   // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: unnecessary temporary object created while calling emplace
1046   // CHECK-FIXES: unordered_multimap.emplace(13, Foo(13));
1047   unordered_multimap.emplace_hint(unordered_multimap.begin(), std::make_pair(13, Foo(13)));
1048   // CHECK-MESSAGES: :[[@LINE-1]]:63: warning: unnecessary temporary object created while calling emplace_hint
1049   // CHECK-FIXES: unordered_multimap.emplace_hint(unordered_multimap.begin(), 13, Foo(13));
1050 
1051   stack.emplace(Foo(13));
1052   // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: unnecessary temporary object created while calling emplace
1053   // CHECK-FIXES: stack.emplace(13);
1054 
1055   queue.emplace(Foo(13));
1056   // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: unnecessary temporary object created while calling emplace
1057   // CHECK-FIXES: queue.emplace(13);
1058 
1059   priority_queue.emplace(Foo(13));
1060   // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: unnecessary temporary object created while calling emplace
1061   // CHECK-FIXES: priority_queue.emplace(13);
1062 }
1063 
1064 struct Bar {
1065 public:
1066   Bar(){};
1067   void testWithPrivateAndProtectedCtor() {
1068     std::vector<Bar> vec;
1069 
1070     vec.emplace_back(Bar(13));
1071     vec.emplace_back(Bar(13, 13));
1072   }
1073 
1074 protected:
1075   Bar(int){};
1076 
1077 private:
1078   Bar(int, int){};
1079 };
1080 
1081 void testPossibleFalsePositives() {
1082   struct Y {
1083     Y(std::pair<int, int> &&) {}
1084   };
1085   std::vector<Y> y;
1086   y.emplace_back(std::make_pair(2, 3));
1087 
1088   std::vector<std::pair<int, int>> v;
1089   v.emplace_back(std::make_pair<char, char>(0, 3));
1090 
1091   struct D {
1092     D(...) {}
1093     operator char() const { return 0; }
1094   };
1095   v.emplace_back(std::make_pair<D, int>(Something(), 2));
1096 }
1097