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