Skip to content

Commit

Permalink
Rollup merge of #69581 - RalfJung:align_to_mut, r=Centril
Browse files Browse the repository at this point in the history
fix aliasing violation in align_to_mut

Fixes #68549

I decided to add the testcase here to make it all one PR, but if you prefer I can also add that test case in the Miri repo instead.
  • Loading branch information
Dylan-DPC committed Feb 29, 2020
2 parents 7d43997 + c34451f commit 02381db
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/libcore/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2571,11 +2571,13 @@ impl<T> [T] {
let (left, rest) = self.split_at_mut(offset);
// now `rest` is definitely aligned, so `from_raw_parts_mut` below is okay
let (us_len, ts_len) = rest.align_to_offsets::<U>();
let rest_len = rest.len();
let mut_ptr = rest.as_mut_ptr();
// We can't use `rest` again after this, that would invalidate its alias `mut_ptr`!
(
left,
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),
)
}
}
Expand Down
12 changes: 12 additions & 0 deletions src/libcore/tests/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
fn test_slice_partition_dedup_by() {
let mut slice: [i32; 9] = [1, -1, 2, 3, 1, -5, 5, -2, 2];
Expand Down

0 comments on commit 02381db

Please sign in to comment.