diff options
| author | bors <bors@rust-lang.org> | 2019-11-03 18:36:59 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-11-03 18:36:59 +0000 |
| commit | b520af6fd515b186caed436d75162a42aa183d95 (patch) | |
| tree | 6d7b585e1cfdde034a31707c546323a07a9837e6 /src/libpanic_unwind/lib.rs | |
| parent | b43a6822597061dc18cbdde1769d9815e718d7bb (diff) | |
| parent | f223e0d6274a8626b9d9428582384955e7f24b15 (diff) | |
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
Diffstat (limited to 'src/libpanic_unwind/lib.rs')
| -rw-r--r-- | src/libpanic_unwind/lib.rs | 9 |
1 files changed, 2 insertions, 7 deletions
diff --git a/src/libpanic_unwind/lib.rs b/src/libpanic_unwind/lib.rs index 2089a02083c..d2a0ef7b1dd 100644 --- a/src/libpanic_unwind/lib.rs +++ b/src/libpanic_unwind/lib.rs @@ -5,9 +5,8 @@ //! essentially gets categorized into three buckets currently: //! //! 1. MSVC targets use SEH in the `seh.rs` file. -//! 2. The 64-bit MinGW target half-uses SEH and half-use gcc-like information -//! in the `seh64_gnu.rs` module. -//! 3. All other targets use libunwind/libgcc in the `gcc/mod.rs` module. +//! 2. Emscripten uses C++ exceptions in the `emcc.rs` file. +//! 3. All other targets use libunwind/libgcc in the `gcc.rs` file. //! //! More documentation about each implementation can be found in the respective //! module. @@ -52,9 +51,6 @@ cfg_if::cfg_if! { } else if #[cfg(target_env = "msvc")] { #[path = "seh.rs"] mod imp; - } else if #[cfg(all(windows, target_arch = "x86_64", target_env = "gnu"))] { - #[path = "seh64_gnu.rs"] - mod imp; } else { // Rust runtime's startup objects depend on these symbols, so make them public. #[cfg(all(target_os="windows", target_arch = "x86", target_env="gnu"))] @@ -65,7 +61,6 @@ cfg_if::cfg_if! { } mod dwarf; -mod windows; // Entry point for catching an exception, implemented using the `try` intrinsic // in the compiler. |
