fix aliasing violation in align_to_mut
This commit is contained in:
parent
04e7f96dd8
commit
c34451ffb7
@ -2571,11 +2571,13 @@ impl<T> [T] {
|
|||||||
let (left, rest) = self.split_at_mut(offset);
|
let (left, rest) = self.split_at_mut(offset);
|
||||||
// now `rest` is definitely aligned, so `from_raw_parts_mut` below is okay
|
// now `rest` is definitely aligned, so `from_raw_parts_mut` below is okay
|
||||||
let (us_len, ts_len) = rest.align_to_offsets::<U>();
|
let (us_len, ts_len) = rest.align_to_offsets::<U>();
|
||||||
|
let rest_len = rest.len();
|
||||||
let mut_ptr = rest.as_mut_ptr();
|
let mut_ptr = rest.as_mut_ptr();
|
||||||
|
// We can't use `rest` again after this, that would invalidate its alias `mut_ptr`!
|
||||||
(
|
(
|
||||||
left,
|
left,
|
||||||
from_raw_parts_mut(mut_ptr as *mut U, us_len),
|
from_raw_parts_mut(mut_ptr as *mut U, us_len),
|
||||||
from_raw_parts_mut(mut_ptr.add(rest.len() - ts_len), ts_len),
|
from_raw_parts_mut(mut_ptr.add(rest_len - ts_len), ts_len),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1570,6 +1570,18 @@ fn test_align_to_empty_mid() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_align_to_mut_aliasing() {
|
||||||
|
let mut val = [1u8, 2, 3, 4, 5];
|
||||||
|
// `align_to_mut` used to create `mid` in a way that there was some intermediate
|
||||||
|
// incorrect aliasing, invalidating the resulting `mid` slice.
|
||||||
|
let (begin, mid, end) = unsafe { val.align_to_mut::<[u8; 2]>() };
|
||||||
|
assert!(begin.len() == 0);
|
||||||
|
assert!(end.len() == 1);
|
||||||
|
mid[0] = mid[1];
|
||||||
|
assert_eq!(val, [3, 4, 3, 4, 5])
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_slice_partition_dedup_by() {
|
fn test_slice_partition_dedup_by() {
|
||||||
let mut slice: [i32; 9] = [1, -1, 2, 3, 1, -5, 5, -2, 2];
|
let mut slice: [i32; 9] = [1, -1, 2, 3, 1, -5, 5, -2, 2];
|
||||||
|
Loading…
Reference in New Issue
Block a user