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