diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2019-01-25 16:59:26 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-01-25 16:59:26 +0100 |
| commit | 7779bb9907c0a9f237bb99e5384c73ede9d0ba6e (patch) | |
| tree | dcce9d65039b6035132d2b466b5cccfa87c9cec4 /src/test | |
| parent | ef5a5bab7ac333746c693c76ecc4a76cd705739b (diff) | |
| parent | 8e4c57fca2f4bae61f7b567e7c72f96245f385bc (diff) | |
| download | rust-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')
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 + |
