189a1d03eSRichard // RUN: %check_clang_tidy %s modernize-use-emplace %t -- \
289a1d03eSRichard // RUN:   -config="{CheckOptions: \
3e8a3ddafSNathan James // RUN:             {modernize-use-emplace.IgnoreImplicitConstructors: \
4e8a3ddafSNathan James // RUN:                true}}"
589a1d03eSRichard 
689a1d03eSRichard namespace std {
7*482c41e9SMital Ashok template <typename E>
889a1d03eSRichard class initializer_list
989a1d03eSRichard {
1089a1d03eSRichard public:
11*482c41e9SMital Ashok   const E *a, *b;
initializer_list()1289a1d03eSRichard   initializer_list() noexcept {}
1389a1d03eSRichard };
1489a1d03eSRichard 
1589a1d03eSRichard template <typename T>
1689a1d03eSRichard class vector {
1789a1d03eSRichard public:
1889a1d03eSRichard   vector() = default;
vector(initializer_list<T>)1989a1d03eSRichard   vector(initializer_list<T>) {}
2089a1d03eSRichard 
push_back(const T &)2189a1d03eSRichard   void push_back(const T &) {}
push_back(T &&)2289a1d03eSRichard   void push_back(T &&) {}
2389a1d03eSRichard 
2489a1d03eSRichard   template <typename... Args>
emplace_back(Args &&...args)2589a1d03eSRichard   void emplace_back(Args &&... args){};
2689a1d03eSRichard   ~vector();
2789a1d03eSRichard };
2889a1d03eSRichard 
2989a1d03eSRichard } // namespace std
3089a1d03eSRichard 
testInts()3189a1d03eSRichard void testInts() {
3289a1d03eSRichard   std::vector<int> v;
3389a1d03eSRichard   v.push_back(42);
3489a1d03eSRichard   v.push_back(int(42));
3589a1d03eSRichard   v.push_back(int{42});
3689a1d03eSRichard   v.push_back(42.0);
3789a1d03eSRichard   int z;
3889a1d03eSRichard   v.push_back(z);
3989a1d03eSRichard }
4089a1d03eSRichard 
4189a1d03eSRichard struct Something {
SomethingSomething4289a1d03eSRichard   Something(int a, int b = 41) {}
SomethingSomething4389a1d03eSRichard   Something() {}
4489a1d03eSRichard   void push_back(Something);
getIntSomething4589a1d03eSRichard   int getInt() { return 42; }
4689a1d03eSRichard };
4789a1d03eSRichard 
4889a1d03eSRichard struct Convertable {
operator SomethingConvertable4989a1d03eSRichard   operator Something() { return Something{}; }
5089a1d03eSRichard };
5189a1d03eSRichard 
5289a1d03eSRichard struct Zoz {
ZozZoz5389a1d03eSRichard   Zoz(Something, int = 42) {}
5489a1d03eSRichard };
5589a1d03eSRichard 
getZoz(Something s)5689a1d03eSRichard Zoz getZoz(Something s) { return Zoz(s); }
5789a1d03eSRichard 
test_Something()5889a1d03eSRichard void test_Something() {
5989a1d03eSRichard   std::vector<Something> v;
6089a1d03eSRichard 
6189a1d03eSRichard   v.push_back(Something(1, 2));
6289a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back instead of push_back [modernize-use-emplace]
6389a1d03eSRichard   // CHECK-FIXES: v.emplace_back(1, 2);
6489a1d03eSRichard 
6589a1d03eSRichard   v.push_back(Something{1, 2});
6689a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
6789a1d03eSRichard   // CHECK-FIXES: v.emplace_back(1, 2);
6889a1d03eSRichard 
6989a1d03eSRichard   v.push_back(Something());
7089a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
7189a1d03eSRichard   // CHECK-FIXES: v.emplace_back();
7289a1d03eSRichard 
7389a1d03eSRichard   v.push_back(Something{});
7489a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
7589a1d03eSRichard   // CHECK-FIXES: v.emplace_back();
7689a1d03eSRichard 
7789a1d03eSRichard   Something Different;
7889a1d03eSRichard   v.push_back(Something(Different.getInt(), 42));
7989a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
8089a1d03eSRichard   // CHECK-FIXES: v.emplace_back(Different.getInt(), 42);
8189a1d03eSRichard 
8289a1d03eSRichard   v.push_back(Different.getInt());
8389a1d03eSRichard   v.push_back(42);
8489a1d03eSRichard 
8589a1d03eSRichard   Something temporary(42, 42);
8689a1d03eSRichard   temporary.push_back(temporary);
8789a1d03eSRichard   v.push_back(temporary);
8889a1d03eSRichard 
8989a1d03eSRichard   v.push_back(Convertable());
9089a1d03eSRichard   v.push_back(Convertable{});
9189a1d03eSRichard   Convertable s;
9289a1d03eSRichard   v.push_back(s);
9389a1d03eSRichard }
9489a1d03eSRichard 
9589a1d03eSRichard template <typename ElemType>
dependOnElem()9689a1d03eSRichard void dependOnElem() {
9789a1d03eSRichard   std::vector<ElemType> v;
9889a1d03eSRichard   v.push_back(ElemType(42));
9989a1d03eSRichard }
10089a1d03eSRichard 
10189a1d03eSRichard template <typename ContainerType>
dependOnContainer()10289a1d03eSRichard void dependOnContainer() {
10389a1d03eSRichard   ContainerType v;
10489a1d03eSRichard   v.push_back(Something(42));
10589a1d03eSRichard }
10689a1d03eSRichard 
callDependent()10789a1d03eSRichard void callDependent() {
10889a1d03eSRichard   dependOnElem<Something>();
10989a1d03eSRichard   dependOnContainer<std::vector<Something>>();
11089a1d03eSRichard }
11189a1d03eSRichard 
test2()11289a1d03eSRichard void test2() {
11389a1d03eSRichard   std::vector<Zoz> v;
11489a1d03eSRichard   v.push_back(Zoz(Something(21, 37)));
11589a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
11689a1d03eSRichard   // CHECK-FIXES: v.emplace_back(Something(21, 37));
11789a1d03eSRichard 
11889a1d03eSRichard   v.push_back(Zoz(Something(21, 37), 42));
11989a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
12089a1d03eSRichard   // CHECK-FIXES: v.emplace_back(Something(21, 37), 42);
12189a1d03eSRichard 
12289a1d03eSRichard   v.push_back(getZoz(Something(1, 2)));
12389a1d03eSRichard }
124