Rollup merge of #106950 - the8472:fix-splice-miri, r=cuviper
Don't do pointer arithmetic on pointers to deallocated memory vec::Splice can invalidate the slice::Iter inside vec::Drain. So we replace them with dangling pointers which, unlike ones to deallocated memory, are allowed. Fixes miri test failures. Fixes https://github.com/rust-lang/miri/issues/2759
This commit is contained in:
commit
1ff4a1259d
@ -223,9 +223,9 @@ fn drop(&mut self) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// as_slice() must only be called when iter.len() is > 0 because
|
// as_slice() must only be called when iter.len() is > 0 because
|
||||||
// vec::Splice modifies vec::Drain fields and may grow the vec which would invalidate
|
// it also gets touched by vec::Splice which may turn it into a dangling pointer
|
||||||
// the iterator's internal pointers. Creating a reference to deallocated memory
|
// which would make it and the vec pointer point to different allocations which would
|
||||||
// is invalid even when it is zero-length
|
// lead to invalid pointer arithmetic below.
|
||||||
let drop_ptr = iter.as_slice().as_ptr();
|
let drop_ptr = iter.as_slice().as_ptr();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -54,6 +54,12 @@ impl<I: Iterator, A: Allocator> ExactSizeIterator for Splice<'_, I, A> {}
|
|||||||
impl<I: Iterator, A: Allocator> Drop for Splice<'_, I, A> {
|
impl<I: Iterator, A: Allocator> Drop for Splice<'_, I, A> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.drain.by_ref().for_each(drop);
|
self.drain.by_ref().for_each(drop);
|
||||||
|
// At this point draining is done and the only remaining tasks are splicing
|
||||||
|
// and moving things into the final place.
|
||||||
|
// Which means we can replace the slice::Iter with pointers that won't point to deallocated
|
||||||
|
// memory, so that Drain::drop is still allowed to call iter.len(), otherwise it would break
|
||||||
|
// the ptr.sub_ptr contract.
|
||||||
|
self.drain.iter = (&[]).iter();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
if self.drain.tail_len == 0 {
|
if self.drain.tail_len == 0 {
|
||||||
|
@ -162,6 +162,11 @@ fn reverse() {
|
|||||||
assert!(v[0].0 == 49);
|
assert!(v[0].0 == 49);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn miri_issue_2759() {
|
||||||
|
let mut input = "1".to_string();
|
||||||
|
input.replace_range(0..0, "0");
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
assert_eq!(vec_reallocate().len(), 5);
|
assert_eq!(vec_reallocate().len(), 5);
|
||||||
|
|
||||||
@ -191,4 +196,5 @@ fn main() {
|
|||||||
swap();
|
swap();
|
||||||
swap_remove();
|
swap_remove();
|
||||||
reverse();
|
reverse();
|
||||||
|
miri_issue_2759();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user