From f7d7102d254be9dd41ebcddd1755ef281ada0df7 Mon Sep 17 00:00:00 2001 From: ltdk Date: Tue, 9 Apr 2024 02:01:21 -0400 Subject: [PATCH] Add assert_unsafe_precondition to unchecked_{add,sub,neg,mul,shl,shr} methods --- library/core/src/lib.rs | 1 + library/core/src/num/int_macros.rs | 99 +++++++++++++++---- library/core/src/num/mod.rs | 1 + library/core/src/num/uint_macros.rs | 80 ++++++++++++--- library/core/src/ops/index_range.rs | 11 +-- library/core/src/ptr/const_ptr.rs | 3 +- library/core/src/ptr/mut_ptr.rs | 3 +- library/core/src/ptr/non_null.rs | 3 +- library/core/src/slice/index.rs | 5 +- ...l_unsigned_smaller.Inline.panic-abort.diff | 22 ++++- ..._unsigned_smaller.Inline.panic-unwind.diff | 22 ++++- ...d_smaller.PreCodegen.after.panic-abort.mir | 4 + ..._smaller.PreCodegen.after.panic-unwind.mir | 4 + ..._shr_signed_bigger.Inline.panic-abort.diff | 22 ++++- ...shr_signed_bigger.Inline.panic-unwind.diff | 22 ++++- ...ed_bigger.PreCodegen.after.panic-abort.mir | 4 + ...d_bigger.PreCodegen.after.panic-unwind.mir | 4 + ...ecked_shl.PreCodegen.after.panic-abort.mir | 4 + ...cked_shl.PreCodegen.after.panic-unwind.mir | 4 + ...ut_range.PreCodegen.after.panic-unwind.mir | 47 ++------- ...ed_range.PreCodegen.after.panic-unwind.mir | 35 +------ 21 files changed, 275 insertions(+), 125 deletions(-) diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index dcf68b36c7a2e..6b3ce47da4148 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 77b1039039b1d..b8b4f581a7e63 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 09a341e4d80ac..ab1ede38979da 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 446d0658c1262..141d164de14a2 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 65bda9177c7be..64214eae377dd 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 c8065b2e70906..8c02aee8bfb40 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -1080,6 +1080,7 @@ impl *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 *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 c53953400addd..7c685156cbb07 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -1224,6 +1224,7 @@ impl *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 *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 617890cf083b1..aac5c745d635d 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -701,6 +701,7 @@ impl NonNull { #[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 NonNull { // 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 8d7b6165510a8..98513340a4741 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 SliceIndex<[T]> for ops::Range { // `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 SliceIndex<[T]> for ops::Range { ); // 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 a624ab78dad15..652e24a5f8ec3 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::::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::::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::::unchecked_shl::precondition_check(_4, const core::num::::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 81a0a5b39f71d..dbcae605f7699 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::::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::::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::::unchecked_shl::precondition_check(_4, const core::num::::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 9e3802b7501f5..dc27685ee79b2 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::::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 9e3802b7501f5..dc27685ee79b2 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::::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 a2b3ad4b3babb..88d0621c2877c 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::::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::::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::::unchecked_shr::precondition_check(_4, const core::num::::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 2ff6b532d61fa..6d4c73cf576a6 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::::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::::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::::unchecked_shr::precondition_check(_4, const core::num::::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 f3961982648a8..54f093b87d19f 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::::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 f3961982648a8..54f093b87d19f 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::::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 af0a0efc2a664..4edf0d2c47c05 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 { let mut _3: bool; let mut _4: u32; scope 2 (inlined core::num::::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 af0a0efc2a664..4edf0d2c47c05 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 { let mut _3: bool; let mut _4: u32; scope 2 (inlined core::num::::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-unwind.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir index 62fe1a8685780..9e93a43ac725b 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) -> debug slice => _1; debug index => _2; let mut _0: &mut [u32]; - let mut _3: usize; - let mut _4: usize; scope 1 (inlined core::slice::::get_unchecked_mut::>) { - let mut _5: *mut [u32]; - let mut _9: *mut [u32]; - scope 2 (inlined 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::::as_mut_ptr) { - } - scope 7 (inlined std::ptr::mut_ptr::::add) { - } - scope 8 (inlined slice_from_raw_parts_mut::) { - } - } - scope 4 (inlined std::ptr::mut_ptr::::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 = 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-unwind.mir b/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-unwind.mir index 000432ccca7de..74e8158e75430 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) - 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::::get_unchecked::>) { - scope 2 (inlined 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::::as_ptr) { - } - scope 7 (inlined std::ptr::const_ptr::::add) { - } - scope 8 (inlined slice_from_raw_parts::) { - } - } - scope 4 (inlined std::ptr::const_ptr::::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 = as SliceIndex<[u32]>>::get_unchecked(move _2, move _1) -> [return: bb1, unwind continue]; + } + + bb1: { return; } }