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