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