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