Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

miri happily dereferences *const ! and continues #157

Closed
oli-obk opened this issue Mar 31, 2017 · 7 comments
Closed

miri happily dereferences *const ! and continues #157

oli-obk opened this issue Mar 31, 2017 · 7 comments
Labels
C-bug Category: This is a bug.

Comments

@oli-obk
Copy link
Contributor

oli-obk commented Mar 31, 2017

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

@solson solson added the C-bug Category: This is a bug. label Mar 31, 2017
@eddyb
Copy link
Member

eddyb commented Mar 31, 2017

cc @rust-lang/compiler The unreachable terminator used to come from NeverToAny coercions.
Are they never emitted now?

@solson
Copy link
Member

solson commented Mar 31, 2017

@eddyb Your ping doesn't work cross-org.

@eddyb
Copy link
Member

eddyb commented Apr 6, 2017

Uh oh. cc @nikomatsakis

@nikomatsakis
Copy link

Yeah, we wouldn't insert a coercion here. It doesn't seem to me that one should be required, since the types are all !. We could add one gratuitously, I suppose, or have MIR generation check for expressions that "produce" a ! natively.

@eddyb
Copy link
Member

eddyb commented Apr 11, 2017

@nikomatsakis So we don't emit unreachable at all anymore? Should we change that?
E.g. I could imagine emitting it after building the MIR for an expression of type ! (other than calls).
Oh nevermind, I misread "or" in your comment as "and" - your second option seems the more palatable.

@oli-obk
Copy link
Contributor Author

oli-obk commented Apr 21, 2017

This has been fixed in miri. Should a separate rustc issue be opened?

@eddyb
Copy link
Member

eddyb commented Apr 21, 2017

@oli-obk That makes sense.

@eddyb eddyb closed this as completed Apr 21, 2017
erickt pushed a commit to erickt/miri that referenced this issue Feb 4, 2022
Let feature "serde" work as well as "serde-1"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests

4 participants