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

C-repr enums are too aggressively checked for validity #2688

Closed
spectria-limina opened this issue Nov 22, 2022 · 4 comments
Closed

C-repr enums are too aggressively checked for validity #2688

spectria-limina opened this issue Nov 22, 2022 · 4 comments
Labels
C-support Category: Not necessarily a bug, but someone asking for support

Comments

@spectria-limina
Copy link

See https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=d382170468c9e33175776afb6e9c3df3

#[repr(u8)] #[derive(Copy, Clone)] enum One { One(u8) }

fn main() {
    let one= [1u8;2];
    unsafe {std::mem::transmute::<_, One>(one)};
}

Gives the error:

error: Undefined Behavior: constructing invalid value at .<enum-tag>: encountered 0x01, but expected a valid enum tag
 --> src/main.rs:5:13
  |
5 |     unsafe {std::mem::transmute::<_, One>(one)};
  |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-tag>: encountered 0x01, but expected a valid enum tag
  |
  = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
  = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
  = note: BACKTRACE:
  = note: inside `main` at src/main.rs:5:13

note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace

But per RFC 2195, this is valid:

For both layouts, it is defined for Rust programs to cast/reinterpret/transmute such an enum into the equivalent Repr definition. Separately manipulating the tag and payload is also defined. The tag and payload need only be in a consistent/initialized state when the value is matched on (which includes Dropping it).

@RalfJung
Copy link
Member

RalfJung commented Nov 22, 2022

I'm afraid the RFC is outdated. It predates our understanding that even unused data must be valid.

RFCs generally document the consensus at the time, but are not updated when things change later. The Reference is the source for current information, though it is unfortunately rather incomplete on unsafe code details. That is something we are working on, but writing a proper spec takes time. The reference however is pretty clear on this particular topic, see "producing an invalid value" on the UB page.

@RalfJung RalfJung added the C-support Category: Not necessarily a bug, but someone asking for support label Nov 22, 2022
@RalfJung
Copy link
Member

Thanks for the report though! It's good to know that we have an RFC that contradicts today's understanding of validity invariants. I'm bringing this up for discussion in Zulip, too.

@RalfJung
Copy link
Member

Note that the parse_my_enum_from example in the RFC is actually fine under the current understanding of the rules, though this is somewhat pending on rust-lang/unsafe-code-guidelines#84.

@RalfJung
Copy link
Member

Closing as there's no bug in Miri here, just an outdated/confusing RFC.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-support Category: Not necessarily a bug, but someone asking for support
Projects
None yet
Development

No branches or pull requests

2 participants