Rollup merge of #87268 - SkiFire13:fix-uninit-ref-list, r=nagisa

Don't create references to uninitialized data in `List::from_arena`

Previously `result` and `arena_slice` were references pointing to uninitialized data, which is technically UB. They may have been fine because the pointed data is `Copy` and and they were only written to, but the semantics of this aren't clearly defined yet, and since we have a sound way to do the same thing I don't think we should keep the possibly-unsound way.
This commit is contained in:
Guillaume Gomez 2021-07-19 11:37:49 +02:00 committed by GitHub
commit 6cb69ea790
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -63,17 +63,17 @@ impl<T: Copy> List<T> {
let (layout, _offset) =
Layout::new::<usize>().extend(Layout::for_value::<[T]>(slice)).unwrap();
let mem = arena.dropless.alloc_raw(layout);
let mem = arena.dropless.alloc_raw(layout) as *mut List<T>;
unsafe {
let result = &mut *(mem as *mut List<T>);
// Write the length
result.len = slice.len();
ptr::addr_of_mut!((*mem).len).write(slice.len());
// Write the elements
let arena_slice = slice::from_raw_parts_mut(result.data.as_mut_ptr(), result.len);
arena_slice.copy_from_slice(slice);
ptr::addr_of_mut!((*mem).data)
.cast::<T>()
.copy_from_nonoverlapping(slice.as_ptr(), slice.len());
result
&mut *mem
}
}