[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / clang / test / SemaCXX / class-layout.cpp
blobf81e526d0e2ad6b267935a5df2d22e3ce654350b
1 // RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -fsyntax-only -verify -std=c++98 -Wno-inaccessible-base
2 // RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base
3 // RUN: %clang_cc1 -triple x86_64-apple-darwin %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -DCLANG_ABI_COMPAT=14
4 // RUN: %clang_cc1 -triple x86_64-scei-ps4 %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -DCLANG_ABI_COMPAT=6
5 // RUN: %clang_cc1 -triple x86_64-sie-ps5 %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -DCLANG_ABI_COMPAT=6
6 // RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -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 -fclang-abi-compat=14 -DCLANG_ABI_COMPAT=14
8 // expected-no-diagnostics
10 #define SA(n, p) int a##n[(p) ? 1 : -1]
12 struct A {
13 int a;
14 char b;
17 SA(0, sizeof(A) == 8);
19 struct B : A {
20 char c;
23 SA(1, sizeof(B) == 12);
25 struct C {
26 // Make fields private so C won't be a POD type.
27 private:
28 int a;
29 char b;
32 SA(2, sizeof(C) == 8);
34 struct D : C {
35 char c;
38 SA(3, sizeof(D) == 8);
40 struct __attribute__((packed)) E {
41 char b;
42 int a;
45 SA(4, sizeof(E) == 5);
47 struct __attribute__((packed)) F : E {
48 char d;
51 SA(5, sizeof(F) == 6);
53 struct G { G(); };
54 struct H : G { };
56 SA(6, sizeof(H) == 1);
58 struct I {
59 char b;
60 int a;
61 } __attribute__((packed));
63 SA(6_1, sizeof(I) == 5);
65 // PR5580
66 namespace PR5580 {
68 class A { bool iv0 : 1; };
69 SA(7, sizeof(A) == 1);
71 class B : A { bool iv0 : 1; };
72 SA(8, sizeof(B) == 2);
74 struct C { bool iv0 : 1; };
75 SA(9, sizeof(C) == 1);
77 struct D : C { bool iv0 : 1; };
78 SA(10, sizeof(D) == 2);
82 namespace Test1 {
84 // Test that we don't assert on this hierarchy.
85 struct A { };
86 struct B : A { virtual void b(); };
87 class C : virtual A { int c; };
88 struct D : virtual B { };
89 struct E : C, virtual D { };
90 class F : virtual E { };
91 struct G : virtual E, F { };
93 SA(0, sizeof(G) == 24);
97 namespace Test2 {
99 // Test that this somewhat complex class structure is laid out correctly.
100 struct A { };
101 struct B : A { virtual void b(); };
102 struct C : virtual B { };
103 struct D : virtual A { };
104 struct E : virtual B, D { };
105 struct F : E, virtual C { };
106 struct G : virtual F, A { };
107 struct H { G g; };
109 SA(0, sizeof(H) == 24);
113 namespace PR16537 {
114 namespace test1 {
115 struct pod_in_11_only {
116 private:
117 long long x;
120 struct tail_padded_pod_in_11_only {
121 pod_in_11_only pod11;
122 char tail_padding;
125 struct might_use_tail_padding : public tail_padded_pod_in_11_only {
126 char may_go_into_tail_padding;
129 SA(0, sizeof(might_use_tail_padding) == 16);
132 namespace test2 {
133 struct pod_in_11_only {
134 private:
135 long long x;
138 struct tail_padded_pod_in_11_only {
139 pod_in_11_only pod11 __attribute__((aligned(16)));
142 struct might_use_tail_padding : public tail_padded_pod_in_11_only {
143 char may_go_into_tail_padding;
146 SA(0, sizeof(might_use_tail_padding) == 16);
149 namespace test3 {
150 struct pod_in_11_only {
151 private:
152 long long x;
155 struct tail_padded_pod_in_11_only {
156 pod_in_11_only pod11;
157 char tail_padding;
160 struct second_base {
161 char foo;
164 struct might_use_tail_padding : public tail_padded_pod_in_11_only, public second_base {
167 SA(0, sizeof(might_use_tail_padding) == 16);
170 namespace test4 {
171 struct pod_in_11_only {
172 private:
173 long long x;
176 struct tail_padded_pod_in_11_only {
177 pod_in_11_only pod11;
178 char tail_padding;
181 struct second_base {
182 char foo;
185 struct might_use_tail_padding : public tail_padded_pod_in_11_only, public second_base {
186 char may_go_into_tail_padding;
188 SA(0, sizeof(might_use_tail_padding) == 16);
191 namespace test5 {
192 struct pod_in_11_only {
193 private:
194 long long x;
197 struct pod_in_11_only2 {
198 private:
199 long long x;
202 struct tail_padded_pod_in_11_only {
203 pod_in_11_only pod11;
204 char tail_padding;
207 struct second_base {
208 pod_in_11_only2 two;
209 char foo;
212 struct might_use_tail_padding : public tail_padded_pod_in_11_only, public second_base {
213 char may_go_into_tail_padding;
215 SA(0, sizeof(might_use_tail_padding) == 32);
218 namespace test6 {
219 struct pod_in_11_only {
220 private:
221 long long x;
224 struct pod_in_11_only2 {
225 private:
226 long long x;
229 struct tail_padded_pod_in_11_only {
230 pod_in_11_only pod11;
231 char tail_padding;
234 struct second_base {
235 pod_in_11_only2 two;
236 char foo;
239 struct might_use_tail_padding : public tail_padded_pod_in_11_only, public second_base {
240 char may_go_into_tail_padding;
242 SA(0, sizeof(might_use_tail_padding) == 32);
245 namespace test7 {
246 struct pod_in_11_only {
247 private:
248 long long x;
251 struct tail_padded_pod_in_11_only {
252 pod_in_11_only pod11;
253 pod_in_11_only pod12;
254 char tail_padding;
257 struct might_use_tail_padding : public tail_padded_pod_in_11_only {
258 char may_go_into_tail_padding;
261 SA(0, sizeof(might_use_tail_padding) == 24);
264 namespace test8 {
265 struct pod_in_11_only {
266 private:
267 long long x;
270 struct tail_padded_pod_in_11_only {
271 pod_in_11_only pod11;
272 char tail_padding;
275 struct another_layer {
276 tail_padded_pod_in_11_only pod;
277 char padding;
280 struct might_use_tail_padding : public another_layer {
281 char may_go_into_tail_padding;
284 SA(0, sizeof(might_use_tail_padding) == 24);
287 namespace test9 {
288 struct pod_in_11_only {
289 private:
290 long long x;
293 struct tail_padded_pod_in_11_only {
294 pod_in_11_only pod11;
295 char tail_padding;
298 struct another_layer : tail_padded_pod_in_11_only {
301 struct might_use_tail_padding : public another_layer {
302 char may_go_into_tail_padding;
305 SA(0, sizeof(might_use_tail_padding) == 16);
308 namespace test10 {
309 struct pod_in_11_only {
310 private:
311 long long x;
314 struct A {
315 pod_in_11_only a;
316 char apad;
319 struct B {
320 char b;
323 struct C {
324 pod_in_11_only c;
325 char cpad;
328 struct D {
329 char d;
332 struct might_use_tail_padding : public A, public B, public C, public D {
335 SA(0, sizeof(might_use_tail_padding) == 32);
338 namespace test11 {
339 struct pod_in_11_only {
340 private:
341 long long x;
344 struct A {
345 pod_in_11_only a;
346 char apad;
349 struct B {
350 char b_pre;
351 pod_in_11_only b;
352 char bpad;
355 struct C {
356 char c_pre;
357 pod_in_11_only c;
358 char cpad;
361 struct D {
362 char d_pre;
363 pod_in_11_only d;
364 char dpad;
367 struct might_use_tail_padding : public A, public B, public C, public D {
368 char m;
371 SA(0, sizeof(might_use_tail_padding) == 88);
374 namespace test12 {
375 struct pod_in_11_only {
376 private:
377 long long x;
380 struct A {
381 pod_in_11_only a __attribute__((aligned(128)));
384 struct B {
385 char bpad;
388 struct C {
389 char cpad;
392 struct D {
393 char dpad;
396 struct might_use_tail_padding : public A, public B, public C, public D {
397 char m;
399 SA(0, sizeof(might_use_tail_padding) == 128);
402 namespace test13 {
403 struct pod_in_11_only {
404 private:
405 long long x;
408 struct A {
409 pod_in_11_only a;
410 char apad;
413 struct B {
416 struct C {
417 char c_pre;
418 pod_in_11_only c;
419 char cpad;
422 struct D {
425 struct might_use_tail_padding : public A, public B, public C, public D {
426 char m;
428 SA(0, sizeof(might_use_tail_padding) == 40);
431 namespace test14 {
432 struct pod_in_11_only {
433 private:
434 long long x;
437 struct A {
438 pod_in_11_only a;
439 char apad;
442 struct might_use_tail_padding : public A {
443 struct {
444 int : 0;
445 } x;
447 SA(0, sizeof(might_use_tail_padding) == 16);
450 namespace test15 {
451 struct pod_in_11_only {
452 private:
453 long long x;
456 struct A {
457 pod_in_11_only a;
458 char apad;
461 struct might_use_tail_padding : public A {
462 struct {
463 char a:1;
464 char b:2;
465 char c:2;
466 char d:2;
467 char e:1;
468 } x;
470 SA(0, sizeof(might_use_tail_padding) == 16);
473 namespace test16 {
474 struct pod_in_11_only {
475 private:
476 long long x;
479 struct A {
480 pod_in_11_only a;
481 char apad;
484 struct B {
485 char bpod;
486 pod_in_11_only b;
487 char bpad;
490 struct C : public A, public B {
493 struct D : public C {
496 struct might_use_tail_padding : public D {
497 char m;
499 SA(0, sizeof(might_use_tail_padding) == 40);
502 namespace test17 {
503 struct pod_in_11_only {
504 private:
505 long long x;
508 struct A {
509 pod_in_11_only a __attribute__((aligned(512)));
512 struct B {
513 char bpad;
514 pod_in_11_only foo;
515 char btail;
518 struct C {
519 char cpad;
522 struct D {
523 char dpad;
526 struct might_use_tail_padding : public A, public B, public C, public D {
527 char a;
529 SA(0, sizeof(might_use_tail_padding) == 512);
532 namespace test18 {
533 struct pod_in_11_only {
534 private:
535 long long x;
538 struct A {
539 pod_in_11_only a;
540 char apad;
543 struct B {
544 char bpod;
545 pod_in_11_only b;
546 char bpad;
549 struct A1 {
550 pod_in_11_only a;
551 char apad;
554 struct B1 {
555 char bpod;
556 pod_in_11_only b;
557 char bpad;
560 struct C : public A, public B {
563 struct D : public A1, public B1 {
566 struct E : public D, public C {
569 struct F : public E {
572 struct might_use_tail_padding : public F {
573 char m;
575 SA(0, sizeof(might_use_tail_padding) == 80);
577 } // namespace PR16537
579 namespace PR37275 {
580 struct X { char c; };
582 struct A { int n; };
583 _Static_assert(_Alignof(A) == _Alignof(int), "");
585 // __attribute__((packed)) does not apply to base classes.
586 struct __attribute__((packed)) B : X, A {};
587 #if defined(CLANG_ABI_COMPAT) && CLANG_ABI_COMPAT <= 6
588 _Static_assert(_Alignof(B) == 1, "");
589 _Static_assert(__builtin_offsetof(B, n) == 1, "");
590 #else
591 _Static_assert(_Alignof(B) == _Alignof(int), "");
592 _Static_assert(__builtin_offsetof(B, n) == 4, "");
593 #endif
595 // #pragma pack does, though.
596 #pragma pack(push, 2)
597 struct C : X, A {};
598 _Static_assert(_Alignof(C) == 2, "");
599 _Static_assert(__builtin_offsetof(C, n) == 2, "");
601 struct __attribute__((packed)) D : X, A {};
602 #if defined(CLANG_ABI_COMPAT) && CLANG_ABI_COMPAT <= 6
603 _Static_assert(_Alignof(D) == 1, "");
604 _Static_assert(__builtin_offsetof(D, n) == 1, "");
605 #else
606 _Static_assert(_Alignof(D) == 2, "");
607 _Static_assert(__builtin_offsetof(D, n) == 2, "");
608 #endif
609 #pragma pack(pop)
612 namespace non_pod {
613 struct t1 {
614 protected:
615 int a;
617 // GCC prints warning: ignoring packed attribute because of unpacked non-POD field 't1 t2::v1'`
618 struct t2 {
619 char c1;
620 short s1;
621 char c2;
622 t1 v1;
623 } __attribute__((packed));
624 #if defined(CLANG_ABI_COMPAT) && CLANG_ABI_COMPAT <= 14
625 _Static_assert(_Alignof(t1) == 4, "");
626 _Static_assert(_Alignof(t2) == 1, "");
627 #else
628 _Static_assert(_Alignof(t1) == 4, "");
629 _Static_assert(_Alignof(t2) == 4, "");
630 #endif
631 _Static_assert(sizeof(t2) == 8, ""); // it's still packing the rest of the struct
632 } // namespace non_pod
634 namespace non_pod_packed {
635 struct t1 {
636 protected:
637 int a;
638 } __attribute__((packed));
639 struct t2 {
640 t1 v1;
641 } __attribute__((packed));
642 _Static_assert(_Alignof(t1) == 1, "");
643 _Static_assert(_Alignof(t2) == 1, "");
644 } // namespace non_pod_packed