xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/performance/noexcept-swap.cpp (revision 356c2c2399e1041439af817e3e179aa35361502e)
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