about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLeSeulArtichaut <leseulartichaut@gmail.com>2020-06-24 13:15:37 +0200
committerLeSeulArtichaut <leseulartichaut@gmail.com>2020-06-30 17:06:16 +0200
commitac7539c6d1036e42e84d388a57a656c420cb9eee (patch)
tree578072cd4e4e8ec41b48068d022c2da3d7b9df84
parent8a515e963cf2711192495802d7bbf2e49979cdf2 (diff)
downloadrust-ac7539c6d1036e42e84d388a57a656c420cb9eee.tar.gz
rust-ac7539c6d1036e42e84d388a57a656c420cb9eee.zip
Deny unsafe ops in unsafe fns, part 3
-rw-r--r--src/libcore/num/f32.rs5
-rw-r--r--src/libcore/num/f64.rs5
-rw-r--r--src/libcore/num/mod.rs28
-rw-r--r--src/libcore/sync/atomic.rs254
-rw-r--r--src/libcore/tests/lib.rs2
5 files changed, 181 insertions, 113 deletions
diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs
index 6313de31ce4..028beb86e68 100644
--- a/src/libcore/num/f32.rs
+++ b/src/libcore/num/f32.rs
@@ -9,6 +9,7 @@
 //! new code should use the associated constants directly on the primitive type.
 
 #![stable(feature = "rust1", since = "1.0.0")]
+#![deny(unsafe_op_in_unsafe_fn)]
 
 use crate::convert::FloatToInt;
 #[cfg(not(test))]
@@ -629,7 +630,9 @@ impl f32 {
     where
         Self: FloatToInt<Int>,
     {
-        FloatToInt::<Int>::to_int_unchecked(self)
+        // SAFETY: the caller must uphold the safety contract for
+        // `FloatToInt::to_int_unchecked`.
+        unsafe { FloatToInt::<Int>::to_int_unchecked(self) }
     }
 
     /// Raw transmutation to `u32`.
diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs
index d42e5392c58..74e38c128b3 100644
--- a/src/libcore/num/f64.rs
+++ b/src/libcore/num/f64.rs
@@ -9,6 +9,7 @@
 //! new code should use the associated constants directly on the primitive type.
 
 #![stable(feature = "rust1", since = "1.0.0")]
+#![deny(unsafe_op_in_unsafe_fn)]
 
 use crate::convert::FloatToInt;
 #[cfg(not(test))]
@@ -643,7 +644,9 @@ impl f64 {
     where
         Self: FloatToInt<Int>,
     {
-        FloatToInt::<Int>::to_int_unchecked(self)
+        // SAFETY: the caller must uphold the safety contract for
+        // `FloatToInt::to_int_unchecked`.
+        unsafe { FloatToInt::<Int>::to_int_unchecked(self) }
     }
 
     /// Raw transmutation to `u64`.
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index d36da90f2ad..918eea7acb3 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -3,6 +3,7 @@
 //! Numeric traits and functions for the built-in numeric types.
 
 #![stable(feature = "rust1", since = "1.0.0")]
+#![deny(unsafe_op_in_unsafe_fn)]
 
 use crate::convert::Infallible;
 use crate::fmt;
@@ -74,7 +75,8 @@ assert_eq!(size_of::<Option<core::num::", stringify!($Ty), ">>(), size_of::<", s
                 #[rustc_const_stable(feature = "nonzero", since = "1.34.0")]
                 #[inline]
                 pub const unsafe fn new_unchecked(n: $Int) -> Self {
-                    Self(n)
+                    // SAFETY: this is guaranteed to be safe by the caller.
+                    unsafe { Self(n) }
                 }
 
                 /// Creates a non-zero if the given value is not zero.
@@ -762,7 +764,9 @@ cannot occur. This results in undefined behavior when `self + rhs > ", stringify
                           without modifying the original"]
             #[inline]
             pub unsafe fn unchecked_add(self, rhs: Self) -> Self {
-                intrinsics::unchecked_add(self, rhs)
+                // SAFETY: the caller must uphold the safety contract for
+                // `unchecked_add`.
+                unsafe { intrinsics::unchecked_add(self, rhs) }
             }
         }
 
@@ -804,7 +808,9 @@ cannot occur. This results in undefined behavior when `self - rhs > ", stringify
                           without modifying the original"]
             #[inline]
             pub unsafe fn unchecked_sub(self, rhs: Self) -> Self {
-                intrinsics::unchecked_sub(self, rhs)
+                // SAFETY: the caller must uphold the safety contract for
+                // `unchecked_sub`.
+                unsafe { intrinsics::unchecked_sub(self, rhs) }
             }
         }
 
@@ -846,7 +852,9 @@ cannot occur. This results in undefined behavior when `self * rhs > ", stringify
                           without modifying the original"]
             #[inline]
             pub unsafe fn unchecked_mul(self, rhs: Self) -> Self {
-                intrinsics::unchecked_mul(self, rhs)
+                // SAFETY: the caller must uphold the safety contract for
+                // `unchecked_mul`.
+                unsafe { intrinsics::unchecked_mul(self, rhs) }
             }
         }
 
@@ -2998,7 +3006,9 @@ cannot occur. This results in undefined behavior when `self + rhs > ", stringify
                           without modifying the original"]
             #[inline]
             pub unsafe fn unchecked_add(self, rhs: Self) -> Self {
-                intrinsics::unchecked_add(self, rhs)
+                // SAFETY: the caller must uphold the safety contract for
+                // `unchecked_add`.
+                unsafe { intrinsics::unchecked_add(self, rhs) }
             }
         }
 
@@ -3038,7 +3048,9 @@ cannot occur. This results in undefined behavior when `self - rhs > ", stringify
                           without modifying the original"]
             #[inline]
             pub unsafe fn unchecked_sub(self, rhs: Self) -> Self {
-                intrinsics::unchecked_sub(self, rhs)
+                // SAFETY: the caller must uphold the safety contract for
+                // `unchecked_sub`.
+                unsafe { intrinsics::unchecked_sub(self, rhs) }
             }
         }
 
@@ -3078,7 +3090,9 @@ cannot occur. This results in undefined behavior when `self * rhs > ", stringify
                           without modifying the original"]
             #[inline]
             pub unsafe fn unchecked_mul(self, rhs: Self) -> Self {
-                intrinsics::unchecked_mul(self, rhs)
+                // SAFETY: the caller must uphold the safety contract for
+                // `unchecked_mul`.
+                unsafe { intrinsics::unchecked_mul(self, rhs) }
             }
         }
 
diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs
index 1cd68f2881b..359c39a065f 100644
--- a/src/libcore/sync/atomic.rs
+++ b/src/libcore/sync/atomic.rs
@@ -115,6 +115,7 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 #![cfg_attr(not(target_has_atomic_load_store = "8"), allow(dead_code))]
 #![cfg_attr(not(target_has_atomic_load_store = "8"), allow(unused_imports))]
+#![deny(unsafe_op_in_unsafe_fn)]
 
 use self::Ordering::*;
 
@@ -2335,35 +2336,44 @@ fn strongest_failure_ordering(order: Ordering) -> Ordering {
 
 #[inline]
 unsafe fn atomic_store<T: Copy>(dst: *mut T, val: T, order: Ordering) {
-    match order {
-        Release => intrinsics::atomic_store_rel(dst, val),
-        Relaxed => intrinsics::atomic_store_relaxed(dst, val),
-        SeqCst => intrinsics::atomic_store(dst, val),
-        Acquire => panic!("there is no such thing as an acquire store"),
-        AcqRel => panic!("there is no such thing as an acquire/release store"),
+    // SAFETY: the caller must uphold the safety contract for `atomic_store`.
+    unsafe {
+        match order {
+            Release => intrinsics::atomic_store_rel(dst, val),
+            Relaxed => intrinsics::atomic_store_relaxed(dst, val),
+            SeqCst => intrinsics::atomic_store(dst, val),
+            Acquire => panic!("there is no such thing as an acquire store"),
+            AcqRel => panic!("there is no such thing as an acquire/release store"),
+        }
     }
 }
 
 #[inline]
 unsafe fn atomic_load<T: Copy>(dst: *const T, order: Ordering) -> T {
-    match order {
-        Acquire => intrinsics::atomic_load_acq(dst),
-        Relaxed => intrinsics::atomic_load_relaxed(dst),
-        SeqCst => intrinsics::atomic_load(dst),
-        Release => panic!("there is no such thing as a release load"),
-        AcqRel => panic!("there is no such thing as an acquire/release load"),
+    // SAFETY: the caller must uphold the safety contract for `atomic_load`.
+    unsafe {
+        match order {
+            Acquire => intrinsics::atomic_load_acq(dst),
+            Relaxed => intrinsics::atomic_load_relaxed(dst),
+            SeqCst => intrinsics::atomic_load(dst),
+            Release => panic!("there is no such thing as a release load"),
+            AcqRel => panic!("there is no such thing as an acquire/release load"),
+        }
     }
 }
 
 #[inline]
 #[cfg(target_has_atomic = "8")]
 unsafe fn atomic_swap<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
-    match order {
-        Acquire => intrinsics::atomic_xchg_acq(dst, val),
-        Release => intrinsics::atomic_xchg_rel(dst, val),
-        AcqRel => intrinsics::atomic_xchg_acqrel(dst, val),
-        Relaxed => intrinsics::atomic_xchg_relaxed(dst, val),
-        SeqCst => intrinsics::atomic_xchg(dst, val),
+    // SAFETY: the caller must uphold the safety contract for `atomic_swap`.
+    unsafe {
+        match order {
+            Acquire => intrinsics::atomic_xchg_acq(dst, val),
+            Release => intrinsics::atomic_xchg_rel(dst, val),
+            AcqRel => intrinsics::atomic_xchg_acqrel(dst, val),
+            Relaxed => intrinsics::atomic_xchg_relaxed(dst, val),
+            SeqCst => intrinsics::atomic_xchg(dst, val),
+        }
     }
 }
 
@@ -2371,12 +2381,15 @@ unsafe fn atomic_swap<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
 #[inline]
 #[cfg(target_has_atomic = "8")]
 unsafe fn atomic_add<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
-    match order {
-        Acquire => intrinsics::atomic_xadd_acq(dst, val),
-        Release => intrinsics::atomic_xadd_rel(dst, val),
-        AcqRel => intrinsics::atomic_xadd_acqrel(dst, val),
-        Relaxed => intrinsics::atomic_xadd_relaxed(dst, val),
-        SeqCst => intrinsics::atomic_xadd(dst, val),
+    // SAFETY: the caller must uphold the safety contract for `atomic_add`.
+    unsafe {
+        match order {
+            Acquire => intrinsics::atomic_xadd_acq(dst, val),
+            Release => intrinsics::atomic_xadd_rel(dst, val),
+            AcqRel => intrinsics::atomic_xadd_acqrel(dst, val),
+            Relaxed => intrinsics::atomic_xadd_relaxed(dst, val),
+            SeqCst => intrinsics::atomic_xadd(dst, val),
+        }
     }
 }
 
@@ -2384,12 +2397,15 @@ unsafe fn atomic_add<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
 #[inline]
 #[cfg(target_has_atomic = "8")]
 unsafe fn atomic_sub<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
-    match order {
-        Acquire => intrinsics::atomic_xsub_acq(dst, val),
-        Release => intrinsics::atomic_xsub_rel(dst, val),
-        AcqRel => intrinsics::atomic_xsub_acqrel(dst, val),
-        Relaxed => intrinsics::atomic_xsub_relaxed(dst, val),
-        SeqCst => intrinsics::atomic_xsub(dst, val),
+    // SAFETY: the caller must uphold the safety contract for `atomic_sub`.
+    unsafe {
+        match order {
+            Acquire => intrinsics::atomic_xsub_acq(dst, val),
+            Release => intrinsics::atomic_xsub_rel(dst, val),
+            AcqRel => intrinsics::atomic_xsub_acqrel(dst, val),
+            Relaxed => intrinsics::atomic_xsub_relaxed(dst, val),
+            SeqCst => intrinsics::atomic_xsub(dst, val),
+        }
     }
 }
 
@@ -2402,19 +2418,22 @@ unsafe fn atomic_compare_exchange<T: Copy>(
     success: Ordering,
     failure: Ordering,
 ) -> Result<T, T> {
-    let (val, ok) = match (success, failure) {
-        (Acquire, Acquire) => intrinsics::atomic_cxchg_acq(dst, old, new),
-        (Release, Relaxed) => intrinsics::atomic_cxchg_rel(dst, old, new),
-        (AcqRel, Acquire) => intrinsics::atomic_cxchg_acqrel(dst, old, new),
-        (Relaxed, Relaxed) => intrinsics::atomic_cxchg_relaxed(dst, old, new),
-        (SeqCst, SeqCst) => intrinsics::atomic_cxchg(dst, old, new),
-        (Acquire, Relaxed) => intrinsics::atomic_cxchg_acq_failrelaxed(dst, old, new),
-        (AcqRel, Relaxed) => intrinsics::atomic_cxchg_acqrel_failrelaxed(dst, old, new),
-        (SeqCst, Relaxed) => intrinsics::atomic_cxchg_failrelaxed(dst, old, new),
-        (SeqCst, Acquire) => intrinsics::atomic_cxchg_failacq(dst, old, new),
-        (_, AcqRel) => panic!("there is no such thing as an acquire/release failure ordering"),
-        (_, Release) => panic!("there is no such thing as a release failure ordering"),
-        _ => panic!("a failure ordering can't be stronger than a success ordering"),
+    // SAFETY: the caller must uphold the safety contract for `atomic_compare_exchange`.
+    let (val, ok) = unsafe {
+        match (success, failure) {
+            (Acquire, Acquire) => intrinsics::atomic_cxchg_acq(dst, old, new),
+            (Release, Relaxed) => intrinsics::atomic_cxchg_rel(dst, old, new),
+            (AcqRel, Acquire) => intrinsics::atomic_cxchg_acqrel(dst, old, new),
+            (Relaxed, Relaxed) => intrinsics::atomic_cxchg_relaxed(dst, old, new),
+            (SeqCst, SeqCst) => intrinsics::atomic_cxchg(dst, old, new),
+            (Acquire, Relaxed) => intrinsics::atomic_cxchg_acq_failrelaxed(dst, old, new),
+            (AcqRel, Relaxed) => intrinsics::atomic_cxchg_acqrel_failrelaxed(dst, old, new),
+            (SeqCst, Relaxed) => intrinsics::atomic_cxchg_failrelaxed(dst, old, new),
+            (SeqCst, Acquire) => intrinsics::atomic_cxchg_failacq(dst, old, new),
+            (_, AcqRel) => panic!("there is no such thing as an acquire/release failure ordering"),
+            (_, Release) => panic!("there is no such thing as a release failure ordering"),
+            _ => panic!("a failure ordering can't be stronger than a success ordering"),
+        }
     };
     if ok { Ok(val) } else { Err(val) }
 }
@@ -2428,19 +2447,22 @@ unsafe fn atomic_compare_exchange_weak<T: Copy>(
     success: Ordering,
     failure: Ordering,
 ) -> Result<T, T> {
-    let (val, ok) = match (success, failure) {
-        (Acquire, Acquire) => intrinsics::atomic_cxchgweak_acq(dst, old, new),
-        (Release, Relaxed) => intrinsics::atomic_cxchgweak_rel(dst, old, new),
-        (AcqRel, Acquire) => intrinsics::atomic_cxchgweak_acqrel(dst, old, new),
-        (Relaxed, Relaxed) => intrinsics::atomic_cxchgweak_relaxed(dst, old, new),
-        (SeqCst, SeqCst) => intrinsics::atomic_cxchgweak(dst, old, new),
-        (Acquire, Relaxed) => intrinsics::atomic_cxchgweak_acq_failrelaxed(dst, old, new),
-        (AcqRel, Relaxed) => intrinsics::atomic_cxchgweak_acqrel_failrelaxed(dst, old, new),
-        (SeqCst, Relaxed) => intrinsics::atomic_cxchgweak_failrelaxed(dst, old, new),
-        (SeqCst, Acquire) => intrinsics::atomic_cxchgweak_failacq(dst, old, new),
-        (_, AcqRel) => panic!("there is no such thing as an acquire/release failure ordering"),
-        (_, Release) => panic!("there is no such thing as a release failure ordering"),
-        _ => panic!("a failure ordering can't be stronger than a success ordering"),
+    // SAFETY: the caller must uphold the safety contract for `atomic_compare_exchange_weak`.
+    let (val, ok) = unsafe {
+        match (success, failure) {
+            (Acquire, Acquire) => intrinsics::atomic_cxchgweak_acq(dst, old, new),
+            (Release, Relaxed) => intrinsics::atomic_cxchgweak_rel(dst, old, new),
+            (AcqRel, Acquire) => intrinsics::atomic_cxchgweak_acqrel(dst, old, new),
+            (Relaxed, Relaxed) => intrinsics::atomic_cxchgweak_relaxed(dst, old, new),
+            (SeqCst, SeqCst) => intrinsics::atomic_cxchgweak(dst, old, new),
+            (Acquire, Relaxed) => intrinsics::atomic_cxchgweak_acq_failrelaxed(dst, old, new),
+            (AcqRel, Relaxed) => intrinsics::atomic_cxchgweak_acqrel_failrelaxed(dst, old, new),
+            (SeqCst, Relaxed) => intrinsics::atomic_cxchgweak_failrelaxed(dst, old, new),
+            (SeqCst, Acquire) => intrinsics::atomic_cxchgweak_failacq(dst, old, new),
+            (_, AcqRel) => panic!("there is no such thing as an acquire/release failure ordering"),
+            (_, Release) => panic!("there is no such thing as a release failure ordering"),
+            _ => panic!("a failure ordering can't be stronger than a success ordering"),
+        }
     };
     if ok { Ok(val) } else { Err(val) }
 }
@@ -2448,48 +2470,60 @@ unsafe fn atomic_compare_exchange_weak<T: Copy>(
 #[inline]
 #[cfg(target_has_atomic = "8")]
 unsafe fn atomic_and<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
-    match order {
-        Acquire => intrinsics::atomic_and_acq(dst, val),
-        Release => intrinsics::atomic_and_rel(dst, val),
-        AcqRel => intrinsics::atomic_and_acqrel(dst, val),
-        Relaxed => intrinsics::atomic_and_relaxed(dst, val),
-        SeqCst => intrinsics::atomic_and(dst, val),
+    // SAFETY: the caller must uphold the safety contract for `atomic_and`
+    unsafe {
+        match order {
+            Acquire => intrinsics::atomic_and_acq(dst, val),
+            Release => intrinsics::atomic_and_rel(dst, val),
+            AcqRel => intrinsics::atomic_and_acqrel(dst, val),
+            Relaxed => intrinsics::atomic_and_relaxed(dst, val),
+            SeqCst => intrinsics::atomic_and(dst, val),
+        }
     }
 }
 
 #[inline]
 #[cfg(target_has_atomic = "8")]
 unsafe fn atomic_nand<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
-    match order {
-        Acquire => intrinsics::atomic_nand_acq(dst, val),
-        Release => intrinsics::atomic_nand_rel(dst, val),
-        AcqRel => intrinsics::atomic_nand_acqrel(dst, val),
-        Relaxed => intrinsics::atomic_nand_relaxed(dst, val),
-        SeqCst => intrinsics::atomic_nand(dst, val),
+    // SAFETY: the caller must uphold the safety contract for `atomic_nand`
+    unsafe {
+        match order {
+            Acquire => intrinsics::atomic_nand_acq(dst, val),
+            Release => intrinsics::atomic_nand_rel(dst, val),
+            AcqRel => intrinsics::atomic_nand_acqrel(dst, val),
+            Relaxed => intrinsics::atomic_nand_relaxed(dst, val),
+            SeqCst => intrinsics::atomic_nand(dst, val),
+        }
     }
 }
 
 #[inline]
 #[cfg(target_has_atomic = "8")]
 unsafe fn atomic_or<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
-    match order {
-        Acquire => intrinsics::atomic_or_acq(dst, val),
-        Release => intrinsics::atomic_or_rel(dst, val),
-        AcqRel => intrinsics::atomic_or_acqrel(dst, val),
-        Relaxed => intrinsics::atomic_or_relaxed(dst, val),
-        SeqCst => intrinsics::atomic_or(dst, val),
+    // SAFETY: the caller must uphold the safety contract for `atomic_or`
+    unsafe {
+        match order {
+            Acquire => intrinsics::atomic_or_acq(dst, val),
+            Release => intrinsics::atomic_or_rel(dst, val),
+            AcqRel => intrinsics::atomic_or_acqrel(dst, val),
+            Relaxed => intrinsics::atomic_or_relaxed(dst, val),
+            SeqCst => intrinsics::atomic_or(dst, val),
+        }
     }
 }
 
 #[inline]
 #[cfg(target_has_atomic = "8")]
 unsafe fn atomic_xor<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
-    match order {
-        Acquire => intrinsics::atomic_xor_acq(dst, val),
-        Release => intrinsics::atomic_xor_rel(dst, val),
-        AcqRel => intrinsics::atomic_xor_acqrel(dst, val),
-        Relaxed => intrinsics::atomic_xor_relaxed(dst, val),
-        SeqCst => intrinsics::atomic_xor(dst, val),
+    // SAFETY: the caller must uphold the safety contract for `atomic_xor`
+    unsafe {
+        match order {
+            Acquire => intrinsics::atomic_xor_acq(dst, val),
+            Release => intrinsics::atomic_xor_rel(dst, val),
+            AcqRel => intrinsics::atomic_xor_acqrel(dst, val),
+            Relaxed => intrinsics::atomic_xor_relaxed(dst, val),
+            SeqCst => intrinsics::atomic_xor(dst, val),
+        }
     }
 }
 
@@ -2497,12 +2531,15 @@ unsafe fn atomic_xor<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
 #[inline]
 #[cfg(target_has_atomic = "8")]
 unsafe fn atomic_max<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
-    match order {
-        Acquire => intrinsics::atomic_max_acq(dst, val),
-        Release => intrinsics::atomic_max_rel(dst, val),
-        AcqRel => intrinsics::atomic_max_acqrel(dst, val),
-        Relaxed => intrinsics::atomic_max_relaxed(dst, val),
-        SeqCst => intrinsics::atomic_max(dst, val),
+    // SAFETY: the caller must uphold the safety contract for `atomic_max`
+    unsafe {
+        match order {
+            Acquire => intrinsics::atomic_max_acq(dst, val),
+            Release => intrinsics::atomic_max_rel(dst, val),
+            AcqRel => intrinsics::atomic_max_acqrel(dst, val),
+            Relaxed => intrinsics::atomic_max_relaxed(dst, val),
+            SeqCst => intrinsics::atomic_max(dst, val),
+        }
     }
 }
 
@@ -2510,12 +2547,15 @@ unsafe fn atomic_max<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
 #[inline]
 #[cfg(target_has_atomic = "8")]
 unsafe fn atomic_min<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
-    match order {
-        Acquire => intrinsics::atomic_min_acq(dst, val),
-        Release => intrinsics::atomic_min_rel(dst, val),
-        AcqRel => intrinsics::atomic_min_acqrel(dst, val),
-        Relaxed => intrinsics::atomic_min_relaxed(dst, val),
-        SeqCst => intrinsics::atomic_min(dst, val),
+    // SAFETY: the caller must uphold the safety contract for `atomic_min`
+    unsafe {
+        match order {
+            Acquire => intrinsics::atomic_min_acq(dst, val),
+            Release => intrinsics::atomic_min_rel(dst, val),
+            AcqRel => intrinsics::atomic_min_acqrel(dst, val),
+            Relaxed => intrinsics::atomic_min_relaxed(dst, val),
+            SeqCst => intrinsics::atomic_min(dst, val),
+        }
     }
 }
 
@@ -2523,12 +2563,15 @@ unsafe fn atomic_min<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
 #[inline]
 #[cfg(target_has_atomic = "8")]
 unsafe fn atomic_umax<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
-    match order {
-        Acquire => intrinsics::atomic_umax_acq(dst, val),
-        Release => intrinsics::atomic_umax_rel(dst, val),
-        AcqRel => intrinsics::atomic_umax_acqrel(dst, val),
-        Relaxed => intrinsics::atomic_umax_relaxed(dst, val),
-        SeqCst => intrinsics::atomic_umax(dst, val),
+    // SAFETY: the caller must uphold the safety contract for `atomic_umax`
+    unsafe {
+        match order {
+            Acquire => intrinsics::atomic_umax_acq(dst, val),
+            Release => intrinsics::atomic_umax_rel(dst, val),
+            AcqRel => intrinsics::atomic_umax_acqrel(dst, val),
+            Relaxed => intrinsics::atomic_umax_relaxed(dst, val),
+            SeqCst => intrinsics::atomic_umax(dst, val),
+        }
     }
 }
 
@@ -2536,12 +2579,15 @@ unsafe fn atomic_umax<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
 #[inline]
 #[cfg(target_has_atomic = "8")]
 unsafe fn atomic_umin<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
-    match order {
-        Acquire => intrinsics::atomic_umin_acq(dst, val),
-        Release => intrinsics::atomic_umin_rel(dst, val),
-        AcqRel => intrinsics::atomic_umin_acqrel(dst, val),
-        Relaxed => intrinsics::atomic_umin_relaxed(dst, val),
-        SeqCst => intrinsics::atomic_umin(dst, val),
+    // SAFETY: the caller must uphold the safety contract for `atomic_umin`
+    unsafe {
+        match order {
+            Acquire => intrinsics::atomic_umin_acq(dst, val),
+            Release => intrinsics::atomic_umin_rel(dst, val),
+            AcqRel => intrinsics::atomic_umin_acqrel(dst, val),
+            Relaxed => intrinsics::atomic_umin_relaxed(dst, val),
+            SeqCst => intrinsics::atomic_umin(dst, val),
+        }
     }
 }
 
diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs
index c60ce8ec837..68a5e20a66f 100644
--- a/src/libcore/tests/lib.rs
+++ b/src/libcore/tests/lib.rs
@@ -44,6 +44,8 @@
 #![feature(option_unwrap_none)]
 #![feature(peekable_next_if)]
 #![feature(partition_point)]
+#![feature(unsafe_block_in_unsafe_fn)]
+#![deny(unsafe_op_in_unsafe_fn)]
 
 extern crate test;