Skip to content

Commit 8677ad3

Browse files
authored
Rollup merge of rust-lang#69208 - RalfJung:debug-assert, r=Mark-Simulacrum
debug_assert a few more raw pointer methods Fixes rust-lang#53871
2 parents ef7c928 + 7a6b451 commit 8677ad3

File tree

3 files changed

+18
-7
lines changed

3 files changed

+18
-7
lines changed

src/libcore/intrinsics.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -1423,13 +1423,14 @@ pub(crate) fn is_aligned_and_not_null<T>(ptr: *const T) -> bool {
14231423
}
14241424

14251425
/// Checks whether the regions of memory starting at `src` and `dst` of size
1426-
/// `count * size_of::<T>()` overlap.
1427-
fn overlaps<T>(src: *const T, dst: *const T, count: usize) -> bool {
1426+
/// `count * size_of::<T>()` do *not* overlap.
1427+
pub(crate) fn is_nonoverlapping<T>(src: *const T, dst: *const T, count: usize) -> bool {
14281428
let src_usize = src as usize;
14291429
let dst_usize = dst as usize;
14301430
let size = mem::size_of::<T>().checked_mul(count).unwrap();
14311431
let diff = if src_usize > dst_usize { src_usize - dst_usize } else { dst_usize - src_usize };
1432-
size > diff
1432+
let overlaps = size > diff;
1433+
!overlaps
14331434
}
14341435

14351436
/// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
@@ -1525,7 +1526,7 @@ pub unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize) {
15251526

15261527
debug_assert!(is_aligned_and_not_null(src), "attempt to copy from unaligned or null pointer");
15271528
debug_assert!(is_aligned_and_not_null(dst), "attempt to copy to unaligned or null pointer");
1528-
debug_assert!(!overlaps(src, dst, count), "attempt to copy to overlapping memory");
1529+
debug_assert!(is_nonoverlapping(src, dst, count), "attempt to copy to overlapping memory");
15291530
copy_nonoverlapping(src, dst, count)
15301531
}
15311532

src/libcore/ptr/mod.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272
use crate::cmp::Ordering;
7373
use crate::fmt;
7474
use crate::hash;
75-
use crate::intrinsics;
75+
use crate::intrinsics::{self, is_aligned_and_not_null, is_nonoverlapping};
7676
use crate::mem::{self, MaybeUninit};
7777

7878
#[stable(feature = "rust1", since = "1.0.0")]
@@ -392,6 +392,10 @@ pub unsafe fn swap<T>(x: *mut T, y: *mut T) {
392392
#[inline]
393393
#[stable(feature = "swap_nonoverlapping", since = "1.27.0")]
394394
pub unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
395+
debug_assert!(is_aligned_and_not_null(x), "attempt to swap unaligned or null pointer");
396+
debug_assert!(is_aligned_and_not_null(y), "attempt to swap unaligned or null pointer");
397+
debug_assert!(is_nonoverlapping(x, y, count), "attempt to swap overlapping memory");
398+
395399
let x = x as *mut u8;
396400
let y = y as *mut u8;
397401
let len = mem::size_of::<T>() * count;
@@ -619,6 +623,7 @@ pub unsafe fn replace<T>(dst: *mut T, mut src: T) -> T {
619623
#[inline]
620624
#[stable(feature = "rust1", since = "1.0.0")]
621625
pub unsafe fn read<T>(src: *const T) -> T {
626+
// `copy_nonoverlapping` takes care of debug_assert.
622627
let mut tmp = MaybeUninit::<T>::uninit();
623628
copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
624629
tmp.assume_init()
@@ -712,6 +717,7 @@ pub unsafe fn read<T>(src: *const T) -> T {
712717
#[inline]
713718
#[stable(feature = "ptr_unaligned", since = "1.17.0")]
714719
pub unsafe fn read_unaligned<T>(src: *const T) -> T {
720+
// `copy_nonoverlapping` takes care of debug_assert.
715721
let mut tmp = MaybeUninit::<T>::uninit();
716722
copy_nonoverlapping(src as *const u8, tmp.as_mut_ptr() as *mut u8, mem::size_of::<T>());
717723
tmp.assume_init()
@@ -804,6 +810,7 @@ pub unsafe fn read_unaligned<T>(src: *const T) -> T {
804810
#[inline]
805811
#[stable(feature = "rust1", since = "1.0.0")]
806812
pub unsafe fn write<T>(dst: *mut T, src: T) {
813+
debug_assert!(is_aligned_and_not_null(dst), "attempt to write to unaligned or null pointer");
807814
intrinsics::move_val_init(&mut *dst, src)
808815
}
809816

@@ -896,6 +903,7 @@ pub unsafe fn write<T>(dst: *mut T, src: T) {
896903
#[inline]
897904
#[stable(feature = "ptr_unaligned", since = "1.17.0")]
898905
pub unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
906+
// `copy_nonoverlapping` takes care of debug_assert.
899907
copy_nonoverlapping(&src as *const T as *const u8, dst as *mut u8, mem::size_of::<T>());
900908
mem::forget(src);
901909
}
@@ -967,6 +975,7 @@ pub unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
967975
#[inline]
968976
#[stable(feature = "volatile", since = "1.9.0")]
969977
pub unsafe fn read_volatile<T>(src: *const T) -> T {
978+
debug_assert!(is_aligned_and_not_null(src), "attempt to read from unaligned or null pointer");
970979
intrinsics::volatile_load(src)
971980
}
972981

@@ -1035,6 +1044,7 @@ pub unsafe fn read_volatile<T>(src: *const T) -> T {
10351044
#[inline]
10361045
#[stable(feature = "volatile", since = "1.9.0")]
10371046
pub unsafe fn write_volatile<T>(dst: *mut T, src: T) {
1047+
debug_assert!(is_aligned_and_not_null(dst), "attempt to write to unaligned or null pointer");
10381048
intrinsics::volatile_store(dst, src);
10391049
}
10401050

src/test/ui/issues/issue-40883.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ fn verify_stack_usage(before_ptr: *mut Vec<Big>) {
7878
let stack_usage = isize::abs(
7979
(&mut stack_var as *mut _ as isize) -
8080
(before_ptr as isize)) as usize;
81-
// give space for 2 copies of `Big` + 128 "misc" bytes.
82-
if stack_usage > mem::size_of::<Big>() * 2 + 128 {
81+
// give space for 2 copies of `Big` + 256 "misc" bytes.
82+
if stack_usage > mem::size_of::<Big>() * 2 + 256 {
8383
panic!("used {} bytes of stack, but `struct Big` is only {} bytes",
8484
stack_usage, mem::size_of::<Big>());
8585
}

0 commit comments

Comments
 (0)