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