1
Fork 0

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)) Err(ManuallyDrop::into_inner(data.p))
}; };
// Compatibility wrapper around the try intrinsic for bootstrap // Compatibility wrapper around the try intrinsic for bootstrap.
#[inline] //
// 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 { unsafe fn do_try(try_fn: fn(*mut u8), data: *mut u8, catch_fn: fn(*mut u8, *mut u8)) -> i32 {
#[cfg(not(bootstrap))] use crate::mem::MaybeUninit;
{ #[cfg(target_env = "msvc")]
intrinsics::r#try(try_fn, data, catch_fn) type TryPayload = [u64; 2];
} #[cfg(not(target_env = "msvc"))]
#[cfg(bootstrap)] 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 mut payload: MaybeUninit<TryPayload> = MaybeUninit::uninit();
let payload_ptr = payload.as_mut_ptr() as *mut u8; let payload_ptr = payload.as_mut_ptr() as *mut u8;
let r = intrinsics::r#try(try_fn, data, payload_ptr); let r = intrinsics::r#try(try_fn, data, payload_ptr);
if r != 0 { if r != 0 {
#[cfg(target_env = "msvc")] #[cfg(target_env = "msvc")]
{ {
catch_fn(data, payload_ptr) catch_fn(data, payload_ptr)
} }
#[cfg(not(target_env = "msvc"))] #[cfg(not(target_env = "msvc"))]
{ {
catch_fn(data, payload.assume_init()) catch_fn(data, payload.assume_init())
}
} }
r
} }
r
} }
// We consider unwinding to be rare, so mark this function as cold. However, // 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 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) { fn do_call<F: FnOnce() -> R, R>(data: *mut u8) {
unsafe { unsafe {
let data = data as *mut Data<F, R>; let data = data as *mut Data<F, R>;