607 lines
10 KiB
C++
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)
|
||
|
}
|