| 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 { |
| 17 | static void f() {} |
| 18 | }; |
| 19 | |
| 20 | template <> |
| 21 | struct TemplateNoexceptWithInt<int> { |
| 22 | 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; |
| 111 | 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 | |