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