memory access sanity checks: abort instead of panic

This commit is contained in:
Ralf Jung 2020-06-06 11:56:58 +02:00 committed by Mark Rousskov
parent c8a9c340de
commit f0a42332b8
2 changed files with 33 additions and 12 deletions

View File

@ -2057,9 +2057,14 @@ pub unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize) {
fn copy_nonoverlapping<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");
debug_assert!(is_nonoverlapping(src, dst, count), "attempt to copy to overlapping memory");
if cfg!(debug_assertions)
&& !(is_aligned_and_not_null(src)
&& is_aligned_and_not_null(dst)
&& is_nonoverlapping(src, dst, count))
{
// Not panicking to keep codegen impact smaller.
abort();
}
copy_nonoverlapping(src, dst, count)
}
@ -2122,8 +2127,10 @@ pub unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
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");
if cfg!(debug_assertions) && !(is_aligned_and_not_null(src) && is_aligned_and_not_null(dst)) {
// Not panicking to keep codegen impact smaller.
abort();
}
copy(src, dst, count)
}

View File

@ -70,7 +70,7 @@
use crate::cmp::Ordering;
use crate::fmt;
use crate::hash;
use crate::intrinsics::{self, is_aligned_and_not_null, is_nonoverlapping};
use crate::intrinsics::{self, abort, is_aligned_and_not_null, is_nonoverlapping};
use crate::mem::{self, MaybeUninit};
#[stable(feature = "rust1", since = "1.0.0")]
@ -420,9 +420,14 @@ pub unsafe fn swap<T>(x: *mut T, y: *mut T) {
#[inline]
#[stable(feature = "swap_nonoverlapping", since = "1.27.0")]
pub unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
debug_assert!(is_aligned_and_not_null(x), "attempt to swap unaligned or null pointer");
debug_assert!(is_aligned_and_not_null(y), "attempt to swap unaligned or null pointer");
debug_assert!(is_nonoverlapping(x, y, count), "attempt to swap overlapping memory");
if cfg!(debug_assertions)
&& !(is_aligned_and_not_null(x)
&& is_aligned_and_not_null(y)
&& is_nonoverlapping(x, y, count))
{
// Not panicking to keep codegen impact smaller.
abort();
}
let x = x as *mut u8;
let y = y as *mut u8;
@ -838,7 +843,10 @@ pub unsafe fn read_unaligned<T>(src: *const T) -> T {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn write<T>(dst: *mut T, src: T) {
debug_assert!(is_aligned_and_not_null(dst), "attempt to write to unaligned or null pointer");
if cfg!(debug_assertions) && !is_aligned_and_not_null(dst) {
// Not panicking to keep codegen impact smaller.
abort();
}
intrinsics::move_val_init(&mut *dst, src)
}
@ -1003,7 +1011,10 @@ pub unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
#[inline]
#[stable(feature = "volatile", since = "1.9.0")]
pub unsafe fn read_volatile<T>(src: *const T) -> T {
debug_assert!(is_aligned_and_not_null(src), "attempt to read from unaligned or null pointer");
if cfg!(debug_assertions) && !is_aligned_and_not_null(src) {
// Not panicking to keep codegen impact smaller.
abort();
}
intrinsics::volatile_load(src)
}
@ -1072,7 +1083,10 @@ pub unsafe fn read_volatile<T>(src: *const T) -> T {
#[inline]
#[stable(feature = "volatile", since = "1.9.0")]
pub unsafe fn write_volatile<T>(dst: *mut T, src: T) {
debug_assert!(is_aligned_and_not_null(dst), "attempt to write to unaligned or null pointer");
if cfg!(debug_assertions) && !is_aligned_and_not_null(dst) {
// Not panicking to keep codegen impact smaller.
abort();
}
intrinsics::volatile_store(dst, src);
}