1 // RUN: %check_clang_tidy %s performance-noexcept-swap %t -- -- -fexceptions 2 3 namespace std 4 { 5 template <typename T> 6 struct is_nothrow_move_constructible 7 { 8 static constexpr bool value = __is_nothrow_constructible(T, __add_rvalue_reference(T)); 9 }; 10 } // namespace std 11 12 void throwing_function() noexcept(false); 13 void noexcept_function() noexcept; 14 15 template <typename> 16 struct TemplateNoexceptWithInt { fTemplateNoexceptWithInt17 static void f() {} 18 }; 19 20 template <> 21 struct TemplateNoexceptWithInt<int> { fTemplateNoexceptWithInt22 static void f() noexcept {} 23 }; 24 25 class A { 26 void swap(A &); 27 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: swap functions should be marked noexcept [performance-noexcept-swap] 28 // CHECK-FIXES: void swap(A &) noexcept ; 29 }; 30 31 void swap(A &, A &); 32 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: swap functions should be marked noexcept [performance-noexcept-swap] 33 // CHECK-FIXES: void swap(A &, A &) noexcept ; 34 35 void iter_swap(A &, A &); 36 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: swap functions should be marked noexcept [performance-noexcept-swap] 37 // CHECK-FIXES: void iter_swap(A &, A &) noexcept ; 38 39 struct B { 40 static constexpr bool kFalse = false; 41 void swap(B &) noexcept(kFalse); 42 // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: noexcept specifier on swap function evaluates to 'false' [performance-noexcept-swap] 43 }; 44 45 void swap(B &, B &) noexcept(B::kFalse); 46 // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: noexcept specifier on swap function evaluates to 'false' [performance-noexcept-swap] 47 48 template <typename> 49 struct C { 50 void swap(C&); 51 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: swap functions should be marked noexcept [performance-noexcept-swap] 52 // CHECK-FIXES: void swap(C&) noexcept ; 53 }; 54 55 template <typename T> 56 void swap(C<T>&, C<T>&); 57 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: swap functions should be marked noexcept [performance-noexcept-swap] 58 // CHECK-FIXES: void swap(C<T>&, C<T>&) noexcept ; 59 void swap(C<int>&, C<int>&); 60 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: swap functions should be marked noexcept [performance-noexcept-swap] 61 // CHECK-FIXES: void swap(C<int>&, C<int>&) noexcept ; 62 63 template <typename> 64 struct D { 65 static constexpr bool kFalse = false; 66 void swap(D &) noexcept(kFalse); 67 // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: noexcept specifier on swap function evaluates to 'false' [performance-noexcept-swap] 68 }; 69 70 void swap(D<int> &, D<int> &) noexcept(D<int>::kFalse); 71 // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: noexcept specifier on swap function evaluates to 'false' [performance-noexcept-swap] 72 73 struct E { 74 void swap(E &) noexcept(noexcept(throwing_function())); 75 // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: noexcept specifier on swap function evaluates to 'false' [performance-noexcept-swap] 76 }; 77 78 void swap(E &, E &) noexcept(noexcept(throwing_function())); 79 // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: noexcept specifier on swap function evaluates to 'false' [performance-noexcept-swap] 80 81 template <typename> 82 struct F { 83 void swap(F &) noexcept(noexcept(throwing_function())); 84 // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: noexcept specifier on swap function evaluates to 'false' [performance-noexcept-swap] 85 }; 86 87 template <typename T> 88 void swap(F<T> &, F<T> &) noexcept(noexcept(throwing_function())); 89 // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: noexcept specifier on swap function evaluates to 'false' [performance-noexcept-swap] 90 void swap(F<int> &, F<int> &) noexcept(noexcept(throwing_function())); 91 // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: noexcept specifier on swap function evaluates to 'false' [performance-noexcept-swap] 92 93 struct G { 94 void swap(G &) noexcept(noexcept(TemplateNoexceptWithInt<double>::f())); 95 // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: noexcept specifier on swap function evaluates to 'false' [performance-noexcept-swap] 96 }; 97 98 void swap(G &, G &) noexcept(noexcept(TemplateNoexceptWithInt<double>::f())); 99 // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: noexcept specifier on swap function evaluates to 'false' [performance-noexcept-swap] 100 101 class OK {}; 102 103 struct OK1 { 104 void swap(OK1 &) noexcept; 105 }; 106 107 void swap(OK1 &, OK1 &) noexcept; 108 109 struct OK2 { 110 static constexpr bool kTrue = true; swapOK2111 void swap(OK2 &) noexcept(kTrue) {} 112 }; 113 114 void swap(OK2 &, OK2 &) noexcept(OK2::kTrue); 115 116 struct OK3 { 117 void swap(OK3 &) = delete; 118 }; 119 120 void swap(OK3 &, OK3 &) = delete; 121 122 struct OK4 { 123 void swap(OK4 &) noexcept(false); 124 }; 125 126 void swap(OK4 &, OK4 &) noexcept(false); 127 128 struct OK5 { 129 void swap(OK5 &) noexcept(true); 130 }; 131 132 void swap(OK5 &, OK5 &)noexcept(true); 133 134 struct OK12 { 135 void swap(OK12 &) noexcept(noexcept(noexcept_function())); 136 }; 137 138 void swap(OK12 &, OK12 &) noexcept(noexcept(noexcept_function())); 139 140 struct OK13 { 141 void swap(OK13 &) noexcept(noexcept(TemplateNoexceptWithInt<int>::f())); 142 }; 143 144 void swap(OK13 &, OK13 &) noexcept(noexcept(TemplateNoexceptWithInt<int>::f())); 145 146 template <typename> 147 class OK14 {}; 148 149 template <typename> 150 struct OK15 { 151 void swap(OK15 &) noexcept; 152 }; 153 154 template <typename T> 155 void swap(OK15<T> &, OK15<T> &) noexcept; 156 void swap(OK15<int> &, OK15<int> &) noexcept; 157 158 template <typename> 159 struct OK16 { 160 static constexpr bool kTrue = true; 161 void swap(OK16 &) noexcept(kTrue); 162 }; 163 164 template <typename T> 165 void swap(OK16<T> &, OK16<T> &) noexcept(OK16<T>::kTrue); 166 template <typename T> 167 void swap(OK16<int> &, OK16<int> &) noexcept(OK16<int>::kTrue); 168 169 template <typename> 170 struct OK17 { 171 void swap(OK17 &) = delete; 172 }; 173 174 template <typename T> 175 void swap(OK17<T> &, OK17<T> &) = delete; 176 void swap(OK17<int> &, OK17<int> &) = delete; 177 178 template <typename> 179 struct OK18 { 180 void swap(OK18 &) noexcept(false); 181 }; 182 183 template <typename T> 184 void swap(OK18<T> &, OK18<T> &) noexcept(false); 185 void swap(OK18<int> &, OK18<int> &) noexcept(false); 186 187 template <typename> 188 struct OK19 { 189 void swap(OK19 &) noexcept(true); 190 }; 191 192 template <typename T> 193 void swap(OK19<T> &, OK19<T> &)noexcept(true); 194 void swap(OK19<int> &, OK19<int> &)noexcept(true); 195 196 template <typename> 197 struct OK20 { 198 void swap(OK20 &) noexcept(noexcept(noexcept_function())); 199 }; 200 201 template <typename T> 202 void swap(OK20<T> &, OK20<T> &) noexcept(noexcept(noexcept_function())); 203 void swap(OK20<int> &, OK20<int> &) noexcept(noexcept(noexcept_function())); 204 205 template <typename> 206 struct OK21 { 207 void swap(OK21 &) noexcept(noexcept(TemplateNoexceptWithInt<int>::f())); 208 }; 209 210 template <typename T> 211 void swap(OK21<T> &, OK21<T> &) noexcept(noexcept(TemplateNoexceptWithInt<int>::f())); 212 void swap(OK21<int> &, OK21<int> &) noexcept(noexcept(TemplateNoexceptWithInt<int>::f())); 213 214 namespace PR64303 { 215 void swap(); 216 void swap(int&, bool&); 217 void swap(int&, int&, int&); 218 void swap(int&); 219 220 struct Test { 221 void swap(); 222 void swap(Test&, Test&); 223 void swap(int&); 224 static void swap(int&, int&); 225 226 friend void swap(Test&, Test&); 227 // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: swap functions should be marked noexcept [performance-noexcept-swap] 228 }; 229 } // namespace PR64303 230 231 namespace gh68101 232 { 233 template <typename T> 234 class Container { 235 public: 236 void swap(Container&) noexcept(std::is_nothrow_move_constructible<T>::value); 237 }; 238 } // namespace gh68101 239