Skip to content

miri happily dereferences *const ! and continues #157

Closed
@oli-obk

Description

@oli-obk

Regression after rust-lang/rust#40224

The MIR of the following code used to include an unreachable statement

#![feature(never_type)]
#![allow(unreachable_code)]

fn main() {
    let y = &5;
    let x: ! = unsafe {
        *(y as *const _ as *const !) //~ ERROR entered unreachable code
    };
    f(x)
}

fn f(x: !) -> ! { x }

old MIR:

fn f(_1: !) -> ! {
    let mut _0: !;                       // return pointer
    scope 1 {
        let _2: !;                       // "x" in scope 1 at <anon>:12:6: 12:7
    }
    let mut _3: !;

    bb0: {
        StorageLive(_2);                 // scope 0 at <anon>:12:6: 12:7
        _2 = _1;                         // scope 0 at <anon>:12:6: 12:7
        _3 = _2;                         // scope 1 at <anon>:12:19: 12:20
        unreachable;                     // scope 1 at <anon>:12:19: 12:20
    }
}

fn main() -> () {
    let mut _0: ();                      // return pointer
    scope 1 {
        let _1: &i32;                    // "y" in scope 1 at <anon>:5:9: 5:10
        scope 2 {
            let _3: !;                   // "x" in scope 2 at <anon>:6:9: 6:10
        }
    }
    let mut _2: i32;
    let mut _4: !;
    let mut _5: *const !;
    let mut _6: *const i32;
    let mut _7: *const i32;
    let mut _8: &i32;
    let mut _9: !;
    let mut _10: !;
    let mut _11: !;

    bb0: {
        StorageLive(_1);                 // scope 0 at <anon>:5:9: 5:10
        _1 = promoted0;                  // scope 0 at <anon>:5:13: 5:15
        StorageLive(_3);                 // scope 1 at <anon>:6:9: 6:10
        StorageLive(_5);                 // scope 1 at <anon>:7:10: 7:37
        StorageLive(_6);                 // scope 1 at <anon>:7:11: 7:24
        StorageLive(_7);                 // scope 1 at <anon>:7:11: 7:12
        StorageLive(_8);                 // scope 1 at <anon>:7:11: 7:12
        _8 = &(*_1);                     // scope 1 at <anon>:7:11: 7:12
        _7 = _8 as *const i32 (Misc);    // scope 1 at <anon>:7:11: 7:12
        StorageDead(_8);                 // scope 1 at <anon>:7:12: 7:12
        _6 = _7;                         // scope 1 at <anon>:7:11: 7:24
        StorageDead(_7);                 // scope 1 at <anon>:7:24: 7:24
        _5 = _6 as *const ! (Misc);      // scope 1 at <anon>:7:10: 7:37
        StorageDead(_6);                 // scope 1 at <anon>:7:37: 7:37
        _4 = (*_5);                      // scope 1 at <anon>:7:9: 7:37
        unreachable;                     // scope 1 at <anon>:7:9: 7:37
    }
}

promoted0 in main: &i32 = {
    let mut _0: &i32;                    // return pointer
    let mut _1: i32;

    bb0: {
        _1 = const 5i32;                 // scope 0 at <anon>:5:14: 5:15
        _0 = &_1;                        // scope 0 at <anon>:5:13: 5:15
        return;                          // scope 0 at <anon>:5:13: 5:15
    }
}

new trace:

    Finished dev [unoptimized + debuginfo] target(s) in 0.11 secs
     Running `target/debug/miri tests/compile-fail/never_say_never.rs`
TRACE:miri::eval_context: load mir Item(DefId { krate: CrateNum(0), node: DefIndex(3) => never_say_never/4089d7c8b778d88cec885baf7b69e6df-exe::main[0] })
TRACE:miri::step:  StorageLive(_1)
TRACE:miri::step:  pushing stack frame for promoted0
TRACE:miri::step:   _1 = const 5i32
TRACE:miri::eval_context:   _1: Undef
TRACE:miri::eval_context:   _1: Bytes(5)
TRACE:miri::step:   _0 = &_1
TRACE:miri::eval_context:   _1: Bytes(5)
TRACE:miri::step:   return
TRACE:miri::memory:  mark_static_initialized AllocId(2), mutable: false
TRACE:miri::eval_context:  deallocating local
TRACE:miri::memory:  Alloc 2:    05 00 00 00 (4 bytes) (immutable)
TRACE:miri::step:  // bb0
TRACE:miri::step:  _1 = promoted0
TRACE:miri::eval_context:  _1: Undef
TRACE:miri::eval_context:  _1: Ptr(Pointer { alloc_id: AllocId(2), offset: 0 })
TRACE:miri::memory:  Alloc 2:    05 00 00 00 (4 bytes) (immutable)
TRACE:miri::step:  StorageLive(_2)
TRACE:miri::step:  StorageLive(_4)
TRACE:miri::step:  StorageLive(_5)
TRACE:miri::step:  StorageLive(_6)
TRACE:miri::step:  StorageLive(_7)
TRACE:miri::step:  _7 = &(*_1)
TRACE:miri::eval_context:  _7: Undef
TRACE:miri::eval_context:  _1: Ptr(Pointer { alloc_id: AllocId(2), offset: 0 })
TRACE:miri::memory:  Alloc 2:    05 00 00 00 (4 bytes) (immutable)
TRACE:miri::lvalue:  deref to i32 on ByVal(Ptr(Pointer { alloc_id: AllocId(2), offset: 0 }))
TRACE:miri::eval_context:  _7: Ptr(Pointer { alloc_id: AllocId(2), offset: 0 })
TRACE:miri::memory:  Alloc 2:    05 00 00 00 (4 bytes) (immutable)
TRACE:miri::step:  _6 = _7 as *const i32 (Misc)
TRACE:miri::eval_context:  _6: Undef
TRACE:miri::eval_context:  _7: Ptr(Pointer { alloc_id: AllocId(2), offset: 0 })
TRACE:miri::memory:  Alloc 2:    05 00 00 00 (4 bytes) (immutable)
TRACE:miri::eval_context:  _6: Ptr(Pointer { alloc_id: AllocId(2), offset: 0 })
TRACE:miri::memory:  Alloc 2:    05 00 00 00 (4 bytes) (immutable)
TRACE:miri::step:  StorageDead(_7)
TRACE:miri::step:  _5 = _6
TRACE:miri::eval_context:  _5: Undef
TRACE:miri::eval_context:  _6: Ptr(Pointer { alloc_id: AllocId(2), offset: 0 })
TRACE:miri::memory:  Alloc 2:    05 00 00 00 (4 bytes) (immutable)
TRACE:miri::eval_context:  _5: Ptr(Pointer { alloc_id: AllocId(2), offset: 0 })
TRACE:miri::memory:  Alloc 2:    05 00 00 00 (4 bytes) (immutable)
TRACE:miri::step:  StorageDead(_6)
TRACE:miri::step:  _4 = _5 as *const ! (Misc)
TRACE:miri::eval_context:  _4: Undef
TRACE:miri::eval_context:  _5: Ptr(Pointer { alloc_id: AllocId(2), offset: 0 })
TRACE:miri::memory:  Alloc 2:    05 00 00 00 (4 bytes) (immutable)
TRACE:miri::eval_context:  _4: Ptr(Pointer { alloc_id: AllocId(2), offset: 0 })
TRACE:miri::memory:  Alloc 2:    05 00 00 00 (4 bytes) (immutable)
TRACE:miri::step:  StorageDead(_5)
TRACE:miri::step:  _3 = (*_4)
TRACE:miri::eval_context:  _3: Undef
TRACE:miri::eval_context:  _4: Ptr(Pointer { alloc_id: AllocId(2), offset: 0 })
TRACE:miri::memory:  Alloc 2:    05 00 00 00 (4 bytes) (immutable)
TRACE:miri::lvalue:  deref to ! on ByVal(Ptr(Pointer { alloc_id: AllocId(2), offset: 0 }))
TRACE:miri::eval_context:  _3:
TRACE:miri::step:  _2 = _3
TRACE:miri::eval_context:  _2: Undef
TRACE:miri::eval_context:  _3:
TRACE:miri::eval_context:  _2:
TRACE:miri::step:  StorageDead(_3)
TRACE:miri::step:  StorageDead(_4)
TRACE:miri::step:  _8 = _2
TRACE:miri::eval_context:  _8: Undef
TRACE:miri::eval_context:  _2:
TRACE:miri::eval_context:  _8:
TRACE:miri::step:  const f(_8)
DEBUG:miri::eval_context: resolve(def_id=DefId { krate: CrateNum(0), node: DefIndex(4) => never_say_never/4089d7c8b778d88cec885baf7b69e6df-exe::f[0] }, substs=Slice([]))
DEBUG:miri::eval_context: apply_param_substs(param_substs=Slice([]), value=fn(!) -> ! {f})
DEBUG:miri::eval_context:  => free item
DEBUG:miri::eval_context: resolve(def_id=DefId { krate: CrateNum(0), node: DefIndex(4) => never_say_never/4089d7c8b778d88cec885baf7b69e6df-exe::f[0] }, substs=Slice([])) = f
TRACE:miri::terminator:  eval_fn_call: Instance {
    def: Item(
        DefId { krate: CrateNum(0), node: DefIndex(4) => never_say_never/4089d7c8b778d88cec885baf7b69e6df-exe::f[0] }
    ),
    substs: Slice(
        []
    )
}
TRACE:miri::eval_context:  _8:
TRACE:miri::terminator:  eval_fn_call_inner: Instance {
    def: Item(
        DefId { krate: CrateNum(0), node: DefIndex(4) => never_say_never/4089d7c8b778d88cec885baf7b69e6df-exe::f[0] }
    ),
    substs: Slice(
        []
    )
}, None
TRACE:miri::eval_context:  load mir Item(DefId { krate: CrateNum(0), node: DefIndex(4) => never_say_never/4089d7c8b778d88cec885baf7b69e6df-exe::f[0] })
TRACE:miri::terminator:   ABI: Rust
TRACE:miri::terminator:   arg_locals: [_1]
TRACE:miri::terminator:   arg_operands: [_8]
TRACE:miri::eval_context:   _1: Undef
TRACE:miri::step:   // bb0
TRACE:miri::step:   StorageLive(_2)
TRACE:miri::step:   _2 = _1
TRACE:miri::eval_context:   _2: Undef
TRACE:miri::eval_context:   _1:
TRACE:miri::eval_context:   _2:
TRACE:miri::step:   _3 = _2
TRACE:miri::eval_context:   _3: Undef
TRACE:miri::eval_context:   _2:
TRACE:miri::eval_context:   _3:
TRACE:miri::step:   _0 = _3
TRACE:miri::eval_context:   _3:
TRACE:miri::step:   StorageDead(_3)
TRACE:miri::step:   StorageDead(_2)
TRACE:miri::step:   return
TRACE:miri::eval_context:  deallocating local
TRACE:miri::eval_context:  deallocating local
TRACE:miri::eval_context:  deallocating local
TRACE:miri::step:  // bb0
TRACE:miri::step:  const f(_8)

infinite loop from here on

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions