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 {
150
150
// the propagation can be skipped next time.
151
151
// It is a performance loss not to call this function when a foreign access occurs.
152
152
// 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 (
154
157
& mut self ,
155
158
access_kind : AccessKind ,
156
159
rel_pos : AccessRelatedness ,
@@ -613,10 +616,7 @@ impl<'tcx> Tree {
613
616
614
617
let old_state = perm. or_insert ( LocationState :: new_uninit ( node. default_initial_perm ) ) ;
615
618
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) ;
620
620
621
621
let protected = global. borrow ( ) . protected_tags . contains_key ( & node. tag ) ;
622
622
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