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