Stream: t-compiler/const-eval

Topic: ICE generating miri stacktrace


RalfJ (Oct 29 2018 at 10:50, on Zulip):

@Oli with -Zmir-opt-level=3, I am seeing an ICE when generating the miri stack trace of one of our compile-fail tests. We get an out-of-bounds access at https://github.com/rust-lang/rust/blob/96064eb61/src/librustc_mir/interpret/eval_context.rs#L718. Is that expected (so we should change that code to return None) or a bug somewhere?

oli (Oct 29 2018 at 11:50, on Zulip):

I've seen this before. If you look at the MIR you see that the MIR is borked post-inlining

RalfJ (Oct 29 2018 at 12:23, on Zulip):

well, just calling rustc on that file works...

oli (Oct 29 2018 at 12:36, on Zulip):

yes it is, but if you do dump-mir and look at the MIR directly after inlining you can see that the source_scope_local_data has fewer elements than referenced by source_info.scope of various statements

oli (Oct 29 2018 at 12:36, on Zulip):

I've not been able to figure out what exactly caused it though

oli (Oct 29 2018 at 12:37, on Zulip):

there's some source_scole_local_data merging going on in inlining, I'd presume the bug is in there

RalfJ (Oct 29 2018 at 12:39, on Zulip):

is there an issue open for this?

oli (Oct 29 2018 at 12:41, on Zulip):

didn't find it, I thought I opened one

oli (Oct 29 2018 at 12:41, on Zulip):

I talked with eddy about it :confused:

RalfJ (Oct 30 2018 at 14:26, on Zulip):

@Oli this is what the printed MIR looks like:

fn make_raw() -> *const f32{
    let mut _0: *const f32;              // return place
    scope 1 {
        scope 2 {
        }
    }

    bb0: {
        _0 = const std::intrinsics::uninit() -> bb1; // bb0[0]: scope 2 at /home/r/src/rust/rustc.2/src/libcore/mem.rs:599:5: 599:25
                                         // ty::Const
                                         // + ty: unsafe extern "rust-intrinsic" fn() -> *const f32 {std::intrinsics::uninit::<*const f32>}
                                         // + val: Scalar(Bits { size: 0, bits: 0 })
                                         // mir::Constant
                                         // + span: /home/r/src/rust/rustc.2/src/libcore/mem.rs:599:5: 599:23
                                         // + ty: unsafe extern "rust-intrinsic" fn() -> *const f32 {std::intrinsics::uninit::<*const f32>}
                                         // + literal: Const { ty: unsafe extern "rust-intrinsic" fn() -> *const f32 {std::intrinsics::uninit::<*const f32>}, val: Scalar(Bits { size: 0, bits: 0 }) }
    }

    bb1: {
        Validate(Acquire, [_0: *const f32]); // bb1[0]: scope 2 at /home/r/src/rust/rustc.2/src/libcore/mem.rs:599:5: 599:25
        Validate(Release, [_0: *const f32]); // bb1[1]: scope 2 at /home/r/src/rust/rustc.2/src/libcore/mem.rs:599:5: 599:25
        return;                          // bb1[2]: scope 0 at tests/compile-fail/validity/undef.rs:8:2: 8:2
    }
}
RalfJ (Oct 30 2018 at 14:27, on Zulip):

I cannot see anything wrong with it? but there is a dangling source_scope_local_data it seems

RalfJ (Oct 30 2018 at 14:29, on Zulip):

would be nice, for a bugreport, to find a way to trigger that ICE without involving miri

RalfJ (Oct 30 2018 at 14:29, on Zulip):

maybe a well-placed debug_assert!? But what would be a good place?

oli (Oct 30 2018 at 15:11, on Zulip):

do we have a "MIR validation" pass like LLVM has for IR? Feels like this would be perfect for such things

RalfJ (Oct 30 2018 at 15:16, on Zulip):

if you don't know about it, I certainly don't. ;)

RalfJ (Oct 30 2018 at 15:17, on Zulip):

@nikomatsakis any suggestions? See above.

oli (Oct 30 2018 at 15:23, on Zulip):

The problem is, I can write such a pass easily, but that will basically break mir opt level 3

RalfJ (Oct 30 2018 at 15:37, on Zulip):

maybe make the pass opt-in via a -Z flag for now?

RalfJ (Oct 30 2018 at 15:37, on Zulip):

then we can slowly work towards enabling it per default on debug builds

RalfJ (Oct 30 2018 at 15:38, on Zulip):

(and still have the -Z flag on release builds)

RalfJ (Oct 30 2018 at 15:38, on Zulip):

@Wesley Wiser has worked on fixing MIR inlining recently, they might be interested in whatever that pass uncovers

RalfJ (Oct 30 2018 at 15:40, on Zulip):

@Wesley Wiser if you want to have an example of something that gets broken by inlining, here's a simple one:

fn make_raw() -> *const f32 {
    unsafe { mem::uninitialized() }
}
RalfJ (Oct 30 2018 at 15:41, on Zulip):

the resulting MIR contains a source_scope_local_data referring to locals that do not exist any more

Wesley Wiser (Oct 30 2018 at 15:45, on Zulip):

@RalfJ I'm not familiar with source_scope_local_data. I'll certainly look into it though. Does that have something to do with debug info?

RalfJ (Oct 30 2018 at 15:51, on Zulip):

I do not have the slightest idea :)

RalfJ (Oct 30 2018 at 15:51, on Zulip):

All I know is that miri accesses it when generating a backtrace, and we are getting an out-of-bounds array access at https://github.com/rust-lang/rust/blob/96064eb61dc703c289fae61bdf90593d3e7b2449/src/librustc_mir/interpret/eval_context.rs#L718

RalfJ (Oct 30 2018 at 15:52, on Zulip):

so it seems there is an invariant that source_info.scope, for the source_info one finds in the MIR, is in-bounds for that array. or so.

Wesley Wiser (Oct 30 2018 at 15:56, on Zulip):

Ah ok. Sounds like it might be debug info related then.

Wesley Wiser (Oct 30 2018 at 15:57, on Zulip):

(Which doesn't mean I'm not interested, I'm just still trying to sort out the mis compilations so it might be awhile before I get around to fixing that)

RalfJ (Oct 30 2018 at 16:00, on Zulip):

sure

Last update: Nov 15 2019 at 20:20UTC