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