diff options
| author | bors <bors@rust-lang.org> | 2023-12-14 07:19:07 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-12-14 07:19:07 +0000 |
| commit | 1a8afa0e748008708950e1a9ff62c598e2cfb3ea (patch) | |
| tree | 7ceeff47da477f9eca5cb3be5e318143ea21a83c /src | |
| parent | d23e1a689426638a5146c204e09278433c509610 (diff) | |
| parent | 7e4c4271f44055b4dbd6f09aad19624254d67f22 (diff) | |
| download | rust-1a8afa0e748008708950e1a9ff62c598e2cfb3ea.tar.gz rust-1a8afa0e748008708950e1a9ff62c598e2cfb3ea.zip | |
Auto merge of #118538 - RalfJung:size-of-val-comments, r=WaffleLapkin
fix dynamic size/align computation logic for packed types with dyn trait tail This logic was never updated to support `packed(N)` where `N > 1`, and it turns out to be wrong for that case. Fixes https://github.com/rust-lang/rust/issues/80925 `@bjorn3` I have not looked at cranelift; I assume it basically copied the size-of-val logic and hence could use much the same patch.
Diffstat (limited to 'src')
| -rw-r--r-- | src/tools/miri/tests/pass/packed-struct-dyn-trait.rs | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/src/tools/miri/tests/pass/packed-struct-dyn-trait.rs b/src/tools/miri/tests/pass/packed-struct-dyn-trait.rs new file mode 100644 index 00000000000..bb73c26c18a --- /dev/null +++ b/src/tools/miri/tests/pass/packed-struct-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<T: ?Sized>(u8, core::mem::ManuallyDrop<T>); + + let p = Packed(0, core::mem::ManuallyDrop::new(1)); + let p: &Packed<usize> = &p; + let sized = (core::mem::size_of_val(p), core::mem::align_of_val(p)); + let sized_offset = unsafe { addr_of!(p.1).cast::<u8>().offset_from(addr_of!(p.0)) }; + let p: &Packed<dyn Send> = 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::<u8>().offset_from(addr_of!(p.0)) }; + assert_eq!(sized, un_sized); + assert_eq!(sized_offset, un_sized_offset); +} |
