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