Skip to content

Commit

Permalink
rc,sync: Do not create references to uninitialized values
Browse files Browse the repository at this point in the history
  • Loading branch information
taiki-e committed Dec 30, 2023
1 parent 8d76d07 commit dd0c5a4
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 16 deletions.
20 changes: 12 additions & 8 deletions library/alloc/src/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1885,10 +1885,10 @@ impl<T: ?Sized> Rc<T> {
// Initialize the RcBox
let inner = mem_to_rcbox(ptr.as_non_null_ptr().as_ptr());
unsafe {
debug_assert_eq!(Layout::for_value(&*inner), layout);
debug_assert_eq!(Layout::for_value_raw(inner), layout);

ptr::write(&mut (*inner).strong, Cell::new(1));
ptr::write(&mut (*inner).weak, Cell::new(1));
ptr::addr_of_mut!((*inner).strong).write(Cell::new(1));
ptr::addr_of_mut!((*inner).weak).write(Cell::new(1));
}

Ok(inner)
Expand Down Expand Up @@ -1918,7 +1918,7 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {
// Copy value as bytes
ptr::copy_nonoverlapping(
&*src as *const T as *const u8,
&mut (*ptr).value as *mut _ as *mut u8,
ptr::addr_of_mut!((*ptr).value) as *mut u8,
value_size,
);

Expand Down Expand Up @@ -1952,7 +1952,11 @@ impl<T> Rc<[T]> {
unsafe fn copy_from_slice(v: &[T]) -> Rc<[T]> {
unsafe {
let ptr = Self::allocate_for_slice(v.len());
ptr::copy_nonoverlapping(v.as_ptr(), &mut (*ptr).value as *mut [T] as *mut T, v.len());
ptr::copy_nonoverlapping(
v.as_ptr(),
ptr::addr_of_mut!((*ptr).value) as *mut T,
v.len(),
);
Self::from_ptr(ptr)
}
}
Expand Down Expand Up @@ -1987,10 +1991,10 @@ impl<T> Rc<[T]> {
let ptr = Self::allocate_for_slice(len);

let mem = ptr as *mut _ as *mut u8;
let layout = Layout::for_value(&*ptr);
let layout = Layout::for_value_raw(ptr);

// Pointer to first element
let elems = &mut (*ptr).value as *mut [T] as *mut T;
let elems = ptr::addr_of_mut!((*ptr).value) as *mut T;

let mut guard = Guard { mem: NonNull::new_unchecked(mem), elems, layout, n_elems: 0 };

Expand Down Expand Up @@ -2524,7 +2528,7 @@ impl<T, A: Allocator> From<Vec<T, A>> for Rc<[T], A> {
let (vec_ptr, len, cap, alloc) = v.into_raw_parts_with_alloc();

let rc_ptr = Self::allocate_for_slice_in(len, &alloc);
ptr::copy_nonoverlapping(vec_ptr, &mut (*rc_ptr).value as *mut [T] as *mut T, len);
ptr::copy_nonoverlapping(vec_ptr, ptr::addr_of_mut!((*rc_ptr).value) as *mut T, len);

// Create a `Vec<T, &A>` with length 0, to deallocate the buffer
// without dropping its contents or the allocator
Expand Down
16 changes: 8 additions & 8 deletions library/alloc/src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1828,11 +1828,11 @@ impl<T: ?Sized> Arc<T> {
mem_to_arcinner: impl FnOnce(*mut u8) -> *mut ArcInner<T>,
) -> *mut ArcInner<T> {
let inner = mem_to_arcinner(ptr.as_non_null_ptr().as_ptr());
debug_assert_eq!(unsafe { Layout::for_value(&*inner) }, layout);
debug_assert_eq!(unsafe { Layout::for_value_raw(inner) }, layout);

unsafe {
ptr::write(&mut (*inner).strong, atomic::AtomicUsize::new(1));
ptr::write(&mut (*inner).weak, atomic::AtomicUsize::new(1));
ptr::addr_of_mut!((*inner).strong).write(atomic::AtomicUsize::new(1));
ptr::addr_of_mut!((*inner).weak).write(atomic::AtomicUsize::new(1));
}

inner
Expand Down Expand Up @@ -1863,7 +1863,7 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> {
// Copy value as bytes
ptr::copy_nonoverlapping(
&*src as *const T as *const u8,
&mut (*ptr).data as *mut _ as *mut u8,
ptr::addr_of_mut!((*ptr).data) as *mut u8,
value_size,
);

Expand Down Expand Up @@ -1898,7 +1898,7 @@ impl<T> Arc<[T]> {
unsafe {
let ptr = Self::allocate_for_slice(v.len());

ptr::copy_nonoverlapping(v.as_ptr(), &mut (*ptr).data as *mut [T] as *mut T, v.len());
ptr::copy_nonoverlapping(v.as_ptr(), ptr::addr_of_mut!((*ptr).data) as *mut T, v.len());

Self::from_ptr(ptr)
}
Expand Down Expand Up @@ -1934,10 +1934,10 @@ impl<T> Arc<[T]> {
let ptr = Self::allocate_for_slice(len);

let mem = ptr as *mut _ as *mut u8;
let layout = Layout::for_value(&*ptr);
let layout = Layout::for_value_raw(ptr);

// Pointer to first element
let elems = &mut (*ptr).data as *mut [T] as *mut T;
let elems = ptr::addr_of_mut!((*ptr).data) as *mut T;

let mut guard = Guard { mem: NonNull::new_unchecked(mem), elems, layout, n_elems: 0 };

Expand Down Expand Up @@ -3383,7 +3383,7 @@ impl<T, A: Allocator + Clone> From<Vec<T, A>> for Arc<[T], A> {
let (vec_ptr, len, cap, alloc) = v.into_raw_parts_with_alloc();

let rc_ptr = Self::allocate_for_slice_in(len, &alloc);
ptr::copy_nonoverlapping(vec_ptr, &mut (*rc_ptr).data as *mut [T] as *mut T, len);
ptr::copy_nonoverlapping(vec_ptr, ptr::addr_of_mut!((*rc_ptr).data) as *mut T, len);

// Create a `Vec<T, &A>` with length 0, to deallocate the buffer
// without dropping its contents or the allocator
Expand Down

0 comments on commit dd0c5a4

Please sign in to comment.