diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2019-10-19 07:10:03 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-10-19 07:10:03 +0200 |
| commit | beec0a5db4ec2a103ad4374788ce05bd4e6b0d82 (patch) | |
| tree | 86930db0e8c3238370b05fe874b6311aa8f35e88 /src/liballoc | |
| parent | 14f0ed64e306cfc232c3209985afb53fa2cadbb2 (diff) | |
| parent | 227db40a98e5bd903aa3658c16f19a3d6f694deb (diff) | |
| download | rust-beec0a5db4ec2a103ad4374788ce05bd4e6b0d82.tar.gz rust-beec0a5db4ec2a103ad4374788ce05bd4e6b0d82.zip | |
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
Diffstat (limited to 'src/liballoc')
| -rw-r--r-- | src/liballoc/boxed.rs | 16 | ||||
| -rw-r--r-- | src/liballoc/tests/boxed.rs | 18 | ||||
| -rw-r--r-- | src/liballoc/tests/lib.rs | 2 |
3 files changed, 33 insertions, 3 deletions
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 9b5d9431ae2..567b8ea7224 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -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)) } } diff --git a/src/liballoc/tests/boxed.rs b/src/liballoc/tests/boxed.rs new file mode 100644 index 00000000000..bc3d53bf30d --- /dev/null +++ b/src/liballoc/tests/boxed.rs @@ -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(), + ); +} diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs index f2a2c80f2f7..676874c8b27 100644 --- a/src/liballoc/tests/lib.rs +++ b/src/liballoc/tests/lib.rs @@ -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; |
