xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/performance/noexcept-destructor.cpp (revision 474a2b9367ad36213ad8575dc349350fdd8fc8f3)
1 // RUN: %check_clang_tidy %s performance-noexcept-destructor %t -- -- -fexceptions
2 
3 struct Empty
4 {};
5 
6 struct IntWrapper {
7   int value;
8 };
9 
10 template <typename T>
11 struct FalseT {
12   static constexpr bool value = false;
13 };
14 
15 template <typename T>
16 struct TrueT {
17   static constexpr bool value = true;
18 };
19 
20 struct ThrowOnAnything {
21   ThrowOnAnything() noexcept(false);
22   ThrowOnAnything(ThrowOnAnything&&) noexcept(false);
23   ThrowOnAnything& operator=(ThrowOnAnything &&) noexcept(false);
24   ~ThrowOnAnything() noexcept(false);
25 };
26 
27 struct B {
28   static constexpr bool kFalse = false;
29   ~B() noexcept(kFalse);
30   // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: noexcept specifier on the destructor evaluates to 'false' [performance-noexcept-destructor]
31 };
32 
33 struct D {
34   static constexpr bool kFalse = false;
35   ~D() noexcept(kFalse) = default;
36   // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: noexcept specifier on the destructor evaluates to 'false' [performance-noexcept-destructor]
37 };
38 
39 template <typename>
40 struct E {
41   static constexpr bool kFalse = false;
42   ~E() noexcept(kFalse);
43   // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: noexcept specifier on the destructor evaluates to 'false'
44 };
45 
46 template <typename>
47 struct F {
48   static constexpr bool kFalse = false;
49   ~F() noexcept(kFalse) = default;
50   // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: noexcept specifier on the destructor evaluates to 'false' [performance-noexcept-destructor]
51 };
52 
53 struct G {
54   ~G() = default;
55   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: destructors should be marked noexcept [performance-noexcept-destructor]
56   // CHECK-FIXES: ~G() noexcept  = default;
57 
58   ThrowOnAnything field;
59 };
60 
throwing_function()61 void throwing_function() noexcept(false) {}
62 
63 struct H {
64   ~H() noexcept(noexcept(throwing_function()));
65   // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: noexcept specifier on the destructor evaluates to 'false' [performance-noexcept-destructor]
66 };
67 
68 template <typename>
69 struct I {
70   ~I() noexcept(noexcept(throwing_function()));
71   // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: noexcept specifier on the destructor evaluates to 'false' [performance-noexcept-destructor]
72 };
73 
74 template <typename T> struct TemplatedType {
fTemplatedType75   static void f() {}
76 };
77 
78 template <> struct TemplatedType<int> {
fTemplatedType79   static void f() noexcept {}
80 };
81 
82 struct J {
83   ~J() noexcept(noexcept(TemplatedType<double>::f()));
84   // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: noexcept specifier on the destructor evaluates to 'false' [performance-noexcept-destructor]
85 };
86 
87 struct K : public ThrowOnAnything {
88   ~K() = default;
89   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: destructors should be marked noexcept [performance-noexcept-destructor]
90   // CHECK-FIXES: ~K() noexcept  = default;
91 };
92 
93 struct InheritFromThrowOnAnything : public ThrowOnAnything
94 {};
95 
96 struct L {
97   ~L() = default;
98   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: destructors should be marked noexcept [performance-noexcept-destructor]
99   // CHECK-FIXES: ~L() noexcept  = default;
100 
101   InheritFromThrowOnAnything IFF;
102 };
103 
104 struct M : public InheritFromThrowOnAnything {
105   ~M() = default;
106   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: destructors should be marked noexcept [performance-noexcept-destructor]
107   // CHECK-FIXES: ~M() noexcept  = default;
108 };
109 
110 struct N : public IntWrapper, ThrowOnAnything {
111   ~N() = default;
112   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: destructors should be marked noexcept [performance-noexcept-destructor]
113   // CHECK-FIXES: ~N() noexcept  = default;
114 };
115 
116 struct O : virtual IntWrapper, ThrowOnAnything {
117   ~O() = default;
118   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: destructors should be marked noexcept [performance-noexcept-destructor]
119   // CHECK-FIXES: ~O() noexcept  = default;
120 };
121 
122 class OK {};
123 
124 struct OK1 {
125   ~OK1() noexcept;
126 };
127 
128 struct OK2 {
129   static constexpr bool kTrue = true;
130 
~OK2OK2131   ~OK2() noexcept(true) {}
132 };
133 
134 struct OK4 {
~OK4OK4135   ~OK4() noexcept(false) {}
136 };
137 
138 struct OK3 {
139   ~OK3() = default;
140 };
141 
142 struct OK5 {
143   ~OK5() noexcept(true) = default;
144 };
145 
146 struct OK6 {
147   ~OK6() = default;
148 };
149 
150 template <typename>
151 struct OK7 {
152   ~OK7() = default;
153 };
154 
155 template <typename>
156 struct OK8 {
157   ~OK8() noexcept = default;
158 };
159 
160 template <typename>
161 struct OK9 {
162   ~OK9() noexcept(true) = default;
163 };
164 
165 template <typename>
166 struct OK10 {
167   ~OK10() noexcept(false) = default;
168 };
169 
170 template <typename>
171 struct OK11 {
172   ~OK11() = delete;
173 };
174 
noexcept_function()175 void noexcept_function() noexcept {}
176 
177 struct OK12 {
178   ~OK12() noexcept(noexcept(noexcept_function()));
179 };
180 
181 struct OK13 {
182   ~OK13() noexcept(noexcept(noexcept_function())) = default;
183 };
184 
185 template <typename>
186 struct OK14 {
187   ~OK14() noexcept(noexcept(TemplatedType<int>::f()));
188 };
189 
190 struct OK15 {
191   ~OK15() = default;
192 
193   int member;
194 };
195 
196 template <typename>
197 struct OK16 {
198   ~OK16() = default;
199 
200   int member;
201 };
202 
203 struct OK17 {
204   ~OK17() = default;
205 
206   OK empty_field;
207 };
208 
209 template <typename>
210 struct OK18 {
211   ~OK18() = default;
212 
213   OK empty_field;
214 };
215 
216 struct OK19 : public OK {
217   ~OK19() = default;
218 };
219 
220 struct OK20 : virtual OK {
221   ~OK20() = default;
222 };
223 
224 template <typename T>
225 struct OK21 : public T {
226   ~OK21() = default;
227 };
228 
229 template <typename T>
230 struct OK22 : virtual T {
231   ~OK22() = default;
232 };
233 
234 template <typename T>
235 struct OK23 {
236   ~OK23() = default;
237 
238   T member;
239 };
240 
testTemplates()241 void testTemplates() {
242   OK21<Empty> value(OK21<Empty>{});
243   value = OK21<Empty>{};
244 
245   OK22<Empty> value2{OK22<Empty>{}};
246   value2 = OK22<Empty>{};
247 
248   OK23<Empty> value3{OK23<Empty>{}};
249   value3 =OK23<Empty>{};
250 }
251 
252 struct OK24 : public Empty, OK1 {
253   ~OK24() = default;
254 };
255 
256 struct OK25 : virtual Empty, OK1 {
257   ~OK25() = default;
258 };
259 
260 struct OK26 : public Empty, IntWrapper {
261   ~OK26() = default;
262 };
263 
264 template <typename T>
265 struct OK27 : public T {
266   ~OK27() = default;
267 };
268 
269 template <typename T>
270 struct OK28 : virtual T {
271   ~OK28() = default;
272 };
273 
274 template <typename T>
275 struct OK29 {
276   ~OK29() = default;
277 
278   T member;
279 };
280 
281 struct OK30 {
282   ~OK30() noexcept(TrueT<OK30>::value) = default;
283 };
284 
285 template <typename>
286 struct OK31 {
287   ~OK31() noexcept(TrueT<int>::value) = default;
288 };
289 
290 struct OK32 {
291   ~OK32();
292 };
293 
294 template <typename>
295 struct OK33 {
296   ~OK33();
297 };
298 
299 struct OK34 {
~OK34OK34300   ~OK34() {}
301 };
302 
303 template <typename>
304 struct OK35 {
~OK35OK35305   ~OK35() {}
306 };
307