|  | // RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -fsyntax-only -verify -std=c++98 -Wno-inaccessible-base | 
|  | // RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base | 
|  | // 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 | 
|  | // expected-no-diagnostics | 
|  |  | 
|  | #define SA(n, p) int a##n[(p) ? 1 : -1] | 
|  |  | 
|  | struct A { | 
|  | int a; | 
|  | char b; | 
|  | }; | 
|  |  | 
|  | SA(0, sizeof(A) == 8); | 
|  |  | 
|  | struct B : A { | 
|  | char c; | 
|  | }; | 
|  |  | 
|  | SA(1, sizeof(B) == 12); | 
|  |  | 
|  | struct C { | 
|  | // Make fields private so C won't be a POD type. | 
|  | private: | 
|  | int a; | 
|  | char b; | 
|  | }; | 
|  |  | 
|  | SA(2, sizeof(C) == 8); | 
|  |  | 
|  | struct D : C { | 
|  | char c; | 
|  | }; | 
|  |  | 
|  | SA(3, sizeof(D) == 8); | 
|  |  | 
|  | struct __attribute__((packed)) E { | 
|  | char b; | 
|  | int a; | 
|  | }; | 
|  |  | 
|  | SA(4, sizeof(E) == 5); | 
|  |  | 
|  | struct __attribute__((packed)) F : E { | 
|  | char d; | 
|  | }; | 
|  |  | 
|  | SA(5, sizeof(F) == 6); | 
|  |  | 
|  | struct G { G(); }; | 
|  | struct H : G { }; | 
|  |  | 
|  | SA(6, sizeof(H) == 1); | 
|  |  | 
|  | struct I { | 
|  | char b; | 
|  | int a; | 
|  | } __attribute__((packed)); | 
|  |  | 
|  | SA(6_1, sizeof(I) == 5); | 
|  |  | 
|  | // PR5580 | 
|  | namespace PR5580 { | 
|  |  | 
|  | class A { bool iv0 : 1; }; | 
|  | SA(7, sizeof(A) == 1); | 
|  |  | 
|  | class B : A { bool iv0 : 1; }; | 
|  | SA(8, sizeof(B) == 2); | 
|  |  | 
|  | struct C { bool iv0 : 1; }; | 
|  | SA(9, sizeof(C) == 1); | 
|  |  | 
|  | struct D : C { bool iv0 : 1; }; | 
|  | SA(10, sizeof(D) == 2); | 
|  |  | 
|  | } | 
|  |  | 
|  | namespace Test1 { | 
|  |  | 
|  | // Test that we don't assert on this hierarchy. | 
|  | struct A { }; | 
|  | struct B : A { virtual void b(); }; | 
|  | class C : virtual A { int c; }; | 
|  | struct D : virtual B { }; | 
|  | struct E : C, virtual D { }; | 
|  | class F : virtual E { }; | 
|  | struct G : virtual E, F { }; | 
|  |  | 
|  | SA(0, sizeof(G) == 24); | 
|  |  | 
|  | } | 
|  |  | 
|  | namespace Test2 { | 
|  |  | 
|  | // Test that this somewhat complex class structure is laid out correctly. | 
|  | struct A { }; | 
|  | struct B : A { virtual void b(); }; | 
|  | struct C : virtual B { }; | 
|  | struct D : virtual A { }; | 
|  | struct E : virtual B, D { }; | 
|  | struct F : E, virtual C { }; | 
|  | struct G : virtual F, A { }; | 
|  | struct H { G g; }; | 
|  |  | 
|  | SA(0, sizeof(H) == 24); | 
|  |  | 
|  | } | 
|  |  | 
|  | namespace PR16537 { | 
|  | namespace test1 { | 
|  | struct pod_in_11_only { | 
|  | private: | 
|  | long long x; | 
|  | }; | 
|  |  | 
|  | struct tail_padded_pod_in_11_only { | 
|  | pod_in_11_only pod11; | 
|  | char tail_padding; | 
|  | }; | 
|  |  | 
|  | struct might_use_tail_padding : public tail_padded_pod_in_11_only { | 
|  | char may_go_into_tail_padding; | 
|  | }; | 
|  |  | 
|  | SA(0, sizeof(might_use_tail_padding) == 16); | 
|  | } | 
|  |  | 
|  | namespace test2 { | 
|  | struct pod_in_11_only { | 
|  | private: | 
|  | long long x; | 
|  | }; | 
|  |  | 
|  | struct tail_padded_pod_in_11_only { | 
|  | pod_in_11_only pod11 __attribute__((aligned(16))); | 
|  | }; | 
|  |  | 
|  | struct might_use_tail_padding : public tail_padded_pod_in_11_only { | 
|  | char may_go_into_tail_padding; | 
|  | }; | 
|  |  | 
|  | SA(0, sizeof(might_use_tail_padding) == 16); | 
|  | } | 
|  |  | 
|  | namespace test3 { | 
|  | struct pod_in_11_only { | 
|  | private: | 
|  | long long x; | 
|  | }; | 
|  |  | 
|  | struct tail_padded_pod_in_11_only { | 
|  | pod_in_11_only pod11; | 
|  | char tail_padding; | 
|  | }; | 
|  |  | 
|  | struct second_base { | 
|  | char foo; | 
|  | }; | 
|  |  | 
|  | struct might_use_tail_padding : public tail_padded_pod_in_11_only, public second_base { | 
|  |  | 
|  | }; | 
|  | SA(0, sizeof(might_use_tail_padding) == 16); | 
|  | } | 
|  |  | 
|  | namespace test4 { | 
|  | struct pod_in_11_only { | 
|  | private: | 
|  | long long x; | 
|  | }; | 
|  |  | 
|  | struct tail_padded_pod_in_11_only { | 
|  | pod_in_11_only pod11; | 
|  | char tail_padding; | 
|  | }; | 
|  |  | 
|  | struct second_base { | 
|  | char foo; | 
|  | }; | 
|  |  | 
|  | struct might_use_tail_padding : public tail_padded_pod_in_11_only, public second_base { | 
|  | char may_go_into_tail_padding; | 
|  | }; | 
|  | SA(0, sizeof(might_use_tail_padding) == 16); | 
|  | } | 
|  |  | 
|  | namespace test5 { | 
|  | struct pod_in_11_only { | 
|  | private: | 
|  | long long x; | 
|  | }; | 
|  |  | 
|  | struct pod_in_11_only2 { | 
|  | private: | 
|  | long long x; | 
|  | }; | 
|  |  | 
|  | struct tail_padded_pod_in_11_only { | 
|  | pod_in_11_only pod11; | 
|  | char tail_padding; | 
|  | }; | 
|  |  | 
|  | struct second_base { | 
|  | pod_in_11_only2 two; | 
|  | char foo; | 
|  | }; | 
|  |  | 
|  | struct might_use_tail_padding : public tail_padded_pod_in_11_only, public second_base { | 
|  | char may_go_into_tail_padding; | 
|  | }; | 
|  | SA(0, sizeof(might_use_tail_padding) == 32); | 
|  | } | 
|  |  | 
|  | namespace test6 { | 
|  | struct pod_in_11_only { | 
|  | private: | 
|  | long long x; | 
|  | }; | 
|  |  | 
|  | struct pod_in_11_only2 { | 
|  | private: | 
|  | long long x; | 
|  | }; | 
|  |  | 
|  | struct tail_padded_pod_in_11_only { | 
|  | pod_in_11_only pod11; | 
|  | char tail_padding; | 
|  | }; | 
|  |  | 
|  | struct second_base { | 
|  | pod_in_11_only2 two; | 
|  | char foo; | 
|  | }; | 
|  |  | 
|  | struct might_use_tail_padding : public tail_padded_pod_in_11_only, public second_base { | 
|  | char may_go_into_tail_padding; | 
|  | }; | 
|  | SA(0, sizeof(might_use_tail_padding) == 32); | 
|  | } | 
|  |  | 
|  | namespace test7 { | 
|  | struct pod_in_11_only { | 
|  | private: | 
|  | long long x; | 
|  | }; | 
|  |  | 
|  | struct tail_padded_pod_in_11_only { | 
|  | pod_in_11_only pod11; | 
|  | pod_in_11_only pod12; | 
|  | char tail_padding; | 
|  | }; | 
|  |  | 
|  | struct might_use_tail_padding : public tail_padded_pod_in_11_only { | 
|  | char may_go_into_tail_padding; | 
|  | }; | 
|  |  | 
|  | SA(0, sizeof(might_use_tail_padding) == 24); | 
|  | } | 
|  |  | 
|  | namespace test8 { | 
|  | struct pod_in_11_only { | 
|  | private: | 
|  | long long x; | 
|  | }; | 
|  |  | 
|  | struct tail_padded_pod_in_11_only { | 
|  | pod_in_11_only pod11; | 
|  | char tail_padding; | 
|  | }; | 
|  |  | 
|  | struct another_layer { | 
|  | tail_padded_pod_in_11_only pod; | 
|  | char padding; | 
|  | }; | 
|  |  | 
|  | struct might_use_tail_padding : public another_layer { | 
|  | char may_go_into_tail_padding; | 
|  | }; | 
|  |  | 
|  | SA(0, sizeof(might_use_tail_padding) == 24); | 
|  | } | 
|  |  | 
|  | namespace test9 { | 
|  | struct pod_in_11_only { | 
|  | private: | 
|  | long long x; | 
|  | }; | 
|  |  | 
|  | struct tail_padded_pod_in_11_only { | 
|  | pod_in_11_only pod11; | 
|  | char tail_padding; | 
|  | }; | 
|  |  | 
|  | struct another_layer : tail_padded_pod_in_11_only { | 
|  | }; | 
|  |  | 
|  | struct might_use_tail_padding : public another_layer { | 
|  | char may_go_into_tail_padding; | 
|  | }; | 
|  |  | 
|  | SA(0, sizeof(might_use_tail_padding) == 16); | 
|  | } | 
|  |  | 
|  | namespace test10 { | 
|  | struct pod_in_11_only { | 
|  | private: | 
|  | long long x; | 
|  | }; | 
|  |  | 
|  | struct A { | 
|  | pod_in_11_only a; | 
|  | char apad; | 
|  | }; | 
|  |  | 
|  | struct B { | 
|  | char b; | 
|  | }; | 
|  |  | 
|  | struct C { | 
|  | pod_in_11_only c; | 
|  | char cpad; | 
|  | }; | 
|  |  | 
|  | struct D { | 
|  | char d; | 
|  | }; | 
|  |  | 
|  | struct might_use_tail_padding : public A, public B, public C, public D { | 
|  | }; | 
|  |  | 
|  | SA(0, sizeof(might_use_tail_padding) == 32); | 
|  | } | 
|  |  | 
|  | namespace test11 { | 
|  | struct pod_in_11_only { | 
|  | private: | 
|  | long long x; | 
|  | }; | 
|  |  | 
|  | struct A { | 
|  | pod_in_11_only a; | 
|  | char apad; | 
|  | }; | 
|  |  | 
|  | struct B { | 
|  | char b_pre; | 
|  | pod_in_11_only b; | 
|  | char bpad; | 
|  | }; | 
|  |  | 
|  | struct C { | 
|  | char c_pre; | 
|  | pod_in_11_only c; | 
|  | char cpad; | 
|  | }; | 
|  |  | 
|  | struct D { | 
|  | char d_pre; | 
|  | pod_in_11_only d; | 
|  | char dpad; | 
|  | }; | 
|  |  | 
|  | struct might_use_tail_padding : public A, public B, public C, public D { | 
|  | char m; | 
|  | }; | 
|  |  | 
|  | SA(0, sizeof(might_use_tail_padding) == 88); | 
|  | } | 
|  |  | 
|  | namespace test12 { | 
|  | struct pod_in_11_only { | 
|  | private: | 
|  | long long x; | 
|  | }; | 
|  |  | 
|  | struct A { | 
|  | pod_in_11_only a __attribute__((aligned(128))); | 
|  | }; | 
|  |  | 
|  | struct B { | 
|  | char bpad; | 
|  | }; | 
|  |  | 
|  | struct C { | 
|  | char cpad; | 
|  | }; | 
|  |  | 
|  | struct D { | 
|  | char dpad; | 
|  | }; | 
|  |  | 
|  | struct might_use_tail_padding : public A, public B, public C, public D { | 
|  | char m; | 
|  | }; | 
|  | SA(0, sizeof(might_use_tail_padding) == 128); | 
|  | } | 
|  |  | 
|  | namespace test13 { | 
|  | struct pod_in_11_only { | 
|  | private: | 
|  | long long x; | 
|  | }; | 
|  |  | 
|  | struct A { | 
|  | pod_in_11_only a; | 
|  | char apad; | 
|  | }; | 
|  |  | 
|  | struct B { | 
|  | }; | 
|  |  | 
|  | struct C { | 
|  | char c_pre; | 
|  | pod_in_11_only c; | 
|  | char cpad; | 
|  | }; | 
|  |  | 
|  | struct D { | 
|  | }; | 
|  |  | 
|  | struct might_use_tail_padding : public A, public B, public C, public D { | 
|  | char m; | 
|  | }; | 
|  | SA(0, sizeof(might_use_tail_padding) == 40); | 
|  | } | 
|  |  | 
|  | namespace test14 { | 
|  | struct pod_in_11_only { | 
|  | private: | 
|  | long long x; | 
|  | }; | 
|  |  | 
|  | struct A { | 
|  | pod_in_11_only a; | 
|  | char apad; | 
|  | }; | 
|  |  | 
|  | struct might_use_tail_padding : public A { | 
|  | struct { | 
|  | int : 0; | 
|  | } x; | 
|  | }; | 
|  | SA(0, sizeof(might_use_tail_padding) == 16); | 
|  | } | 
|  |  | 
|  | namespace test15 { | 
|  | struct pod_in_11_only { | 
|  | private: | 
|  | long long x; | 
|  | }; | 
|  |  | 
|  | struct A { | 
|  | pod_in_11_only a; | 
|  | char apad; | 
|  | }; | 
|  |  | 
|  | struct might_use_tail_padding : public A { | 
|  | struct { | 
|  | char a:1; | 
|  | char b:2; | 
|  | char c:2; | 
|  | char d:2; | 
|  | char e:1; | 
|  | } x; | 
|  | }; | 
|  | SA(0, sizeof(might_use_tail_padding) == 16); | 
|  | } | 
|  |  | 
|  | namespace test16 { | 
|  | struct pod_in_11_only { | 
|  | private: | 
|  | long long x; | 
|  | }; | 
|  |  | 
|  | struct A  { | 
|  | pod_in_11_only a; | 
|  | char apad; | 
|  | }; | 
|  |  | 
|  | struct B { | 
|  | char bpod; | 
|  | pod_in_11_only b; | 
|  | char bpad; | 
|  | }; | 
|  |  | 
|  | struct C : public A, public B { | 
|  | }; | 
|  |  | 
|  | struct D : public C { | 
|  | }; | 
|  |  | 
|  | struct might_use_tail_padding : public D { | 
|  | char m; | 
|  | }; | 
|  | SA(0, sizeof(might_use_tail_padding) == 40); | 
|  | } | 
|  |  | 
|  | namespace test17 { | 
|  | struct pod_in_11_only { | 
|  | private: | 
|  | long long x; | 
|  | }; | 
|  |  | 
|  | struct A { | 
|  | pod_in_11_only a __attribute__((aligned(512))); | 
|  | }; | 
|  |  | 
|  | struct B { | 
|  | char bpad; | 
|  | pod_in_11_only foo; | 
|  | char btail; | 
|  | }; | 
|  |  | 
|  | struct C { | 
|  | char cpad; | 
|  | }; | 
|  |  | 
|  | struct D { | 
|  | char dpad; | 
|  | }; | 
|  |  | 
|  | struct might_use_tail_padding : public A, public B, public C, public D { | 
|  | char a; | 
|  | }; | 
|  | SA(0, sizeof(might_use_tail_padding) == 512); | 
|  | } | 
|  |  | 
|  | namespace test18 { | 
|  | struct pod_in_11_only { | 
|  | private: | 
|  | long long x; | 
|  | }; | 
|  |  | 
|  | struct A  { | 
|  | pod_in_11_only a; | 
|  | char apad; | 
|  | }; | 
|  |  | 
|  | struct B { | 
|  | char bpod; | 
|  | pod_in_11_only b; | 
|  | char bpad; | 
|  | }; | 
|  |  | 
|  | struct A1  { | 
|  | pod_in_11_only a; | 
|  | char apad; | 
|  | }; | 
|  |  | 
|  | struct B1 { | 
|  | char bpod; | 
|  | pod_in_11_only b; | 
|  | char bpad; | 
|  | }; | 
|  |  | 
|  | struct C : public A, public B { | 
|  | }; | 
|  |  | 
|  | struct D : public A1, public B1 { | 
|  | }; | 
|  |  | 
|  | struct E : public D, public C { | 
|  | }; | 
|  |  | 
|  | struct F : public E { | 
|  | }; | 
|  |  | 
|  | struct might_use_tail_padding : public F { | 
|  | char m; | 
|  | }; | 
|  | SA(0, sizeof(might_use_tail_padding) == 80); | 
|  | } | 
|  | } // namespace PR16537 | 
|  |  | 
|  | namespace PR37275 { | 
|  | struct X { char c; }; | 
|  |  | 
|  | struct A { int n; }; | 
|  | _Static_assert(_Alignof(A) == _Alignof(int), ""); | 
|  |  | 
|  | // __attribute__((packed)) does not apply to base classes. | 
|  | struct __attribute__((packed)) B : X, A {}; | 
|  | #if defined(CLANG_ABI_COMPAT) && CLANG_ABI_COMPAT <= 6 | 
|  | _Static_assert(_Alignof(B) == 1, ""); | 
|  | _Static_assert(__builtin_offsetof(B, n) == 1, ""); | 
|  | #else | 
|  | _Static_assert(_Alignof(B) == _Alignof(int), ""); | 
|  | _Static_assert(__builtin_offsetof(B, n) == 4, ""); | 
|  | #endif | 
|  |  | 
|  | // #pragma pack does, though. | 
|  | #pragma pack(push, 2) | 
|  | struct C : X, A {}; | 
|  | _Static_assert(_Alignof(C) == 2, ""); | 
|  | _Static_assert(__builtin_offsetof(C, n) == 2, ""); | 
|  |  | 
|  | struct __attribute__((packed)) D : X, A {}; | 
|  | #if defined(CLANG_ABI_COMPAT) && CLANG_ABI_COMPAT <= 6 | 
|  | _Static_assert(_Alignof(D) == 1, ""); | 
|  | _Static_assert(__builtin_offsetof(D, n) == 1, ""); | 
|  | #else | 
|  | _Static_assert(_Alignof(D) == 2, ""); | 
|  | _Static_assert(__builtin_offsetof(D, n) == 2, ""); | 
|  | #endif | 
|  | #pragma pack(pop) | 
|  | } |