Skip to content

Commit f10999a

Browse files
committed
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.
2 parents feb2582 + ef755e0 commit f10999a

File tree

1 file changed

+4
-5
lines changed

1 file changed

+4
-5
lines changed

alloc/src/raw_vec.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -244,9 +244,7 @@ impl<T, A: Allocator> RawVec<T, A> {
244244
// We have an allocated chunk of memory, so we can bypass runtime
245245
// checks to get our current layout.
246246
unsafe {
247-
let align = mem::align_of::<T>();
248-
let size = mem::size_of::<T>() * self.cap;
249-
let layout = Layout::from_size_align_unchecked(size, align);
247+
let layout = Layout::array::<T>(self.cap).unwrap_unchecked();
250248
Some((self.ptr.cast().into(), layout))
251249
}
252250
}
@@ -427,10 +425,11 @@ impl<T, A: Allocator> RawVec<T, A> {
427425
assert!(cap <= self.capacity(), "Tried to shrink to a larger capacity");
428426

429427
let (ptr, layout) = if let Some(mem) = self.current_memory() { mem } else { return Ok(()) };
430-
let new_size = cap * mem::size_of::<T>();
431428

432429
let ptr = unsafe {
433-
let new_layout = Layout::from_size_align_unchecked(new_size, layout.align());
430+
// `Layout::array` cannot overflow here because it would have
431+
// overflowed earlier when capacity was larger.
432+
let new_layout = Layout::array::<T>(cap).unwrap_unchecked();
434433
self.alloc
435434
.shrink(ptr, layout, new_layout)
436435
.map_err(|_| AllocError { layout: new_layout, non_exhaustive: () })?

0 commit comments

Comments
 (0)