Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unexpected alignment of repr(packed) struct containing a DST #2632

Closed
nicholasbishop opened this issue Oct 28, 2022 · 1 comment · Fixed by rust-lang/rust#103729
Closed

Comments

@nicholasbishop
Copy link

Example code (playground link)

#![feature(layout_for_ptr, ptr_metadata)]
use std::{mem, ptr};

#[repr(C, packed)]
struct A {
    f: u32,
}

#[repr(C, packed)]
struct B {
    f: [u32],
}

fn main() {
    let a = A { f: 0 };
    dbg!(mem::align_of_val(&a));

    let storage = [0u8; 4];
    let b: *const B = ptr::from_raw_parts(storage.as_ptr().cast(), 1);

    dbg!(unsafe { mem::align_of_val_raw(b) });
}

Running this outside of Miri gives the output I would expect; values of A and B both have an alignment of 1:

[src/main.rs:16] mem::align_of_val(&a) = 1
[src/main.rs:21] unsafe { mem::align_of_val_raw(b) } = 1

But when running under Miri, I get this instead:

[src/main.rs:16] mem::align_of_val(&a) = 1
[src/main.rs:21] unsafe { mem::align_of_val_raw(b) } = 4

I would have expected the alignment of B to be 1 since it is repr(packed). https://doc.rust-lang.org/nomicon/other-reprs.html#reprpacked says "repr(packed) forces Rust to strip any padding, and only align the type to a byte", and doesn't mention an exception for DSTs.

@RalfJung
Copy link
Member

Good catch! This indeed seems wrong.

Miri's logic for this is here. And it seems like that subtly differs from the codegen logic. The cranelift one is here and it does contain a special case for packed types. Cc @bjorn3

Looks like we really would want some way to share this code between all the backends and Miri...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants