1// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -fsyntax-only -verify -std=c++98
2// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -fsyntax-only -verify -std=c++11
3// expected-no-diagnostics
4
5#define SA(n, p) int a##n[(p) ? 1 : -1]
6
7struct A {
8  int a;
9  char b;
10};
11
12SA(0, sizeof(A) == 8);
13
14struct B : A {
15  char c;
16};
17
18SA(1, sizeof(B) == 12);
19
20struct C {
21// Make fields private so C won't be a POD type.
22private:
23  int a;
24  char b;
25};
26
27SA(2, sizeof(C) == 8);
28
29struct D : C {
30  char c;
31};
32
33SA(3, sizeof(D) == 8);
34
35struct __attribute__((packed)) E {
36  char b;
37  int a;
38};
39
40SA(4, sizeof(E) == 5);
41
42struct __attribute__((packed)) F : E {
43  char d;
44};
45
46SA(5, sizeof(F) == 6);
47
48struct G { G(); };
49struct H : G { };
50
51SA(6, sizeof(H) == 1);
52
53struct I {
54  char b;
55  int a;
56} __attribute__((packed));
57
58SA(6_1, sizeof(I) == 5);
59
60// PR5580
61namespace PR5580 {
62
63class A { bool iv0 : 1; };
64SA(7, sizeof(A) == 1);
65
66class B : A { bool iv0 : 1; };
67SA(8, sizeof(B) == 2);
68
69struct C { bool iv0 : 1; };
70SA(9, sizeof(C) == 1);
71
72struct D : C { bool iv0 : 1; };
73SA(10, sizeof(D) == 2);
74
75}
76
77namespace Test1 {
78
79// Test that we don't assert on this hierarchy.
80struct A { };
81struct B : A { virtual void b(); };
82class C : virtual A { int c; };
83struct D : virtual B { };
84struct E : C, virtual D { };
85class F : virtual E { };
86struct G : virtual E, F { };
87
88SA(0, sizeof(G) == 24);
89
90}
91
92namespace Test2 {
93
94// Test that this somewhat complex class structure is laid out correctly.
95struct A { };
96struct B : A { virtual void b(); };
97struct C : virtual B { };
98struct D : virtual A { };
99struct E : virtual B, D { };
100struct F : E, virtual C { };
101struct G : virtual F, A { };
102struct H { G g; };
103
104SA(0, sizeof(H) == 24);
105
106}
107
108namespace PR16537 {
109namespace test1 {
110  struct pod_in_11_only {
111  private:
112    long long x;
113  };
114
115  struct tail_padded_pod_in_11_only {
116    pod_in_11_only pod11;
117    char tail_padding;
118  };
119
120  struct might_use_tail_padding : public tail_padded_pod_in_11_only {
121    char may_go_into_tail_padding;
122  };
123
124  SA(0, sizeof(might_use_tail_padding) == 16);
125}
126
127namespace test2 {
128  struct pod_in_11_only {
129  private:
130    long long x;
131  };
132
133  struct tail_padded_pod_in_11_only {
134    pod_in_11_only pod11 __attribute__((aligned(16)));
135  };
136
137  struct might_use_tail_padding : public tail_padded_pod_in_11_only {
138    char may_go_into_tail_padding;
139  };
140
141  SA(0, sizeof(might_use_tail_padding) == 16);
142}
143
144namespace test3 {
145  struct pod_in_11_only {
146  private:
147    long long x;
148  };
149
150  struct tail_padded_pod_in_11_only {
151    pod_in_11_only pod11;
152    char tail_padding;
153  };
154
155  struct second_base {
156      char foo;
157  };
158
159  struct might_use_tail_padding : public tail_padded_pod_in_11_only, public second_base {
160
161  };
162  SA(0, sizeof(might_use_tail_padding) == 16);
163}
164
165namespace test4 {
166  struct pod_in_11_only {
167  private:
168    long long x;
169  };
170
171  struct tail_padded_pod_in_11_only {
172    pod_in_11_only pod11;
173    char tail_padding;
174  };
175
176  struct second_base {
177    char foo;
178  };
179
180  struct might_use_tail_padding : public tail_padded_pod_in_11_only, public second_base {
181    char may_go_into_tail_padding;
182  };
183  SA(0, sizeof(might_use_tail_padding) == 16);
184}
185
186namespace test5 {
187  struct pod_in_11_only {
188  private:
189    long long x;
190  };
191
192  struct pod_in_11_only2 {
193  private:
194    long long x;
195  };
196
197  struct tail_padded_pod_in_11_only {
198    pod_in_11_only pod11;
199    char tail_padding;
200  };
201
202  struct second_base {
203    pod_in_11_only2 two;
204    char foo;
205  };
206
207  struct might_use_tail_padding : public tail_padded_pod_in_11_only, public second_base {
208    char may_go_into_tail_padding;
209  };
210  SA(0, sizeof(might_use_tail_padding) == 32);
211}
212
213namespace test6 {
214  struct pod_in_11_only {
215  private:
216    long long x;
217  };
218
219  struct pod_in_11_only2 {
220  private:
221    long long x;
222  };
223
224  struct tail_padded_pod_in_11_only {
225    pod_in_11_only pod11;
226    char tail_padding;
227  };
228
229  struct second_base {
230    pod_in_11_only2 two;
231    char foo;
232  };
233
234  struct might_use_tail_padding : public tail_padded_pod_in_11_only, public second_base {
235    char may_go_into_tail_padding;
236  };
237  SA(0, sizeof(might_use_tail_padding) == 32);
238}
239
240namespace test7 {
241  struct pod_in_11_only {
242  private:
243    long long x;
244  };
245
246  struct tail_padded_pod_in_11_only {
247    pod_in_11_only pod11;
248    pod_in_11_only pod12;
249    char tail_padding;
250  };
251
252  struct might_use_tail_padding : public tail_padded_pod_in_11_only {
253    char may_go_into_tail_padding;
254  };
255
256  SA(0, sizeof(might_use_tail_padding) == 24);
257}
258
259namespace test8 {
260  struct pod_in_11_only {
261  private:
262    long long x;
263  };
264
265  struct tail_padded_pod_in_11_only {
266    pod_in_11_only pod11;
267    char tail_padding;
268  };
269
270  struct another_layer {
271    tail_padded_pod_in_11_only pod;
272    char padding;
273  };
274
275  struct might_use_tail_padding : public another_layer {
276    char may_go_into_tail_padding;
277  };
278
279  SA(0, sizeof(might_use_tail_padding) == 24);
280}
281
282namespace test9 {
283  struct pod_in_11_only {
284  private:
285    long long x;
286  };
287
288  struct tail_padded_pod_in_11_only {
289    pod_in_11_only pod11;
290    char tail_padding;
291  };
292
293  struct another_layer : tail_padded_pod_in_11_only {
294  };
295
296  struct might_use_tail_padding : public another_layer {
297    char may_go_into_tail_padding;
298  };
299
300  SA(0, sizeof(might_use_tail_padding) == 16);
301}
302
303namespace test10 {
304  struct pod_in_11_only {
305  private:
306    long long x;
307  };
308
309  struct A {
310    pod_in_11_only a;
311    char apad;
312  };
313
314  struct B {
315    char b;
316  };
317
318  struct C {
319    pod_in_11_only c;
320    char cpad;
321  };
322
323  struct D {
324    char d;
325  };
326
327  struct might_use_tail_padding : public A, public B, public C, public D {
328  };
329
330  SA(0, sizeof(might_use_tail_padding) == 32);
331}
332
333namespace test11 {
334  struct pod_in_11_only {
335  private:
336    long long x;
337  };
338
339  struct A {
340    pod_in_11_only a;
341    char apad;
342  };
343
344  struct B {
345    char b_pre;
346    pod_in_11_only b;
347    char bpad;
348  };
349
350  struct C {
351    char c_pre;
352    pod_in_11_only c;
353    char cpad;
354  };
355
356  struct D {
357    char d_pre;
358    pod_in_11_only d;
359    char dpad;
360  };
361
362  struct might_use_tail_padding : public A, public B, public C, public D {
363    char m;
364  };
365
366  SA(0, sizeof(might_use_tail_padding) == 88);
367}
368
369namespace test12 {
370  struct pod_in_11_only {
371  private:
372    long long x;
373  };
374
375  struct A {
376    pod_in_11_only a __attribute__((aligned(128)));
377  };
378
379  struct B {
380    char bpad;
381  };
382
383  struct C {
384    char cpad;
385  };
386
387  struct D {
388    char dpad;
389  };
390
391  struct might_use_tail_padding : public A, public B, public C, public D {
392    char m;
393  };
394  SA(0, sizeof(might_use_tail_padding) == 128);
395}
396
397namespace test13 {
398  struct pod_in_11_only {
399  private:
400    long long x;
401  };
402
403  struct A {
404    pod_in_11_only a;
405    char apad;
406  };
407
408  struct B {
409  };
410
411  struct C {
412    char c_pre;
413    pod_in_11_only c;
414    char cpad;
415  };
416
417  struct D {
418  };
419
420  struct might_use_tail_padding : public A, public B, public C, public D {
421    char m;
422  };
423  SA(0, sizeof(might_use_tail_padding) == 40);
424}
425
426namespace test14 {
427  struct pod_in_11_only {
428  private:
429    long long x;
430  };
431
432  struct A {
433    pod_in_11_only a;
434    char apad;
435  };
436
437  struct might_use_tail_padding : public A {
438    struct {
439      int : 0;
440    } x;
441  };
442  SA(0, sizeof(might_use_tail_padding) == 16);
443}
444
445namespace test15 {
446  struct pod_in_11_only {
447  private:
448    long long x;
449  };
450
451  struct A {
452    pod_in_11_only a;
453    char apad;
454  };
455
456  struct might_use_tail_padding : public A {
457    struct {
458      char a:1;
459      char b:2;
460      char c:2;
461      char d:2;
462      char e:1;
463    } x;
464  };
465  SA(0, sizeof(might_use_tail_padding) == 16);
466}
467
468namespace test16 {
469  struct pod_in_11_only {
470  private:
471    long long x;
472  };
473
474  struct A  {
475    pod_in_11_only a;
476    char apad;
477  };
478
479  struct B {
480    char bpod;
481    pod_in_11_only b;
482    char bpad;
483  };
484
485  struct C : public A, public B {
486  };
487
488  struct D : public C {
489  };
490
491  struct might_use_tail_padding : public D {
492    char m;
493  };
494  SA(0, sizeof(might_use_tail_padding) == 40);
495}
496
497namespace test17 {
498  struct pod_in_11_only {
499  private:
500    long long x;
501  };
502
503  struct A {
504    pod_in_11_only a __attribute__((aligned(512)));
505  };
506
507  struct B {
508    char bpad;
509    pod_in_11_only foo;
510    char btail;
511  };
512
513  struct C {
514    char cpad;
515  };
516
517  struct D {
518    char dpad;
519  };
520
521  struct might_use_tail_padding : public A, public B, public C, public D {
522    char a;
523  };
524  SA(0, sizeof(might_use_tail_padding) == 512);
525}
526
527namespace test18 {
528  struct pod_in_11_only {
529  private:
530    long long x;
531  };
532
533  struct A  {
534    pod_in_11_only a;
535    char apad;
536  };
537
538  struct B {
539    char bpod;
540    pod_in_11_only b;
541    char bpad;
542  };
543
544  struct A1  {
545    pod_in_11_only a;
546    char apad;
547  };
548
549  struct B1 {
550    char bpod;
551    pod_in_11_only b;
552    char bpad;
553  };
554
555  struct C : public A, public B {
556  };
557
558  struct D : public A1, public B1 {
559  };
560
561  struct E : public D, public C {
562  };
563
564  struct F : public E {
565  };
566
567  struct might_use_tail_padding : public F {
568    char m;
569  };
570  SA(0, sizeof(might_use_tail_padding) == 80);
571}
572} // namespace PR16537
573