1// RUN: %check_clang_tidy %s modernize-use-emplace %t -- \
2// RUN: -config="{CheckOptions: \
3// RUN: {modernize-use-emplace.ContainersWithPushBack: \
4// RUN: '::std::vector; ::std::list; ::std::deque; llvm::LikeASmallVector', \
5// RUN: modernize-use-emplace.TupleTypes: \
6// RUN: '::std::pair; std::tuple; ::test::Single', \
7// RUN: modernize-use-emplace.TupleMakeFunctions: \
8// RUN: '::std::make_pair; ::std::make_tuple; ::test::MakeSingle'}}"
9
10namespace std {
11template <typename E>
12class initializer_list {
13public:
14 const E *a, *b;
15 initializer_list() noexcept {}
16};
17
18template <typename T1, typename T2>
19class pair {
20public:
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
34template <typename T>
35class vector {
36public:
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
56template <typename T>
57class list {
58public:
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
80template <typename T>
81class deque {
82public:
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
104template <typename T>
105class forward_list {
106public:
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
122template <typename T>
123class set {
124public:
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
137template <typename Key, typename T>
138class map {
139public:
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
152template <typename T>
153class multiset {
154public:
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
167template <typename Key, typename T>
168class multimap {
169public:
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
182template <typename T>
183class unordered_set {
184public:
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
197template <typename Key, typename T>
198class unordered_map {
199public:
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
212template <typename T>
213class unordered_multiset {
214public:
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
227template <typename Key, typename T>
228class unordered_multimap {
229public:
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
242template <typename T>
243class stack {
244public:
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
254template <typename T>
255class queue {
256public:
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
266template <typename T>
267class priority_queue {
268public:
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
278template <typename T>
279struct remove_reference { using type = T; };
280template <typename T>
281struct remove_reference<T &> { using type = T; };
282template <typename T>
283struct remove_reference<T &&> { using type = T; };
284
285template <typename T1, typename T2>
286pair<typename remove_reference<T1>::type, typename remove_reference<T2>::type>
287make_pair(T1 &&, T2 &&) {
288 return {};
289};
290
291template <typename... Ts>
292class tuple {
293public:
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
316template <typename... Ts>
317tuple<typename remove_reference<Ts>::type...> make_tuple(Ts &&...) {
318 return {};
319}
320
321template <typename T>
322class unique_ptr {
323public:
324 explicit unique_ptr(T *) {}
325 ~unique_ptr();
326};
327} // namespace std
328
329namespace llvm {
330template <typename T>
331class LikeASmallVector {
332public:
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
342void 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
352struct Something {
353 Something(int a, int b = 41) {}
354 Something() {}
355 void push_back(Something);
356 int getInt() { return 42; }
357};
358
359struct Convertable {
360 operator Something() { return Something{}; }
361};
362
363struct Zoz {
364 Zoz(Something, int = 42) {}
365};
366
367Zoz getZoz(Something s) { return Zoz(s); }
368
369void 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
411template <typename ElemType>
412void dependOnElem() {
413 std::vector<ElemType> v;
414 v.push_back(ElemType(42));
415}
416
417template <typename ContainerType>
418void dependOnContainer() {
419 ContainerType v;
420 v.push_back(Something(42));
421}
422
423void callDependent() {
424 dependOnElem<Something>();
425 dependOnContainer<std::vector<Something>>();
426}
427
428void 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(s: Something(1, 2)));
439}
440
441struct GetPair {
442 std::pair<int, long> getPair();
443};
444void 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
461void 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
485struct Base {
486 Base(int, int *, int = 42);
487};
488
489struct Derived : Base {
490 Derived(int *, Something) : Base(42, nullptr) {}
491};
492
493void testDerived() {
494 std::vector<Base> v;
495 v.push_back(Derived(nullptr, Something{}));
496}
497
498void testNewExpr() {
499 std::vector<Derived> v;
500 v.push_back(Derived(new int, Something{}));
501}
502
503void 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
544void 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
560void 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
606void 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
623namespace test {
624template <typename T>
625struct 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
644template <typename T>
645Single<typename std::remove_reference<T>::type> MakeSingle(T &&) {
646 return {};
647}
648} // namespace test
649
650void 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
682void 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
727class IntWrapper {
728public:
729 IntWrapper(int x) : value(x) {}
730 IntWrapper operator+(const IntWrapper other) const {
731 return IntWrapper(value + other.value);
732 }
733
734private:
735 int value;
736};
737
738void 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 )
752void 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
779struct A {
780 int value1, value2;
781};
782
783struct B {
784 B(A) {}
785};
786
787struct C {
788 int value1, value2, value3;
789};
790
791void 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({.value1: 1, .value2: 2}));
797
798 std::vector<B> vb;
799 vb.push_back(B({.value1: 10, .value2: 42}));
800}
801
802struct Bitfield {
803 unsigned bitfield : 1;
804 unsigned notBitfield;
805};
806
807void 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
822class PrivateCtor {
823 PrivateCtor(int z);
824
825public:
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
835struct WithDtor {
836 WithDtor(int) {}
837 ~WithDtor();
838};
839
840void 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
848void 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
861class Foo {
862public:
863 Foo(){};
864 Foo(int){};
865 Foo(int, int){};
866 Foo(std::pair<int, int>){};
867
868protected:
869 Foo(char *) : Foo(){};
870};
871
872void 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(args: 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(args: 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(pos: v1.begin(), args: 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(args: 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(args: 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(args: 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(args: 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(args: std::make_pair(3, 3));
908
909 m1.emplace(args: 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(args: 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(args: 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(args: 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(args: 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(args: test::Single<int>(13));
927 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
928 v5.emplace_back(args: test::MakeSingle(13));
929 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
930}
931
932void 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(args: 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(pos: vector.begin(), args: 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(pos: deque.begin(), args: 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(args: 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(args: 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(pos: forward_list.begin(), args: 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(args: 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(pos: list.begin(), args: 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(args: 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(args: 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(args: 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(pos: set.begin(), args: 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(args: 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(pos: map.begin(), args: 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(args: 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(pos: multiset.begin(), args: 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(args: 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(pos: multimap.begin(), args: 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(args: 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(pos: unordered_set.begin(), args: 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(args: 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(pos: unordered_map.begin(), args: 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(args: 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(pos: unordered_multiset.begin(), args: 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(args: 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(pos: unordered_multimap.begin(), args: 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(args: 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(args: 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(args: 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
1064void test_AliasEmplacyFunctions() {
1065 typedef std::list<Foo> L;
1066 using DQ = std::deque<Foo>;
1067 L l;
1068 l.emplace_back(args: 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(args: 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(args: 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(args: 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(args: 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(args: 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
1102void 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
1140struct Bar {
1141public:
1142 Bar(){};
1143 void testWithPrivateAndProtectedCtor() {
1144 std::vector<Bar> vec;
1145
1146 vec.emplace_back(args: Bar(13));
1147 vec.emplace_back(args: Bar(13, 13));
1148 }
1149
1150protected:
1151 Bar(int){};
1152
1153private:
1154 Bar(int, int){};
1155};
1156
1157void testPossibleFalsePositives() {
1158 struct Y {
1159 Y(std::pair<int, int> &&) {}
1160 };
1161 std::vector<Y> y;
1162 y.emplace_back(args: std::make_pair(2, 3));
1163
1164 std::vector<std::pair<int, int>> v;
1165 v.emplace_back(args: std::make_pair<char, char>(0, 3));
1166
1167 struct D {
1168 D(...) {}
1169 operator char() const { return 0; }
1170 };
1171 v.emplace_back(args: std::make_pair<D, int>(Something(), 2));
1172}
1173
1174struct InnerType {
1175 InnerType();
1176 InnerType(char const*);
1177};
1178
1179struct NonTrivialNoCtor {
1180 InnerType it;
1181};
1182
1183struct NonTrivialWithVector {
1184 std::vector<int> it;
1185};
1186
1187struct NonTrivialWithIntAndVector {
1188 int x;
1189 std::vector<int> it;
1190};
1191
1192struct NonTrivialWithCtor {
1193 NonTrivialWithCtor();
1194 NonTrivialWithCtor(std::vector<int> const&);
1195};
1196
1197void 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{.it: InnerType{}});
1210 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1211 // CHECK-FIXES: v1.emplace_back();
1212 v1.push_back({.it: InnerType{}});
1213 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1214 // CHECK-FIXES: v1.emplace_back();
1215 v1.push_back(NonTrivialNoCtor{.it: InnerType()});
1216 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1217 // CHECK-FIXES: v1.emplace_back();
1218 v1.push_back({.it: InnerType()});
1219 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1220 // CHECK-FIXES: v1.emplace_back();
1221 v1.push_back({.it: {}});
1222 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1223 // CHECK-FIXES: v1.emplace_back();
1224
1225 v1.emplace_back(args: 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(args: 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(args: NonTrivialNoCtor{.it: 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(args: NonTrivialNoCtor{.it: {}});
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{.it: ""});
1241 v1.push_back({.it: ""});
1242 v1.push_back(NonTrivialNoCtor{.it: InnerType{""}});
1243 v1.push_back({.it: InnerType{""}});
1244 v1.emplace_back(args: NonTrivialNoCtor{.it: ""});
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{.it: std::vector<int>{}});
1258 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1259 // CHECK-FIXES: v2.emplace_back();
1260 v2.push_back({.it: std::vector<int>{}});
1261 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1262 // CHECK-FIXES: v2.emplace_back();
1263 v2.push_back(NonTrivialWithVector{.it: std::vector<int>()});
1264 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1265 // CHECK-FIXES: v2.emplace_back();
1266 v2.push_back({.it: std::vector<int>()});
1267 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1268 // CHECK-FIXES: v2.emplace_back();
1269 v2.push_back({.it: {}});
1270 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
1271 // CHECK-FIXES: v2.emplace_back();
1272
1273 v2.emplace_back(args: 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(args: 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(args: NonTrivialWithVector{.it: 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(args: NonTrivialWithVector{.it: {}});
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{.it: {0}});
1290 v2.push_back({.it: {0}});
1291 v2.push_back(NonTrivialWithVector{.it: std::vector<int>{0}});
1292 v2.push_back({.it: std::vector<int>{0}});
1293 v2.emplace_back(args: NonTrivialWithVector{.it: 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(args: 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(args: 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(args: 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(args: 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{.x: 1, .it: {}});
1347 v4.push_back(NonTrivialWithIntAndVector{});
1348 v4.push_back({});
1349}
1350
1351void 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(args: 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(args: 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(args: 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(args: 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(args: 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(args: 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(args: 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(args: 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(args: 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(args: 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(args: 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(args: Something{});
1434 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: unnecessary temporary object created while calling emplace
1435 // CHECK-FIXES: sp->emplace();
1436}
1437

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

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