Skip to content

Commit

Permalink
Add a workaround for catch_unwind in stage1 mingw target
Browse files Browse the repository at this point in the history
Fixes #70001
  • Loading branch information
Amanieu committed Mar 14, 2020
1 parent 0f1e814 commit 864d05b
Showing 1 changed file with 28 additions and 26 deletions.
54 changes: 28 additions & 26 deletions src/libstd/panicking.rs
Expand Up @@ -278,36 +278,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;
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")]
type TryPayload = [u64; 2];
{
catch_fn(data, payload_ptr)
}
#[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())
}
{
catch_fn(data, payload.assume_init())
}
r
}
r
}

// We consider unwinding to be rare, so mark this function as cold. However,
Expand All @@ -321,7 +321,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>;
Expand Down

0 comments on commit 864d05b

Please sign in to comment.