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 }
174