about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-01-25 16:59:26 +0100
committerGitHub <noreply@github.com>2019-01-25 16:59:26 +0100
commit7779bb9907c0a9f237bb99e5384c73ede9d0ba6e (patch)
treedcce9d65039b6035132d2b466b5cccfa87c9cec4 /src/test
parentef5a5bab7ac333746c693c76ecc4a76cd705739b (diff)
parent8e4c57fca2f4bae61f7b567e7c72f96245f385bc (diff)
downloadrust-7779bb9907c0a9f237bb99e5384c73ede9d0ba6e.tar.gz
rust-7779bb9907c0a9f237bb99e5384c73ede9d0ba6e.zip
Rollup merge of #57645 - nikomatsakis:issue-56877-abi-aggregates, r=eddyb
distinguish "no data" from "heterogeneous" in ABI

Ignore zero-sized types when computing whether something is a homogeneous aggregate, except be careful of VLA.

cc #56877

r? @arielb1
cc @eddyb
Diffstat (limited to 'src/test')
-rw-r--r--src/test/ui/layout/homogeneous-aggr-zero-sized-c-struct.rs36
-rw-r--r--src/test/ui/layout/homogeneous-aggr-zero-sized-c-struct.stderr14
-rw-r--r--src/test/ui/layout/homogeneous-aggr-zero-sized-repr-rust.rs73
-rw-r--r--src/test/ui/layout/homogeneous-aggr-zero-sized-repr-rust.stderr32
-rw-r--r--src/test/ui/layout/zero-sized-array-union.rs95
-rw-r--r--src/test/ui/layout/zero-sized-array-union.stderr26
6 files changed, 276 insertions, 0 deletions
diff --git a/src/test/ui/layout/homogeneous-aggr-zero-sized-c-struct.rs b/src/test/ui/layout/homogeneous-aggr-zero-sized-c-struct.rs
new file mode 100644
index 00000000000..622709e7de5
--- /dev/null
+++ b/src/test/ui/layout/homogeneous-aggr-zero-sized-c-struct.rs
@@ -0,0 +1,36 @@
+#![feature(rustc_attrs)]
+
+// Show that `homogeneous_aggregate` code ignores zero-length C
+// arrays.  This matches the recent C standard, though not the
+// behavior of all older compilers, which somtimes consider `T[0]` to
+// be a "flexible array member" (see discussion on #56877 for
+// details).
+
+#[repr(C)]
+pub struct Foo {
+    x: u32
+}
+
+#[repr(C)]
+pub struct Middle {
+    pub a: f32,
+    pub foo: [Foo; 0],
+    pub b: f32,
+}
+
+#[rustc_layout(homogeneous_aggregate)]
+pub type TestMiddle = Middle;
+//~^ ERROR homogeneous_aggregate: Homogeneous
+
+#[repr(C)]
+pub struct Final {
+    pub a: f32,
+    pub b: f32,
+    pub foo: [Foo; 0],
+}
+
+#[rustc_layout(homogeneous_aggregate)]
+pub type TestFinal = Final;
+//~^ ERROR homogeneous_aggregate: Homogeneous
+
+fn main() { }
diff --git a/src/test/ui/layout/homogeneous-aggr-zero-sized-c-struct.stderr b/src/test/ui/layout/homogeneous-aggr-zero-sized-c-struct.stderr
new file mode 100644
index 00000000000..0d442606351
--- /dev/null
+++ b/src/test/ui/layout/homogeneous-aggr-zero-sized-c-struct.stderr
@@ -0,0 +1,14 @@
+error: homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })
+  --> $DIR/homogeneous-aggr-zero-sized-c-struct.rs:22:1
+   |
+LL | pub type TestMiddle = Middle;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })
+  --> $DIR/homogeneous-aggr-zero-sized-c-struct.rs:33:1
+   |
+LL | pub type TestFinal = Final;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/layout/homogeneous-aggr-zero-sized-repr-rust.rs b/src/test/ui/layout/homogeneous-aggr-zero-sized-repr-rust.rs
new file mode 100644
index 00000000000..4b429412aeb
--- /dev/null
+++ b/src/test/ui/layout/homogeneous-aggr-zero-sized-repr-rust.rs
@@ -0,0 +1,73 @@
+#![feature(rustc_attrs)]
+
+// Regression test for #56877. We want to ensure that the presence of
+// `PhantomData` does not prevent `Bar` from being considered a
+// homogeneous aggregate.
+
+#[repr(C)]
+pub struct BaseCase {
+    pub a: f32,
+    pub b: f32,
+}
+
+#[repr(C)]
+pub struct WithPhantomData {
+    pub a: f32,
+    pub b: f32,
+    pub _unit: std::marker::PhantomData<()>,
+}
+
+pub struct EmptyRustStruct {
+}
+
+#[repr(C)]
+pub struct WithEmptyRustStruct {
+    pub a: f32,
+    pub b: f32,
+    pub _unit: EmptyRustStruct,
+}
+
+pub struct TransitivelyEmptyRustStruct {
+    field: EmptyRustStruct,
+    array: [u32; 0],
+}
+
+#[repr(C)]
+pub struct WithTransitivelyEmptyRustStruct {
+    pub a: f32,
+    pub b: f32,
+    pub _unit: TransitivelyEmptyRustStruct,
+}
+
+pub enum EmptyRustEnum {
+    Dummy,
+}
+
+#[repr(C)]
+pub struct WithEmptyRustEnum {
+    pub a: f32,
+    pub b: f32,
+    pub _unit: EmptyRustEnum,
+}
+
+#[rustc_layout(homogeneous_aggregate)]
+pub type Test1 = BaseCase;
+//~^ ERROR homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })
+
+#[rustc_layout(homogeneous_aggregate)]
+pub type Test2 = WithPhantomData;
+//~^ ERROR homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })
+
+#[rustc_layout(homogeneous_aggregate)]
+pub type Test3 = WithEmptyRustStruct;
+//~^ ERROR homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })
+
+#[rustc_layout(homogeneous_aggregate)]
+pub type Test4 = WithTransitivelyEmptyRustStruct;
+//~^ ERROR homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })
+
+#[rustc_layout(homogeneous_aggregate)]
+pub type Test5 = WithEmptyRustEnum;
+//~^ ERROR homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })
+
+fn main() { }
diff --git a/src/test/ui/layout/homogeneous-aggr-zero-sized-repr-rust.stderr b/src/test/ui/layout/homogeneous-aggr-zero-sized-repr-rust.stderr
new file mode 100644
index 00000000000..be04ba3e7f6
--- /dev/null
+++ b/src/test/ui/layout/homogeneous-aggr-zero-sized-repr-rust.stderr
@@ -0,0 +1,32 @@
+error: homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })
+  --> $DIR/homogeneous-aggr-zero-sized-repr-rust.rs:54:1
+   |
+LL | pub type Test1 = BaseCase;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })
+  --> $DIR/homogeneous-aggr-zero-sized-repr-rust.rs:58:1
+   |
+LL | pub type Test2 = WithPhantomData;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })
+  --> $DIR/homogeneous-aggr-zero-sized-repr-rust.rs:62:1
+   |
+LL | pub type Test3 = WithEmptyRustStruct;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })
+  --> $DIR/homogeneous-aggr-zero-sized-repr-rust.rs:66:1
+   |
+LL | pub type Test4 = WithTransitivelyEmptyRustStruct;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })
+  --> $DIR/homogeneous-aggr-zero-sized-repr-rust.rs:70:1
+   |
+LL | pub type Test5 = WithEmptyRustEnum;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 5 previous errors
+
diff --git a/src/test/ui/layout/zero-sized-array-union.rs b/src/test/ui/layout/zero-sized-array-union.rs
new file mode 100644
index 00000000000..68b218249eb
--- /dev/null
+++ b/src/test/ui/layout/zero-sized-array-union.rs
@@ -0,0 +1,95 @@
+#![feature(rustc_attrs)]
+
+// Various tests around the behavior of zero-sized arrays and
+// unions. This matches the behavior of modern C compilers, though
+// older compilers (and sometimes clang) treat `T[0]` as a "flexible
+// array member". See more
+// details in #56877.
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+struct Empty { }
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+struct Empty2 {
+    e: Empty
+}
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+struct Empty3 {
+    z: [f32; 0],
+}
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+struct Empty4 {
+    e: Empty3
+}
+
+#[repr(C)]
+union U1 {
+    s: Empty
+}
+
+#[repr(C)]
+union U2 {
+    s: Empty2
+}
+
+#[repr(C)]
+union U3 {
+    s: Empty3
+}
+
+#[repr(C)]
+union U4 {
+    s: Empty4
+}
+
+#[repr(C)]
+struct Baz1 {
+    x: f32,
+    y: f32,
+    u: U1,
+}
+
+#[rustc_layout(homogeneous_aggregate)]
+type TestBaz1 = Baz1;
+//~^ ERROR homogeneous_aggregate: Homogeneous
+
+#[repr(C)]
+struct Baz2 {
+    x: f32,
+    y: f32,
+    u: U2,
+}
+
+#[rustc_layout(homogeneous_aggregate)]
+type TestBaz2 = Baz2;
+//~^ ERROR homogeneous_aggregate: Homogeneous
+
+#[repr(C)]
+struct Baz3 {
+    x: f32,
+    y: f32,
+    u: U3,
+}
+
+#[rustc_layout(homogeneous_aggregate)]
+type TestBaz3 = Baz3;
+//~^ ERROR homogeneous_aggregate: Homogeneous
+
+#[repr(C)]
+struct Baz4 {
+    x: f32,
+    y: f32,
+    u: U4,
+}
+
+#[rustc_layout(homogeneous_aggregate)]
+type TestBaz4 = Baz4;
+//~^ ERROR homogeneous_aggregate: Homogeneous
+
+fn main() { }
diff --git a/src/test/ui/layout/zero-sized-array-union.stderr b/src/test/ui/layout/zero-sized-array-union.stderr
new file mode 100644
index 00000000000..1bb31aaf7b7
--- /dev/null
+++ b/src/test/ui/layout/zero-sized-array-union.stderr
@@ -0,0 +1,26 @@
+error: homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })
+  --> $DIR/zero-sized-array-union.rs:59:1
+   |
+LL | type TestBaz1 = Baz1;
+   | ^^^^^^^^^^^^^^^^^^^^^
+
+error: homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })
+  --> $DIR/zero-sized-array-union.rs:70:1
+   |
+LL | type TestBaz2 = Baz2;
+   | ^^^^^^^^^^^^^^^^^^^^^
+
+error: homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })
+  --> $DIR/zero-sized-array-union.rs:81:1
+   |
+LL | type TestBaz3 = Baz3;
+   | ^^^^^^^^^^^^^^^^^^^^^
+
+error: homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })
+  --> $DIR/zero-sized-array-union.rs:92:1
+   |
+LL | type TestBaz4 = Baz4;
+   | ^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
+