@@ -278,36 +278,36 @@ pub unsafe fn r#try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any + Send>>
278
278
Err ( ManuallyDrop :: into_inner ( data. p ) )
279
279
} ;
280
280
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) ]
283
290
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 {
291
301
#[ cfg( target_env = "msvc" ) ]
292
- type TryPayload = [ u64 ; 2 ] ;
302
+ {
303
+ catch_fn ( data, payload_ptr)
304
+ }
293
305
#[ 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 ( ) )
308
308
}
309
- r
310
309
}
310
+ r
311
311
}
312
312
313
313
// 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>>
321
321
obj
322
322
}
323
323
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) ]
325
327
fn do_call < F : FnOnce ( ) -> R , R > ( data : * mut u8 ) {
326
328
unsafe {
327
329
let data = data as * mut Data < F , R > ;
0 commit comments