xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/modernize/use-emplace.cpp (revision 482c41e992c1edf8833a4577b56ff9dda49fbc83)
1 // RUN: %check_clang_tidy %s modernize-use-emplace %t -- \
2 // RUN:   -config="{CheckOptions: \
3 // RUN:             {modernize-use-emplace.ContainersWithPushBack: \
4 // RUN:                '::std::vector; ::std::list; ::std::deque; llvm::LikeASmallVector', \
5 // RUN:              modernize-use-emplace.TupleTypes: \
6 // RUN:                '::std::pair; std::tuple; ::test::Single', \
7 // RUN:              modernize-use-emplace.TupleMakeFunctions: \
8 // RUN:                '::std::make_pair; ::std::make_tuple; ::test::MakeSingle'}}"
9 
10 namespace std {
11 template <typename E>
12 class initializer_list {
13 public:
14   const E *a, *b;
initializer_list()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 
pair(const T1 &,const T2 &)25   pair(const T1 &, const T2 &) {}
pair(T1 &&,T2 &&)26   pair(T1 &&, T2 &&) {}
27 
28   template <typename U1, typename U2>
pair(const pair<U1,U2> &)29   pair(const pair<U1, U2> &){};
30   template <typename U1, typename U2>
pair(pair<U1,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 {};
begin()41   const_iterator begin() { return const_iterator{}; }
42 
43   vector() = default;
vector(initializer_list<T>)44   vector(initializer_list<T>) {}
45 
push_back(const T &)46   void push_back(const T &) {}
push_back(T &&)47   void push_back(T &&) {}
48 
49   template <typename... Args>
emplace_back(Args &&...args)50   void emplace_back(Args &&... args){};
51   template <typename... Args>
emplace(const_iterator pos,Args &&...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 {};
begin()63   const_iterator begin() { return const_iterator{}; }
64 
push_front(const T &)65   void push_front(const T &) {}
push_front(T &&)66   void push_front(T &&) {}
67 
push_back(const T &)68   void push_back(const T &) {}
push_back(T &&)69   void push_back(T &&) {}
70 
71   template <typename... Args>
emplace(const_iterator pos,Args &&...args)72   iterator emplace(const_iterator pos, Args &&...args){};
73   template <typename... Args>
emplace_back(Args &&...args)74   void emplace_back(Args &&... args){};
75   template <typename... Args>
emplace_front(Args &&...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 {};
begin()87   const_iterator begin() { return const_iterator{}; }
88 
push_back(const T &)89   void push_back(const T &) {}
push_back(T &&)90   void push_back(T &&) {}
91 
push_front(const T &)92   void push_front(const T &) {}
push_front(T &&)93   void push_front(T &&) {}
94 
95   template <typename... Args>
emplace(const_iterator pos,Args &&...args)96   iterator emplace(const_iterator pos, Args &&...args){};
97   template <typename... Args>
emplace_back(Args &&...args)98   void emplace_back(Args &&... args){};
99   template <typename... Args>
emplace_front(Args &&...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 {};
begin()111   const_iterator begin() { return const_iterator{}; }
112 
push_front(const T &)113   void push_front(const T &) {}
push_front(T &&)114   void push_front(T &&) {}
115 
116   template <typename... Args>
emplace_front(Args &&...args)117   void emplace_front(Args &&...args){};
118   template <typename... Args>
emplace_after(const_iterator pos,Args &&...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 {};
begin()129   const_iterator begin() { return const_iterator{}; }
130 
131   template <typename... Args>
emplace(Args &&...args)132   void emplace(Args &&...args){};
133   template <typename... Args>
emplace_hint(const_iterator pos,Args &&...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 {};
begin()144   const_iterator begin() { return const_iterator{}; }
145 
146   template <typename... Args>
emplace(Args &&...args)147   void emplace(Args &&...args){};
148   template <typename... Args>
emplace_hint(const_iterator pos,Args &&...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 {};
begin()159   const_iterator begin() { return const_iterator{}; }
160 
161   template <typename... Args>
emplace(Args &&...args)162   void emplace(Args &&...args){};
163   template <typename... Args>
emplace_hint(const_iterator pos,Args &&...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 {};
begin()174   const_iterator begin() { return const_iterator{}; }
175 
176   template <typename... Args>
emplace(Args &&...args)177   void emplace(Args &&...args){};
178   template <typename... Args>
emplace_hint(const_iterator pos,Args &&...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 {};
begin()189   const_iterator begin() { return const_iterator{}; }
190 
191   template <typename... Args>
emplace(Args &&...args)192   void emplace(Args &&...args){};
193   template <typename... Args>
emplace_hint(const_iterator pos,Args &&...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 {};
begin()204   const_iterator begin() { return const_iterator{}; }
205 
206   template <typename... Args>
emplace(Args &&...args)207   void emplace(Args &&...args){};
208   template <typename... Args>
emplace_hint(const_iterator pos,Args &&...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 {};
begin()219   const_iterator begin() { return const_iterator{}; }
220 
221   template <typename... Args>
emplace(Args &&...args)222   void emplace(Args &&...args){};
223   template <typename... Args>
emplace_hint(const_iterator pos,Args &&...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 {};
begin()234   const_iterator begin() { return const_iterator{}; }
235 
236   template <typename... Args>
emplace(Args &&...args)237   void emplace(Args &&...args){};
238   template <typename... Args>
emplace_hint(const_iterator pos,Args &&...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 
push(const T &)247   void push(const T &) {}
push(T &&)248   void push(T &&) {}
249 
250   template <typename... Args>
emplace(Args &&...args)251   void emplace(Args &&...args){};
252 };
253 
254 template <typename T>
255 class queue {
256 public:
257   using value_type = T;
258 
push(const T &)259   void push(const T &) {}
push(T &&)260   void push(T &&) {}
261 
262   template <typename... Args>
emplace(Args &&...args)263   void emplace(Args &&...args){};
264 };
265 
266 template <typename T>
267 class priority_queue {
268 public:
269   using value_type = T;
270 
push(const T &)271   void push(const T &) {}
push(T &&)272   void push(T &&) {}
273 
274   template <typename... Args>
emplace(Args &&...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>
make_pair(T1 &&,T2 &&)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 
tuple(const Ts &...)298   tuple(const Ts &...) {}
tuple(Ts &&...)299   tuple(Ts &&...) {}
300 
301   template <typename... Us>
tuple(const tuple<Us...> &)302   tuple(const tuple<Us...> &){};
303   template <typename... Us>
tuple(tuple<Us...> &&)304   tuple(tuple<Us...> &&) {}
305 
306   template <typename U1, typename U2>
tuple(const pair<U1,U2> &)307   tuple(const pair<U1, U2> &) {
308     static_assert(sizeof...(Ts) == 2, "Wrong tuple size");
309   };
310   template <typename U1, typename U2>
tuple(pair<U1,U2> &&)311   tuple(pair<U1, U2> &&) {
312     static_assert(sizeof...(Ts) == 2, "Wrong tuple size");
313   };
314 };
315 
316 template <typename... Ts>
make_tuple(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:
unique_ptr(T *)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:
push_back(const T &)333   void push_back(const T &) {}
push_back(T &&)334   void push_back(T &&) {}
335 
336   template <typename... Args>
emplace_back(Args &&...args)337   void emplace_back(Args &&... args){};
338 };
339 
340 } // namespace llvm
341 
testInts()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 {
SomethingSomething353   Something(int a, int b = 41) {}
SomethingSomething354   Something() {}
355   void push_back(Something);
getIntSomething356   int getInt() { return 42; }
357 };
358 
359 struct Convertable {
operator SomethingConvertable360   operator Something() { return Something{}; }
361 };
362 
363 struct Zoz {
ZozZoz364   Zoz(Something, int = 42) {}
365 };
366 
getZoz(Something s)367 Zoz getZoz(Something s) { return Zoz(s); }
368 
test_Something()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>
dependOnElem()412 void dependOnElem() {
413   std::vector<ElemType> v;
414   v.push_back(ElemType(42));
415 }
416 
417 template <typename ContainerType>
dependOnContainer()418 void dependOnContainer() {
419   ContainerType v;
420   v.push_back(Something(42));
421 }
422 
callDependent()423 void callDependent() {
424   dependOnElem<Something>();
425   dependOnContainer<std::vector<Something>>();
426 }
427 
test2()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 };
testPair()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 
testTuple()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 {
DerivedDerived490   Derived(int *, Something) : Base(42, nullptr) {}
491 };
492 
testDerived()493 void testDerived() {
494   std::vector<Base> v;
495   v.push_back(Derived(nullptr, Something{}));
496 }
497 
testNewExpr()498 void testNewExpr() {
499   std::vector<Derived> v;
500   v.push_back(Derived(new int, Something{}));
501 }
502 
testSpaces()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 
testPointers()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 
testMakePair()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 
testMakeTuple()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 
Singletest::Single630   Single(const T &) {}
Singletest::Single631   Single(T &&) {}
632 
633   template <typename U>
Singletest::Single634   Single(const Single<U> &) {}
635   template <typename U>
Singletest::Single636   Single(Single<U> &&) {}
637 
638   template <typename U>
Singletest::Single639   Single(const std::tuple<U> &) {}
640   template <typename U>
Singletest::Single641   Single(std::tuple<U> &&) {}
642 };
643 
644 template <typename T>
MakeSingle(T &&)645 Single<typename std::remove_reference<T>::type> MakeSingle(T &&) {
646   return {};
647 }
648 } // namespace test
649 
testOtherTuples()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 
testOtherContainers()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:
IntWrapper(int x)729   IntWrapper(int x) : value(x) {}
operator +(const IntWrapper other) const730   IntWrapper operator+(const IntWrapper other) const {
731     return IntWrapper(value + other.value);
732   }
733 
734 private:
735   int value;
736 };
737 
testMultipleOpsInPushBack()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 )
macroTest()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 {
BB784   B(A) {}
785 };
786 
787 struct C {
788   int value1, value2, value3;
789 };
790 
testAggregation()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 
testBitfields()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:
doStuff()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 {
WithDtorWithDtor836   WithDtor(int) {}
837   ~WithDtor();
838 };
839 
testWithDtor()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 
testInitializerList()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:
Foo()863   Foo(){};
Foo(int)864   Foo(int){};
Foo(int,int)865   Foo(int, int){};
Foo(std::pair<int,int>)866   Foo(std::pair<int, int>){};
867 
868 protected:
Foo(char *)869   Foo(char *) : Foo(){};
870 };
871 
testSomeEmplaceCases()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 
testAllSTLEmplacyFunctions()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 
test_AliasEmplacyFunctions()1064 void test_AliasEmplacyFunctions() {
1065   typedef std::list<Foo> L;
1066   using DQ = std::deque<Foo>;
1067   L l;
1068   l.emplace_back(Foo(3));
1069   // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: unnecessary temporary object created while calling emplace_back
1070   // CHECK-FIXES: l.emplace_back(3);
1071 
1072   DQ dq;
1073   dq.emplace_back(Foo(3));
1074   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
1075   // CHECK-FIXES: dq.emplace_back(3);
1076 
1077   typedef std::stack<Foo> STACK;
1078   using PQ = std::priority_queue<Foo>;
1079   STACK stack;
1080   stack.emplace(Foo(3));
1081   // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: unnecessary temporary object created while calling emplace
1082   // CHECK-FIXES: stack.emplace(3);
1083 
1084   PQ pq;
1085   pq.emplace(Foo(3));
1086   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: unnecessary temporary object created while calling emplace
1087   // CHECK-FIXES: pq.emplace(3);
1088 
1089   typedef std::forward_list<Foo> FL;
1090   using DQ2 = std::deque<Foo>;
1091   FL fl;
1092   fl.emplace_front(Foo(3));
1093   // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: unnecessary temporary object created while calling emplace_front
1094   // CHECK-FIXES: fl.emplace_front(3);
1095 
1096   DQ2 dq2;
1097   dq2.emplace_front(Foo(3));
1098   // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: unnecessary temporary object created while calling emplace_front
1099   // CHECK-FIXES: dq2.emplace_front(3);
1100 }
1101 
test_Alias()1102 void test_Alias() {
1103   typedef std::list<Foo> L;
1104   using DQ = std::deque<Foo>;
1105   L l;
1106   l.push_back(Foo(3));
1107   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back instead of push_back [modernize-use-emplace]
1108   // CHECK-FIXES: l.emplace_back(3);
1109 
1110   DQ dq;
1111   dq.push_back(Foo(3));
1112   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back instead of push_back [modernize-use-emplace]
1113   // CHECK-FIXES: dq.emplace_back(3);
1114 
1115   typedef std::stack<Foo> STACK;
1116   using PQ = std::priority_queue<Foo>;
1117   STACK stack;
1118   stack.push(Foo(3));
1119   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use emplace instead of push [modernize-use-emplace]
1120   // CHECK-FIXES: stack.emplace(3);
1121 
1122   PQ pq;
1123   pq.push(Foo(3));
1124   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace instead of push [modernize-use-emplace]
1125   // CHECK-FIXES: pq.emplace(3);
1126 
1127   typedef std::forward_list<Foo> FL;
1128   using DQ2 = std::deque<Foo>;
1129   FL fl;
1130   fl.push_front(Foo(3));
1131   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_front instead of push_front [modernize-use-emplace]
1132   // CHECK-FIXES: fl.emplace_front(3);
1133 
1134   DQ2 dq2;
1135   dq2.push_front(Foo(3));
1136   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace_front instead of push_front [modernize-use-emplace]
1137   // CHECK-FIXES: dq2.emplace_front(3);
1138 }
1139 
1140 struct Bar {
1141 public:
BarBar1142   Bar(){};
testWithPrivateAndProtectedCtorBar1143   void testWithPrivateAndProtectedCtor() {
1144     std::vector<Bar> vec;
1145 
1146     vec.emplace_back(Bar(13));
1147     vec.emplace_back(Bar(13, 13));
1148   }
1149 
1150 protected:
BarBar1151   Bar(int){};
1152 
1153 private:
BarBar1154   Bar(int, int){};
1155 };
1156 
testPossibleFalsePositives()1157 void testPossibleFalsePositives() {
1158   struct Y {
1159     Y(std::pair<int, int> &&) {}
1160   };
1161   std::vector<Y> y;
1162   y.emplace_back(std::make_pair(2, 3));
1163 
1164   std::vector<std::pair<int, int>> v;
1165   v.emplace_back(std::make_pair<char, char>(0, 3));
1166 
1167   struct D {
1168     D(...) {}
1169     operator char() const { return 0; }
1170   };
1171   v.emplace_back(std::make_pair<D, int>(Something(), 2));
1172 }
1173 
1174 struct InnerType {
1175   InnerType();
1176   InnerType(char const*);
1177 };
1178 
1179 struct NonTrivialNoCtor {
1180   InnerType it;
1181 };
1182 
1183 struct NonTrivialWithVector {
1184   std::vector<int> it;
1185 };
1186 
1187 struct NonTrivialWithIntAndVector {
1188   int x;
1189   std::vector<int> it;
1190 };
1191 
1192 struct NonTrivialWithCtor {
1193   NonTrivialWithCtor();
1194   NonTrivialWithCtor(std::vector<int> const&);
1195 };
1196 
testBracedInitTemporaries()1197 void testBracedInitTemporaries() {
1198   std::vector<NonTrivialNoCtor> v1;
1199 
1200   v1.push_back(NonTrivialNoCtor());
1201   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1202   // CHECK-FIXES: v1.emplace_back();
1203   v1.push_back(NonTrivialNoCtor{});
1204   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1205   // CHECK-FIXES: v1.emplace_back();
1206   v1.push_back({});
1207   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1208   // CHECK-FIXES: v1.emplace_back();
1209   v1.push_back(NonTrivialNoCtor{InnerType{}});
1210   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1211   // CHECK-FIXES: v1.emplace_back();
1212   v1.push_back({InnerType{}});
1213   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1214   // CHECK-FIXES: v1.emplace_back();
1215   v1.push_back(NonTrivialNoCtor{InnerType()});
1216   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1217   // CHECK-FIXES: v1.emplace_back();
1218   v1.push_back({InnerType()});
1219   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1220   // CHECK-FIXES: v1.emplace_back();
1221   v1.push_back({{}});
1222   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1223   // CHECK-FIXES: v1.emplace_back();
1224 
1225   v1.emplace_back(NonTrivialNoCtor());
1226   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
1227   // CHECK-FIXES: v1.emplace_back();
1228   v1.emplace_back(NonTrivialNoCtor{});
1229   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
1230   // CHECK-FIXES: v1.emplace_back();
1231   v1.emplace_back(NonTrivialNoCtor{InnerType{}});
1232   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
1233   // CHECK-FIXES: v1.emplace_back();
1234   v1.emplace_back(NonTrivialNoCtor{{}});
1235   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
1236   // CHECK-FIXES: v1.emplace_back();
1237 
1238   // These should not be noticed or fixed; after the correction, the code won't
1239   // compile.
1240   v1.push_back(NonTrivialNoCtor{""});
1241   v1.push_back({""});
1242   v1.push_back(NonTrivialNoCtor{InnerType{""}});
1243   v1.push_back({InnerType{""}});
1244   v1.emplace_back(NonTrivialNoCtor{""});
1245 
1246   std::vector<NonTrivialWithVector> v2;
1247 
1248   v2.push_back(NonTrivialWithVector());
1249   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1250   // CHECK-FIXES: v2.emplace_back();
1251   v2.push_back(NonTrivialWithVector{});
1252   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1253   // CHECK-FIXES: v2.emplace_back();
1254   v2.push_back({});
1255   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1256   // CHECK-FIXES: v2.emplace_back();
1257   v2.push_back(NonTrivialWithVector{std::vector<int>{}});
1258   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1259   // CHECK-FIXES: v2.emplace_back();
1260   v2.push_back({std::vector<int>{}});
1261   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1262   // CHECK-FIXES: v2.emplace_back();
1263   v2.push_back(NonTrivialWithVector{std::vector<int>()});
1264   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1265   // CHECK-FIXES: v2.emplace_back();
1266   v2.push_back({std::vector<int>()});
1267   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1268   // CHECK-FIXES: v2.emplace_back();
1269   v2.push_back({{}});
1270   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1271   // CHECK-FIXES: v2.emplace_back();
1272 
1273   v2.emplace_back(NonTrivialWithVector());
1274   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
1275   // CHECK-FIXES: v2.emplace_back();
1276   v2.emplace_back(NonTrivialWithVector{});
1277   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
1278   // CHECK-FIXES: v2.emplace_back();
1279   v2.emplace_back(NonTrivialWithVector{std::vector<int>{}});
1280   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
1281   // CHECK-FIXES: v2.emplace_back();
1282   v2.emplace_back(NonTrivialWithVector{{}});
1283   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
1284   // CHECK-FIXES: v2.emplace_back();
1285 
1286 
1287   // These should not be noticed or fixed; after the correction, the code won't
1288   // compile.
1289   v2.push_back(NonTrivialWithVector{{0}});
1290   v2.push_back({{0}});
1291   v2.push_back(NonTrivialWithVector{std::vector<int>{0}});
1292   v2.push_back({std::vector<int>{0}});
1293   v2.emplace_back(NonTrivialWithVector{std::vector<int>{0}});
1294 
1295   std::vector<NonTrivialWithCtor> v3;
1296 
1297   v3.push_back(NonTrivialWithCtor());
1298   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1299   // CHECK-FIXES: v3.emplace_back();
1300   v3.push_back(NonTrivialWithCtor{});
1301   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1302   // CHECK-FIXES: v3.emplace_back();
1303   v3.push_back({});
1304   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1305   // CHECK-FIXES: v3.emplace_back();
1306   v3.push_back(NonTrivialWithCtor{std::vector<int>()});
1307   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1308   // CHECK-FIXES: v3.emplace_back(std::vector<int>());
1309   v3.push_back(NonTrivialWithCtor{std::vector<int>{0}});
1310   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1311   // CHECK-FIXES: v3.emplace_back(std::vector<int>{0});
1312   v3.push_back(NonTrivialWithCtor{std::vector<int>{}});
1313   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1314   // CHECK-FIXES: v3.emplace_back(std::vector<int>{});
1315   v3.push_back({std::vector<int>{0}});
1316   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1317   // CHECK-FIXES: v3.emplace_back(std::vector<int>{0});
1318   v3.push_back({std::vector<int>{}});
1319   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1320   // CHECK-FIXES: v3.emplace_back(std::vector<int>{});
1321 
1322   v3.emplace_back(NonTrivialWithCtor());
1323   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
1324   // CHECK-FIXES: v3.emplace_back();
1325   v3.emplace_back(NonTrivialWithCtor{});
1326   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
1327   // CHECK-FIXES: v3.emplace_back();
1328   v3.emplace_back(NonTrivialWithCtor{std::vector<int>{}});
1329   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
1330   // CHECK-FIXES: v3.emplace_back(std::vector<int>{});
1331   v3.emplace_back(NonTrivialWithCtor{std::vector<int>{0}});
1332   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
1333   // CHECK-FIXES: v3.emplace_back(std::vector<int>{0});
1334 
1335   // These should not be noticed or fixed; after the correction, the code won't
1336   // compile.
1337   v3.push_back(NonTrivialWithCtor{{0}});
1338   v3.push_back(NonTrivialWithCtor{{}});
1339   v3.push_back({{0}});
1340   v3.push_back({{}});
1341 
1342   std::vector<NonTrivialWithIntAndVector> v4;
1343 
1344   // These should not be noticed or fixed; after the correction, the code won't
1345   // compile.
1346   v4.push_back(NonTrivialWithIntAndVector{1, {}});
1347   v4.push_back(NonTrivialWithIntAndVector{});
1348   v4.push_back({});
1349 }
1350 
testWithPointerTypes()1351 void testWithPointerTypes() {
1352   std::list<Something> l;
1353   std::list<Something>* lp = &l;
1354   std::stack<Something> s;
1355   std::stack<Something>* sp;
1356 
1357   lp->push_back(Something(1, 2));
1358   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace_back instead of push_back [modernize-use-emplace]
1359   // CHECK-FIXES: lp->emplace_back(1, 2);
1360   lp->push_front(Something(1, 2));
1361   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace_front instead of push_front [modernize-use-emplace]
1362   // CHECK-FIXES: lp->emplace_front(1, 2);
1363   sp->push(Something(1, 2));
1364   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace instead of push [modernize-use-emplace]
1365   // CHECK-FIXES: sp->emplace(1, 2);
1366 
1367   lp->push_back(Something{1, 2});
1368   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace_back instead of push_back [modernize-use-emplace]
1369   // CHECK-FIXES: lp->emplace_back(1, 2);
1370   lp->push_front(Something{1, 2});
1371   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace_front instead of push_front [modernize-use-emplace]
1372   // CHECK-FIXES: lp->emplace_front(1, 2);
1373   sp->push(Something{1, 2});
1374   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace instead of push [modernize-use-emplace]
1375   // CHECK-FIXES: sp->emplace(1, 2);
1376 
1377   lp->push_back(Something());
1378   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace_back instead of push_back [modernize-use-emplace]
1379   // CHECK-FIXES: lp->emplace_back();
1380   lp->push_front(Something());
1381   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace_front instead of push_front [modernize-use-emplace]
1382   // CHECK-FIXES: lp->emplace_front();
1383   sp->push(Something());
1384   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace instead of push [modernize-use-emplace]
1385   // CHECK-FIXES: sp->emplace();
1386 
1387   lp->push_back(Something{});
1388   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace_back instead of push_back [modernize-use-emplace]
1389   // CHECK-FIXES: lp->emplace_back();
1390   lp->push_front(Something{});
1391   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace_front instead of push_front [modernize-use-emplace]
1392   // CHECK-FIXES: lp->emplace_front();
1393   sp->push(Something{});
1394   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace instead of push [modernize-use-emplace]
1395   // CHECK-FIXES: sp->emplace();
1396 
1397   lp->emplace_back(Something(1, 2));
1398   // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: unnecessary temporary object created while calling emplace_back
1399   // CHECK-FIXES: lp->emplace_back(1, 2);
1400   lp->emplace_front(Something(1, 2));
1401   // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: unnecessary temporary object created while calling emplace_front
1402   // CHECK-FIXES: lp->emplace_front(1, 2);
1403   sp->emplace(Something(1, 2));
1404   // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: unnecessary temporary object created while calling emplace
1405   // CHECK-FIXES: sp->emplace(1, 2);
1406 
1407   lp->emplace_back(Something{1, 2});
1408   // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: unnecessary temporary object created while calling emplace_back
1409   // CHECK-FIXES: lp->emplace_back(1, 2);
1410   lp->emplace_front(Something{1, 2});
1411   // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: unnecessary temporary object created while calling emplace_front
1412   // CHECK-FIXES: lp->emplace_front(1, 2);
1413   sp->emplace(Something{1, 2});
1414   // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: unnecessary temporary object created while calling emplace
1415   // CHECK-FIXES: sp->emplace(1, 2);
1416 
1417   lp->emplace_back(Something());
1418   // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: unnecessary temporary object created while calling emplace_back
1419   // CHECK-FIXES: lp->emplace_back();
1420   lp->emplace_front(Something());
1421   // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: unnecessary temporary object created while calling emplace_front
1422   // CHECK-FIXES: lp->emplace_front();
1423   sp->emplace(Something());
1424   // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: unnecessary temporary object created while calling emplace
1425   // CHECK-FIXES: sp->emplace();
1426 
1427   lp->emplace_back(Something{});
1428   // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: unnecessary temporary object created while calling emplace_back
1429   // CHECK-FIXES: lp->emplace_back();
1430   lp->emplace_front(Something{});
1431   // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: unnecessary temporary object created while calling emplace_front
1432   // CHECK-FIXES: lp->emplace_front();
1433   sp->emplace(Something{});
1434   // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: unnecessary temporary object created while calling emplace
1435   // CHECK-FIXES: sp->emplace();
1436 }
1437