diff options
| author | bors <bors@rust-lang.org> | 2024-05-25 18:07:32 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-05-25 18:07:32 +0000 |
| commit | 48f00110d0dae38b3046a9ac05d20ea321fd6637 (patch) | |
| tree | 6417020d2d7bfc7adea7f7632eb00216e544dc44 | |
| parent | 14562ddf8c4302a52c72c9c71f5be6516fec5537 (diff) | |
| parent | 18cb2fa851e13879f182b19883541f66719b714f (diff) | |
| download | rust-48f00110d0dae38b3046a9ac05d20ea321fd6637.tar.gz rust-48f00110d0dae38b3046a9ac05d20ea321fd6637.zip | |
Auto merge of #121571 - clarfonthey:unchecked-math-preconditions, r=saethlin
Add assert_unsafe_precondition to unchecked_{add,sub,neg,mul,shl,shr} methods
(Old PR is haunted, opening a new one. See #117494 for previous discussion.)
This ensures that these preconditions are actually checked in debug mode, and hopefully should let people know if they messed up. I've also replaced the calls (I could find) in the code that use these intrinsics directly with those that use these methods, so that the asserts actually apply.
More discussions on people misusing these methods in the tracking issue: https://github.com/rust-lang/rust/issues/85122.
24 files changed, 291 insertions, 199 deletions
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 206d1ab8852..86078c8377b 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -191,6 +191,7 @@ #![feature(str_split_remainder)] #![feature(strict_provenance)] #![feature(ub_checks)] +#![feature(unchecked_neg)] #![feature(unchecked_shifts)] #![feature(utf16_extra)] #![feature(utf16_extra_const)] diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 77b1039039b..b8b4f581a7e 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -488,9 +488,19 @@ macro_rules! int_impl { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_add(self, rhs: Self) -> Self { - // SAFETY: the caller must uphold the safety contract for - // `unchecked_add`. - unsafe { intrinsics::unchecked_add(self, rhs) } + assert_unsafe_precondition!( + check_language_ub, + concat!(stringify!($SelfT), "::unchecked_add cannot overflow"), + ( + lhs: $SelfT = self, + rhs: $SelfT = rhs, + ) => !lhs.overflowing_add(rhs).1, + ); + + // SAFETY: this is guaranteed to be safe by the caller. + unsafe { + intrinsics::unchecked_add(self, rhs) + } } /// Checked addition with an unsigned integer. Computes `self + rhs`, @@ -630,9 +640,19 @@ macro_rules! int_impl { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_sub(self, rhs: Self) -> Self { - // SAFETY: the caller must uphold the safety contract for - // `unchecked_sub`. - unsafe { intrinsics::unchecked_sub(self, rhs) } + assert_unsafe_precondition!( + check_language_ub, + concat!(stringify!($SelfT), "::unchecked_sub cannot overflow"), + ( + lhs: $SelfT = self, + rhs: $SelfT = rhs, + ) => !lhs.overflowing_sub(rhs).1, + ); + + // SAFETY: this is guaranteed to be safe by the caller. + unsafe { + intrinsics::unchecked_sub(self, rhs) + } } /// Checked subtraction with an unsigned integer. Computes `self - rhs`, @@ -772,9 +792,19 @@ macro_rules! int_impl { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_mul(self, rhs: Self) -> Self { - // SAFETY: the caller must uphold the safety contract for - // `unchecked_mul`. - unsafe { intrinsics::unchecked_mul(self, rhs) } + assert_unsafe_precondition!( + check_language_ub, + concat!(stringify!($SelfT), "::unchecked_mul cannot overflow"), + ( + lhs: $SelfT = self, + rhs: $SelfT = rhs, + ) => !lhs.overflowing_mul(rhs).1, + ); + + // SAFETY: this is guaranteed to be safe by the caller. + unsafe { + intrinsics::unchecked_mul(self, rhs) + } } /// Checked integer division. Computes `self / rhs`, returning `None` if `rhs == 0` @@ -1111,9 +1141,22 @@ macro_rules! int_impl { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_neg(self) -> Self { - // SAFETY: the caller must uphold the safety contract for - // `unchecked_neg`. - unsafe { intrinsics::unchecked_sub(0, self) } + // ICE resolved by #125184 isn't in bootstrap compiler + #[cfg(not(bootstrap))] + { + assert_unsafe_precondition!( + check_language_ub, + concat!(stringify!($SelfT), "::unchecked_neg cannot overflow"), + ( + lhs: $SelfT = self, + ) => !lhs.overflowing_neg().1, + ); + } + + // SAFETY: this is guaranteed to be safe by the caller. + unsafe { + intrinsics::unchecked_sub(0, self) + } } /// Strict negation. Computes `-self`, panicking if `self == MIN`. @@ -1234,9 +1277,19 @@ macro_rules! int_impl { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self { - // SAFETY: the caller must uphold the safety contract for - // `unchecked_shl`. - unsafe { intrinsics::unchecked_shl(self, rhs) } + assert_unsafe_precondition!( + check_language_ub, + concat!(stringify!($SelfT), "::unchecked_shl cannot overflow"), + ( + rhs: u32 = rhs, + bits: u32 = Self::BITS, + ) => rhs < bits, + ); + + // SAFETY: this is guaranteed to be safe by the caller. + unsafe { + intrinsics::unchecked_shl(self, rhs) + } } /// Checked shift right. Computes `self >> rhs`, returning `None` if `rhs` is @@ -1323,9 +1376,19 @@ macro_rules! int_impl { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self { - // SAFETY: the caller must uphold the safety contract for - // `unchecked_shr`. - unsafe { intrinsics::unchecked_shr(self, rhs) } + assert_unsafe_precondition!( + check_language_ub, + concat!(stringify!($SelfT), "::unchecked_shr cannot overflow"), + ( + rhs: u32 = rhs, + bits: u32 = Self::BITS, + ) => rhs < bits, + ); + + // SAFETY: this is guaranteed to be safe by the caller. + unsafe { + intrinsics::unchecked_shr(self, rhs) + } } /// Checked absolute value. Computes `self.abs()`, returning `None` if diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 09a341e4d80..ab1ede38979 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -7,6 +7,7 @@ use crate::hint; use crate::intrinsics; use crate::mem; use crate::str::FromStr; +use crate::ub_checks::assert_unsafe_precondition; // Used because the `?` operator is not allowed in a const context. macro_rules! try_opt { diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 446d0658c12..141d164de14 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -495,9 +495,19 @@ macro_rules! uint_impl { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_add(self, rhs: Self) -> Self { - // SAFETY: the caller must uphold the safety contract for - // `unchecked_add`. - unsafe { intrinsics::unchecked_add(self, rhs) } + assert_unsafe_precondition!( + check_language_ub, + concat!(stringify!($SelfT), "::unchecked_add cannot overflow"), + ( + lhs: $SelfT = self, + rhs: $SelfT = rhs, + ) => !lhs.overflowing_add(rhs).1, + ); + + // SAFETY: this is guaranteed to be safe by the caller. + unsafe { + intrinsics::unchecked_add(self, rhs) + } } /// Checked addition with a signed integer. Computes `self + rhs`, @@ -677,9 +687,19 @@ macro_rules! uint_impl { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_sub(self, rhs: Self) -> Self { - // SAFETY: the caller must uphold the safety contract for - // `unchecked_sub`. - unsafe { intrinsics::unchecked_sub(self, rhs) } + assert_unsafe_precondition!( + check_language_ub, + concat!(stringify!($SelfT), "::unchecked_sub cannot overflow"), + ( + lhs: $SelfT = self, + rhs: $SelfT = rhs, + ) => !lhs.overflowing_sub(rhs).1, + ); + + // SAFETY: this is guaranteed to be safe by the caller. + unsafe { + intrinsics::unchecked_sub(self, rhs) + } } /// Checked integer multiplication. Computes `self * rhs`, returning @@ -763,9 +783,19 @@ macro_rules! uint_impl { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_mul(self, rhs: Self) -> Self { - // SAFETY: the caller must uphold the safety contract for - // `unchecked_mul`. - unsafe { intrinsics::unchecked_mul(self, rhs) } + assert_unsafe_precondition!( + check_language_ub, + concat!(stringify!($SelfT), "::unchecked_mul cannot overflow"), + ( + lhs: $SelfT = self, + rhs: $SelfT = rhs, + ) => !lhs.overflowing_mul(rhs).1, + ); + + // SAFETY: this is guaranteed to be safe by the caller. + unsafe { + intrinsics::unchecked_mul(self, rhs) + } } /// Checked integer division. Computes `self / rhs`, returning `None` @@ -1334,9 +1364,19 @@ macro_rules! uint_impl { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self { - // SAFETY: the caller must uphold the safety contract for - // `unchecked_shl`. - unsafe { intrinsics::unchecked_shl(self, rhs) } + assert_unsafe_precondition!( + check_language_ub, + concat!(stringify!($SelfT), "::unchecked_shl cannot overflow"), + ( + rhs: u32 = rhs, + bits: u32 = Self::BITS, + ) => rhs < bits, + ); + + // SAFETY: this is guaranteed to be safe by the caller. + unsafe { + intrinsics::unchecked_shl(self, rhs) + } } /// Checked shift right. Computes `self >> rhs`, returning `None` @@ -1423,9 +1463,19 @@ macro_rules! uint_impl { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self { - // SAFETY: the caller must uphold the safety contract for - // `unchecked_shr`. - unsafe { intrinsics::unchecked_shr(self, rhs) } + assert_unsafe_precondition!( + check_language_ub, + concat!(stringify!($SelfT), "::unchecked_shr cannot overflow"), + ( + rhs: u32 = rhs, + bits: u32 = Self::BITS, + ) => rhs < bits, + ); + + // SAFETY: this is guaranteed to be safe by the caller. + unsafe { + intrinsics::unchecked_shr(self, rhs) + } } /// Checked exponentiation. Computes `self.pow(exp)`, returning `None` if diff --git a/library/core/src/ops/index_range.rs b/library/core/src/ops/index_range.rs index 65bda9177c7..64214eae377 100644 --- a/library/core/src/ops/index_range.rs +++ b/library/core/src/ops/index_range.rs @@ -1,4 +1,3 @@ -use crate::intrinsics::{unchecked_add, unchecked_sub}; use crate::iter::{FusedIterator, TrustedLen}; use crate::num::NonZero; use crate::ub_checks; @@ -46,7 +45,7 @@ impl IndexRange { #[inline] pub const fn len(&self) -> usize { // SAFETY: By invariant, this cannot wrap - unsafe { unchecked_sub(self.end, self.start) } + unsafe { self.end.unchecked_sub(self.start) } } /// # Safety @@ -57,7 +56,7 @@ impl IndexRange { let value = self.start; // SAFETY: The range isn't empty, so this cannot overflow - self.start = unsafe { unchecked_add(value, 1) }; + self.start = unsafe { value.unchecked_add(1) }; value } @@ -68,7 +67,7 @@ impl IndexRange { debug_assert!(self.start < self.end); // SAFETY: The range isn't empty, so this cannot overflow - let value = unsafe { unchecked_sub(self.end, 1) }; + let value = unsafe { self.end.unchecked_sub(1) }; self.end = value; value } @@ -83,7 +82,7 @@ impl IndexRange { let mid = if n <= self.len() { // SAFETY: We just checked that this will be between start and end, // and thus the addition cannot overflow. - unsafe { unchecked_add(self.start, n) } + unsafe { self.start.unchecked_add(n) } } else { self.end }; @@ -102,7 +101,7 @@ impl IndexRange { let mid = if n <= self.len() { // SAFETY: We just checked that this will be between start and end, // and thus the addition cannot overflow. - unsafe { unchecked_sub(self.end, n) } + unsafe { self.end.unchecked_sub(n) } } else { self.start }; diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index c8065b2e709..8c02aee8bfb 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -1080,6 +1080,7 @@ impl<T: ?Sized> *const T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[must_use = "returns a new pointer rather than modifying its argument"] #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] + #[rustc_allow_const_fn_unstable(unchecked_neg)] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn sub(self, count: usize) -> Self @@ -1093,7 +1094,7 @@ impl<T: ?Sized> *const T { // SAFETY: the caller must uphold the safety contract for `offset`. // Because the pointee is *not* a ZST, that means that `count` is // at most `isize::MAX`, and thus the negation cannot overflow. - unsafe { self.offset(intrinsics::unchecked_sub(0, count as isize)) } + unsafe { self.offset((count as isize).unchecked_neg()) } } } diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index c53953400ad..7c685156cbb 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -1224,6 +1224,7 @@ impl<T: ?Sized> *mut T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[must_use = "returns a new pointer rather than modifying its argument"] #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] + #[rustc_allow_const_fn_unstable(unchecked_neg)] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn sub(self, count: usize) -> Self @@ -1237,7 +1238,7 @@ impl<T: ?Sized> *mut T { // SAFETY: the caller must uphold the safety contract for `offset`. // Because the pointee is *not* a ZST, that means that `count` is // at most `isize::MAX`, and thus the negation cannot overflow. - unsafe { self.offset(intrinsics::unchecked_sub(0, count as isize)) } + unsafe { self.offset((count as isize).unchecked_neg()) } } } diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index 617890cf083..aac5c745d63 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -701,6 +701,7 @@ impl<T: ?Sized> NonNull<T> { #[must_use = "returns a new pointer rather than modifying its argument"] #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[rustc_allow_const_fn_unstable(unchecked_neg)] pub const unsafe fn sub(self, count: usize) -> Self where T: Sized, @@ -712,7 +713,7 @@ impl<T: ?Sized> NonNull<T> { // SAFETY: the caller must uphold the safety contract for `offset`. // Because the pointee is *not* a ZST, that means that `count` is // at most `isize::MAX`, and thus the negation cannot overflow. - unsafe { self.offset(intrinsics::unchecked_sub(0, count as isize)) } + unsafe { self.offset((count as isize).unchecked_neg()) } } } diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs index 8d7b6165510..98513340a47 100644 --- a/library/core/src/slice/index.rs +++ b/library/core/src/slice/index.rs @@ -1,7 +1,6 @@ //! Indexing implementations for `[T]`. use crate::intrinsics::const_eval_select; -use crate::intrinsics::unchecked_sub; use crate::ops; use crate::ptr; use crate::ub_checks::assert_unsafe_precondition; @@ -374,7 +373,7 @@ unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> { // `self` is in bounds of `slice` so `self` cannot overflow an `isize`, // so the call to `add` is safe and the length calculation cannot overflow. unsafe { - let new_len = unchecked_sub(self.end, self.start); + let new_len = self.end.unchecked_sub(self.start); ptr::slice_from_raw_parts(slice.as_ptr().add(self.start), new_len) } } @@ -392,7 +391,7 @@ unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> { ); // SAFETY: see comments for `get_unchecked` above. unsafe { - let new_len = unchecked_sub(self.end, self.start); + let new_len = self.end.unchecked_sub(self.start); ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().add(self.start), new_len) } } diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff index a624ab78dad..652e24a5f8e 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff @@ -8,6 +8,12 @@ let mut _3: u16; let mut _4: u32; + scope 1 (inlined core::num::<impl u16>::unchecked_shl) { ++ let mut _5: bool; ++ let _6: (); ++ scope 2 (inlined core::ub_checks::check_language_ub) { ++ scope 3 (inlined core::ub_checks::check_language_ub::runtime) { ++ } ++ } + } bb0: { @@ -16,10 +22,20 @@ StorageLive(_4); _4 = _2; - _0 = core::num::<impl u16>::unchecked_shl(move _3, move _4) -> [return: bb1, unwind unreachable]; -- } -- -- bb1: { ++ StorageLive(_6); ++ StorageLive(_5); ++ _5 = UbChecks(); ++ switchInt(move _5) -> [0: bb2, otherwise: bb1]; + } + + bb1: { ++ _6 = core::num::<impl u16>::unchecked_shl::precondition_check(_4, const core::num::<impl u16>::BITS) -> [return: bb2, unwind unreachable]; ++ } ++ ++ bb2: { ++ StorageDead(_5); + _0 = ShlUnchecked(_3, _4); ++ StorageDead(_6); StorageDead(_4); StorageDead(_3); return; diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff index 81a0a5b39f7..dbcae605f76 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff @@ -8,6 +8,12 @@ let mut _3: u16; let mut _4: u32; + scope 1 (inlined core::num::<impl u16>::unchecked_shl) { ++ let mut _5: bool; ++ let _6: (); ++ scope 2 (inlined core::ub_checks::check_language_ub) { ++ scope 3 (inlined core::ub_checks::check_language_ub::runtime) { ++ } ++ } + } bb0: { @@ -16,10 +22,20 @@ StorageLive(_4); _4 = _2; - _0 = core::num::<impl u16>::unchecked_shl(move _3, move _4) -> [return: bb1, unwind continue]; -- } -- -- bb1: { ++ StorageLive(_6); ++ StorageLive(_5); ++ _5 = UbChecks(); ++ switchInt(move _5) -> [0: bb2, otherwise: bb1]; + } + + bb1: { ++ _6 = core::num::<impl u16>::unchecked_shl::precondition_check(_4, const core::num::<impl u16>::BITS) -> [return: bb2, unwind unreachable]; ++ } ++ ++ bb2: { ++ StorageDead(_5); + _0 = ShlUnchecked(_3, _4); ++ StorageDead(_6); StorageDead(_4); StorageDead(_3); return; diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-abort.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-abort.mir index 9e3802b7501..dc27685ee79 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-abort.mir @@ -5,6 +5,10 @@ fn unchecked_shl_unsigned_smaller(_1: u16, _2: u32) -> u16 { debug b => _2; let mut _0: u16; scope 1 (inlined core::num::<impl u16>::unchecked_shl) { + scope 2 (inlined core::ub_checks::check_language_ub) { + scope 3 (inlined core::ub_checks::check_language_ub::runtime) { + } + } } bb0: { diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-unwind.mir index 9e3802b7501..dc27685ee79 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-unwind.mir @@ -5,6 +5,10 @@ fn unchecked_shl_unsigned_smaller(_1: u16, _2: u32) -> u16 { debug b => _2; let mut _0: u16; scope 1 (inlined core::num::<impl u16>::unchecked_shl) { + scope 2 (inlined core::ub_checks::check_language_ub) { + scope 3 (inlined core::ub_checks::check_language_ub::runtime) { + } + } } bb0: { diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-abort.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-abort.diff index a2b3ad4b3ba..88d0621c287 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-abort.diff @@ -8,6 +8,12 @@ let mut _3: i64; let mut _4: u32; + scope 1 (inlined core::num::<impl i64>::unchecked_shr) { ++ let mut _5: bool; ++ let _6: (); ++ scope 2 (inlined core::ub_checks::check_language_ub) { ++ scope 3 (inlined core::ub_checks::check_language_ub::runtime) { ++ } ++ } + } bb0: { @@ -16,10 +22,20 @@ StorageLive(_4); _4 = _2; - _0 = core::num::<impl i64>::unchecked_shr(move _3, move _4) -> [return: bb1, unwind unreachable]; -- } -- -- bb1: { ++ StorageLive(_6); ++ StorageLive(_5); ++ _5 = UbChecks(); ++ switchInt(move _5) -> [0: bb2, otherwise: bb1]; + } + + bb1: { ++ _6 = core::num::<impl i64>::unchecked_shr::precondition_check(_4, const core::num::<impl i64>::BITS) -> [return: bb2, unwind unreachable]; ++ } ++ ++ bb2: { ++ StorageDead(_5); + _0 = ShrUnchecked(_3, _4); ++ StorageDead(_6); StorageDead(_4); StorageDead(_3); return; diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff index 2ff6b532d61..6d4c73cf576 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff @@ -8,6 +8,12 @@ let mut _3: i64; let mut _4: u32; + scope 1 (inlined core::num::<impl i64>::unchecked_shr) { ++ let mut _5: bool; ++ let _6: (); ++ scope 2 (inlined core::ub_checks::check_language_ub) { ++ scope 3 (inlined core::ub_checks::check_language_ub::runtime) { ++ } ++ } + } bb0: { @@ -16,10 +22,20 @@ StorageLive(_4); _4 = _2; - _0 = core::num::<impl i64>::unchecked_shr(move _3, move _4) -> [return: bb1, unwind continue]; -- } -- -- bb1: { ++ StorageLive(_6); ++ StorageLive(_5); ++ _5 = UbChecks(); ++ switchInt(move _5) -> [0: bb2, otherwise: bb1]; + } + + bb1: { ++ _6 = core::num::<impl i64>::unchecked_shr::precondition_check(_4, const core::num::<impl i64>::BITS) -> [return: bb2, unwind unreachable]; ++ } ++ ++ bb2: { ++ StorageDead(_5); + _0 = ShrUnchecked(_3, _4); ++ StorageDead(_6); StorageDead(_4); StorageDead(_3); return; diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.PreCodegen.after.panic-abort.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.PreCodegen.after.panic-abort.mir index f3961982648..54f093b87d1 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.PreCodegen.after.panic-abort.mir @@ -5,6 +5,10 @@ fn unchecked_shr_signed_bigger(_1: i64, _2: u32) -> i64 { debug b => _2; let mut _0: i64; scope 1 (inlined core::num::<impl i64>::unchecked_shr) { + scope 2 (inlined core::ub_checks::check_language_ub) { + scope 3 (inlined core::ub_checks::check_language_ub::runtime) { + } + } } bb0: { diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.PreCodegen.after.panic-unwind.mir index f3961982648..54f093b87d1 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.PreCodegen.after.panic-unwind.mir @@ -5,6 +5,10 @@ fn unchecked_shr_signed_bigger(_1: i64, _2: u32) -> i64 { debug b => _2; let mut _0: i64; scope 1 (inlined core::num::<impl i64>::unchecked_shr) { + scope 2 (inlined core::ub_checks::check_language_ub) { + scope 3 (inlined core::ub_checks::check_language_ub::runtime) { + } + } } bb0: { diff --git a/tests/mir-opt/pre-codegen/checked_ops.checked_shl.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/checked_ops.checked_shl.PreCodegen.after.panic-abort.mir index af0a0efc2a6..4edf0d2c47c 100644 --- a/tests/mir-opt/pre-codegen/checked_ops.checked_shl.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/checked_ops.checked_shl.PreCodegen.after.panic-abort.mir @@ -8,6 +8,10 @@ fn checked_shl(_1: u32, _2: u32) -> Option<u32> { let mut _3: bool; let mut _4: u32; scope 2 (inlined core::num::<impl u32>::unchecked_shl) { + scope 3 (inlined core::ub_checks::check_language_ub) { + scope 4 (inlined core::ub_checks::check_language_ub::runtime) { + } + } } } diff --git a/tests/mir-opt/pre-codegen/checked_ops.checked_shl.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/checked_ops.checked_shl.PreCodegen.after.panic-unwind.mir index af0a0efc2a6..4edf0d2c47c 100644 --- a/tests/mir-opt/pre-codegen/checked_ops.checked_shl.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/checked_ops.checked_shl.PreCodegen.after.panic-unwind.mir @@ -8,6 +8,10 @@ fn checked_shl(_1: u32, _2: u32) -> Option<u32> { let mut _3: bool; let mut _4: u32; scope 2 (inlined core::num::<impl u32>::unchecked_shl) { + scope 3 (inlined core::ub_checks::check_language_ub) { + scope 4 (inlined core::ub_checks::check_language_ub::runtime) { + } + } } } diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir index 62fe1a86857..ef3f4a21720 100644 --- a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir @@ -4,47 +4,20 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) -> debug slice => _1; debug index => _2; let mut _0: &mut [u32]; - let mut _3: usize; - let mut _4: usize; scope 1 (inlined core::slice::<impl [u32]>::get_unchecked_mut::<std::ops::Range<usize>>) { - let mut _5: *mut [u32]; - let mut _9: *mut [u32]; - scope 2 (inlined <std::ops::Range<usize> as SliceIndex<[u32]>>::get_unchecked_mut) { - let _6: usize; - let mut _7: *mut u32; - let mut _8: *mut u32; - scope 3 { - scope 6 (inlined std::ptr::mut_ptr::<impl *mut [u32]>::as_mut_ptr) { - } - scope 7 (inlined std::ptr::mut_ptr::<impl *mut u32>::add) { - } - scope 8 (inlined slice_from_raw_parts_mut::<u32>) { - } - } - scope 4 (inlined std::ptr::mut_ptr::<impl *mut [u32]>::len) { - scope 5 (inlined std::ptr::metadata::<[u32]>) { - } - } - } + let mut _3: *mut [u32]; + let mut _4: *mut [u32]; } bb0: { - _3 = move (_2.0: usize); - _4 = move (_2.1: usize); - StorageLive(_5); - _5 = &raw mut (*_1); - StorageLive(_6); - _6 = SubUnchecked(_4, _3); - StorageLive(_8); - StorageLive(_7); - _7 = _5 as *mut u32 (PtrToPtr); - _8 = Offset(_7, _3); - StorageDead(_7); - _9 = *mut [u32] from (_8, _6); - StorageDead(_8); - StorageDead(_6); - StorageDead(_5); - _0 = &mut (*_9); + StorageLive(_3); + _3 = &raw mut (*_1); + _4 = <std::ops::Range<usize> as SliceIndex<[u32]>>::get_unchecked_mut(move _2, move _3) -> [return: bb1, unwind unreachable]; + } + + bb1: { + StorageDead(_3); + _0 = &mut (*_4); return; } } diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir index 62fe1a86857..9e93a43ac72 100644 --- a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir @@ -4,47 +4,20 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) -> debug slice => _1; debug index => _2; let mut _0: &mut [u32]; - let mut _3: usize; - let mut _4: usize; scope 1 (inlined core::slice::<impl [u32]>::get_unchecked_mut::<std::ops::Range<usize>>) { - let mut _5: *mut [u32]; - let mut _9: *mut [u32]; - scope 2 (inlined <std::ops::Range<usize> as SliceIndex<[u32]>>::get_unchecked_mut) { - let _6: usize; - let mut _7: *mut u32; - let mut _8: *mut u32; - scope 3 { - scope 6 (inlined std::ptr::mut_ptr::<impl *mut [u32]>::as_mut_ptr) { - } - scope 7 (inlined std::ptr::mut_ptr::<impl *mut u32>::add) { - } - scope 8 (inlined slice_from_raw_parts_mut::<u32>) { - } - } - scope 4 (inlined std::ptr::mut_ptr::<impl *mut [u32]>::len) { - scope 5 (inlined std::ptr::metadata::<[u32]>) { - } - } - } + let mut _3: *mut [u32]; + let mut _4: *mut [u32]; } bb0: { - _3 = move (_2.0: usize); - _4 = move (_2.1: usize); - StorageLive(_5); - _5 = &raw mut (*_1); - StorageLive(_6); - _6 = SubUnchecked(_4, _3); - StorageLive(_8); - StorageLive(_7); - _7 = _5 as *mut u32 (PtrToPtr); - _8 = Offset(_7, _3); - StorageDead(_7); - _9 = *mut [u32] from (_8, _6); - StorageDead(_8); - StorageDead(_6); - StorageDead(_5); - _0 = &mut (*_9); + StorageLive(_3); + _3 = &raw mut (*_1); + _4 = <std::ops::Range<usize> as SliceIndex<[u32]>>::get_unchecked_mut(move _2, move _3) -> [return: bb1, unwind continue]; + } + + bb1: { + StorageDead(_3); + _0 = &mut (*_4); return; } } diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-abort.mir index 000432ccca7..650069ee6ce 100644 --- a/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-abort.mir @@ -4,41 +4,14 @@ fn slice_ptr_get_unchecked_range(_1: *const [u32], _2: std::ops::Range<usize>) - debug slice => _1; debug index => _2; let mut _0: *const [u32]; - let mut _3: usize; - let mut _4: usize; scope 1 (inlined std::ptr::const_ptr::<impl *const [u32]>::get_unchecked::<std::ops::Range<usize>>) { - scope 2 (inlined <std::ops::Range<usize> as SliceIndex<[u32]>>::get_unchecked) { - let _5: usize; - let mut _6: *const u32; - let mut _7: *const u32; - scope 3 { - scope 6 (inlined std::ptr::const_ptr::<impl *const [u32]>::as_ptr) { - } - scope 7 (inlined std::ptr::const_ptr::<impl *const u32>::add) { - } - scope 8 (inlined slice_from_raw_parts::<u32>) { - } - } - scope 4 (inlined std::ptr::const_ptr::<impl *const [u32]>::len) { - scope 5 (inlined std::ptr::metadata::<[u32]>) { - } - } - } } bb0: { - _3 = move (_2.0: usize); - _4 = move (_2.1: usize); - StorageLive(_5); - _5 = SubUnchecked(_4, _3); - StorageLive(_7); - StorageLive(_6); - _6 = _1 as *const u32 (PtrToPtr); - _7 = Offset(_6, _3); - StorageDead(_6); - _0 = *const [u32] from (_7, _5); - StorageDead(_7); - StorageDead(_5); + _0 = <std::ops::Range<usize> as SliceIndex<[u32]>>::get_unchecked(move _2, move _1) -> [return: bb1, unwind unreachable]; + } + + bb1: { return; } } diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-unwind.mir index 000432ccca7..74e8158e754 100644 --- a/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-unwind.mir @@ -4,41 +4,14 @@ fn slice_ptr_get_unchecked_range(_1: *const [u32], _2: std::ops::Range<usize>) - debug slice => _1; debug index => _2; let mut _0: *const [u32]; - let mut _3: usize; - let mut _4: usize; scope 1 (inlined std::ptr::const_ptr::<impl *const [u32]>::get_unchecked::<std::ops::Range<usize>>) { - scope 2 (inlined <std::ops::Range<usize> as SliceIndex<[u32]>>::get_unchecked) { - let _5: usize; - let mut _6: *const u32; - let mut _7: *const u32; - scope 3 { - scope 6 (inlined std::ptr::const_ptr::<impl *const [u32]>::as_ptr) { - } - scope 7 (inlined std::ptr::const_ptr::<impl *const u32>::add) { - } - scope 8 (inlined slice_from_raw_parts::<u32>) { - } - } - scope 4 (inlined std::ptr::const_ptr::<impl *const [u32]>::len) { - scope 5 (inlined std::ptr::metadata::<[u32]>) { - } - } - } } bb0: { - _3 = move (_2.0: usize); - _4 = move (_2.1: usize); - StorageLive(_5); - _5 = SubUnchecked(_4, _3); - StorageLive(_7); - StorageLive(_6); - _6 = _1 as *const u32 (PtrToPtr); - _7 = Offset(_6, _3); - StorageDead(_6); - _0 = *const [u32] from (_7, _5); - StorageDead(_7); - StorageDead(_5); + _0 = <std::ops::Range<usize> as SliceIndex<[u32]>>::get_unchecked(move _2, move _1) -> [return: bb1, unwind continue]; + } + + bb1: { return; } } diff --git a/tests/run-make/libtest-padding/tests.rs b/tests/run-make/libtest-padding/tests.rs index cadf07237e9..97a99b47b5c 100644 --- a/tests/run-make/libtest-padding/tests.rs +++ b/tests/run-make/libtest-padding/tests.rs @@ -8,11 +8,7 @@ fn short_test_name() {} fn this_is_a_really_long_test_name() {} #[bench] -fn short_bench_name(b: &mut test::Bencher) { - b.iter(|| 1); -} +fn short_bench_name(b: &mut test::Bencher) {} #[bench] -fn this_is_a_really_long_bench_name(b: &mut test::Bencher) { - b.iter(|| 1); -} +fn this_is_a_really_long_bench_name(b: &mut test::Bencher) {} |
