1 // RUN: %check_clang_tidy %s modernize-use-emplace %t -- \
2 // RUN:   -config="{CheckOptions: \
3 // RUN:             [{key: modernize-use-emplace.IgnoreImplicitConstructors, \
4 // RUN:               value: true}] \
5 // RUN:             }"
6 
7 namespace std {
8 template <typename>
9 class initializer_list
10 {
11 public:
initializer_list()12   initializer_list() noexcept {}
13 };
14 
15 template <typename T>
16 class vector {
17 public:
18   vector() = default;
vector(initializer_list<T>)19   vector(initializer_list<T>) {}
20 
push_back(const T &)21   void push_back(const T &) {}
push_back(T &&)22   void push_back(T &&) {}
23 
24   template <typename... Args>
emplace_back(Args &&...args)25   void emplace_back(Args &&... args){};
26   ~vector();
27 };
28 
29 } // namespace std
30 
testInts()31 void testInts() {
32   std::vector<int> v;
33   v.push_back(42);
34   v.push_back(int(42));
35   v.push_back(int{42});
36   v.push_back(42.0);
37   int z;
38   v.push_back(z);
39 }
40 
41 struct Something {
SomethingSomething42   Something(int a, int b = 41) {}
SomethingSomething43   Something() {}
44   void push_back(Something);
getIntSomething45   int getInt() { return 42; }
46 };
47 
48 struct Convertable {
operator SomethingConvertable49   operator Something() { return Something{}; }
50 };
51 
52 struct Zoz {
ZozZoz53   Zoz(Something, int = 42) {}
54 };
55 
getZoz(Something s)56 Zoz getZoz(Something s) { return Zoz(s); }
57 
test_Something()58 void test_Something() {
59   std::vector<Something> v;
60 
61   v.push_back(Something(1, 2));
62   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back instead of push_back [modernize-use-emplace]
63   // CHECK-FIXES: v.emplace_back(1, 2);
64 
65   v.push_back(Something{1, 2});
66   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
67   // CHECK-FIXES: v.emplace_back(1, 2);
68 
69   v.push_back(Something());
70   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
71   // CHECK-FIXES: v.emplace_back();
72 
73   v.push_back(Something{});
74   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
75   // CHECK-FIXES: v.emplace_back();
76 
77   Something Different;
78   v.push_back(Something(Different.getInt(), 42));
79   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
80   // CHECK-FIXES: v.emplace_back(Different.getInt(), 42);
81 
82   v.push_back(Different.getInt());
83   v.push_back(42);
84 
85   Something temporary(42, 42);
86   temporary.push_back(temporary);
87   v.push_back(temporary);
88 
89   v.push_back(Convertable());
90   v.push_back(Convertable{});
91   Convertable s;
92   v.push_back(s);
93 }
94 
95 template <typename ElemType>
dependOnElem()96 void dependOnElem() {
97   std::vector<ElemType> v;
98   v.push_back(ElemType(42));
99 }
100 
101 template <typename ContainerType>
dependOnContainer()102 void dependOnContainer() {
103   ContainerType v;
104   v.push_back(Something(42));
105 }
106 
callDependent()107 void callDependent() {
108   dependOnElem<Something>();
109   dependOnContainer<std::vector<Something>>();
110 }
111 
test2()112 void test2() {
113   std::vector<Zoz> v;
114   v.push_back(Zoz(Something(21, 37)));
115   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
116   // CHECK-FIXES: v.emplace_back(Something(21, 37));
117 
118   v.push_back(Zoz(Something(21, 37), 42));
119   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
120   // CHECK-FIXES: v.emplace_back(Something(21, 37), 42);
121 
122   v.push_back(getZoz(Something(1, 2)));
123 }
124