Skip to content

Commit 864d05b

Browse files
committed
Add a workaround for catch_unwind in stage1 mingw target
Fixes #70001
1 parent 0f1e814 commit 864d05b

File tree

1 file changed

+28
-26
lines changed

1 file changed

+28
-26
lines changed

src/libstd/panicking.rs

+28-26
Original file line numberDiff line numberDiff line change
@@ -278,36 +278,36 @@ pub unsafe fn r#try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any + Send>>
278278
Err(ManuallyDrop::into_inner(data.p))
279279
};
280280

281-
// Compatibility wrapper around the try intrinsic for bootstrap
282-
#[inline]
281+
// Compatibility wrapper around the try intrinsic for bootstrap.
282+
//
283+
// We also need to mark it #[inline(never)] to work around a bug on MinGW
284+
// targets: the unwinding implementation was relying on UB, but this only
285+
// becomes a problem in practice if inlining is involved.
286+
#[cfg(not(bootstrap))]
287+
use intrinsics::r#try as do_try;
288+
#[cfg(bootstrap)]
289+
#[inline(never)]
283290
unsafe fn do_try(try_fn: fn(*mut u8), data: *mut u8, catch_fn: fn(*mut u8, *mut u8)) -> i32 {
284-
#[cfg(not(bootstrap))]
285-
{
286-
intrinsics::r#try(try_fn, data, catch_fn)
287-
}
288-
#[cfg(bootstrap)]
289-
{
290-
use crate::mem::MaybeUninit;
291+
use crate::mem::MaybeUninit;
292+
#[cfg(target_env = "msvc")]
293+
type TryPayload = [u64; 2];
294+
#[cfg(not(target_env = "msvc"))]
295+
type TryPayload = *mut u8;
296+
297+
let mut payload: MaybeUninit<TryPayload> = MaybeUninit::uninit();
298+
let payload_ptr = payload.as_mut_ptr() as *mut u8;
299+
let r = intrinsics::r#try(try_fn, data, payload_ptr);
300+
if r != 0 {
291301
#[cfg(target_env = "msvc")]
292-
type TryPayload = [u64; 2];
302+
{
303+
catch_fn(data, payload_ptr)
304+
}
293305
#[cfg(not(target_env = "msvc"))]
294-
type TryPayload = *mut u8;
295-
296-
let mut payload: MaybeUninit<TryPayload> = MaybeUninit::uninit();
297-
let payload_ptr = payload.as_mut_ptr() as *mut u8;
298-
let r = intrinsics::r#try(try_fn, data, payload_ptr);
299-
if r != 0 {
300-
#[cfg(target_env = "msvc")]
301-
{
302-
catch_fn(data, payload_ptr)
303-
}
304-
#[cfg(not(target_env = "msvc"))]
305-
{
306-
catch_fn(data, payload.assume_init())
307-
}
306+
{
307+
catch_fn(data, payload.assume_init())
308308
}
309-
r
310309
}
310+
r
311311
}
312312

313313
// We consider unwinding to be rare, so mark this function as cold. However,
@@ -321,7 +321,9 @@ pub unsafe fn r#try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any + Send>>
321321
obj
322322
}
323323

324-
#[inline]
324+
// See comment on do_try above for why #[inline(never)] is needed on bootstrap.
325+
#[cfg_attr(bootstrap, inline(never))]
326+
#[cfg_attr(not(bootstrap), inline)]
325327
fn do_call<F: FnOnce() -> R, R>(data: *mut u8) {
326328
unsafe {
327329
let data = data as *mut Data<F, R>;

0 commit comments

Comments
 (0)