xref: /llvm-project/clang/test/SemaCXX/class-layout.cpp (revision 5fa5ffeb6cb5bc9aa414c02513e44b8405f0e7cc)
1 // RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -fsyntax-only -verify -std=c++98 -Wno-inaccessible-base -Wno-invalid-offsetof -Wno-c++11-extensions
2 // RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -Wno-invalid-offsetof
3 // RUN: %clang_cc1 -triple x86_64-apple-darwin    %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -Wno-invalid-offsetof -DCLANG_ABI_COMPAT=15
4 // RUN: %clang_cc1 -triple x86_64-scei-ps4        %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -Wno-invalid-offsetof -DCLANG_ABI_COMPAT=6
5 // RUN: %clang_cc1 -triple x86_64-sie-ps5         %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -Wno-invalid-offsetof -DCLANG_ABI_COMPAT=6
6 // RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -Wno-invalid-offsetof -fclang-abi-compat=6 -DCLANG_ABI_COMPAT=6
7 // RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -Wno-invalid-offsetof -fclang-abi-compat=14 -DCLANG_ABI_COMPAT=14
8 // RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -Wno-invalid-offsetof -fclang-abi-compat=15 -DCLANG_ABI_COMPAT=15
9 // RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -Wno-invalid-offsetof -fclang-abi-compat=16 -DCLANG_ABI_COMPAT=16
10 // RUN: %clang_cc1 -triple powerpc-ibm-aix7.3.0.0 %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -Wno-invalid-offsetof -DCLANG_ABI_COMPAT=15
11 // RUN: %clang_cc1 -triple powerpc-ibm-aix7.3.0.0 %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -Wno-invalid-offsetof -fclang-abi-compat=15 -DCLANG_ABI_COMPAT=15
12 // RUN: %clang_cc1 -triple powerpc64-ibm-aix7.3.0.0 %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -Wno-invalid-offsetof -DCLANG_ABI_COMPAT=15
13 // RUN: %clang_cc1 -triple powerpc64-ibm-aix7.3.0.0 %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -Wno-invalid-offsetof -fclang-abi-compat=15 -DCLANG_ABI_COMPAT=15
14 // RUN: %clang_cc1 -triple s390x-none-zos %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -Wno-invalid-offsetof
15 // RUN: %clang_cc1 -triple s390x-none-zos %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -Wno-invalid-offsetof -fclang-abi-compat=15 -DCLANG_ABI_COMPAT=15
16 
17 // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -triple x86_64-unknown-unknown %s -fsyntax-only -verify -std=c++98 -Wno-inaccessible-base -Wno-c++11-extensions -Wno-invalid-offsetof
18 // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -triple x86_64-unknown-unknown %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -Wno-invalid-offsetof
19 // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -triple x86_64-apple-darwin    %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -DCLANG_ABI_COMPAT=15 -Wno-invalid-offsetof
20 // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -triple x86_64-scei-ps4        %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -DCLANG_ABI_COMPAT=6 -Wno-invalid-offsetof
21 // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -triple x86_64-sie-ps5         %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -DCLANG_ABI_COMPAT=6 -Wno-invalid-offsetof
22 // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -triple x86_64-unknown-unknown %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -fclang-abi-compat=6 -DCLANG_ABI_COMPAT=6 -Wno-invalid-offsetof
23 // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -triple x86_64-unknown-unknown %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -fclang-abi-compat=14 -DCLANG_ABI_COMPAT=14 -Wno-invalid-offsetof
24 // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -triple x86_64-unknown-unknown %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -fclang-abi-compat=15 -DCLANG_ABI_COMPAT=15 -Wno-invalid-offsetof
25 // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -triple x86_64-unknown-unknown %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -fclang-abi-compat=16 -DCLANG_ABI_COMPAT=16 -Wno-invalid-offsetof
26 // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -triple powerpc-ibm-aix7.3.0.0 %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -DCLANG_ABI_COMPAT=15 -Wno-invalid-offsetof
27 // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -triple powerpc-ibm-aix7.3.0.0 %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -fclang-abi-compat=15 -DCLANG_ABI_COMPAT=15 -Wno-invalid-offsetof
28 // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -triple powerpc64-ibm-aix7.3.0.0 %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -DCLANG_ABI_COMPAT=15 -Wno-invalid-offsetof
29 // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -triple powerpc64-ibm-aix7.3.0.0 %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -fclang-abi-compat=15 -DCLANG_ABI_COMPAT=15 -Wno-invalid-offsetof
30 // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -triple s390x-none-zos %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -Wno-invalid-offsetof
31 // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -triple s390x-none-zos %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -fclang-abi-compat=15 -DCLANG_ABI_COMPAT=15 -Wno-invalid-offsetof
32 
33 
34 
35 
36 // expected-no-diagnostics
37 
38 #if !defined(__MVS__) && !defined(_AIX)
39 
40 #define SA(n, p) int a##n[(p) ? 1 : -1]
41 
42 struct A {
43   int a;
44   char b;
45 };
46 
47 SA(0, sizeof(A) == 8);
48 
49 struct B : A {
50   char c;
51 };
52 
53 SA(1, sizeof(B) == 12);
54 
55 struct C {
56 // Make fields private so C won't be a POD type.
57 private:
58   int a;
59   char b;
60 };
61 
62 SA(2, sizeof(C) == 8);
63 
64 struct D : C {
65   char c;
66 };
67 
68 SA(3, sizeof(D) == 8);
69 
70 struct __attribute__((packed)) E {
71   char b;
72   int a;
73 };
74 
75 SA(4, sizeof(E) == 5);
76 
77 struct __attribute__((packed)) F : E {
78   char d;
79 };
80 
81 SA(5, sizeof(F) == 6);
82 
83 struct G { G(); };
84 struct H : G { };
85 
86 SA(6, sizeof(H) == 1);
87 
88 struct I {
89   char b;
90   int a;
91 } __attribute__((packed));
92 
93 SA(6_1, sizeof(I) == 5);
94 
95 // PR5580
96 namespace PR5580 {
97 
98 class A { bool iv0 : 1; };
99 SA(7, sizeof(A) == 1);
100 
101 class B : A { bool iv0 : 1; };
102 SA(8, sizeof(B) == 2);
103 
104 struct C { bool iv0 : 1; };
105 SA(9, sizeof(C) == 1);
106 
107 struct D : C { bool iv0 : 1; };
108 SA(10, sizeof(D) == 2);
109 
110 }
111 
112 namespace Test1 {
113 
114 // Test that we don't assert on this hierarchy.
115 struct A { };
116 struct B : A { virtual void b(); };
117 class C : virtual A { int c; };
118 struct D : virtual B { };
119 struct E : C, virtual D { };
120 class F : virtual E { };
121 struct G : virtual E, F { };
122 
123 SA(0, sizeof(G) == 24);
124 
125 }
126 
127 namespace Test2 {
128 
129 // Test that this somewhat complex class structure is laid out correctly.
130 struct A { };
131 struct B : A { virtual void b(); };
132 struct C : virtual B { };
133 struct D : virtual A { };
134 struct E : virtual B, D { };
135 struct F : E, virtual C { };
136 struct G : virtual F, A { };
137 struct H { G g; };
138 
139 SA(0, sizeof(H) == 24);
140 
141 }
142 
143 namespace PR16537 {
144 namespace test1 {
145   struct pod_in_11_only {
146   private:
147     long long x;
148   };
149 
150   struct tail_padded_pod_in_11_only {
151     pod_in_11_only pod11;
152     char tail_padding;
153   };
154 
155   struct might_use_tail_padding : public tail_padded_pod_in_11_only {
156     char may_go_into_tail_padding;
157   };
158 
159   SA(0, sizeof(might_use_tail_padding) == 16);
160 }
161 
162 namespace test2 {
163   struct pod_in_11_only {
164   private:
165     long long x;
166   };
167 
168   struct tail_padded_pod_in_11_only {
169     pod_in_11_only pod11 __attribute__((aligned(16)));
170   };
171 
172   struct might_use_tail_padding : public tail_padded_pod_in_11_only {
173     char may_go_into_tail_padding;
174   };
175 
176   SA(0, sizeof(might_use_tail_padding) == 16);
177 }
178 
179 namespace test3 {
180   struct pod_in_11_only {
181   private:
182     long long x;
183   };
184 
185   struct tail_padded_pod_in_11_only {
186     pod_in_11_only pod11;
187     char tail_padding;
188   };
189 
190   struct second_base {
191       char foo;
192   };
193 
194   struct might_use_tail_padding : public tail_padded_pod_in_11_only, public second_base {
195 
196   };
197   SA(0, sizeof(might_use_tail_padding) == 16);
198 }
199 
200 namespace test4 {
201   struct pod_in_11_only {
202   private:
203     long long x;
204   };
205 
206   struct tail_padded_pod_in_11_only {
207     pod_in_11_only pod11;
208     char tail_padding;
209   };
210 
211   struct second_base {
212     char foo;
213   };
214 
215   struct might_use_tail_padding : public tail_padded_pod_in_11_only, public second_base {
216     char may_go_into_tail_padding;
217   };
218   SA(0, sizeof(might_use_tail_padding) == 16);
219 }
220 
221 namespace test5 {
222   struct pod_in_11_only {
223   private:
224     long long x;
225   };
226 
227   struct pod_in_11_only2 {
228   private:
229     long long x;
230   };
231 
232   struct tail_padded_pod_in_11_only {
233     pod_in_11_only pod11;
234     char tail_padding;
235   };
236 
237   struct second_base {
238     pod_in_11_only2 two;
239     char foo;
240   };
241 
242   struct might_use_tail_padding : public tail_padded_pod_in_11_only, public second_base {
243     char may_go_into_tail_padding;
244   };
245   SA(0, sizeof(might_use_tail_padding) == 32);
246 }
247 
248 namespace test6 {
249   struct pod_in_11_only {
250   private:
251     long long x;
252   };
253 
254   struct pod_in_11_only2 {
255   private:
256     long long x;
257   };
258 
259   struct tail_padded_pod_in_11_only {
260     pod_in_11_only pod11;
261     char tail_padding;
262   };
263 
264   struct second_base {
265     pod_in_11_only2 two;
266     char foo;
267   };
268 
269   struct might_use_tail_padding : public tail_padded_pod_in_11_only, public second_base {
270     char may_go_into_tail_padding;
271   };
272   SA(0, sizeof(might_use_tail_padding) == 32);
273 }
274 
275 namespace test7 {
276   struct pod_in_11_only {
277   private:
278     long long x;
279   };
280 
281   struct tail_padded_pod_in_11_only {
282     pod_in_11_only pod11;
283     pod_in_11_only pod12;
284     char tail_padding;
285   };
286 
287   struct might_use_tail_padding : public tail_padded_pod_in_11_only {
288     char may_go_into_tail_padding;
289   };
290 
291   SA(0, sizeof(might_use_tail_padding) == 24);
292 }
293 
294 namespace test8 {
295   struct pod_in_11_only {
296   private:
297     long long x;
298   };
299 
300   struct tail_padded_pod_in_11_only {
301     pod_in_11_only pod11;
302     char tail_padding;
303   };
304 
305   struct another_layer {
306     tail_padded_pod_in_11_only pod;
307     char padding;
308   };
309 
310   struct might_use_tail_padding : public another_layer {
311     char may_go_into_tail_padding;
312   };
313 
314   SA(0, sizeof(might_use_tail_padding) == 24);
315 }
316 
317 namespace test9 {
318   struct pod_in_11_only {
319   private:
320     long long x;
321   };
322 
323   struct tail_padded_pod_in_11_only {
324     pod_in_11_only pod11;
325     char tail_padding;
326   };
327 
328   struct another_layer : tail_padded_pod_in_11_only {
329   };
330 
331   struct might_use_tail_padding : public another_layer {
332     char may_go_into_tail_padding;
333   };
334 
335   SA(0, sizeof(might_use_tail_padding) == 16);
336 }
337 
338 namespace test10 {
339   struct pod_in_11_only {
340   private:
341     long long x;
342   };
343 
344   struct A {
345     pod_in_11_only a;
346     char apad;
347   };
348 
349   struct B {
350     char b;
351   };
352 
353   struct C {
354     pod_in_11_only c;
355     char cpad;
356   };
357 
358   struct D {
359     char d;
360   };
361 
362   struct might_use_tail_padding : public A, public B, public C, public D {
363   };
364 
365   SA(0, sizeof(might_use_tail_padding) == 32);
366 }
367 
368 namespace test11 {
369   struct pod_in_11_only {
370   private:
371     long long x;
372   };
373 
374   struct A {
375     pod_in_11_only a;
376     char apad;
377   };
378 
379   struct B {
380     char b_pre;
381     pod_in_11_only b;
382     char bpad;
383   };
384 
385   struct C {
386     char c_pre;
387     pod_in_11_only c;
388     char cpad;
389   };
390 
391   struct D {
392     char d_pre;
393     pod_in_11_only d;
394     char dpad;
395   };
396 
397   struct might_use_tail_padding : public A, public B, public C, public D {
398     char m;
399   };
400 
401   SA(0, sizeof(might_use_tail_padding) == 88);
402 }
403 
404 namespace test12 {
405   struct pod_in_11_only {
406   private:
407     long long x;
408   };
409 
410   struct A {
411     pod_in_11_only a __attribute__((aligned(128)));
412   };
413 
414   struct B {
415     char bpad;
416   };
417 
418   struct C {
419     char cpad;
420   };
421 
422   struct D {
423     char dpad;
424   };
425 
426   struct might_use_tail_padding : public A, public B, public C, public D {
427     char m;
428   };
429   SA(0, sizeof(might_use_tail_padding) == 128);
430 }
431 
432 namespace test13 {
433   struct pod_in_11_only {
434   private:
435     long long x;
436   };
437 
438   struct A {
439     pod_in_11_only a;
440     char apad;
441   };
442 
443   struct B {
444   };
445 
446   struct C {
447     char c_pre;
448     pod_in_11_only c;
449     char cpad;
450   };
451 
452   struct D {
453   };
454 
455   struct might_use_tail_padding : public A, public B, public C, public D {
456     char m;
457   };
458   SA(0, sizeof(might_use_tail_padding) == 40);
459 }
460 
461 namespace test14 {
462   struct pod_in_11_only {
463   private:
464     long long x;
465   };
466 
467   struct A {
468     pod_in_11_only a;
469     char apad;
470   };
471 
472   struct might_use_tail_padding : public A {
473     struct {
474       int : 0;
475     } x;
476   };
477   SA(0, sizeof(might_use_tail_padding) == 16);
478 }
479 
480 namespace test15 {
481   struct pod_in_11_only {
482   private:
483     long long x;
484   };
485 
486   struct A {
487     pod_in_11_only a;
488     char apad;
489   };
490 
491   struct might_use_tail_padding : public A {
492     struct {
493       char a:1;
494       char b:2;
495       char c:2;
496       char d:2;
497       char e:1;
498     } x;
499   };
500   SA(0, sizeof(might_use_tail_padding) == 16);
501 }
502 
503 namespace test16 {
504   struct pod_in_11_only {
505   private:
506     long long x;
507   };
508 
509   struct A  {
510     pod_in_11_only a;
511     char apad;
512   };
513 
514   struct B {
515     char bpod;
516     pod_in_11_only b;
517     char bpad;
518   };
519 
520   struct C : public A, public B {
521   };
522 
523   struct D : public C {
524   };
525 
526   struct might_use_tail_padding : public D {
527     char m;
528   };
529   SA(0, sizeof(might_use_tail_padding) == 40);
530 }
531 
532 namespace test17 {
533   struct pod_in_11_only {
534   private:
535     long long x;
536   };
537 
538   struct A {
539     pod_in_11_only a __attribute__((aligned(512)));
540   };
541 
542   struct B {
543     char bpad;
544     pod_in_11_only foo;
545     char btail;
546   };
547 
548   struct C {
549     char cpad;
550   };
551 
552   struct D {
553     char dpad;
554   };
555 
556   struct might_use_tail_padding : public A, public B, public C, public D {
557     char a;
558   };
559   SA(0, sizeof(might_use_tail_padding) == 512);
560 }
561 
562 namespace test18 {
563   struct pod_in_11_only {
564   private:
565     long long x;
566   };
567 
568   struct A  {
569     pod_in_11_only a;
570     char apad;
571   };
572 
573   struct B {
574     char bpod;
575     pod_in_11_only b;
576     char bpad;
577   };
578 
579   struct A1  {
580     pod_in_11_only a;
581     char apad;
582   };
583 
584   struct B1 {
585     char bpod;
586     pod_in_11_only b;
587     char bpad;
588   };
589 
590   struct C : public A, public B {
591   };
592 
593   struct D : public A1, public B1 {
594   };
595 
596   struct E : public D, public C {
597   };
598 
599   struct F : public E {
600   };
601 
602   struct might_use_tail_padding : public F {
603     char m;
604   };
605   SA(0, sizeof(might_use_tail_padding) == 80);
606 }
607 } // namespace PR16537
608 
609 namespace PR37275 {
610   struct X { char c; };
611 
612   struct A { int n; };
613   _Static_assert(_Alignof(A) == _Alignof(int), "");
614 
615   // __attribute__((packed)) does not apply to base classes.
616   struct __attribute__((packed)) B : X, A {};
617 #if defined(CLANG_ABI_COMPAT) && CLANG_ABI_COMPAT <= 6
618   _Static_assert(_Alignof(B) == 1, "");
619   _Static_assert(__builtin_offsetof(B, n) == 1, "");
620 #else
621   _Static_assert(_Alignof(B) == _Alignof(int), "");
622   _Static_assert(__builtin_offsetof(B, n) == 4, "");
623 #endif
624 
625   // #pragma pack does, though.
626 #pragma pack(push, 2)
627   struct C : X, A {};
628   _Static_assert(_Alignof(C) == 2, "");
629   _Static_assert(__builtin_offsetof(C, n) == 2, "");
630 
631   struct __attribute__((packed)) D : X, A {};
632 #if defined(CLANG_ABI_COMPAT) && CLANG_ABI_COMPAT <= 6
633   _Static_assert(_Alignof(D) == 1, "");
634   _Static_assert(__builtin_offsetof(D, n) == 1, "");
635 #else
636   _Static_assert(_Alignof(D) == 2, "");
637   _Static_assert(__builtin_offsetof(D, n) == 2, "");
638 #endif
639 #pragma pack(pop)
640 }
641 
642 #endif // !defined(__MVS__) && !defined(__AIX__)
643 
644 namespace non_pod {
645 struct t1 {
646 protected:
647   int a;
648 };
649 // GCC prints warning: ignoring packed attribute because of unpacked non-POD field 't1 t2::v1'`
650 struct t2 {
651   char c1;
652   short s1;
653   char c2;
654   t1 v1;
655 } __attribute__((packed));
656 #if defined(CLANG_ABI_COMPAT) && CLANG_ABI_COMPAT <= 15
657 _Static_assert(_Alignof(t1) == 4, "");
658 _Static_assert(_Alignof(t2) == 1, "");
659 #else
660 _Static_assert(_Alignof(t1) == 4, "");
661 _Static_assert(_Alignof(t2) == 4, "");
662 #endif
663 _Static_assert(sizeof(t2) == 8, ""); // it's still packing the rest of the struct
664 } // namespace non_pod
665 
666 namespace non_pod_packed {
667 struct t1 {
668 protected:
669   int a;
670 } __attribute__((packed));
671 struct t2 {
672   t1 v1;
673 } __attribute__((packed));
674 _Static_assert(_Alignof(t1) == 1, "");
675 _Static_assert(_Alignof(t2) == 1, "");
676 } // namespace non_pod_packed
677 
678 namespace non_pod_packed_packed {
679 struct B {
680   int b;
681 };
682 struct  FromB : B {
683 } __attribute__((packed));
684 struct C {
685   char a[3];
686   FromB b;
687 } __attribute__((packed));
688 _Static_assert(__builtin_offsetof(C, b) == 3, "");
689 }
690 
691 namespace cxx11_pod {
692 struct t1 {
693   t1() = default;
694   t1(const t1&) = delete;
695   ~t1() = delete;
696   t1(t1&&) = default;
697   int a;
698   char c;
699 };
700 struct t2 {
701   t1 v1;
702 } __attribute__((packed));
703 #if (defined(CLANG_ABI_COMPAT) && CLANG_ABI_COMPAT <= 15) || !defined(__MVS__)
704 _Static_assert(_Alignof(t2) == 1, "");
705 #else
706 _Static_assert(_Alignof(t2) == 4, "");
707 #endif
708 struct t3 : t1 {
709   char c;
710 };
711 #if (defined(CLANG_ABI_COMPAT) && CLANG_ABI_COMPAT <= 15) || defined(__MVS__)
712 _Static_assert(sizeof(t3) == 8, "");
713 #else
714 _Static_assert(sizeof(t3) == 12, "");
715 #endif
716 }
717