about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/panicking.rs54
1 files changed, 28 insertions, 26 deletions
diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs
index 0be71b52d9e..05a31358443 100644
--- a/src/libstd/panicking.rs
+++ b/src/libstd/panicking.rs
@@ -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,
@@ -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>;