File tree Expand file tree Collapse file tree 3 files changed +59
-5
lines changed
src/borrow_tracker/tree_borrows Expand file tree Collapse file tree 3 files changed +59
-5
lines changed Original file line number Diff line number Diff line change @@ -150,7 +150,10 @@ impl LocationState {
150150 // the propagation can be skipped next time.
151151 // It is a performance loss not to call this function when a foreign access occurs.
152152 // It is unsound not to call this function when a child access occurs.
153- fn skip_if_known_noop (
153+ // FIXME: This optimization is wrong, and is currently disabled (by ignoring the
154+ // result returned here). Since we presumably want an optimization like this,
155+ // we should add it back. See #3864 for more information.
156+ fn update_last_foreign_access (
154157 & mut self ,
155158 access_kind : AccessKind ,
156159 rel_pos : AccessRelatedness ,
@@ -613,10 +616,7 @@ impl<'tcx> Tree {
613616
614617 let old_state = perm. or_insert ( LocationState :: new_uninit ( node. default_initial_perm ) ) ;
615618
616- match old_state. skip_if_known_noop ( access_kind, rel_pos) {
617- ContinueTraversal :: SkipChildren => return Ok ( ContinueTraversal :: SkipChildren ) ,
618- _ => { }
619- }
619+ old_state. update_last_foreign_access ( access_kind, rel_pos) ;
620620
621621 let protected = global. borrow ( ) . protected_tags . contains_key ( & node. tag ) ;
622622 let transition = old_state. perform_access ( access_kind, rel_pos, protected) ?;
Original file line number Diff line number Diff line change 1+ //@compile-flags: -Zmiri-tree-borrows
2+
3+ use std:: ptr:: addr_of_mut;
4+
5+ fn do_something ( _: u8 ) { }
6+
7+ unsafe fn access_after_sub_1 ( x : & mut u8 , orig_ptr : * mut u8 ) {
8+ // causes a second access, which should make the lazy part of `x` be `Reserved {conflicted: true}`
9+ do_something ( * orig_ptr) ;
10+ // read from the conflicted pointer
11+ * ( x as * mut u8 ) . byte_sub ( 1 ) = 42 ; //~ ERROR: /write access through .* is forbidden/
12+ }
13+
14+ pub fn main ( ) {
15+ unsafe {
16+ let mut alloc = [ 0u8 , 0u8 ] ;
17+ let orig_ptr = addr_of_mut ! ( alloc) as * mut u8 ;
18+ let foo = & mut * orig_ptr;
19+ // cause a foreign read access to foo
20+ do_something ( alloc[ 0 ] ) ;
21+ access_after_sub_1 ( & mut * ( foo as * mut u8 ) . byte_add ( 1 ) , orig_ptr) ;
22+ }
23+ }
Original file line number Diff line number Diff line change 1+ error: Undefined Behavior: write access through <TAG> at ALLOC[0x0] is forbidden
2+ --> $DIR/repeated_foreign_read_lazy_conflicted.rs:LL:CC
3+ |
4+ LL | *(x as *mut u8).byte_sub(1) = 42;
5+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ write access through <TAG> at ALLOC[0x0] is forbidden
6+ |
7+ = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
8+ = help: the accessed tag <TAG> has state Reserved (conflicted) which forbids this child write access
9+ help: the accessed tag <TAG> was created here, in the initial state Reserved
10+ --> $DIR/repeated_foreign_read_lazy_conflicted.rs:LL:CC
11+ |
12+ LL | unsafe fn access_after_sub_1(x: &mut u8, orig_ptr: *mut u8) {
13+ | ^
14+ help: the accessed tag <TAG> later transitioned to Reserved (conflicted) due to a foreign read access at offsets [0x0..0x1]
15+ --> $DIR/repeated_foreign_read_lazy_conflicted.rs:LL:CC
16+ |
17+ LL | do_something(*orig_ptr);
18+ | ^^^^^^^^^
19+ = help: this transition corresponds to a temporary loss of write permissions until function exit
20+ = note: BACKTRACE (of the first span):
21+ = note: inside `access_after_sub_1` at $DIR/repeated_foreign_read_lazy_conflicted.rs:LL:CC
22+ note: inside `main`
23+ --> $DIR/repeated_foreign_read_lazy_conflicted.rs:LL:CC
24+ |
25+ LL | access_after_sub_1(&mut *(foo as *mut u8).byte_add(1), orig_ptr);
26+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
27+
28+ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
29+
30+ error: aborting due to 1 previous error
31+
You can’t perform that action at this time.
0 commit comments