Skip to content

Feature request: more information in enum layout #1046

@N1ark

Description

@N1ark

TL;DR: Charon needs more information regarding niche layouts, as otherwise we cannot reliably compute whether a tag is valid

The current information Charon outputs for an enum layout is actually not sufficient to detect some fun cases of UB reliably. I discovered this through this miri test.

In particular it has this enum:

enum Foo {
    Var1,       // variant 0, tag 2
    Var2(bool), // variant 1, untagged (valid values are 0=false and 1=true)
    Var3,       // variant 2, tag 4
}

And then does this:

let invalid: Foo = mem::transmute(3u8);
assert!(matches!(invalid, Foo::Var2(_)));

Although line 1 is UB with validity checks, Miri allows disabling those, in which case instead we get UB on line 2 for a different reason:

  • the niche_variants range of the enum (which variants are niches) is 0..=2 (it includes 1, but 1 is the untagged variant)
  • however using 3 is not valid, and is verified in const-eval by these lines
    https://github.com/rust-lang/rust/blob/1b7d722f429f09c87b08b757d89c689c6cf7f6e7/compiler/rustc_const_eval/src/interpret/discriminant.rs#L177-L181
  • basically, we're in the niche range (0..=2) but we're using the untagged variant (1), so it's invalid
  • however Charon currently only exports the fact variant 1 is niched and that variants 0 and 2 have tags 2 and 4 respectively; there is no information on what the niche range is; as such the only way to detect this UB is by deserialising the whole value with validity checks, which is "too much work", we should be able to detect it earlier.

The solution to this is extending TagEncoding::Niche to include the niche_variants range and niche_start, enabling client to reproduce the const-eval calculation of tags.

cc @firefighterduck this might be of interest to you :3

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions