]> git.lizzy.rs Git - rust.git/commit
Auto merge of #65646 - Amanieu:foreign-exceptions, r=nikomatsakis
authorbors <bors@rust-lang.org>
Sun, 3 Nov 2019 18:36:59 +0000 (18:36 +0000)
committerbors <bors@rust-lang.org>
Sun, 3 Nov 2019 18:36:59 +0000 (18:36 +0000)
commitb520af6fd515b186caed436d75162a42aa183d95
tree6d7b585e1cfdde034a31707c546323a07a9837e6
parentb43a6822597061dc18cbdde1769d9815e718d7bb
parentf223e0d6274a8626b9d9428582384955e7f24b15
Auto merge of #65646 - Amanieu:foreign-exceptions, r=nikomatsakis

Allow foreign exceptions to unwind through Rust code and Rust panics to unwind through FFI

This PR fixes interactions between Rust panics and foreign (mainly C++) exceptions.

C++ exceptions (and other FFI exceptions) can now safely unwind through Rust code:
- The FFI function causing the unwind must be marked with `#[unwind(allowed)]`. If this is not the case then LLVM may optimize landing pads away with the assumption that they are unreachable.
- Drop code will be executed as the exception unwinds through the stack, as with a Rust panic.
- `catch_unwind` will *not* catch the exception, instead the exception will silently continue unwinding past it.

Rust panics can now safely unwind through C++ code:
- C++ destructors will be called as the stack unwinds.
- The Rust panic can only be caught with `catch (...)`, after which it can be either rethrown or discarded.
- C++ cannot name the type of the Rust exception object used for unwinding, which means that it can't be caught explicitly or have its contents inspected.

Tests have been added to ensure all of the above works correctly.

Some notes about non-C++ exceptions:
- `pthread_cancel` and `pthread_exit` use unwinding on glibc. This has the same behavior as a C++ exception: destructors are run but it cannot be caught by `catch_unwind`.
- `longjmp` on Windows is implemented using unwinding. Destructors are run on MSVC, but not on MinGW. In both cases the unwind cannot be caught by `catch_unwind`.
- As with C++ exceptions, you need to mark the relevant FFI functions with `#[unwind(allowed)]`, otherwise LLVM will optimize out the destructors since they seem unreachable.

I haven't updated any of the documentation, so officially unwinding through FFI is still UB. However this is a step towards making it well-defined.

Fixes #65441

cc @gnzlbg
r? @alexcrichton