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