Rollup merge of #107954 - RalfJung:tree-borrows-fix, r=m-ou-se

avoid mixing accesses of ptrs derived from a mutable ref and parent ptrs

``@Vanille-N`` is working on a successor for Stacked Borrows. It will mostly accept strictly more code than Stacked Borrows did, with one exception: the following pattern no longer works.
```rust
let mut root = 6u8;
let mref = &mut root;
let ptr = mref as *mut u8;
*ptr = 0; // Write
assert_eq!(root, 0); // Parent Read
*ptr = 0; // Attempted Write
```
This worked in Stacked Borrows kind of by accident: when doing the "parent read", under SB we Disable `mref`, but the raw ptrs derived from it remain usable. The fact that we can still use the "children" of a reference that is no longer usable is quite nasty and leads to some undesirable effects (in particular it is the major blocker for resolving https://github.com/rust-lang/unsafe-code-guidelines/issues/257). So in Tree Borrows we no longer do that; instead, reading from `root` makes `mref` and all its children read-only.

Due to other improvements in Tree Borrows, the entire Miri test suite still passes with this new behavior, and even the entire libcore and liballoc test suite, except for these 2 cases this PR fixes. Both of these involve code where the programmer wrote `&mut` but then used pointers derived from that reference in ways that alias with the parent pointer, which arguably is violating uniqueness. They are fixed by properly using raw pointers throughout.
This commit is contained in:
Matthias Krüger 2023-02-12 22:29:49 +01:00 committed by GitHub
commit 454ae9fb8b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 3 additions and 3 deletions

View File

@ -25,7 +25,7 @@ fn test() {
snd: isize,
}
let mut p = Pair { fst: 10, snd: 20 };
let pptr: *mut Pair = &mut p;
let pptr: *mut Pair = addr_of_mut!(p);
let iptr: *mut isize = pptr as *mut isize;
assert_eq!(*iptr, 10);
*iptr = 30;
@ -1070,8 +1070,8 @@ fn swap_copy_untyped() {
let mut x = 5u8;
let mut y = 6u8;
let ptr1 = &mut x as *mut u8 as *mut bool;
let ptr2 = &mut y as *mut u8 as *mut bool;
let ptr1 = addr_of_mut!(x).cast::<bool>();
let ptr2 = addr_of_mut!(y).cast::<bool>();
unsafe {
ptr::swap(ptr1, ptr2);