summaryrefslogtreecommitdiff
path: root/test/Layout
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2018-07-28 11:06:01 +0000
committerDimitry Andric <dim@FreeBSD.org>2018-07-28 11:06:01 +0000
commit486754660bb926339aefcf012a3f848592babb8b (patch)
treeecdbc446c9876f4f120f701c243373cd3cb43db3 /test/Layout
parent55e6d896ad333f07bb3b1ba487df214fc268a4ab (diff)
Notes
Diffstat (limited to 'test/Layout')
-rw-r--r--test/Layout/itanium-pack-and-align.cpp26
-rw-r--r--test/Layout/ms-x86-pack-and-align.cpp24
-rw-r--r--test/Layout/v6-empty.cpp20
-rw-r--r--test/Layout/watchos-standard-layout.cpp47
4 files changed, 105 insertions, 12 deletions
diff --git a/test/Layout/itanium-pack-and-align.cpp b/test/Layout/itanium-pack-and-align.cpp
new file mode 100644
index 000000000000..ac64979af33b
--- /dev/null
+++ b/test/Layout/itanium-pack-and-align.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm-only -fdump-record-layouts %s \
+// RUN: | FileCheck %s
+
+struct S {
+ char x;
+ int y;
+} __attribute__((packed, aligned(8)));
+
+struct alignas(8) T {
+ char x;
+ int y;
+} __attribute__((packed));
+
+S s;
+T t;
+// CHECK: 0 | struct T
+// CHECK-NEXT: 0 | char x
+// CHECK-NEXT: 1 | int y
+// CHECK-NEXT: | [sizeof=8, dsize=8, align=8,
+// CHECK-NEXT: | nvsize=8, nvalign=8]
+
+// CHECK: 0 | struct S
+// CHECK-NEXT: 0 | char x
+// CHECK-NEXT: 1 | int y
+// CHECK-NEXT: | [sizeof=8, dsize=8, align=8,
+// CHECK-NEXT: | nvsize=8, nvalign=8]
diff --git a/test/Layout/ms-x86-pack-and-align.cpp b/test/Layout/ms-x86-pack-and-align.cpp
index 958ee1958148..ccf8fac38e82 100644
--- a/test/Layout/ms-x86-pack-and-align.cpp
+++ b/test/Layout/ms-x86-pack-and-align.cpp
@@ -188,12 +188,12 @@ struct YA {
__declspec(align(32)) char : 1;
};
// CHECK: *** Dumping AST Record Layout
-// CHECK-NEXT: 0 | struct YA (empty)
+// CHECK-NEXT: 0 | struct YA
// CHECK-NEXT:0:0-0 | char
// CHECK-NEXT: | [sizeof=32, align=32
// CHECK-NEXT: | nvsize=32, nvalign=32]
// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64-NEXT: 0 | struct YA (empty)
+// CHECK-X64-NEXT: 0 | struct YA
// CHECK-X64-NEXT:0:0-0 | char
// CHECK-X64-NEXT: | [sizeof=32, align=32
// CHECK-X64-NEXT: | nvsize=32, nvalign=32]
@@ -206,14 +206,14 @@ struct YB {
// CHECK: *** Dumping AST Record Layout
// CHECK-NEXT: 0 | struct YB
// CHECK-NEXT: 0 | char a
-// CHECK-NEXT: 1 | struct YA b (empty)
+// CHECK-NEXT: 1 | struct YA b
// CHECK-NEXT:1:0-0 | char
// CHECK-NEXT: | [sizeof=33, align=1
// CHECK-NEXT: | nvsize=33, nvalign=1]
// CHECK-X64: *** Dumping AST Record Layout
// CHECK-X64-NEXT: 0 | struct YB
// CHECK-X64-NEXT: 0 | char a
-// CHECK-X64-NEXT: 1 | struct YA b (empty)
+// CHECK-X64-NEXT: 1 | struct YA b
// CHECK-X64-NEXT:1:0-0 | char
// CHECK-X64-NEXT: | [sizeof=33, align=1
// CHECK-X64-NEXT: | nvsize=33, nvalign=1]
@@ -223,12 +223,12 @@ struct YC {
__declspec(align(32)) char : 1;
};
// CHECK: *** Dumping AST Record Layout
-// CHECK-NEXT: 0 | struct YC (empty)
+// CHECK-NEXT: 0 | struct YC
// CHECK-NEXT:0:0-0 | char
// CHECK-NEXT: | [sizeof=32, align=32
// CHECK-NEXT: | nvsize=32, nvalign=32]
// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64-NEXT: 0 | struct YC (empty)
+// CHECK-X64-NEXT: 0 | struct YC
// CHECK-X64-NEXT: 0:0-0 | char
// CHECK-X64-NEXT: | [sizeof=8, align=32
// CHECK-X64-NEXT: | nvsize=8, nvalign=32]
@@ -241,14 +241,14 @@ struct YD {
// CHECK: *** Dumping AST Record Layout
// CHECK-NEXT: 0 | struct YD
// CHECK-NEXT: 0 | char a
-// CHECK-NEXT: 1 | struct YC b (empty)
+// CHECK-NEXT: 1 | struct YC b
// CHECK-NEXT:1:0-0 | char
// CHECK-NEXT: | [sizeof=33, align=1
// CHECK-NEXT: | nvsize=33, nvalign=1]
// CHECK-X64: *** Dumping AST Record Layout
// CHECK-X64-NEXT: 0 | struct YD
// CHECK-X64-NEXT: 0 | char a
-// CHECK-X64-NEXT: 1 | struct YC b (empty)
+// CHECK-X64-NEXT: 1 | struct YC b
// CHECK-X64-NEXT:1:0-0 | char
// CHECK-X64-NEXT: | [sizeof=9, align=1
// CHECK-X64-NEXT: | nvsize=9, nvalign=1]
@@ -258,12 +258,12 @@ struct YE {
__declspec(align(32)) char : 1;
};
// CHECK: *** Dumping AST Record Layout
-// CHECK-NEXT: 0 | struct YE (empty)
+// CHECK-NEXT: 0 | struct YE
// CHECK-NEXT: 0:0-0 | char
// CHECK-NEXT: | [sizeof=4, align=32
// CHECK-NEXT: | nvsize=4, nvalign=32]
// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64-NEXT: 0 | struct YE (empty)
+// CHECK-X64-NEXT: 0 | struct YE
// CHECK-X64-NEXT: 0:0-0 | char
// CHECK-X64-NEXT: | [sizeof=4, align=32
// CHECK-X64-NEXT: | nvsize=4, nvalign=32]
@@ -276,14 +276,14 @@ struct YF {
// CHECK: *** Dumping AST Record Layout
// CHECK-NEXT: 0 | struct YF
// CHECK-NEXT: 0 | char a
-// CHECK-NEXT: 1 | struct YE b (empty)
+// CHECK-NEXT: 1 | struct YE b
// CHECK-NEXT:1:0-0 | char
// CHECK-NEXT: | [sizeof=5, align=1
// CHECK-NEXT: | nvsize=5, nvalign=1]
// CHECK-X64: *** Dumping AST Record Layout
// CHECK-X64-NEXT: 0 | struct YF
// CHECK-X64-NEXT: 0 | char a
-// CHECK-X64-NEXT: 1 | struct YE b (empty)
+// CHECK-X64-NEXT: 1 | struct YE b
// CHECK-X64-NEXT:1:0-0 | char
// CHECK-X64-NEXT: | [sizeof=5, align=1
// CHECK-X64-NEXT: | nvsize=5, nvalign=1]
diff --git a/test/Layout/v6-empty.cpp b/test/Layout/v6-empty.cpp
new file mode 100644
index 000000000000..d43db8dc32ec
--- /dev/null
+++ b/test/Layout/v6-empty.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only -fclang-abi-compat=6 -triple x86_64-linux-gnu -fdump-record-layouts %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-V6
+// RUN: %clang_cc1 -fsyntax-only -fclang-abi-compat=7 -triple x86_64-linux-gnu -fdump-record-layouts %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-V7
+
+// In Clang 6 and before, we determined that Nonempty was empty, so we
+// applied EBO to it.
+struct Nonempty { int : 4; };
+struct A : Nonempty { int n; };
+int k = sizeof(A);
+
+// CHECK:*** Dumping AST Record Layout
+// CHECK: 0 | struct A
+// CHECK-V6-NEXT: 0 | struct Nonempty (base) (empty)
+// CHECK-V7-NEXT: 0 | struct Nonempty (base){{$}}
+// CHECK-NEXT: 0:0-3 | int
+// CHECK-V6-NEXT: 0 | int n
+// CHECK-V7-NEXT: 4 | int n
+// CHECK-V6-NEXT: | [sizeof=4, dsize=4, align=4,
+// CHECK-V6-NEXT: | nvsize=4, nvalign=4]
+// CHECK-V7-NEXT: | [sizeof=8, dsize=8, align=4,
+// CHECK-V7-NEXT: | nvsize=8, nvalign=4]
diff --git a/test/Layout/watchos-standard-layout.cpp b/test/Layout/watchos-standard-layout.cpp
new file mode 100644
index 000000000000..bd7bb1a434bd
--- /dev/null
+++ b/test/Layout/watchos-standard-layout.cpp
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -fsyntax-only -triple armv7k-apple-darwin-watchos -fdump-record-layouts %s | FileCheck %s
+
+// WatchOS, 64-bit iOS, and WebAssembly use the C++11 definition of POD to
+// determine whether we can reuse the tail padding of a struct (POD is
+// "trivially copyable and standard layout"). The definition of standard
+// layout changed some time around C++17; check that we still use the old
+// ABI rule.
+
+// B is not standard-layout, but it was under C++11's rule, so we pack
+// C::d into its tail padding anyway.
+struct A { int : 0; };
+struct B : A { int n; char c[3]; };
+struct C : B { char d; };
+int c = sizeof(C);
+static_assert(!__is_standard_layout(B));
+
+// CHECK:*** Dumping AST Record Layout
+// CHECK: 0 | struct C
+// CHECK-NEXT: 0 | struct B (base)
+// CHECK-NEXT: 0 | struct A (base) (empty)
+// CHECK-NEXT: 0:- | int
+// CHECK-NEXT: 0 | int n
+// CHECK-NEXT: 4 | char [3] c
+// CHECK-NEXT: 8 | char d
+// CHECK-NEXT: | [sizeof=12, dsize=9, align=4,
+// CHECK-NEXT: | nvsize=9, nvalign=4]
+
+// F is not standard-layout due to the repeated D base class, but it was under
+// C++11's rule, so we pack G::d into its tail padding anyway.
+struct D {};
+struct E : D {};
+struct F : D, E { int n; char c[3]; };
+struct G : F { G(const G&); char d; };
+int g = sizeof(G);
+static_assert(!__is_standard_layout(F));
+
+// CHECK:*** Dumping AST Record Layout
+// CHECK: 0 | struct G
+// CHECK-NEXT: 0 | struct F (base)
+// CHECK-NEXT: 0 | struct D (base) (empty)
+// CHECK-NEXT: 1 | struct E (base) (empty)
+// CHECK-NEXT: 1 | struct D (base) (empty)
+// CHECK-NEXT: 0 | int n
+// CHECK-NEXT: 4 | char [3] c
+// CHECK-NEXT: 8 | char d
+// CHECK-NEXT: | [sizeof=12, dsize=9, align=4,
+// CHECK-NEXT: | nvsize=9, nvalign=4]