llvm-project/clang/test/SemaCXX/class-layout.cpp

607 lines
10 KiB
C++

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