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

Running diverging closure coerced to fn ptr fails: "invalid use of NULL pointer" #1075

Closed
RalfJung opened this issue Nov 25, 2019 · 4 comments · Fixed by rust-lang/rust#66827
Labels
A-interpreter Area: affects the core interpreter C-bug Category: This is a bug.

Comments

@RalfJung
Copy link
Member

The following code fails to run in Miri:

fn main() {
    let f: fn() -> ! = || std::process::exit(0);  
    f();
}

The error is

error: Miri evaluation error: invalid use of NULL pointer
   --> /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libcore/ops/function.rs:227:5
    |
227 |     extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Miri evaluation error: invalid use of NULL pointer
    |
note: inside call to `<[closure@src/main.rs:2:24: 2:48] as std::ops::FnOnce<()>>::call_once - shim` at src/main.rs:3:5
   --> src/main.rs:3:5
    |
3   |     f();
    |     ^^^

I am not entirely sure what is happening; it looks like this has something to do with the shim that is used to coerce non-capturing closures to function pointers.

Cc @eddyb @oli-obk

bors added a commit that referenced this issue Nov 25, 2019
test closure-to-fn-ptr coercions a bit more

Also add some commented-out failing tests, Cc rust-lang/rust#66738 #1075
@eddyb
Copy link
Member

eddyb commented Nov 25, 2019

Does it have to be -> !? I can't think why that could affect the outcome.

@RalfJung
Copy link
Member Author

I don't understand it either, but replacing ! by () in the example fixes it.

@RalfJung
Copy link
Member Author

There is something weird about the coercion of diverging closures anyway, see rust-lang/rust#66738.

@RalfJung
Copy link
Member Author

Looks like the exception comes from here

https://github.com/rust-lang/rust/blob/04e69e4f4234beb4f12cc76dcc53e2cc4247a9be/src/librustc_mir/interpret/terminator.rs#L80

and then probably

https://github.com/rust-lang/rust/blob/04e69e4f4234beb4f12cc76dcc53e2cc4247a9be/src/librustc_mir/interpret/place.rs#L667

So, we have a function call with a return place, but that return place is actually the callers return place, and the caller diverges. This is okay because the callee also diverges, but we error out when just creating that return place.

@RalfJung RalfJung added A-interpreter Area: affects the core interpreter C-bug Category: This is a bug. labels Nov 27, 2019
Centril added a commit to Centril/rust that referenced this issue Dec 1, 2019
…oli-obk

handle diverging functions forwarding their return place

Fixes rust-lang/miri#1075: the shim around diverging closures turned into function pointers actually "obtains" a return place inside a diverging function, but just uses it as the return place for a diverging callee. Handle this by using NULL places.

This is kind of a hack as it breaks our invariant that all places are dereferencable, but we'd eventually let raw pointers break that anyway I assume so that seems fine.

r? @oli-obk
RalfJung added a commit to RalfJung/rust that referenced this issue Dec 2, 2019
…oli-obk

handle diverging functions forwarding their return place

Fixes rust-lang/miri#1075: the shim around diverging closures turned into function pointers actually "obtains" a return place inside a diverging function, but just uses it as the return place for a diverging callee. Handle this by using NULL places.

This is kind of a hack as it breaks our invariant that all places are dereferencable, but we'd eventually let raw pointers break that anyway I assume so that seems fine.

r? @oli-obk
RalfJung added a commit to RalfJung/rust that referenced this issue Dec 2, 2019
…oli-obk

handle diverging functions forwarding their return place

Fixes rust-lang/miri#1075: the shim around diverging closures turned into function pointers actually "obtains" a return place inside a diverging function, but just uses it as the return place for a diverging callee. Handle this by using NULL places.

This is kind of a hack as it breaks our invariant that all places are dereferencable, but we'd eventually let raw pointers break that anyway I assume so that seems fine.

r? @oli-obk
bors added a commit that referenced this issue Dec 2, 2019
Test diverging closure coercion

Adds a test for #1075. Depends on rust-lang/rust#66827.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-interpreter Area: affects the core interpreter C-bug Category: This is a bug.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants