From 9918693037dce8aa4bb6f08741b6812923486c18 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 19 Jun 2024 11:26:03 +0200 Subject: Merging upstream version 1.76.0+dfsg1. Signed-off-by: Daniel Baumann --- tests/ui/packed/dyn-trait.rs | 21 ++++++++++++ tests/ui/packed/issue-118537-field-offset-ice.rs | 39 ++++++++++++++++++++++ tests/ui/packed/issue-118537-field-offset.rs | 36 ++++++++++++++++++++ tests/ui/packed/issue-27060-2.stderr | 2 +- .../packed-struct-borrow-element-64bit.stderr | 2 +- tests/ui/packed/packed-struct-generic-transmute.rs | 27 +++++++++++++++ .../packed/packed-struct-generic-transmute.stderr | 12 +++++++ tests/ui/packed/packed-struct-transmute.rs | 29 ++++++++++++++++ tests/ui/packed/packed-struct-transmute.stderr | 12 +++++++ 9 files changed, 178 insertions(+), 2 deletions(-) create mode 100644 tests/ui/packed/dyn-trait.rs create mode 100644 tests/ui/packed/issue-118537-field-offset-ice.rs create mode 100644 tests/ui/packed/issue-118537-field-offset.rs create mode 100644 tests/ui/packed/packed-struct-generic-transmute.rs create mode 100644 tests/ui/packed/packed-struct-generic-transmute.stderr create mode 100644 tests/ui/packed/packed-struct-transmute.rs create mode 100644 tests/ui/packed/packed-struct-transmute.stderr (limited to 'tests/ui/packed') diff --git a/tests/ui/packed/dyn-trait.rs b/tests/ui/packed/dyn-trait.rs new file mode 100644 index 000000000..bb73c26c1 --- /dev/null +++ b/tests/ui/packed/dyn-trait.rs @@ -0,0 +1,21 @@ +// run-pass +use std::ptr::addr_of; + +// When the unsized tail is a `dyn Trait`, its alignments is only dynamically known. This means the +// packed(2) needs to be applied at runtime: the actual alignment of the field is `min(2, +// usual_alignment)`. Here we check that we do this right by comparing size, alignment, and field +// offset before and after unsizing. +fn main() { + #[repr(C, packed(2))] + struct Packed(u8, core::mem::ManuallyDrop); + + let p = Packed(0, core::mem::ManuallyDrop::new(1)); + let p: &Packed = &p; + let sized = (core::mem::size_of_val(p), core::mem::align_of_val(p)); + let sized_offset = unsafe { addr_of!(p.1).cast::().offset_from(addr_of!(p.0)) }; + let p: &Packed = p; + let un_sized = (core::mem::size_of_val(p), core::mem::align_of_val(p)); + let un_sized_offset = unsafe { addr_of!(p.1).cast::().offset_from(addr_of!(p.0)) }; + assert_eq!(sized, un_sized); + assert_eq!(sized_offset, un_sized_offset); +} diff --git a/tests/ui/packed/issue-118537-field-offset-ice.rs b/tests/ui/packed/issue-118537-field-offset-ice.rs new file mode 100644 index 000000000..657aec640 --- /dev/null +++ b/tests/ui/packed/issue-118537-field-offset-ice.rs @@ -0,0 +1,39 @@ +// run-pass +#![feature(layout_for_ptr)] +use std::mem; + +#[repr(packed(4))] +struct Slice([u32]); + +#[repr(packed(2), C)] +struct PackedSized { + f: u8, + d: [u32; 4], +} + +#[repr(packed(2), C)] +struct PackedUnsized { + f: u8, + d: Slice, +} + +impl PackedSized { + fn unsize(&self) -> &PackedUnsized { + // We can't unsize via a generic type since then we get the error + // that packed structs with unsized tail don't work if the tail + // might need dropping. + let len = 4usize; + unsafe { mem::transmute((self, len)) } + } +} + +fn main() { unsafe { + let p = PackedSized { f: 0, d: [1, 2, 3, 4] }; + let p = p.unsize() as *const PackedUnsized; + // Make sure the size computation correctly adds exact 1 byte of padding + // in front of the `d` field. + assert_eq!(mem::size_of_val_raw(p), 1 + 1 + 4*4); + // And likewise for the offset computation. + let d = std::ptr::addr_of!((*p).d); + assert_eq!(d.cast::().read_unaligned(), 1); +} } diff --git a/tests/ui/packed/issue-118537-field-offset.rs b/tests/ui/packed/issue-118537-field-offset.rs new file mode 100644 index 000000000..cd17f7679 --- /dev/null +++ b/tests/ui/packed/issue-118537-field-offset.rs @@ -0,0 +1,36 @@ +// run-pass +#![feature(layout_for_ptr)] +use std::mem; + +#[repr(packed, C)] +struct PackedSized { + f: u8, + d: [u32; 4], +} + +#[repr(packed, C)] +struct PackedUnsized { + f: u8, + d: [u32], +} + +impl PackedSized { + fn unsize(&self) -> &PackedUnsized { + // We can't unsize via a generic type since then we get the error + // that packed structs with unsized tail don't work if the tail + // might need dropping. + let len = 4usize; + unsafe { mem::transmute((self, len)) } + } +} + +fn main() { unsafe { + let p = PackedSized { f: 0, d: [1, 2, 3, 4] }; + let p = p.unsize() as *const PackedUnsized; + // Make sure the size computation does *not* think there is + // any padding in front of the `d` field. + assert_eq!(mem::size_of_val_raw(p), 1 + 4*4); + // And likewise for the offset computation. + let d = std::ptr::addr_of!((*p).d); + assert_eq!(d.cast::().read_unaligned(), 1); +} } diff --git a/tests/ui/packed/issue-27060-2.stderr b/tests/ui/packed/issue-27060-2.stderr index cf5f4e530..7ee732217 100644 --- a/tests/ui/packed/issue-27060-2.stderr +++ b/tests/ui/packed/issue-27060-2.stderr @@ -22,6 +22,6 @@ help: the `Box` type always has a statically known size and allocates its conten LL | data: Box, | ++++ + -error: aborting due to previous error +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/packed/packed-struct-borrow-element-64bit.stderr b/tests/ui/packed/packed-struct-borrow-element-64bit.stderr index 57630a4b4..a464b1893 100644 --- a/tests/ui/packed/packed-struct-borrow-element-64bit.stderr +++ b/tests/ui/packed/packed-struct-borrow-element-64bit.stderr @@ -8,6 +8,6 @@ LL | let brw = &foo.baz; = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) -error: aborting due to previous error +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0793`. diff --git a/tests/ui/packed/packed-struct-generic-transmute.rs b/tests/ui/packed/packed-struct-generic-transmute.rs new file mode 100644 index 000000000..c6264b6d2 --- /dev/null +++ b/tests/ui/packed/packed-struct-generic-transmute.rs @@ -0,0 +1,27 @@ +// This assumes the packed and non-packed structs are different sizes. + +// the error points to the start of the file, not the line with the +// transmute + +// error-pattern: cannot transmute between types of different sizes, or dependently-sized types + +use std::mem; + +#[repr(packed)] +struct Foo { + bar: T, + baz: S +} + +struct Oof { + rab: T, + zab: S +} + +fn main() { + let foo = Foo { bar: [1u8, 2, 3, 4, 5], baz: 10i32 }; + unsafe { + let oof: Oof<[u8; 5], i32> = mem::transmute(foo); + println!("{:?} {:?}", &oof.rab[..], oof.zab); + } +} diff --git a/tests/ui/packed/packed-struct-generic-transmute.stderr b/tests/ui/packed/packed-struct-generic-transmute.stderr new file mode 100644 index 000000000..e91f49884 --- /dev/null +++ b/tests/ui/packed/packed-struct-generic-transmute.stderr @@ -0,0 +1,12 @@ +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/packed-struct-generic-transmute.rs:24:38 + | +LL | let oof: Oof<[u8; 5], i32> = mem::transmute(foo); + | ^^^^^^^^^^^^^^ + | + = note: source type: `Foo<[u8; 5], i32>` (72 bits) + = note: target type: `Oof<[u8; 5], i32>` (96 bits) + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0512`. diff --git a/tests/ui/packed/packed-struct-transmute.rs b/tests/ui/packed/packed-struct-transmute.rs new file mode 100644 index 000000000..a7d284025 --- /dev/null +++ b/tests/ui/packed/packed-struct-transmute.rs @@ -0,0 +1,29 @@ +// This assumes the packed and non-packed structs are different sizes. + +// the error points to the start of the file, not the line with the +// transmute + +// normalize-stderr-test "\d+ bits" -> "N bits" +// error-pattern: cannot transmute between types of different sizes, or dependently-sized types + +use std::mem; + +#[repr(packed)] +struct Foo { + bar: u8, + baz: usize +} + +#[derive(Debug)] +struct Oof { + rab: u8, + zab: usize +} + +fn main() { + let foo = Foo { bar: 1, baz: 10 }; + unsafe { + let oof: Oof = mem::transmute(foo); + println!("{:?}", oof); + } +} diff --git a/tests/ui/packed/packed-struct-transmute.stderr b/tests/ui/packed/packed-struct-transmute.stderr new file mode 100644 index 000000000..4d75820e9 --- /dev/null +++ b/tests/ui/packed/packed-struct-transmute.stderr @@ -0,0 +1,12 @@ +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/packed-struct-transmute.rs:26:24 + | +LL | let oof: Oof = mem::transmute(foo); + | ^^^^^^^^^^^^^^ + | + = note: source type: `Foo` (N bits) + = note: target type: `Oof` (N bits) + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0512`. -- cgit v1.2.3