diff options
| author | Dylan DPC <dylan.dpc@gmail.com> | 2020-02-29 18:54:02 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-02-29 18:54:02 +0100 |
| commit | 02381db8e0cd4412bec4254fd78e140e7b036fa7 (patch) | |
| tree | 297c8e798f66c0e210e9463ba3f15473986b01dc | |
| parent | 7d43997053f940d3aa656a5054995a08edf5f3d4 (diff) | |
| parent | c34451ffb78e0a0851c7aa97897a1621beed8c82 (diff) | |
| download | rust-02381db8e0cd4412bec4254fd78e140e7b036fa7.tar.gz rust-02381db8e0cd4412bec4254fd78e140e7b036fa7.zip | |
Rollup merge of #69581 - RalfJung:align_to_mut, r=Centril
fix aliasing violation in align_to_mut Fixes https://github.com/rust-lang/rust/issues/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.
| -rw-r--r-- | src/libcore/slice/mod.rs | 4 | ||||
| -rw-r--r-- | src/libcore/tests/slice.rs | 12 |
2 files changed, 15 insertions, 1 deletions
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 9a4561f2869..1670c841842 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -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), ) } } diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs index cc274b4aecf..dbab433e33f 100644 --- a/src/libcore/tests/slice.rs +++ b/src/libcore/tests/slice.rs @@ -1571,6 +1571,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]; |
