-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Closed
Labels
A-layoutArea: Memory layout of typesArea: Memory layout of typesC-bugCategory: This is a bug.Category: This is a bug.I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-mediumMedium priorityMedium priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Description
This code panics, but it should not:
use std::mem;
struct Slice([u32]);
#[repr(packed, C)]
struct PackedSized {
f: u8,
d: [u32; 4],
}
#[repr(packed, 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;
let d = std::ptr::addr_of!((*p).d);
assert_eq!(d.cast::<u32>().read_unaligned(), 1);
} }
The panic disappears when the Newtype
is inlined (because then we hit a different code path in this match).
What happens here is a bug in the logic that computes the offset of d
: since it is an unsized field, the offset is computed dynamically, by taking the statically known offset and then rounding it up to the dynamic alignment of the field. However, since the struct is packed, we need to cap the dynamic alignment of the field to the packing of the surrounding struct -- which we currently do not do. This is just yet another case where the non-compositional nature of repr(packed)
is causing issues...
Metadata
Metadata
Assignees
Labels
A-layoutArea: Memory layout of typesArea: Memory layout of typesC-bugCategory: This is a bug.Category: This is a bug.I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-mediumMedium priorityMedium priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.