1// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -fsyntax-only -verify 2// expected-no-diagnostics 3 4#define SA(n, p) int a##n[(p) ? 1 : -1] 5 6namespace Test0 { 7 8struct A { int a; }; 9SA(0, sizeof(A) == 4); 10 11struct B { }; 12SA(1, sizeof(B) == 1); 13 14struct C : A, B { }; 15SA(2, sizeof(C) == 4); 16 17struct D { }; 18struct E : D { }; 19struct F : E { }; 20 21struct G : E, F { }; 22SA(3, sizeof(G) == 2); 23 24struct Empty { Empty(); }; 25 26struct I : Empty { 27 Empty e; 28}; 29SA(4, sizeof(I) == 2); 30 31struct J : Empty { 32 Empty e[2]; 33}; 34SA(5, sizeof(J) == 3); 35 36template<int N> struct Derived : Empty, Derived<N - 1> { 37}; 38template<> struct Derived<0> : Empty { }; 39 40struct S1 : virtual Derived<10> { 41 Empty e; 42}; 43SA(6, sizeof(S1) == 24); 44 45struct S2 : virtual Derived<10> { 46 Empty e[2]; 47}; 48SA(7, sizeof(S2) == 24); 49 50struct S3 { 51 Empty e; 52}; 53 54struct S4 : Empty, S3 { 55}; 56SA(8, sizeof(S4) == 2); 57 58struct S5 : S3, Empty {}; 59SA(9, sizeof(S5) == 2); 60 61struct S6 : S5 { }; 62SA(10, sizeof(S6) == 2); 63 64struct S7 : Empty { 65 void *v; 66}; 67SA(11, sizeof(S7) == 8); 68 69struct S8 : Empty, A { 70}; 71SA(12, sizeof(S8) == 4); 72 73} 74 75namespace Test1 { 76 77// Test that we don't try to place both A subobjects at offset 0. 78struct A { }; 79class B { virtual void f(); }; 80class C : A, virtual B { }; 81struct D : virtual C { }; 82struct E : virtual A { }; 83class F : D, E { }; 84 85SA(0, sizeof(F) == 24); 86 87} 88 89namespace Test2 { 90 91// Test that B::a isn't laid out at offset 0. 92struct Empty { }; 93struct A : Empty { }; 94struct B : Empty { 95 A a; 96}; 97 98SA(0, sizeof(B) == 2); 99 100} 101 102namespace Test3 { 103 104// Test that B::a isn't laid out at offset 0. 105struct Empty { }; 106struct A { Empty e; }; 107struct B : Empty { A a; }; 108SA(0, sizeof(B) == 2); 109 110} 111 112namespace Test4 { 113 114// Test that C::Empty isn't laid out at offset 0. 115struct Empty { }; 116struct A : Empty { }; 117struct B { A a; }; 118struct C : B, Empty { }; 119SA(0, sizeof(C) == 2); 120 121} 122 123namespace Test5 { 124 125// Test that B::Empty isn't laid out at offset 0. 126struct Empty { }; 127struct Field : virtual Empty { }; 128struct A { 129 Field f; 130}; 131struct B : A, Empty { }; 132SA(0, sizeof(B) == 16); 133 134} 135 136namespace Test6 { 137 138// Test that B::A isn't laid out at offset 0. 139struct Empty { }; 140struct Field : virtual Empty { }; 141struct A { 142 Field f; 143}; 144struct B : Empty, A { }; 145SA(0, sizeof(B) == 16); 146 147} 148 149namespace 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 160namespace 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