Skip to content

Commit ef2ceec

Browse files
committed
Fix(alloc): Correctly handle ZST alignment for IntoIter::nth_back (#148682)
This commit consolidates all changes, including the core logic fix for IntoIter::nth_back and the addition of the Miri regression test in `library/alloctests/tests/vec.rs`, to prevent Undefined Behavior (UB) when dealing with highly-aligned Zero-Sized Types.
1 parent 467250d commit ef2ceec

File tree

2 files changed

+20
-1
lines changed

2 files changed

+20
-1
lines changed

library/alloc/src/vec/into_iter.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,12 @@ impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> {
411411
// SAFETY: same as for advance_by()
412412
self.end = unsafe { self.end.sub(step_size) };
413413
}
414-
let to_drop = ptr::slice_from_raw_parts_mut(self.end as *mut T, step_size);
414+
let to_drop = if T::IS_ZST {
415+
// ZST may cause unalignment
416+
ptr::slice_from_raw_parts_mut(ptr::NonNull::<T>::dangling().as_ptr(), step_size)
417+
} else {
418+
ptr::slice_from_raw_parts_mut(self.end as *mut T, step_size)
419+
};
415420
// SAFETY: same as for advance_by()
416421
unsafe {
417422
ptr::drop_in_place(to_drop);

library/alloctests/tests/vec.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2717,3 +2717,17 @@ fn vec_null_ptr_roundtrip() {
27172717
let new = roundtripped.with_addr(ptr.addr());
27182718
unsafe { new.read() };
27192719
}
2720+
2721+
// Regression test for Undefined Behavior (UB) caused by IntoIter::nth_back (#148682)
2722+
// when dealing with high-aligned Zero-Sized Types (ZSTs).
2723+
#[test]
2724+
fn zst_vec_iter_nth_back_regression() {
2725+
#[repr(align(8))]
2726+
struct Thing;
2727+
let v = vec![Thing, Thing];
2728+
let mut iter = v.into_iter();
2729+
let _ = iter.nth_back(1);
2730+
let v2 = vec![Thing, Thing];
2731+
let mut iter2 = v2.into_iter();
2732+
let _ = iter2.nth_back(0);
2733+
}

0 commit comments

Comments
 (0)