Skip to content

EarlyOtherwiseBranch can insert storage markers incorrectly, creating use of a dead local #141212

Open
@saethlin

Description

@saethlin

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

A-mir-optArea: MIR optimizationsA-rustlantisA miscompilation found by RustlantisC-bugCategory: This is a bug.I-miscompileIssue: Correct Rust code lowers to incorrect machine codeI-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-mediumMedium priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions