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