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: 12 initializer_list() noexcept {} 13 }; 14 15 template <typename T> 16 class vector { 17 public: 18 vector() = default; 19 vector(initializer_list<T>) {} 20 21 void push_back(const T &) {} 22 void push_back(T &&) {} 23 24 template <typename... Args> 25 void emplace_back(Args &&... args){}; 26 ~vector(); 27 }; 28 29 } // namespace std 30 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 { 42 Something(int a, int b = 41) {} 43 Something() {} 44 void push_back(Something); 45 int getInt() { return 42; } 46 }; 47 48 struct Convertable { 49 operator Something() { return Something{}; } 50 }; 51 52 struct Zoz { 53 Zoz(Something, int = 42) {} 54 }; 55 56 Zoz getZoz(Something s) { return Zoz(s); } 57 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> 96 void dependOnElem() { 97 std::vector<ElemType> v; 98 v.push_back(ElemType(42)); 99 } 100 101 template <typename ContainerType> 102 void dependOnContainer() { 103 ContainerType v; 104 v.push_back(Something(42)); 105 } 106 107 void callDependent() { 108 dependOnElem<Something>(); 109 dependOnContainer<std::vector<Something>>(); 110 } 111 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