Rollup merge of #149272 - DrAsu33:fix-vec-iter-zst-alignment-148682, r=Mark-Simulacrum
Fix vec iter zst alignment Closes rust-lang/rust#148682
This commit is contained in:
commit
735c45eda4
2 changed files with 38 additions and 1 deletions
|
|
@ -411,7 +411,12 @@ impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> {
|
|||
// SAFETY: same as for advance_by()
|
||||
self.end = unsafe { self.end.sub(step_size) };
|
||||
}
|
||||
let to_drop = ptr::slice_from_raw_parts_mut(self.end as *mut T, step_size);
|
||||
let to_drop = if T::IS_ZST {
|
||||
// ZST may cause unalignment
|
||||
ptr::slice_from_raw_parts_mut(ptr::NonNull::<T>::dangling().as_ptr(), step_size)
|
||||
} else {
|
||||
ptr::slice_from_raw_parts_mut(self.end as *mut T, step_size)
|
||||
};
|
||||
// SAFETY: same as for advance_by()
|
||||
unsafe {
|
||||
ptr::drop_in_place(to_drop);
|
||||
|
|
|
|||
|
|
@ -2717,3 +2717,35 @@ fn vec_null_ptr_roundtrip() {
|
|||
let new = roundtripped.with_addr(ptr.addr());
|
||||
unsafe { new.read() };
|
||||
}
|
||||
|
||||
// Regression test for Undefined Behavior (UB) caused by IntoIter::nth_back (#148682)
|
||||
// when dealing with high-aligned Zero-Sized Types (ZSTs).
|
||||
use std::collections::{BTreeMap, BinaryHeap, HashMap, LinkedList, VecDeque};
|
||||
#[test]
|
||||
fn zst_collections_iter_nth_back_regression() {
|
||||
#[repr(align(8))]
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
|
||||
struct Thing;
|
||||
let v = vec![Thing, Thing];
|
||||
let _ = v.into_iter().nth_back(1);
|
||||
let mut d = VecDeque::new();
|
||||
d.push_back(Thing);
|
||||
d.push_back(Thing);
|
||||
let _ = d.into_iter().nth_back(1);
|
||||
let mut map = BTreeMap::new();
|
||||
map.insert(0, Thing);
|
||||
map.insert(1, Thing);
|
||||
let _ = map.into_values().nth_back(0);
|
||||
let mut hash_map = HashMap::new();
|
||||
hash_map.insert(1, Thing);
|
||||
hash_map.insert(2, Thing);
|
||||
let _ = hash_map.into_values().nth(1);
|
||||
let mut heap = BinaryHeap::new();
|
||||
heap.push(Thing);
|
||||
heap.push(Thing);
|
||||
let _ = heap.into_iter().nth_back(1);
|
||||
let mut list = LinkedList::new();
|
||||
list.push_back(Thing);
|
||||
list.push_back(Thing);
|
||||
let _ = list.into_iter().nth_back(1);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue