Add debug assertions to write_bytes and copy*
This commit is contained in:
parent
5480b47d7f
commit
009c4a7efe
@ -36,6 +36,8 @@
|
||||
issue = "0")]
|
||||
#![allow(missing_docs)]
|
||||
|
||||
use crate::mem;
|
||||
|
||||
#[stable(feature = "drop_in_place", since = "1.8.0")]
|
||||
#[rustc_deprecated(reason = "no longer an intrinsic - use `ptr::drop_in_place` directly",
|
||||
since = "1.18.0")]
|
||||
@ -1323,6 +1325,26 @@ pub fn volatile_copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T,
|
||||
// (`transmute` also falls into this category, but it cannot be wrapped due to the
|
||||
// check that `T` and `U` have the same size.)
|
||||
|
||||
/// Checks whether `ptr` is properly aligned with respect to
|
||||
/// `align_of::<T>()`.
|
||||
pub(crate) fn is_aligned_and_not_null<T>(ptr: *const T) -> bool {
|
||||
!ptr.is_null() && ptr as usize % mem::align_of::<T>() == 0
|
||||
}
|
||||
|
||||
/// Checks whether the regions of memory starting at `src` and `dst` of size
|
||||
/// `count * size_of::<T>()` overlap.
|
||||
fn overlaps<T>(src: *const T, dst: *const T, count: usize) -> bool {
|
||||
let src_usize = src as usize;
|
||||
let dst_usize = dst as usize;
|
||||
let size = mem::size_of::<T>().checked_mul(count).unwrap();
|
||||
let diff = if src_usize > dst_usize {
|
||||
src_usize - dst_usize
|
||||
} else {
|
||||
dst_usize - src_usize
|
||||
};
|
||||
size > diff
|
||||
}
|
||||
|
||||
/// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
|
||||
/// and destination must *not* overlap.
|
||||
///
|
||||
@ -1412,7 +1434,11 @@ pub unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize) {
|
||||
extern "rust-intrinsic" {
|
||||
fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
|
||||
}
|
||||
copy_nonoverlapping(src, dst, count);
|
||||
|
||||
debug_assert!(is_aligned_and_not_null(src), "attempt to copy from unaligned or null pointer");
|
||||
debug_assert!(is_aligned_and_not_null(dst), "attempt to copy to unaligned or null pointer");
|
||||
debug_assert!(!overlaps(src, dst, count), "attempt to copy to overlapping memory");
|
||||
copy_nonoverlapping(src, dst, count)
|
||||
}
|
||||
|
||||
/// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
|
||||
@ -1472,6 +1498,9 @@ pub unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
|
||||
extern "rust-intrinsic" {
|
||||
fn copy<T>(src: *const T, dst: *mut T, count: usize);
|
||||
}
|
||||
|
||||
debug_assert!(is_aligned_and_not_null(src), "attempt to copy from unaligned or null pointer");
|
||||
debug_assert!(is_aligned_and_not_null(dst), "attempt to copy to unaligned or null pointer");
|
||||
copy(src, dst, count)
|
||||
}
|
||||
|
||||
@ -1553,5 +1582,7 @@ pub unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
|
||||
extern "rust-intrinsic" {
|
||||
fn write_bytes<T>(dst: *mut T, val: u8, count: usize);
|
||||
}
|
||||
|
||||
debug_assert!(is_aligned_and_not_null(dst), "attempt to write to unaligned or null pointer");
|
||||
write_bytes(dst, val, count)
|
||||
}
|
||||
|
@ -25,7 +25,7 @@
|
||||
use crate::cmp::Ordering::{self, Less, Equal, Greater};
|
||||
use crate::cmp;
|
||||
use crate::fmt;
|
||||
use crate::intrinsics::{assume, exact_div, unchecked_sub};
|
||||
use crate::intrinsics::{assume, exact_div, unchecked_sub, is_aligned_and_not_null};
|
||||
use crate::isize;
|
||||
use crate::iter::*;
|
||||
use crate::ops::{FnMut, Try, self};
|
||||
@ -5228,7 +5228,7 @@ fn may_have_side_effect() -> bool { false }
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] {
|
||||
debug_assert!(data as usize % mem::align_of::<T>() == 0, "attempt to create unaligned slice");
|
||||
debug_assert!(is_aligned_and_not_null(data), "attempt to create unaligned or null slice");
|
||||
debug_assert!(mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize,
|
||||
"attempt to create slice covering half the address space");
|
||||
&*ptr::slice_from_raw_parts(data, len)
|
||||
@ -5249,7 +5249,7 @@ pub unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] {
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] {
|
||||
debug_assert!(data as usize % mem::align_of::<T>() == 0, "attempt to create unaligned slice");
|
||||
debug_assert!(is_aligned_and_not_null(data), "attempt to create unaligned or null slice");
|
||||
debug_assert!(mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize,
|
||||
"attempt to create slice covering half the address space");
|
||||
&mut *ptr::slice_from_raw_parts_mut(data, len)
|
||||
|
Loading…
Reference in New Issue
Block a user