diff options
| author | bors <bors@rust-lang.org> | 2022-02-22 20:50:38 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-02-22 20:50:38 +0000 |
| commit | 5bd1ec3283874b97b27da4539b2950fbd01c4b0e (patch) | |
| tree | 5642d3a3c816dfd39caf9fdd11d3274a8bbe4ba8 /library/alloc/src | |
| parent | 68369a041cea809a87e5bd80701da90e0e0a4799 (diff) | |
| parent | 5376317c7f39c41250f354d6c35858bd383d1970 (diff) | |
| download | rust-5bd1ec3283874b97b27da4539b2950fbd01c4b0e.tar.gz rust-5bd1ec3283874b97b27da4539b2950fbd01c4b0e.zip | |
Auto merge of #83706 - a1phyr:fix_vec_layout_calculation, r=JohnTitor
Fix a layout possible miscalculation in `alloc::RawVec` A layout miscalculation could happen in `RawVec` when used with a type whose size isn't a multiple of its alignment. I don't know if such type can exist in Rust, but the Layout API provides ways to manipulate such types. Anyway, it is better to calculate memory size in a consistent way.
Diffstat (limited to 'library/alloc/src')
| -rw-r--r-- | library/alloc/src/raw_vec.rs | 9 |
1 files changed, 4 insertions, 5 deletions
diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs index 8fa0242ca9a..0ce2beb63d6 100644 --- a/library/alloc/src/raw_vec.rs +++ b/library/alloc/src/raw_vec.rs @@ -244,9 +244,7 @@ impl<T, A: Allocator> RawVec<T, A> { // We have an allocated chunk of memory, so we can bypass runtime // checks to get our current layout. unsafe { - let align = mem::align_of::<T>(); - let size = mem::size_of::<T>() * self.cap; - let layout = Layout::from_size_align_unchecked(size, align); + let layout = Layout::array::<T>(self.cap).unwrap_unchecked(); Some((self.ptr.cast().into(), layout)) } } @@ -427,10 +425,11 @@ impl<T, A: Allocator> RawVec<T, A> { assert!(cap <= self.capacity(), "Tried to shrink to a larger capacity"); let (ptr, layout) = if let Some(mem) = self.current_memory() { mem } else { return Ok(()) }; - let new_size = cap * mem::size_of::<T>(); let ptr = unsafe { - let new_layout = Layout::from_size_align_unchecked(new_size, layout.align()); + // `Layout::array` cannot overflow here because it would have + // overflowed earlier when capacity was larger. + let new_layout = Layout::array::<T>(cap).unwrap_unchecked(); self.alloc .shrink(ptr, layout, new_layout) .map_err(|_| AllocError { layout: new_layout, non_exhaustive: () })? |
