Auto merge of #70010 - Amanieu:fix-opt-catch, r=Mark-Simulacrum

Add a workaround for catch_unwind in stage1 mingw target

Fixes #70001

cc @petrochenkov

r? @Mark-Simulacrum
This commit is contained in:
bors 2020-03-16 08:08:51 +00:00
commit 8e6de3244c

View File

@ -277,36 +277,36 @@ pub unsafe fn r#try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any + Send>>
Err(ManuallyDrop::into_inner(data.p))
};
// Compatibility wrapper around the try intrinsic for bootstrap
#[inline]
// Compatibility wrapper around the try intrinsic for bootstrap.
//
// We also need to mark it #[inline(never)] to work around a bug on MinGW
// targets: the unwinding implementation was relying on UB, but this only
// becomes a problem in practice if inlining is involved.
#[cfg(not(bootstrap))]
use intrinsics::r#try as do_try;
#[cfg(bootstrap)]
#[inline(never)]
unsafe fn do_try(try_fn: fn(*mut u8), data: *mut u8, catch_fn: fn(*mut u8, *mut u8)) -> i32 {
#[cfg(not(bootstrap))]
{
intrinsics::r#try(try_fn, data, catch_fn)
}
#[cfg(bootstrap)]
{
use crate::mem::MaybeUninit;
#[cfg(target_env = "msvc")]
type TryPayload = [u64; 2];
#[cfg(not(target_env = "msvc"))]
type TryPayload = *mut u8;
use crate::mem::MaybeUninit;
#[cfg(target_env = "msvc")]
type TryPayload = [u64; 2];
#[cfg(not(target_env = "msvc"))]
type TryPayload = *mut u8;
let mut payload: MaybeUninit<TryPayload> = MaybeUninit::uninit();
let payload_ptr = payload.as_mut_ptr() as *mut u8;
let r = intrinsics::r#try(try_fn, data, payload_ptr);
if r != 0 {
#[cfg(target_env = "msvc")]
{
catch_fn(data, payload_ptr)
}
#[cfg(not(target_env = "msvc"))]
{
catch_fn(data, payload.assume_init())
}
let mut payload: MaybeUninit<TryPayload> = MaybeUninit::uninit();
let payload_ptr = payload.as_mut_ptr() as *mut u8;
let r = intrinsics::r#try(try_fn, data, payload_ptr);
if r != 0 {
#[cfg(target_env = "msvc")]
{
catch_fn(data, payload_ptr)
}
#[cfg(not(target_env = "msvc"))]
{
catch_fn(data, payload.assume_init())
}
r
}
r
}
// We consider unwinding to be rare, so mark this function as cold. However,
@ -320,7 +320,9 @@ pub unsafe fn r#try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any + Send>>
obj
}
#[inline]
// See comment on do_try above for why #[inline(never)] is needed on bootstrap.
#[cfg_attr(bootstrap, inline(never))]
#[cfg_attr(not(bootstrap), inline)]
fn do_call<F: FnOnce() -> R, R>(data: *mut u8) {
unsafe {
let data = data as *mut Data<F, R>;