Open
Description
Reduced example from rustlantis, which is accepted by Miri using Tree Borrows without optimizations enabled:
#![feature(custom_mir, core_intrinsics)]
#![allow(internal_features)]
use std::intrinsics::mir::*;
#[custom_mir(dialect = "runtime")]
fn main() {
mir!{
let _1;
let _2;
let _3;
{
_1 = 19;
Goto(bb1)
}
bb1 = {
match _1 {
19 => bb2,
_ => bb1,
}
}
bb2 = {
match _1 {
19 => bb3,
_ => bb1,
}
}
bb3 = {
_2 = _1;
_3 = &mut _1;
*_3 = _2;
_3 = &mut _2;
Return()
}
}
}
If I run this under Miri with -Zmir-enable-passes=+EarlyOtherwiseBranch
, I see:
error: Undefined Behavior: accessing a dead local variable
--> 9632589322447897120.rs:16:13
|
16 | / match _1 {
17 | | 19 => bb2,
18 | | _ => bb1,
19 | | }
| |_____________^ accessing a dead local variable
The MIR diff for EarlyOtherwiseBranch is:
fn main() -> () {
let mut _0: ();
let mut _1: i32;
let mut _2: i32;
let mut _3: &mut i32;
+ let mut _4: bool;
bb0: {
_1 = const 19_i32;
goto -> bb1;
}
bb1: {
- switchInt(copy _1) -> [19: bb2, otherwise: bb1];
+ StorageLive(_4);
+ _4 = Ne(copy _1, copy _1);
+ StorageDead(_4);
+ switchInt(move _4) -> [0: bb3, otherwise: bb1];
}
bb2: {
- switchInt(copy _1) -> [19: bb3, otherwise: bb1];
- }
-
- bb3: {
_2 = copy _1;
_3 = &mut _1;
(*_3) = copy _2;
_3 = &mut _2;
return;
}
+
+ bb3: {
+ StorageDead(_4);
+ switchInt(copy _1) -> [19: bb2, otherwise: bb1];
+ }
}
Metadata
Metadata
Assignees
Labels
Area: MIR optimizationsA miscompilation found by RustlantisCategory: This is a bug.Issue: Correct Rust code lowers to incorrect machine codeIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessMedium priorityRelevant to the compiler team, which will review and decide on the PR/issue.