Skip to content

Commit 8e6de32

Browse files
committed
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
2 parents 97eda01 + 864d05b commit 8e6de32

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
@@ -277,36 +277,36 @@ pub unsafe fn r#try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any + Send>>
277277
Err(ManuallyDrop::into_inner(data.p))
278278
};
279279

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

312312
// 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>>
320320
obj
321321
}
322322

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

0 commit comments

Comments
 (0)