diff --git a/src/tools/miri/tests/fail/tree_borrows/write-during-2phase.rs b/src/tools/miri/tests/fail/tree_borrows/write-during-2phase.rs index a47bb671e32b8..a2e8a533c43ad 100644 --- a/src/tools/miri/tests/fail/tree_borrows/write-during-2phase.rs +++ b/src/tools/miri/tests/fail/tree_borrows/write-during-2phase.rs @@ -8,8 +8,8 @@ struct Foo(u64); impl Foo { - #[rustfmt::skip] // rustfmt is wrong about which line contains an error - fn add(&mut self, n: u64) -> u64 { //~ ERROR: /reborrow through .* is forbidden/ + fn add(&mut self, n: u64) -> u64 { + //~^ ERROR: /reborrow through .* is forbidden/ self.0 + n } } diff --git a/src/tools/miri/tests/pass/stacked-borrows/2phase.rs b/src/tools/miri/tests/pass/stacked-borrows/2phase.rs index eb543d691e10b..fb4ba60583736 100644 --- a/src/tools/miri/tests/pass/stacked-borrows/2phase.rs +++ b/src/tools/miri/tests/pass/stacked-borrows/2phase.rs @@ -1,3 +1,6 @@ +// FIXME: this miscompiles with optimizations, see . +//@compile-flags: -Zmir-opt-level=0 + trait S: Sized { fn tpb(&mut self, _s: Self) {} } @@ -75,6 +78,25 @@ fn with_interior_mutability() { }); } +// This one really shouldn't be accepted, but since we treat 2phase as raw, we do accept it. +// Tree Borrows rejects it. +fn aliasing_violation() { + struct Foo(u64); + impl Foo { + fn add(&mut self, n: u64) -> u64 { + self.0 + n + } + } + + let mut f = Foo(0); + let alias = &mut f.0 as *mut u64; + let res = f.add(unsafe { + *alias = 42; + 0 + }); + assert_eq!(res, 42); +} + fn main() { two_phase1(); two_phase2(); @@ -84,4 +106,5 @@ fn main() { with_interior_mutability(); two_phase_overlapping1(); two_phase_overlapping2(); + aliasing_violation(); } diff --git a/src/tools/miri/tests/pass/stacked-borrows/stacked-borrows.rs b/src/tools/miri/tests/pass/stacked-borrows/stacked-borrows.rs index c75824d7f9be0..4261f411eea47 100644 --- a/src/tools/miri/tests/pass/stacked-borrows/stacked-borrows.rs +++ b/src/tools/miri/tests/pass/stacked-borrows/stacked-borrows.rs @@ -8,6 +8,7 @@ fn main() { mut_raw_then_mut_shr(); mut_shr_then_mut_raw(); mut_raw_mut(); + mut_raw_mut2(); partially_invalidate_mut(); drop_after_sharing(); // direct_mut_to_const_raw(); @@ -96,6 +97,18 @@ fn mut_raw_mut() { assert_eq!(x, 4); } +// A variant of `mut_raw_mut` that does *not* get accepted by Tree Borrows. +// It's kind of an accident that we accept it in Stacked Borrows... +fn mut_raw_mut2() { + unsafe { + let mut root = 0; + let to = &mut root as *mut i32; + *to = 0; + let _val = root; + *to = 0; + } +} + fn partially_invalidate_mut() { let data = &mut (0u8, 0u8); let reborrow = &mut *data as *mut (u8, u8);