Rollup merge of #78602 - RalfJung:raw-ptr-aliasing-issues, r=m-ou-se
fix various aliasing issues in the standard library This fixes various cases where the standard library either used raw pointers after they were already invalidated by using the original reference again, or created raw pointers for one element of a slice and used it to access neighboring elements.
This commit is contained in:
commit
8ed31d2782
@ -1036,8 +1036,9 @@ unsafe fn move_to(&mut self, index: usize) {
|
||||
debug_assert!(index != self.pos);
|
||||
debug_assert!(index < self.data.len());
|
||||
unsafe {
|
||||
let index_ptr: *const _ = self.data.get_unchecked(index);
|
||||
let hole_ptr = self.data.get_unchecked_mut(self.pos);
|
||||
let ptr = self.data.as_mut_ptr();
|
||||
let index_ptr: *const _ = ptr.add(index);
|
||||
let hole_ptr = ptr.add(self.pos);
|
||||
ptr::copy_nonoverlapping(index_ptr, hole_ptr, 1);
|
||||
}
|
||||
self.pos = index;
|
||||
|
@ -595,7 +595,6 @@ fn fmt_u128(n: u128, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::R
|
||||
// 2^128 is about 3*10^38, so 39 gives an extra byte of space
|
||||
let mut buf = [MaybeUninit::<u8>::uninit(); 39];
|
||||
let mut curr = buf.len() as isize;
|
||||
let buf_ptr = MaybeUninit::slice_as_mut_ptr(&mut buf);
|
||||
|
||||
let (n, rem) = udiv_1e19(n);
|
||||
parse_u64_into(rem, &mut buf, &mut curr);
|
||||
@ -606,7 +605,11 @@ fn fmt_u128(n: u128, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::R
|
||||
// SAFETY: Guaranteed that we wrote at most 19 bytes, and there must be space
|
||||
// remaining since it has length 39
|
||||
unsafe {
|
||||
ptr::write_bytes(buf_ptr.offset(target), b'0', (curr - target) as usize);
|
||||
ptr::write_bytes(
|
||||
MaybeUninit::slice_as_mut_ptr(&mut buf).offset(target),
|
||||
b'0',
|
||||
(curr - target) as usize,
|
||||
);
|
||||
}
|
||||
curr = target;
|
||||
|
||||
@ -615,6 +618,9 @@ fn fmt_u128(n: u128, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::R
|
||||
// Should this following branch be annotated with unlikely?
|
||||
if n != 0 {
|
||||
let target = (buf.len() - 38) as isize;
|
||||
// The raw `buf_ptr` pointer is only valid until `buf` is used the next time,
|
||||
// buf `buf` is not used in this scope so we are good.
|
||||
let buf_ptr = MaybeUninit::slice_as_mut_ptr(&mut buf);
|
||||
// SAFETY: At this point we wrote at most 38 bytes, pad up to that point,
|
||||
// There can only be at most 1 digit remaining.
|
||||
unsafe {
|
||||
@ -629,7 +635,7 @@ fn fmt_u128(n: u128, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::R
|
||||
// UTF-8 since `DEC_DIGITS_LUT` is
|
||||
let buf_slice = unsafe {
|
||||
str::from_utf8_unchecked(slice::from_raw_parts(
|
||||
buf_ptr.offset(curr),
|
||||
MaybeUninit::slice_as_mut_ptr(&mut buf).offset(curr),
|
||||
buf.len() - curr as usize,
|
||||
))
|
||||
};
|
||||
|
@ -111,7 +111,7 @@ macro_rules! load_int_le {
|
||||
debug_assert!($i + mem::size_of::<$int_ty>() <= $buf.len());
|
||||
let mut data = 0 as $int_ty;
|
||||
ptr::copy_nonoverlapping(
|
||||
$buf.get_unchecked($i),
|
||||
$buf.as_ptr().add($i),
|
||||
&mut data as *mut _ as *mut u8,
|
||||
mem::size_of::<$int_ty>(),
|
||||
);
|
||||
|
@ -842,13 +842,13 @@ pub unsafe fn slice_assume_init_mut(slice: &mut [Self]) -> &mut [T] {
|
||||
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
|
||||
#[inline(always)]
|
||||
pub fn slice_as_ptr(this: &[MaybeUninit<T>]) -> *const T {
|
||||
this as *const [MaybeUninit<T>] as *const T
|
||||
this.as_ptr() as *const T
|
||||
}
|
||||
|
||||
/// Gets a mutable pointer to the first element of the array.
|
||||
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
|
||||
#[inline(always)]
|
||||
pub fn slice_as_mut_ptr(this: &mut [MaybeUninit<T>]) -> *mut T {
|
||||
this as *mut [MaybeUninit<T>] as *mut T
|
||||
this.as_mut_ptr() as *mut T
|
||||
}
|
||||
}
|
||||
|
@ -178,7 +178,8 @@ pub fn sleep(dur: Duration) {
|
||||
tv_nsec: nsecs,
|
||||
};
|
||||
secs -= ts.tv_sec as u64;
|
||||
if libc::nanosleep(&ts, &mut ts) == -1 {
|
||||
let ts_ptr = &mut ts as *mut _;
|
||||
if libc::nanosleep(ts_ptr, ts_ptr) == -1 {
|
||||
assert_eq!(os::errno(), libc::EINTR);
|
||||
secs += ts.tv_sec as u64;
|
||||
nsecs = ts.tv_nsec;
|
||||
|
Loading…
Reference in New Issue
Block a user