Skip to content

Commit ee88552

Browse files
committed
Fix copy* contract to make it untyped
The intrinsics `copy` and `copy_nonoverlapping` are untyped copies, so they don't respect the validity requirements of `T`.
1 parent d4aa09f commit ee88552

File tree

1 file changed

+6
-6
lines changed

1 file changed

+6
-6
lines changed

library/core/src/intrinsics.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -2728,7 +2728,7 @@ pub const fn is_val_statically_known<T: Copy>(_arg: T) -> bool {
27282728
#[requires(ub_checks::can_dereference(x) && ub_checks::can_write(x))]
27292729
#[requires(ub_checks::can_dereference(y) && ub_checks::can_write(y))]
27302730
#[requires(x.addr() != y.addr() || core::mem::size_of::<T>() == 0)]
2731-
#[requires((x.addr() >= y.addr() + core::mem::size_of::<T>()) || (y.addr() >= x.addr() + core::mem::size_of::<T>()))]
2731+
#[requires(ub_checks::is_nonoverlapping(x as *const (), x as *const (), size_of::<T>(), 1))]
27322732
pub const unsafe fn typed_swap<T>(x: *mut T, y: *mut T) {
27332733
// SAFETY: The caller provided single non-overlapping items behind
27342734
// pointers, so swapping them with `count: 1` is fine.
@@ -2943,11 +2943,11 @@ impl<P: ?Sized, T: ptr::Thin> AggregateRawPtr<*mut T> for *mut P {
29432943
#[inline(always)]
29442944
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
29452945
#[rustc_diagnostic_item = "ptr_copy_nonoverlapping"]
2946+
// Copy is "untyped".
29462947
#[requires(!count.overflowing_mul(size_of::<T>()).1
2947-
&& ub_checks::can_dereference(core::ptr::slice_from_raw_parts(src, count))
2948+
&& ub_checks::can_dereference(core::ptr::slice_from_raw_parts(src as *const crate::mem::MaybeUninit<T>, count))
29482949
&& ub_checks::can_write(core::ptr::slice_from_raw_parts_mut(dst, count)))]
2949-
#[requires(src.addr() != dst.addr() || core::mem::size_of::<T>() == 0)]
2950-
#[requires((src.addr() >= dst.addr() + core::mem::size_of::<T>()) || (dst.addr() >= src.addr() + core::mem::size_of::<T>()))]
2950+
#[requires(ub_checks::is_nonoverlapping(src as *const (), dst as *const (), size_of::<T>(), count))]
29512951
// TODO: Modifies doesn't work with slices today.
29522952
// https://github.com/model-checking/kani/pull/3295
29532953
// #[cfg_attr(kani, kani::modifies(crate::ptr::slice_from_raw_parts(dst, count)))]
@@ -3055,8 +3055,8 @@ pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: us
30553055
#[rustc_diagnostic_item = "ptr_copy"]
30563056
// FIXME: How to verify safety for types that do not implement Copy and count > 1??
30573057
#[requires(!count.overflowing_mul(size_of::<T>()).1
3058-
&& ub_checks::can_dereference(core::ptr::slice_from_raw_parts(src, count))
3059-
&& ub_checks::can_write(core::ptr::slice_from_raw_parts_mut(dst, count)))]
3058+
&& ub_checks::can_dereference(core::ptr::slice_from_raw_parts(src as *const crate::mem::MaybeUninit<T>, count))
3059+
&& ub_checks::can_write(core::ptr::slice_from_raw_parts_mut(dst, count)))]
30603060
// TODO: Modifies doesn't work with slices today.
30613061
// https://github.com/model-checking/kani/pull/3295
30623062
// #[cfg_attr(kani, kani::modifies(crate::ptr::slice_from_raw_parts(dst, count)))]

0 commit comments

Comments
 (0)