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