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