Rollup merge of #65174 - SimonSapin:zero-box, r=alexcrichton
Fix zero-size uninitialized boxes Requesting a zero-size allocation is not allowed, return a dangling pointer instead. CC https://github.com/rust-lang/rust/issues/63291#issuecomment-538692745
This commit is contained in:
commit
beec0a5db4
@ -142,6 +142,9 @@ impl<T> Box<T> {
|
||||
#[unstable(feature = "new_uninit", issue = "63291")]
|
||||
pub fn new_uninit() -> Box<mem::MaybeUninit<T>> {
|
||||
let layout = alloc::Layout::new::<mem::MaybeUninit<T>>();
|
||||
if layout.size() == 0 {
|
||||
return Box(NonNull::dangling().into())
|
||||
}
|
||||
let ptr = unsafe {
|
||||
Global.alloc(layout)
|
||||
.unwrap_or_else(|_| alloc::handle_alloc_error(layout))
|
||||
@ -182,9 +185,16 @@ impl<T> Box<[T]> {
|
||||
#[unstable(feature = "new_uninit", issue = "63291")]
|
||||
pub fn new_uninit_slice(len: usize) -> Box<[mem::MaybeUninit<T>]> {
|
||||
let layout = alloc::Layout::array::<mem::MaybeUninit<T>>(len).unwrap();
|
||||
let ptr = unsafe { alloc::alloc(layout) };
|
||||
let unique = Unique::new(ptr).unwrap_or_else(|| alloc::handle_alloc_error(layout));
|
||||
let slice = unsafe { slice::from_raw_parts_mut(unique.cast().as_ptr(), len) };
|
||||
let ptr = if layout.size() == 0 {
|
||||
NonNull::dangling()
|
||||
} else {
|
||||
unsafe {
|
||||
Global.alloc(layout)
|
||||
.unwrap_or_else(|_| alloc::handle_alloc_error(layout))
|
||||
.cast()
|
||||
}
|
||||
};
|
||||
let slice = unsafe { slice::from_raw_parts_mut(ptr.as_ptr(), len) };
|
||||
Box(Unique::from(slice))
|
||||
}
|
||||
}
|
||||
|
18
src/liballoc/tests/boxed.rs
Normal file
18
src/liballoc/tests/boxed.rs
Normal file
@ -0,0 +1,18 @@
|
||||
use std::ptr::NonNull;
|
||||
use std::mem::MaybeUninit;
|
||||
|
||||
#[test]
|
||||
fn unitialized_zero_size_box() {
|
||||
assert_eq!(
|
||||
&*Box::<()>::new_uninit() as *const _,
|
||||
NonNull::<MaybeUninit<()>>::dangling().as_ptr(),
|
||||
);
|
||||
assert_eq!(
|
||||
Box::<[()]>::new_uninit_slice(4).as_ptr(),
|
||||
NonNull::<MaybeUninit<()>>::dangling().as_ptr(),
|
||||
);
|
||||
assert_eq!(
|
||||
Box::<[String]>::new_uninit_slice(0).as_ptr(),
|
||||
NonNull::<MaybeUninit<String>>::dangling().as_ptr(),
|
||||
);
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
#![feature(box_syntax)]
|
||||
#![feature(drain_filter)]
|
||||
#![feature(exact_size_is_empty)]
|
||||
#![feature(new_uninit)]
|
||||
#![feature(option_flattening)]
|
||||
#![feature(pattern)]
|
||||
#![feature(trusted_len)]
|
||||
@ -14,6 +15,7 @@ use std::collections::hash_map::DefaultHasher;
|
||||
|
||||
mod arc;
|
||||
mod binary_heap;
|
||||
mod boxed;
|
||||
mod btree;
|
||||
mod cow_str;
|
||||
mod fmt;
|
||||
|
Loading…
x
Reference in New Issue
Block a user