xref: /llvm-project/clang/test/CodeGenCXX/sanitize-dtor-zero-size-field.cpp (revision 1b9a6e58a8b831193c9e5e733f881aabe0d2d06b)
1 // RUN: %clang_cc1 -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-passes -std=c++20 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s --implicit-check-not "call void @__sanitizer_dtor_callback_fields"
2 // RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-passes -std=c++20 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s --implicit-check-not "call void @__sanitizer_dtor_callback_fields"
3 
4 struct Empty {};
5 
6 struct EmptyNonTrivial {
7   ~EmptyNonTrivial();
8 };
9 
10 struct Trivial {
11   int a;
12   char c;
13 };
14 static_assert(sizeof(Trivial) == 8);
15 
16 struct NonTrivial {
17   int a;
18   char c;
19   ~NonTrivial();
20 };
21 static_assert(sizeof(NonTrivial) == 8);
22 
23 namespace T0 {
24 struct Struct {
25   Trivial f1;
26   int f2;
27   char f3;
~StructT0::Struct28   ~Struct(){};
29 } var;
30 static_assert(sizeof(Struct) == 16);
31 } // namespace T0
32 // CHECK-LABEL: define {{.*}} @_ZN2T06StructD2Ev(
33 // CHECK:         call void @__sanitizer_dtor_callback_fields(ptr {{.*}}, i64 13)
34 // CHECK-NEXT:    ret void
35 
36 namespace empty {
37 namespace T1 {
38 struct Struct {
39   NonTrivial nt;
40   Trivial f1;
41   int f2;
42   char f3;
43 } var;
44 static_assert(sizeof(Struct) == 24);
45 } // namespace T1
46 // CHECK-LABEL: define {{.*}} @_ZN5empty2T16StructD2Ev(
47 // CHECK:         [[GEP:%.+]] = getelementptr i8, {{.*}}, i64 8{{$}}
48 // CHECK:         call void @__sanitizer_dtor_callback_fields(ptr [[GEP]], i64 13)
49 // CHECK:         call void @_ZN10NonTrivialD1Ev(
50 // CHECK-NEXT:    ret void
51 
52 namespace T2 {
53 struct Struct {
54   Trivial f1;
55   NonTrivial nt;
56   int f2;
57   char f3;
58 } var;
59 static_assert(sizeof(Struct) == 24);
60 } // namespace T2
61 // CHECK-LABEL: define {{.*}} @_ZN5empty2T26StructD2Ev(
62 // CHECK:         [[GEP1:%.+]] = getelementptr i8, {{.*}}, i64 16{{$}}
63 // CHECK:         call void @__sanitizer_dtor_callback_fields(ptr [[GEP1]], i64 5)
64 // CHECK:         call void @_ZN10NonTrivialD1Ev(
65 // CHECK:         [[GEP2:%.+]] = getelementptr i8, {{.*}}, i64 0{{$}}
66 // CHECK:         call void @__sanitizer_dtor_callback_fields(ptr [[GEP2]], i64 8)
67 // CHECK-NEXT:    ret void
68 
69 namespace T3 {
70 struct Struct {
71   Trivial f1;
72   int f2;
73   NonTrivial nt;
74   char f3;
75 } var;
76 static_assert(sizeof(Struct) == 24);
77 } // namespace T3
78 // CHECK-LABEL: define {{.*}} @_ZN5empty2T36StructD2Ev(
79 // CHECK:         [[GEP1:%.+]] = getelementptr i8, {{.*}}, i64 20{{$}}
80 // CHECK:         call void @__sanitizer_dtor_callback_fields(ptr [[GEP1]], i64 1)
81 // CHECK:         call void @_ZN10NonTrivialD1Ev(
82 // CHECK:         [[GEP2:%.+]] = getelementptr i8, {{.*}}, i64 0{{$}}
83 // CHECK:         call void @__sanitizer_dtor_callback_fields(ptr [[GEP2]], i64 12)
84 // CHECK-NEXT:    ret void
85 
86 namespace T4 {
87 struct Struct {
88   Trivial f1;
89   int f2;
90   char f3;
91   NonTrivial nt;
92 } var;
93 static_assert(sizeof(Struct) == 24);
94 } // namespace T4
95 // CHECK-LABEL: define {{.*}} @_ZN5empty2T46StructD2Ev(
96 // CHECK:         call void @__sanitizer_dtor_callback_fields(ptr {{.*}}, i64 16)
97 // CHECK-NEXT:    ret void
98 
99 namespace T5 {
100 struct Struct {
101   [[no_unique_address]] Empty e;
102   NonTrivial nt;
103   Trivial f1;
104   int f2;
105   char f3;
106 } var;
107 static_assert(sizeof(Struct) == 24);
108 } // namespace T5
109 // CHECK-LABEL: define {{.*}} @_ZN5empty2T56StructD2Ev(
110 // CHECK:         call void @__sanitizer_dtor_callback_fields(ptr {{.*}}, i64 13)
111 // CHECK:         call void @_ZN10NonTrivialD1Ev(
112 // CHECK-NEXT:    ret void
113 
114 namespace T6 {
115 struct Struct {
116   NonTrivial nt;
117   [[no_unique_address]] Empty e;
118   Trivial f1;
119   int f2;
120   char f3;
121 } var;
122 static_assert(sizeof(Struct) == 24);
123 } // namespace T6
124 // CHECK-LABEL: define {{.*}} @_ZN5empty2T66StructD2Ev(
125 // CHECK:         call void @__sanitizer_dtor_callback_fields(ptr {{.*}}, i64 13)
126 // CHECK:         call void @_ZN10NonTrivialD1Ev(
127 // CHECK-NEXT:    ret void
128 
129 namespace T7 {
130 struct Struct {
131   Trivial f1;
132   NonTrivial nt;
133   [[no_unique_address]] Empty e;
134   int f2;
135   char f3;
136 } var;
137 static_assert(sizeof(Struct) == 24);
138 } // namespace T7
139 // CHECK-LABEL: define {{.*}} @_ZN5empty2T76StructD2Ev(
140 // CHECK:         call void @__sanitizer_dtor_callback_fields(ptr {{.*}}, i64 5)
141 // CHECK:         call void @_ZN10NonTrivialD1Ev(
142 // CHECK:         call void @__sanitizer_dtor_callback_fields(ptr {{.*}}, i64 8)
143 // CHECK-NEXT:    ret void
144 
145 namespace T8 {
146 struct Struct {
147   Trivial f1;
148   [[no_unique_address]] Empty e;
149   NonTrivial nt;
150   int f2;
151   char f3;
152 } var;
153 static_assert(sizeof(Struct) == 24);
154 } // namespace T8
155 // CHECK-LABEL: define {{.*}} @_ZN5empty2T86StructD2Ev(
156 // CHECK:         call void @__sanitizer_dtor_callback_fields(ptr {{.*}}, i64 5)
157 // CHECK:         call void @__sanitizer_dtor_callback_fields(ptr {{.*}}, i64 8)
158 // CHECK-NEXT:    ret void
159 
160 namespace T9 {
161 struct Struct {
162   Trivial f1;
163   int f2;
164   NonTrivial nt;
165   [[no_unique_address]] Empty e;
166   char f3;
167 } var;
168 static_assert(sizeof(Struct) == 24);
169 } // namespace T9
170 // CHECK-LABEL: define {{.*}} @_ZN5empty2T96StructD2Ev(
171 // CHECK:         call void @__sanitizer_dtor_callback_fields(ptr {{.*}}, i64 1)
172 // CHECK:         call void @__sanitizer_dtor_callback_fields(ptr {{.*}}, i64 12)
173 // CHECK-NEXT:    ret void
174 
175 namespace T10 {
176 struct Struct {
177   Trivial f1;
178   int f2;
179   [[no_unique_address]] Empty e;
180   NonTrivial nt;
181   char f3;
182 } var;
183 static_assert(sizeof(Struct) == 24);
184 } // namespace T10
185 // CHECK-LABEL: define {{.*}} @_ZN5empty3T106StructD2Ev(
186 // CHECK:         call void @__sanitizer_dtor_callback_fields(ptr {{.*}}, i64 1)
187 // CHECK:         call void @__sanitizer_dtor_callback_fields(ptr {{.*}}, i64 12)
188 // CHECK-NEXT:    ret void
189 
190 namespace T11 {
191 struct Struct {
192   Trivial f1;
193   int f2;
194   char f3;
195   NonTrivial nt;
196   [[no_unique_address]] Empty e;
197 } var;
198 static_assert(sizeof(Struct) == 24);
199 } // namespace T11
200 // CHECK-LABEL: define {{.*}} @_ZN5empty3T116StructD2Ev(
201 // CHECK:         call void @__sanitizer_dtor_callback_fields(ptr {{.*}}, i64 16)
202 // CHECK-NEXT:    ret void
203 
204 namespace T12 {
205 struct Struct {
206   Trivial f1;
207   int f2;
208   char f3;
209   [[no_unique_address]] Empty e;
210   NonTrivial nt;
211 } var;
212 static_assert(sizeof(Struct) == 24);
213 } // namespace T12
214 } // namespace empty
215 // CHECK-LABEL: define {{.*}} @_ZN5empty3T126StructD2Ev(
216 // CHECK:         call void @_ZN10NonTrivialD1Ev(
217 // CHECK:         call void @__sanitizer_dtor_callback_fields(ptr {{.*}}, i64 16)
218 // CHECK-NEXT:    ret void
219 
220 namespace empty_non_trivial {
221 namespace T1 {
222 struct Struct {
223   NonTrivial nt;
224   Trivial f1;
225   int f2;
226   char f3;
227 } var;
228 static_assert(sizeof(Struct) == 24);
229 } // namespace T1
230 // CHECK-LABEL: define {{.*}} @_ZN17empty_non_trivial2T16StructD2Ev(
231 // CHECK:         call void @__sanitizer_dtor_callback_fields(ptr {{.*}}, i64 13)
232 // CHECK:         call void @_ZN10NonTrivialD1Ev(
233 // CHECK-NEXT:    ret void
234 
235 namespace T2 {
236 struct Struct {
237   Trivial f1;
238   NonTrivial nt;
239   int f2;
240   char f3;
241 } var;
242 static_assert(sizeof(Struct) == 24);
243 } // namespace T2
244 // CHECK-LABEL: define {{.*}} @_ZN17empty_non_trivial2T26StructD2Ev(
245 // CHECK:         call void @__sanitizer_dtor_callback_fields(ptr {{.*}}, i64 5)
246 // CHECK:         call void @__sanitizer_dtor_callback_fields(ptr {{.*}}, i64 8)
247 // CHECK-NEXT:    ret void
248 
249 namespace T3 {
250 struct Struct {
251   Trivial f1;
252   int f2;
253   NonTrivial nt;
254   char f3;
255 } var;
256 static_assert(sizeof(Struct) == 24);
257 } // namespace T3
258 // CHECK-LABEL: define {{.*}} @_ZN17empty_non_trivial2T36StructD2Ev(
259 // CHECK:         call void @__sanitizer_dtor_callback_fields(ptr {{.*}}, i64 1)
260 // CHECK:         call void @__sanitizer_dtor_callback_fields(ptr {{.*}}, i64 12)
261 // CHECK-NEXT:    ret void
262 
263 namespace T4 {
264 struct Struct {
265   Trivial f1;
266   int f2;
267   char f3;
268   NonTrivial nt;
269 } var;
270 static_assert(sizeof(Struct) == 24);
271 } // namespace T4
272 // CHECK-LABEL: define {{.*}} @_ZN17empty_non_trivial2T46StructD2Ev(
273 // CHECK:         call void @__sanitizer_dtor_callback_fields(ptr {{.*}}, i64 16)
274 // CHECK-NEXT:    ret void
275 
276 namespace T5 {
277 struct Struct {
278   [[no_unique_address]] EmptyNonTrivial e;
279   NonTrivial nt;
280   Trivial f1;
281   int f2;
282   char f3;
283 } var;
284 static_assert(sizeof(Struct) == 24);
285 } // namespace T5
286 // CHECK-LABEL: define {{.*}} @_ZN17empty_non_trivial2T56StructD2Ev(
287 // CHECK:         call void @__sanitizer_dtor_callback_fields(ptr {{.*}}, i64 13)
288 // CHECK:         call void @_ZN10NonTrivialD1Ev(
289 // CHECK:         call void @_ZN15EmptyNonTrivialD1Ev(
290 // CHECK-NEXT:    ret void
291 
292 namespace T6 {
293 struct Struct {
294   NonTrivial nt;
295   [[no_unique_address]] EmptyNonTrivial e;
296   Trivial f1;
297   int f2;
298   char f3;
299 } var;
300 static_assert(sizeof(Struct) == 24);
301 } // namespace T6
302 // CHECK-LABEL: define {{.*}} @_ZN17empty_non_trivial2T66StructD2Ev(
303 // CHECK:         call void @__sanitizer_dtor_callback_fields(ptr {{.*}}, i64 13)
304 // CHECK:         call void @_ZN15EmptyNonTrivialD1Ev(
305 // CHECK:         call void @_ZN10NonTrivialD1Ev(
306 // CHECK-NEXT:    ret void
307 
308 namespace T7 {
309 struct Struct {
310   Trivial f1;
311   NonTrivial nt;
312   [[no_unique_address]] EmptyNonTrivial e;
313   int f2;
314   char f3;
315 } var;
316 static_assert(sizeof(Struct) == 24);
317 } // namespace T7
318 // CHECK-LABEL: define {{.*}} @_ZN17empty_non_trivial2T76StructD2Ev(
319 // CHECK:         call void @__sanitizer_dtor_callback_fields(ptr {{.*}}, i64 5)
320 // CHECK:         call void @_ZN15EmptyNonTrivialD1Ev(
321 // CHECK:         call void @_ZN10NonTrivialD1Ev(
322 // CHECK:         call void @__sanitizer_dtor_callback_fields(ptr {{.*}}, i64 8)
323 // CHECK-NEXT:    ret void
324 
325 namespace T8 {
326 struct Struct {
327   Trivial f1;
328   [[no_unique_address]] EmptyNonTrivial e;
329   NonTrivial nt;
330   int f2;
331   char f3;
332 } var;
333 static_assert(sizeof(Struct) == 24);
334 } // namespace T8
335 // CHECK-LABEL: define {{.*}} @_ZN17empty_non_trivial2T86StructD2Ev(
336 // CHECK:         call void @__sanitizer_dtor_callback_fields(ptr {{.*}}, i64 5)
337 // CHECK:         call void @_ZN10NonTrivialD1Ev(
338 // CHECK:         call void @__sanitizer_dtor_callback_fields(ptr {{.*}}, i64 8)
339 // CHECK:         call void @_ZN15EmptyNonTrivialD1Ev(
340 // CHECK-NEXT:    ret void
341 
342 namespace T9 {
343 struct Struct {
344   Trivial f1;
345   int f2;
346   NonTrivial nt;
347   [[no_unique_address]] EmptyNonTrivial e;
348   char f3;
349 } var;
350 static_assert(sizeof(Struct) == 24);
351 } // namespace T9
352 // CHECK-LABEL: define {{.*}} @_ZN17empty_non_trivial2T96StructD2Ev(
353 // CHECK:         call void @__sanitizer_dtor_callback_fields(ptr {{.*}}, i64 1)
354 // CHECK:         call void @_ZN15EmptyNonTrivialD1Ev(
355 // CHECK:         call void @_ZN10NonTrivialD1Ev(
356 // CHECK:         call void @__sanitizer_dtor_callback_fields(ptr {{.*}}, i64 12)
357 // CHECK-NEXT:    ret void
358 
359 namespace T10 {
360 struct Struct {
361   Trivial f1;
362   int f2;
363   [[no_unique_address]] EmptyNonTrivial e;
364   NonTrivial nt;
365   char f3;
366 } var;
367 static_assert(sizeof(Struct) == 24);
368 } // namespace T10
369 // CHECK-LABEL: define {{.*}} @_ZN17empty_non_trivial3T106StructD2Ev(
370 // CHECK:         call void @__sanitizer_dtor_callback_fields(ptr {{.*}}, i64 1)
371 // CHECK:         call void @_ZN10NonTrivialD1Ev(
372 // CHECK:         call void @__sanitizer_dtor_callback_fields(ptr {{.*}}, i64 12)
373 // CHECK:         call void @_ZN15EmptyNonTrivialD1Ev(
374 // CHECK-NEXT:    ret void
375 
376 namespace T11 {
377 struct Struct {
378   Trivial f1;
379   int f2;
380   char f3;
381   NonTrivial nt;
382   [[no_unique_address]] EmptyNonTrivial e;
383 } var;
384 static_assert(sizeof(Struct) == 24);
385 } // namespace T11
386 // CHECK-LABEL: define {{.*}} @_ZN17empty_non_trivial3T116StructD2Ev(
387 // CHECK:         call void @_ZN15EmptyNonTrivialD1Ev(
388 // CHECK:         call void @_ZN10NonTrivialD1Ev(
389 // CHECK:         call void @__sanitizer_dtor_callback_fields(ptr {{.*}}, i64 16)
390 // CHECK-NEXT:    ret void
391 
392 namespace T12 {
393 struct Struct {
394   Trivial f1;
395   int f2;
396   char f3;
397   [[no_unique_address]] EmptyNonTrivial e;
398   NonTrivial nt;
399 } var;
400 static_assert(sizeof(Struct) == 24);
401 } // namespace T12
402 } // namespace empty_non_trivial
403 // CHECK-LABEL: define {{.*}} @_ZN17empty_non_trivial3T126StructD2Ev(
404 // CHECK:         call void @_ZN10NonTrivialD1Ev(
405 // CHECK:         call void @__sanitizer_dtor_callback_fields(ptr {{.*}}, i64 16)
406 // CHECK:         call void @_ZN15EmptyNonTrivialD1Ev(
407 // CHECK:         ret void
408