Clang Project

clang_source_code/test/SemaCXX/class-layout.cpp
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
8struct A {
9  int a;
10  char b;
11};
12
13SA(0, sizeof(A) == 8);
14
15struct B : A {
16  char c;
17};
18
19SA(1, sizeof(B) == 12);
20
21struct C {
22// Make fields private so C won't be a POD type.
23private:
24  int a;
25  char b;
26};
27
28SA(2, sizeof(C) == 8);
29
30struct D : C {
31  char c;
32};
33
34SA(3, sizeof(D) == 8);
35
36struct __attribute__((packed)) E {
37  char b;
38  int a;
39};
40
41SA(4, sizeof(E) == 5);
42
43struct __attribute__((packed)) F : E {
44  char d;
45};
46
47SA(5, sizeof(F) == 6);
48
49struct G { G(); };
50struct H : G { };
51
52SA(6, sizeof(H) == 1);
53
54struct I {
55  char b;
56  int a;
57} __attribute__((packed));
58
59SA(6_1, sizeof(I) == 5);
60
61// PR5580
62namespace PR5580 {
63
64class A { bool iv0 : 1; };
65SA(7, sizeof(A) == 1);  
66
67class B : A { bool iv0 : 1; };
68SA(8, sizeof(B) == 2);
69
70struct C { bool iv0 : 1; };
71SA(9, sizeof(C) == 1);  
72
73struct D : C { bool iv0 : 1; };
74SA(10, sizeof(D) == 2);
75
76}
77
78namespace Test1 {
79
80// Test that we don't assert on this hierarchy.
81struct A { };
82struct B : A { virtual void b(); };
83class C : virtual A { int c; };
84struct D : virtual B { };
85struct E : C, virtual D { };
86class F : virtual E { };
87struct G : virtual E, F { };
88
89SA(0, sizeof(G) == 24);
90
91}
92
93namespace Test2 {
94
95// Test that this somewhat complex class structure is laid out correctly.
96struct A { };
97struct B : A { virtual void b(); };
98struct C : virtual B { };
99struct D : virtual A { };
100struct E : virtual B, D { };
101struct F : E, virtual C { };
102struct G : virtual F, A { };
103struct H { G g; };
104
105SA(0, sizeof(H) == 24);
106
107}
108
109namespace PR16537 {
110namespace 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
128namespace 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
145namespace 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
166namespace 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
187namespace 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
214namespace 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
241namespace 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
260namespace 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
283namespace 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
304namespace 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
334namespace 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
370namespace 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
398namespace 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
427namespace 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
446namespace 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
469namespace 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
498namespace 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
528namespace 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
575namespace 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