| // 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) |
| } |