about summary refs log tree commit diff
path: root/src/rustllvm/RustWrapper.cpp
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2018-02-28 23:33:32 -0800
committerManish Goregaokar <manishsmail@gmail.com>2018-03-01 09:29:40 -0800
commit8025e1555c60e5f542ab4541a55ca540495290f7 (patch)
tree6515e08e83f88d5e59a7211d12b97425b4640907 /src/rustllvm/RustWrapper.cpp
parent75b8c103912f1d5a38d4f4ecb2564a0010444902 (diff)
parent804666f4ad5a66e6a1bae3b2e326efa030135a05 (diff)
downloadrust-8025e1555c60e5f542ab4541a55ca540495290f7.tar.gz
rust-8025e1555c60e5f542ab4541a55ca540495290f7.zip
Rollup merge of #48572 - alexcrichton:noexcept-msvc2, r=eddyb
rustc: Tweak funclet cleanups of ffi functions

This commit is targeted at addressing #48251 by specifically fixing a case where
a longjmp over Rust frames on MSVC runs cleanups, accidentally running the
"abort the program" cleanup as well. Added in #46833 `extern` ABI functions in
Rust will abort the process if Rust panics, and currently this is modeled as a
normal cleanup like all other destructors.

Unfortunately it turns out that `longjmp` on MSVC is implemented with SEH, the
same mechanism used to implement panics in Rust. This means that `longjmp` over
Rust frames will run Rust cleanups (even though we don't necessarily want it
to). Notably this means that if you `longjmp` over a Rust stack frame then that
probably means you'll abort the program because one of the cleanups will abort
the process.

After some discussion on IRC it turns out that `longjmp` doesn't run cleanups
for *caught* exceptions, it only runs cleanups for cleanup pads. Using this
information this commit tweaks the codegen for an `extern` function to
a catch-all clause for exceptions instead of a cleanup block. This catch-all is
equivalent to the C++ code:

    try {
        foo();
    } catch (...) {
        bar();
    }

and in fact our codegen here is designed to match exactly what clang emits for
that C++ code!

With this tweak a longjmp over Rust code will no longer abort the process. A
longjmp will continue to "accidentally" run Rust cleanups (destructors) on MSVC.
Other non-MSVC platforms will not rust destructors with a longjmp, so we'll
probably still recommend "don't have destructors on the stack", but in any case
this is a more surgical fix than #48567 and should help us stick to standard
personality functions a bit longer.
Diffstat (limited to 'src/rustllvm/RustWrapper.cpp')
0 files changed, 0 insertions, 0 deletions