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 | |