Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rc,sync: Do not create references to uninitialized values #119433

Merged
merged 1 commit into from
Jan 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 16 additions & 11 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 All @@ -1902,7 +1902,7 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {
// Allocate for the `RcBox<T>` using the given value.
unsafe {
Rc::<T>::allocate_for_layout(
Layout::for_value(&*ptr),
Layout::for_value_raw(ptr),
|layout| alloc.allocate(layout),
|mem| mem.with_metadata_of(ptr as *const RcBox<T>),
)
Expand All @@ -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 @@ -2096,7 +2100,8 @@ unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for Rc<T, A> {
self.inner().dec_weak();

if self.inner().weak() == 0 {
self.alloc.deallocate(self.ptr.cast(), Layout::for_value(self.ptr.as_ref()));
self.alloc
.deallocate(self.ptr.cast(), Layout::for_value_raw(self.ptr.as_ptr()));
}
}
}
Expand Down Expand Up @@ -2524,7 +2529,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 Expand Up @@ -3514,7 +3519,7 @@ unsafe impl<#[may_dangle] T> Drop for UniqueRc<T> {
self.ptr.as_ref().dec_weak();

if self.ptr.as_ref().weak() == 0 {
Global.deallocate(self.ptr.cast(), Layout::for_value(self.ptr.as_ref()));
Global.deallocate(self.ptr.cast(), Layout::for_value_raw(self.ptr.as_ptr()));
}
}
}
Expand Down
18 changes: 9 additions & 9 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 All @@ -1847,7 +1847,7 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> {
// Allocate for the `ArcInner<T>` using the given value.
unsafe {
Arc::allocate_for_layout(
Layout::for_value(&*ptr),
Layout::for_value_raw(ptr),
|layout| alloc.allocate(layout),
|mem| mem.with_metadata_of(ptr as *const ArcInner<T>),
)
Expand All @@ -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 @@ -3380,7 +3380,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
Loading