Skip to content

Partial pointers in padding can make const-eval fail #148470

Description

@theemathas

I'm not sure if this is a bug or not.

#![allow(unused)]

#[repr(C, align(16))]
#[derive(Clone, Copy)]
struct Thing {
    x: u128,
    y: u64,
    // Replace the above line with the below line to make it stop compiling
    // y: std::mem::MaybeUninit<u64>,
    // 8 bytes of padding here
}
#[derive(Clone, Copy)]
union PreservePad {
    thing: Thing,
    bytes: [u8; 32],
}

const A: Thing = unsafe {
    let mut buffer = [PreservePad { bytes: [0u8; 32] }; 2];
    (&raw mut buffer).cast::<&i32>().byte_add(28).write_unaligned(&1);
    buffer[0].thing
};

fn main() {}

The above code compiles fine, even in Miri. However, changing the y: u64line to y: std::mem::MaybeUninit<u64> causes the following compile error:

error[E0080]: unable to read parts of a pointer from memory at alloc4
  --> src/main.rs:21:5
   |
21 |     buffer[0].thing
   |     ^^^^^^^^^^^^^^^ evaluation of `A` failed here
   |
   = help: this code performed an operation that depends on the underlying bytes representing a pointer
   = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported

For more information about this error, try `rustc --explain E0080`.

It seems that copying Thing in consteval discards the padding if y is a u64, but copies the padding if y is a MaybeUninit<u64>. This is implemented in the compiler here and here.

Normally, this implementation detail is observable in user code only by, say, printing padding bytes after doing a copy, which is UB. However, the compiler also cares about the contents of padding bytes potentially containing pointer fragments, making the implementation detail observable in user code without invoking UB.

cc @RalfJung

Somewhat related to #147959 and #148259, but this issue doesn't depend on those two issues.

Meta

Reproducible on the playground with stable rust version 1.91.0

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-ABIArea: Concerning the application binary interface (ABI)A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)C-bugCategory: This is a bug.I-lang-radarItems that are on lang's radar and will need eventual work or consideration.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamT-opsemRelevant to the opsem team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions