1*44b21749SNathan Sidwell // RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -fsyntax-only -verify -Wno-inaccessible-base
2c6e68daaSAndy Gibbs // expected-no-diagnostics
3f24b18fbSAnders Carlsson 
4f24b18fbSAnders Carlsson #define SA(n, p) int a##n[(p) ? 1 : -1]
5f24b18fbSAnders Carlsson 
65773205aSAnders Carlsson namespace Test0 {
75773205aSAnders Carlsson 
8f24b18fbSAnders Carlsson struct A { int a; };
9f24b18fbSAnders Carlsson SA(0, sizeof(A) == 4);
10f24b18fbSAnders Carlsson 
11f24b18fbSAnders Carlsson struct B { };
12f24b18fbSAnders Carlsson SA(1, sizeof(B) == 1);
13f24b18fbSAnders Carlsson 
14f24b18fbSAnders Carlsson struct C : A, B { };
15f24b18fbSAnders Carlsson SA(2, sizeof(C) == 4);
16bb66bc8eSAnders Carlsson 
17bb66bc8eSAnders Carlsson struct D { };
18bb66bc8eSAnders Carlsson struct E : D { };
19bb66bc8eSAnders Carlsson struct F : E { };
20bb66bc8eSAnders Carlsson 
21bb66bc8eSAnders Carlsson struct G : E, F { };
22bb66bc8eSAnders Carlsson SA(3, sizeof(G) == 2);
236f95c705SAnders Carlsson 
244bf82141SAnders Carlsson struct Empty { Empty(); };
256f95c705SAnders Carlsson 
264bf82141SAnders Carlsson struct I : Empty {
274bf82141SAnders Carlsson   Empty e;
286f95c705SAnders Carlsson };
296f95c705SAnders Carlsson SA(4, sizeof(I) == 2);
304bf82141SAnders Carlsson 
314bf82141SAnders Carlsson struct J : Empty {
324bf82141SAnders Carlsson   Empty e[2];
334bf82141SAnders Carlsson };
344bf82141SAnders Carlsson SA(5, sizeof(J) == 3);
35e1883100SAnders Carlsson 
36e1883100SAnders Carlsson template<int N> struct Derived : Empty, Derived<N - 1> {
37e1883100SAnders Carlsson };
38e1883100SAnders Carlsson template<> struct Derived<0> : Empty { };
39e1883100SAnders Carlsson 
40e1883100SAnders Carlsson struct S1 : virtual Derived<10> {
41e1883100SAnders Carlsson   Empty e;
42e1883100SAnders Carlsson };
43e1883100SAnders Carlsson SA(6, sizeof(S1) == 24);
44e1883100SAnders Carlsson 
45e1883100SAnders Carlsson struct S2 : virtual Derived<10> {
46e1883100SAnders Carlsson   Empty e[2];
47e1883100SAnders Carlsson };
48e1883100SAnders Carlsson SA(7, sizeof(S2) == 24);
49d7d358a6SAnders Carlsson 
50d7d358a6SAnders Carlsson struct S3 {
51d7d358a6SAnders Carlsson   Empty e;
52d7d358a6SAnders Carlsson };
53d7d358a6SAnders Carlsson 
54d7d358a6SAnders Carlsson struct S4 : Empty, S3 {
55d7d358a6SAnders Carlsson };
56d7d358a6SAnders Carlsson SA(8, sizeof(S4) == 2);
57d7d358a6SAnders Carlsson 
58d7d358a6SAnders Carlsson struct S5 : S3, Empty {};
59d7d358a6SAnders Carlsson SA(9, sizeof(S5) == 2);
60d7d358a6SAnders Carlsson 
61d7d358a6SAnders Carlsson struct S6 : S5 { };
62d7d358a6SAnders Carlsson SA(10, sizeof(S6) == 2);
63a6d95b5aSAnders Carlsson 
64a6d95b5aSAnders Carlsson struct S7 : Empty {
65a6d95b5aSAnders Carlsson   void *v;
66a6d95b5aSAnders Carlsson };
67a6d95b5aSAnders Carlsson SA(11, sizeof(S7) == 8);
687f78d85bSAnders Carlsson 
697f78d85bSAnders Carlsson struct S8 : Empty, A {
707f78d85bSAnders Carlsson };
717f78d85bSAnders Carlsson SA(12, sizeof(S8) == 4);
725773205aSAnders Carlsson 
735773205aSAnders Carlsson }
745773205aSAnders Carlsson 
755773205aSAnders Carlsson namespace Test1 {
765773205aSAnders Carlsson 
775773205aSAnders Carlsson // Test that we don't try to place both A subobjects at offset 0.
785773205aSAnders Carlsson struct A { };
795773205aSAnders Carlsson class B { virtual void f(); };
805773205aSAnders Carlsson class C : A, virtual B { };
815773205aSAnders Carlsson struct D : virtual C { };
825773205aSAnders Carlsson struct E : virtual A { };
835773205aSAnders Carlsson class F : D, E { };
845773205aSAnders Carlsson 
855773205aSAnders Carlsson SA(0, sizeof(F) == 24);
865773205aSAnders Carlsson 
875773205aSAnders Carlsson }
881ff101cbSAnders Carlsson 
891ff101cbSAnders Carlsson namespace Test2 {
901ff101cbSAnders Carlsson 
911ff101cbSAnders Carlsson // Test that B::a isn't laid out at offset 0.
921ff101cbSAnders Carlsson struct Empty { };
931ff101cbSAnders Carlsson struct A : Empty { };
941ff101cbSAnders Carlsson struct B : Empty {
951ff101cbSAnders Carlsson   A a;
961ff101cbSAnders Carlsson };
971ff101cbSAnders Carlsson 
981ff101cbSAnders Carlsson SA(0, sizeof(B) == 2);
991ff101cbSAnders Carlsson 
1001ff101cbSAnders Carlsson }
1011ff101cbSAnders Carlsson 
1021ff101cbSAnders Carlsson namespace Test3 {
1031ff101cbSAnders Carlsson 
1041ff101cbSAnders Carlsson // Test that B::a isn't laid out at offset 0.
1051ff101cbSAnders Carlsson struct Empty { };
1061ff101cbSAnders Carlsson struct A { Empty e; };
1073e88da9fSAnders Carlsson struct B : Empty { A a; };
1081ff101cbSAnders Carlsson SA(0, sizeof(B) == 2);
1091ff101cbSAnders Carlsson 
1101ff101cbSAnders Carlsson }
1113e88da9fSAnders Carlsson 
1123e88da9fSAnders Carlsson namespace Test4 {
1133e88da9fSAnders Carlsson 
1143e88da9fSAnders Carlsson // Test that C::Empty isn't laid out at offset 0.
1153e88da9fSAnders Carlsson struct Empty { };
1163e88da9fSAnders Carlsson struct A : Empty { };
1173e88da9fSAnders Carlsson struct B { A a; };
1183e88da9fSAnders Carlsson struct C : B, Empty { };
1193e88da9fSAnders Carlsson SA(0, sizeof(C) == 2);
1203e88da9fSAnders Carlsson 
1213e88da9fSAnders Carlsson }
12244687206SAnders Carlsson 
12344687206SAnders Carlsson namespace Test5 {
12444687206SAnders Carlsson 
12544687206SAnders Carlsson // Test that B::Empty isn't laid out at offset 0.
12644687206SAnders Carlsson struct Empty { };
12744687206SAnders Carlsson struct Field : virtual Empty { };
12844687206SAnders Carlsson struct A {
12944687206SAnders Carlsson   Field f;
13044687206SAnders Carlsson };
13144687206SAnders Carlsson struct B : A, Empty { };
13244687206SAnders Carlsson SA(0, sizeof(B) == 16);
13344687206SAnders Carlsson 
13444687206SAnders Carlsson }
13544687206SAnders Carlsson 
13644687206SAnders Carlsson namespace Test6 {
13744687206SAnders Carlsson 
13844687206SAnders Carlsson // Test that B::A isn't laid out at offset 0.
13944687206SAnders Carlsson struct Empty { };
14044687206SAnders Carlsson struct Field : virtual Empty { };
14144687206SAnders Carlsson struct A {
14244687206SAnders Carlsson   Field f;
14344687206SAnders Carlsson };
14444687206SAnders Carlsson struct B : Empty, A { };
14544687206SAnders Carlsson SA(0, sizeof(B) == 16);
14644687206SAnders Carlsson 
14744687206SAnders Carlsson }
1482e108376SEli Friedman 
1492e108376SEli Friedman namespace Test7 {
1502e108376SEli Friedman   // Make sure we reserve enough space for both bases; PR11745.
1512e108376SEli Friedman   struct Empty { };
1522e108376SEli Friedman   struct Base1 : Empty { };
1532e108376SEli Friedman   struct Base2 : Empty { };
1542e108376SEli Friedman   struct Test : Base1, Base2 {
1552e108376SEli Friedman     char c;
1562e108376SEli Friedman   };
1572e108376SEli Friedman   SA(0, sizeof(Test) == 2);
1582e108376SEli Friedman }
1597808c6aaSRichard Smith 
1607808c6aaSRichard Smith namespace Test8 {
1617808c6aaSRichard Smith   // Test that type sugar doesn't make us incorrectly determine the size of an
1627808c6aaSRichard Smith   // array of empty classes.
1637808c6aaSRichard Smith   struct Empty1 {};
1647808c6aaSRichard Smith   struct Empty2 {};
1657808c6aaSRichard Smith   struct Empties : Empty1, Empty2 {};
1667808c6aaSRichard Smith   typedef Empty1 Sugar[4];
1677808c6aaSRichard Smith   struct A : Empty2, Empties {
1687808c6aaSRichard Smith     // This must go at offset 2, because if it were at offset 0,
1697808c6aaSRichard Smith     // V[0][1] would overlap Empties::Empty1.
1707808c6aaSRichard Smith     Sugar V[1];
1717808c6aaSRichard Smith   };
1727808c6aaSRichard Smith   SA(0, sizeof(A) == 6);
1737808c6aaSRichard Smith }
174