xref: /aosp_15_r20/external/clang/test/SemaCXX/empty-class-layout.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -fsyntax-only -verify -Wno-inaccessible-base
2*67e74705SXin Li // expected-no-diagnostics
3*67e74705SXin Li 
4*67e74705SXin Li #define SA(n, p) int a##n[(p) ? 1 : -1]
5*67e74705SXin Li 
6*67e74705SXin Li namespace Test0 {
7*67e74705SXin Li 
8*67e74705SXin Li struct A { int a; };
9*67e74705SXin Li SA(0, sizeof(A) == 4);
10*67e74705SXin Li 
11*67e74705SXin Li struct B { };
12*67e74705SXin Li SA(1, sizeof(B) == 1);
13*67e74705SXin Li 
14*67e74705SXin Li struct C : A, B { };
15*67e74705SXin Li SA(2, sizeof(C) == 4);
16*67e74705SXin Li 
17*67e74705SXin Li struct D { };
18*67e74705SXin Li struct E : D { };
19*67e74705SXin Li struct F : E { };
20*67e74705SXin Li 
21*67e74705SXin Li struct G : E, F { };
22*67e74705SXin Li SA(3, sizeof(G) == 2);
23*67e74705SXin Li 
24*67e74705SXin Li struct Empty { Empty(); };
25*67e74705SXin Li 
26*67e74705SXin Li struct I : Empty {
27*67e74705SXin Li   Empty e;
28*67e74705SXin Li };
29*67e74705SXin Li SA(4, sizeof(I) == 2);
30*67e74705SXin Li 
31*67e74705SXin Li struct J : Empty {
32*67e74705SXin Li   Empty e[2];
33*67e74705SXin Li };
34*67e74705SXin Li SA(5, sizeof(J) == 3);
35*67e74705SXin Li 
36*67e74705SXin Li template<int N> struct Derived : Empty, Derived<N - 1> {
37*67e74705SXin Li };
38*67e74705SXin Li template<> struct Derived<0> : Empty { };
39*67e74705SXin Li 
40*67e74705SXin Li struct S1 : virtual Derived<10> {
41*67e74705SXin Li   Empty e;
42*67e74705SXin Li };
43*67e74705SXin Li SA(6, sizeof(S1) == 24);
44*67e74705SXin Li 
45*67e74705SXin Li struct S2 : virtual Derived<10> {
46*67e74705SXin Li   Empty e[2];
47*67e74705SXin Li };
48*67e74705SXin Li SA(7, sizeof(S2) == 24);
49*67e74705SXin Li 
50*67e74705SXin Li struct S3 {
51*67e74705SXin Li   Empty e;
52*67e74705SXin Li };
53*67e74705SXin Li 
54*67e74705SXin Li struct S4 : Empty, S3 {
55*67e74705SXin Li };
56*67e74705SXin Li SA(8, sizeof(S4) == 2);
57*67e74705SXin Li 
58*67e74705SXin Li struct S5 : S3, Empty {};
59*67e74705SXin Li SA(9, sizeof(S5) == 2);
60*67e74705SXin Li 
61*67e74705SXin Li struct S6 : S5 { };
62*67e74705SXin Li SA(10, sizeof(S6) == 2);
63*67e74705SXin Li 
64*67e74705SXin Li struct S7 : Empty {
65*67e74705SXin Li   void *v;
66*67e74705SXin Li };
67*67e74705SXin Li SA(11, sizeof(S7) == 8);
68*67e74705SXin Li 
69*67e74705SXin Li struct S8 : Empty, A {
70*67e74705SXin Li };
71*67e74705SXin Li SA(12, sizeof(S8) == 4);
72*67e74705SXin Li 
73*67e74705SXin Li }
74*67e74705SXin Li 
75*67e74705SXin Li namespace Test1 {
76*67e74705SXin Li 
77*67e74705SXin Li // Test that we don't try to place both A subobjects at offset 0.
78*67e74705SXin Li struct A { };
79*67e74705SXin Li class B { virtual void f(); };
80*67e74705SXin Li class C : A, virtual B { };
81*67e74705SXin Li struct D : virtual C { };
82*67e74705SXin Li struct E : virtual A { };
83*67e74705SXin Li class F : D, E { };
84*67e74705SXin Li 
85*67e74705SXin Li SA(0, sizeof(F) == 24);
86*67e74705SXin Li 
87*67e74705SXin Li }
88*67e74705SXin Li 
89*67e74705SXin Li namespace Test2 {
90*67e74705SXin Li 
91*67e74705SXin Li // Test that B::a isn't laid out at offset 0.
92*67e74705SXin Li struct Empty { };
93*67e74705SXin Li struct A : Empty { };
94*67e74705SXin Li struct B : Empty {
95*67e74705SXin Li   A a;
96*67e74705SXin Li };
97*67e74705SXin Li 
98*67e74705SXin Li SA(0, sizeof(B) == 2);
99*67e74705SXin Li 
100*67e74705SXin Li }
101*67e74705SXin Li 
102*67e74705SXin Li namespace Test3 {
103*67e74705SXin Li 
104*67e74705SXin Li // Test that B::a isn't laid out at offset 0.
105*67e74705SXin Li struct Empty { };
106*67e74705SXin Li struct A { Empty e; };
107*67e74705SXin Li struct B : Empty { A a; };
108*67e74705SXin Li SA(0, sizeof(B) == 2);
109*67e74705SXin Li 
110*67e74705SXin Li }
111*67e74705SXin Li 
112*67e74705SXin Li namespace Test4 {
113*67e74705SXin Li 
114*67e74705SXin Li // Test that C::Empty isn't laid out at offset 0.
115*67e74705SXin Li struct Empty { };
116*67e74705SXin Li struct A : Empty { };
117*67e74705SXin Li struct B { A a; };
118*67e74705SXin Li struct C : B, Empty { };
119*67e74705SXin Li SA(0, sizeof(C) == 2);
120*67e74705SXin Li 
121*67e74705SXin Li }
122*67e74705SXin Li 
123*67e74705SXin Li namespace Test5 {
124*67e74705SXin Li 
125*67e74705SXin Li // Test that B::Empty isn't laid out at offset 0.
126*67e74705SXin Li struct Empty { };
127*67e74705SXin Li struct Field : virtual Empty { };
128*67e74705SXin Li struct A {
129*67e74705SXin Li   Field f;
130*67e74705SXin Li };
131*67e74705SXin Li struct B : A, Empty { };
132*67e74705SXin Li SA(0, sizeof(B) == 16);
133*67e74705SXin Li 
134*67e74705SXin Li }
135*67e74705SXin Li 
136*67e74705SXin Li namespace Test6 {
137*67e74705SXin Li 
138*67e74705SXin Li // Test that B::A isn't laid out at offset 0.
139*67e74705SXin Li struct Empty { };
140*67e74705SXin Li struct Field : virtual Empty { };
141*67e74705SXin Li struct A {
142*67e74705SXin Li   Field f;
143*67e74705SXin Li };
144*67e74705SXin Li struct B : Empty, A { };
145*67e74705SXin Li SA(0, sizeof(B) == 16);
146*67e74705SXin Li 
147*67e74705SXin Li }
148*67e74705SXin Li 
149*67e74705SXin Li namespace Test7 {
150*67e74705SXin Li   // Make sure we reserve enough space for both bases; PR11745.
151*67e74705SXin Li   struct Empty { };
152*67e74705SXin Li   struct Base1 : Empty { };
153*67e74705SXin Li   struct Base2 : Empty { };
154*67e74705SXin Li   struct Test : Base1, Base2 {
155*67e74705SXin Li     char c;
156*67e74705SXin Li   };
157*67e74705SXin Li   SA(0, sizeof(Test) == 2);
158*67e74705SXin Li }
159*67e74705SXin Li 
160*67e74705SXin Li namespace Test8 {
161*67e74705SXin Li   // Test that type sugar doesn't make us incorrectly determine the size of an
162*67e74705SXin Li   // array of empty classes.
163*67e74705SXin Li   struct Empty1 {};
164*67e74705SXin Li   struct Empty2 {};
165*67e74705SXin Li   struct Empties : Empty1, Empty2 {};
166*67e74705SXin Li   typedef Empty1 Sugar[4];
167*67e74705SXin Li   struct A : Empty2, Empties {
168*67e74705SXin Li     // This must go at offset 2, because if it were at offset 0,
169*67e74705SXin Li     // V[0][1] would overlap Empties::Empty1.
170*67e74705SXin Li     Sugar V[1];
171*67e74705SXin Li   };
172*67e74705SXin Li   SA(0, sizeof(A) == 6);
173*67e74705SXin Li }
174