Skip to content

Commit 22996ad

Browse files
committed
Apply suggestions
- split test into two revisions - clarify comments
1 parent 2de6e7f commit 22996ad

File tree

4 files changed

+52
-18
lines changed

4 files changed

+52
-18
lines changed

src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,8 @@ impl<'tcx> NewPermission {
145145
// As demonstrated by `tests/fail/tree_borrows/reservedim_spurious_write.rs`,
146146
// interior mutability and protectors interact poorly.
147147
// To eliminate the case of Protected Reserved IM we override interior mutability
148-
// in the case of a protected reference.
148+
// in the case of a protected reference: protected references are always considered
149+
// "freeze".
149150
let initial_state = match mutability {
150151
Mutability::Mut if ty_is_unpin =>
151152
Permission::new_reserved(ty_is_freeze || is_protected),

src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.rs

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,20 @@
22
// and protectors, that makes spurious writes fail in the previous model of Tree Borrows.
33
// As for all similar tests, we disable preemption so that the error message is deterministic.
44
//@compile-flags: -Zmiri-tree-borrows -Zmiri-preemption-rate=0
5+
//
6+
// One revision without spurious read (default source code) and one with spurious read.
7+
// Both are expected to be UB. Both revisions are expected to have the *same* error
8+
// because we are aligning the behavior of `without` to that of `with` so that the
9+
// spurious write is effectively a noop in the long term.
10+
//@revisions: without with
511

612
use std::cell::Cell;
713
use std::sync::{Arc, Barrier};
814
use std::thread;
915

1016
// Here is the problematic interleaving:
1117
// - thread 1: retag and activate `x` (protected)
12-
// - thread 2: create but do not retag (lazy) `y` as Reserved with interior mutability
18+
// - thread 2: retag but do not initialize (lazy) `y` as Reserved with interior mutability
1319
// - thread 1: spurious write through `x` would go here
1420
// - thread 2: function exit (noop due to lazyness)
1521
// - thread 1: function exit (no permanent effect on `y` because it is now Reserved IM unprotected)
@@ -35,18 +41,6 @@ macro_rules! synchronized {
3541
}
3642

3743
fn main() {
38-
eprintln!("Without spurious write");
39-
example(false);
40-
41-
eprintln!("\nIf this text is visible then the model forbids spurious writes.\n");
42-
43-
eprintln!("With spurious write");
44-
example(true);
45-
46-
eprintln!("\nIf this text is visible then the model fails to detect a noalias violation.\n");
47-
}
48-
49-
fn example(spurious: bool) {
5044
// For this example it is important that we have at least two bytes
5145
// because lazyness is involved.
5246
let mut data = [0u8; 2];
@@ -62,12 +56,12 @@ fn example(spurious: bool) {
6256
synchronized!(b, "start");
6357
let ptr = ptr;
6458
synchronized!(b, "retag x (&mut, protect)");
65-
fn inner(x: &mut u8, b: IdxBarrier, spurious: bool) {
59+
fn inner(x: &mut u8, b: IdxBarrier) {
6660
*x = 42; // activate immediately
6761
synchronized!(b, "[lazy] retag y (&mut, protect, IM)");
6862
// A spurious write should be valid here because `x` is
6963
// `Active` and protected.
70-
if spurious {
64+
if cfg!(with) {
7165
synchronized!(b, "spurious write x (executed)");
7266
*x = 64;
7367
} else {
@@ -76,7 +70,7 @@ fn example(spurious: bool) {
7670
synchronized!(b, "ret y");
7771
synchronized!(b, "ret x");
7872
}
79-
inner(unsafe { &mut *ptr.0 }, b.clone(), spurious);
73+
inner(unsafe { &mut *ptr.0 }, b.clone());
8074
synchronized!(b, "write y");
8175
synchronized!(b, "end");
8276
});
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
Thread 1 executing: start
2+
Thread 2 executing: start
3+
Thread 2 executing: retag x (&mut, protect)
4+
Thread 1 executing: retag x (&mut, protect)
5+
Thread 1 executing: [lazy] retag y (&mut, protect, IM)
6+
Thread 2 executing: [lazy] retag y (&mut, protect, IM)
7+
Thread 2 executing: spurious write x
8+
Thread 1 executing: spurious write x (executed)
9+
Thread 1 executing: ret y
10+
Thread 2 executing: ret y
11+
Thread 2 executing: ret x
12+
Thread 1 executing: ret x
13+
Thread 1 executing: write y
14+
Thread 2 executing: write y
15+
error: Undefined Behavior: write access through <TAG> at ALLOC[0x0] is forbidden
16+
--> $DIR/reservedim_spurious_write.rs:LL:CC
17+
|
18+
LL | unsafe { *y.wrapping_sub(1) = 13 }
19+
| ^^^^^^^^^^^^^^^^^^^^^^^ write access through <TAG> at ALLOC[0x0] is forbidden
20+
|
21+
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
22+
= help: the accessed tag <TAG> has state Disabled which forbids this child write access
23+
help: the accessed tag <TAG> was created here, in the initial state Reserved
24+
--> $DIR/reservedim_spurious_write.rs:LL:CC
25+
|
26+
LL | fn inner(y: &mut Cell<u8>, b: IdxBarrier) -> *mut u8 {
27+
| ^
28+
help: the accessed tag <TAG> later transitioned to Disabled due to a foreign write access at offsets [0x0..0x1]
29+
--> $DIR/reservedim_spurious_write.rs:LL:CC
30+
|
31+
LL | *x = 64;
32+
| ^^^^^^^
33+
= help: this transition corresponds to a loss of read and write permissions
34+
= note: BACKTRACE (of the first span) on thread `unnamed-ID`:
35+
= note: inside closure at $DIR/reservedim_spurious_write.rs:LL:CC
36+
37+
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
38+
39+
error: aborting due to 1 previous error
40+

src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.stderr renamed to src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.without.stderr

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
Without spurious write
21
Thread 1 executing: start
32
Thread 2 executing: start
43
Thread 2 executing: retag x (&mut, protect)

0 commit comments

Comments
 (0)