mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-07 17:18:32 +03:00
5999ec3328
miri: make read_discriminant UB when the tag is not in the validity range of the tag field
Arguably, reading an enum discriminant is an operation that uses the "type" of the discriminant field -- and therefore it should fail when the value in that field isn't valid at that type. Therefore, code like this should be UB:
```rust
fn main() {
unsafe {
let x = 12u8;
let x_ptr: *const u8 = &x;
let cast_ptr = x_ptr as *const Option<bool>;
// Reading the discriminant should fail since the tag value is not in the valid
// range for the tag field.
let _val = matches!(*cast_ptr, None);
//~^ ERROR: invalid tag
}
}
```
However, Miri currently sees no UB here. (MiniRust does see UB.) This is because we never actually check whether the tag we read is in the validity range for its field. So let's add such a check, and a corresponding test.
In fact, we have to do this check, since the codegen backend adds range metadata on the discriminant load, as can be seen in [this example](https://play.rust-lang.org/?version=stable&mode=release&edition=2024&gist=02ef5e80fdfe61540e44198dd827b630). In other words, the above code has UB in LLVM IR but not in Miri, which is a critical Miri bug.