diff --git a/src/tools/miri/tests/fail/stacked_borrows/alias_through_mutation.rs b/src/tools/miri/tests/fail/both_borrows/alias_through_mutation.rs similarity index 63% rename from src/tools/miri/tests/fail/stacked_borrows/alias_through_mutation.rs rename to src/tools/miri/tests/fail/both_borrows/alias_through_mutation.rs index 73095bb2fc94b..f40bf327cac17 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/alias_through_mutation.rs +++ b/src/tools/miri/tests/fail/both_borrows/alias_through_mutation.rs @@ -1,3 +1,6 @@ +//@revisions: stack tree +//@[tree]compile-flags: -Zmiri-tree-borrows + // This makes a ref that was passed to us via &mut alias with things it should not alias with fn retarget(x: &mut &u32, target: &mut u32) { unsafe { @@ -11,5 +14,7 @@ fn main() { retarget(&mut target_alias, target); // now `target_alias` points to the same thing as `target` *target = 13; - let _val = *target_alias; //~ ERROR: /read access .* tag does not exist in the borrow stack/ + let _val = *target_alias; + //~[stack]^ ERROR: /read access .* tag does not exist in the borrow stack/ + //~[tree]| ERROR: /read access through .* is forbidden/ } diff --git a/src/tools/miri/tests/fail/stacked_borrows/alias_through_mutation.stderr b/src/tools/miri/tests/fail/both_borrows/alias_through_mutation.stack.stderr similarity index 100% rename from src/tools/miri/tests/fail/stacked_borrows/alias_through_mutation.stderr rename to src/tools/miri/tests/fail/both_borrows/alias_through_mutation.stack.stderr diff --git a/src/tools/miri/tests/fail/both_borrows/alias_through_mutation.tree.stderr b/src/tools/miri/tests/fail/both_borrows/alias_through_mutation.tree.stderr new file mode 100644 index 0000000000000..a7c78b3140e6e --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/alias_through_mutation.tree.stderr @@ -0,0 +1,32 @@ +error: Undefined Behavior: read access through is forbidden + --> $DIR/alias_through_mutation.rs:LL:CC + | +LL | let _val = *target_alias; + | ^^^^^^^^^^^^^ read access through is forbidden + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: the accessed tag is a child of the conflicting tag + = help: the conflicting tag has state Disabled which forbids child read accesses +help: the accessed tag was created here + --> $DIR/alias_through_mutation.rs:LL:CC + | +LL | *x = &mut *(target as *mut _); + | ^^^^^^^^^^^^^^^^^^^^^^^^ +help: the conflicting tag was created here, in the initial state Reserved + --> $DIR/alias_through_mutation.rs:LL:CC + | +LL | retarget(&mut target_alias, target); + | ^^^^^^ +help: the conflicting tag later transitioned to Disabled due to a foreign write access at offsets [0x0..0x4] + --> $DIR/alias_through_mutation.rs:LL:CC + | +LL | *target = 13; + | ^^^^^^^^^^^^ + = help: this corresponds to a loss of read and write permissions + = note: BACKTRACE (of the first span): + = note: inside `main` at $DIR/alias_through_mutation.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/stacked_borrows/aliasing_mut1.rs b/src/tools/miri/tests/fail/both_borrows/aliasing_mut1.rs similarity index 68% rename from src/tools/miri/tests/fail/stacked_borrows/aliasing_mut1.rs rename to src/tools/miri/tests/fail/both_borrows/aliasing_mut1.rs index 14a27d8e9dd65..a9efe17fddfab 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/aliasing_mut1.rs +++ b/src/tools/miri/tests/fail/both_borrows/aliasing_mut1.rs @@ -1,6 +1,12 @@ +//@revisions: stack tree +//@[tree]compile-flags: -Zmiri-tree-borrows use std::mem; -pub fn safe(_x: &mut i32, _y: &mut i32) {} //~ ERROR: protect +pub fn safe(x: &mut i32, y: &mut i32) { + //~[stack]^ ERROR: protect + *x = 1; //~[tree] ERROR: /write access through .* is forbidden/ + *y = 2; +} fn main() { let mut x = 0; diff --git a/src/tools/miri/tests/fail/stacked_borrows/aliasing_mut1.stderr b/src/tools/miri/tests/fail/both_borrows/aliasing_mut1.stack.stderr similarity index 79% rename from src/tools/miri/tests/fail/stacked_borrows/aliasing_mut1.stderr rename to src/tools/miri/tests/fail/both_borrows/aliasing_mut1.stack.stderr index 3ce39968cbb13..678211a700dbc 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/aliasing_mut1.stderr +++ b/src/tools/miri/tests/fail/both_borrows/aliasing_mut1.stack.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: not granting access to tag because that would remove [Unique for ] which is strongly protected because it is an argument of call ID --> $DIR/aliasing_mut1.rs:LL:CC | -LL | pub fn safe(_x: &mut i32, _y: &mut i32) {} - | ^^ not granting access to tag because that would remove [Unique for ] which is strongly protected because it is an argument of call ID +LL | pub fn safe(x: &mut i32, y: &mut i32) { + | ^ not granting access to tag because that would remove [Unique for ] which is strongly protected because it is an argument of call ID | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information @@ -14,8 +14,8 @@ LL | let xraw: *mut i32 = unsafe { mem::transmute(&mut x) }; help: is this argument --> $DIR/aliasing_mut1.rs:LL:CC | -LL | pub fn safe(_x: &mut i32, _y: &mut i32) {} - | ^^ +LL | pub fn safe(x: &mut i32, y: &mut i32) { + | ^ = note: BACKTRACE (of the first span): = note: inside `safe` at $DIR/aliasing_mut1.rs:LL:CC note: inside `main` diff --git a/src/tools/miri/tests/fail/both_borrows/aliasing_mut1.tree.stderr b/src/tools/miri/tests/fail/both_borrows/aliasing_mut1.tree.stderr new file mode 100644 index 0000000000000..358bb8761ef70 --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/aliasing_mut1.tree.stderr @@ -0,0 +1,31 @@ +error: Undefined Behavior: write access through is forbidden + --> $DIR/aliasing_mut1.rs:LL:CC + | +LL | *x = 1; + | ^^^^^^ write access through is forbidden + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: the accessed tag has state Frozen which forbids child write accesses +help: the accessed tag was created here, in the initial state Reserved + --> $DIR/aliasing_mut1.rs:LL:CC + | +LL | pub fn safe(x: &mut i32, y: &mut i32) { + | ^ +help: the accessed tag later transitioned to Frozen due to a foreign read access at offsets [0x0..0x4] + --> $DIR/aliasing_mut1.rs:LL:CC + | +LL | pub fn safe(x: &mut i32, y: &mut i32) { + | ^ + = help: this corresponds to a loss of write permissions + = note: BACKTRACE (of the first span): + = note: inside `safe` at $DIR/aliasing_mut1.rs:LL:CC +note: inside `main` + --> $DIR/aliasing_mut1.rs:LL:CC + | +LL | safe_raw(xraw, xraw); + | ^^^^^^^^^^^^^^^^^^^^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/stacked_borrows/aliasing_mut2.rs b/src/tools/miri/tests/fail/both_borrows/aliasing_mut2.rs similarity index 62% rename from src/tools/miri/tests/fail/stacked_borrows/aliasing_mut2.rs rename to src/tools/miri/tests/fail/both_borrows/aliasing_mut2.rs index 84d901f83bbcc..74ea2b28627c1 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/aliasing_mut2.rs +++ b/src/tools/miri/tests/fail/both_borrows/aliasing_mut2.rs @@ -1,6 +1,12 @@ +//@revisions: stack tree +//@[tree]compile-flags: -Zmiri-tree-borrows use std::mem; -pub fn safe(_x: &i32, _y: &mut i32) {} //~ ERROR: protect +pub fn safe(x: &i32, y: &mut i32) { + //~[stack]^ ERROR: protect + let _v = *x; + *y = 2; //~[tree] ERROR: /write access through .* is forbidden/ +} fn main() { let mut x = 0; diff --git a/src/tools/miri/tests/fail/stacked_borrows/aliasing_mut2.stderr b/src/tools/miri/tests/fail/both_borrows/aliasing_mut2.stack.stderr similarity index 79% rename from src/tools/miri/tests/fail/stacked_borrows/aliasing_mut2.stderr rename to src/tools/miri/tests/fail/both_borrows/aliasing_mut2.stack.stderr index df4b6cf02561c..90134ce367a19 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/aliasing_mut2.stderr +++ b/src/tools/miri/tests/fail/both_borrows/aliasing_mut2.stack.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: not granting access to tag because that would remove [SharedReadOnly for ] which is strongly protected because it is an argument of call ID --> $DIR/aliasing_mut2.rs:LL:CC | -LL | pub fn safe(_x: &i32, _y: &mut i32) {} - | ^^ not granting access to tag because that would remove [SharedReadOnly for ] which is strongly protected because it is an argument of call ID +LL | pub fn safe(x: &i32, y: &mut i32) { + | ^ not granting access to tag because that would remove [SharedReadOnly for ] which is strongly protected because it is an argument of call ID | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information @@ -14,8 +14,8 @@ LL | let xref = &mut x; help: is this argument --> $DIR/aliasing_mut2.rs:LL:CC | -LL | pub fn safe(_x: &i32, _y: &mut i32) {} - | ^^ +LL | pub fn safe(x: &i32, y: &mut i32) { + | ^ = note: BACKTRACE (of the first span): = note: inside `safe` at $DIR/aliasing_mut2.rs:LL:CC note: inside `main` diff --git a/src/tools/miri/tests/fail/both_borrows/aliasing_mut2.tree.stderr b/src/tools/miri/tests/fail/both_borrows/aliasing_mut2.tree.stderr new file mode 100644 index 0000000000000..f485114d4e520 --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/aliasing_mut2.tree.stderr @@ -0,0 +1,31 @@ +error: Undefined Behavior: write access through is forbidden + --> $DIR/aliasing_mut2.rs:LL:CC + | +LL | *y = 2; + | ^^^^^^ write access through is forbidden + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: the accessed tag has state Frozen which forbids child write accesses +help: the accessed tag was created here, in the initial state Reserved + --> $DIR/aliasing_mut2.rs:LL:CC + | +LL | pub fn safe(x: &i32, y: &mut i32) { + | ^ +help: the accessed tag later transitioned to Frozen due to a foreign read access at offsets [0x0..0x4] + --> $DIR/aliasing_mut2.rs:LL:CC + | +LL | let _v = *x; + | ^^ + = help: this corresponds to a loss of write permissions + = note: BACKTRACE (of the first span): + = note: inside `safe` at $DIR/aliasing_mut2.rs:LL:CC +note: inside `main` + --> $DIR/aliasing_mut2.rs:LL:CC + | +LL | safe_raw(xshr, xraw); + | ^^^^^^^^^^^^^^^^^^^^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/stacked_borrows/aliasing_mut3.rs b/src/tools/miri/tests/fail/both_borrows/aliasing_mut3.rs similarity index 61% rename from src/tools/miri/tests/fail/stacked_borrows/aliasing_mut3.rs rename to src/tools/miri/tests/fail/both_borrows/aliasing_mut3.rs index f1ba06b6e4f7a..8cb60faf2d078 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/aliasing_mut3.rs +++ b/src/tools/miri/tests/fail/both_borrows/aliasing_mut3.rs @@ -1,6 +1,12 @@ +//@revisions: stack tree +//@[tree]compile-flags: -Zmiri-tree-borrows use std::mem; -pub fn safe(_x: &mut i32, _y: &i32) {} //~ ERROR: borrow stack +pub fn safe(x: &mut i32, y: &i32) { + //~[stack]^ ERROR: borrow stack + *x = 1; //~[tree] ERROR: /write access through .* is forbidden/ + let _v = *y; +} fn main() { let mut x = 0; diff --git a/src/tools/miri/tests/fail/stacked_borrows/aliasing_mut3.stderr b/src/tools/miri/tests/fail/both_borrows/aliasing_mut3.stack.stderr similarity index 76% rename from src/tools/miri/tests/fail/stacked_borrows/aliasing_mut3.stderr rename to src/tools/miri/tests/fail/both_borrows/aliasing_mut3.stack.stderr index ae54d0248dc3d..a457bd9a6accf 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/aliasing_mut3.stderr +++ b/src/tools/miri/tests/fail/both_borrows/aliasing_mut3.stack.stderr @@ -1,11 +1,11 @@ error: Undefined Behavior: trying to retag from for SharedReadOnly permission at ALLOC[0x0], but that tag does not exist in the borrow stack for this location --> $DIR/aliasing_mut3.rs:LL:CC | -LL | pub fn safe(_x: &mut i32, _y: &i32) {} - | ^^ - | | - | trying to retag from for SharedReadOnly permission at ALLOC[0x0], but that tag does not exist in the borrow stack for this location - | this error occurs as part of function-entry retag at ALLOC[0x0..0x4] +LL | pub fn safe(x: &mut i32, y: &i32) { + | ^ + | | + | trying to retag from for SharedReadOnly permission at ALLOC[0x0], but that tag does not exist in the borrow stack for this location + | this error occurs as part of function-entry retag at ALLOC[0x0..0x4] | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information diff --git a/src/tools/miri/tests/fail/both_borrows/aliasing_mut3.tree.stderr b/src/tools/miri/tests/fail/both_borrows/aliasing_mut3.tree.stderr new file mode 100644 index 0000000000000..f1d89074ad704 --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/aliasing_mut3.tree.stderr @@ -0,0 +1,31 @@ +error: Undefined Behavior: write access through is forbidden + --> $DIR/aliasing_mut3.rs:LL:CC + | +LL | *x = 1; + | ^^^^^^ write access through is forbidden + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: the accessed tag has state Frozen which forbids child write accesses +help: the accessed tag was created here, in the initial state Reserved + --> $DIR/aliasing_mut3.rs:LL:CC + | +LL | pub fn safe(x: &mut i32, y: &i32) { + | ^ +help: the accessed tag later transitioned to Frozen due to a foreign read access at offsets [0x0..0x4] + --> $DIR/aliasing_mut3.rs:LL:CC + | +LL | pub fn safe(x: &mut i32, y: &i32) { + | ^ + = help: this corresponds to a loss of write permissions + = note: BACKTRACE (of the first span): + = note: inside `safe` at $DIR/aliasing_mut3.rs:LL:CC +note: inside `main` + --> $DIR/aliasing_mut3.rs:LL:CC + | +LL | safe_raw(xraw, xshr); + | ^^^^^^^^^^^^^^^^^^^^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/stacked_borrows/aliasing_mut4.rs b/src/tools/miri/tests/fail/both_borrows/aliasing_mut4.rs similarity index 65% rename from src/tools/miri/tests/fail/stacked_borrows/aliasing_mut4.rs rename to src/tools/miri/tests/fail/both_borrows/aliasing_mut4.rs index 52081b56223da..e188a1f0c3438 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/aliasing_mut4.rs +++ b/src/tools/miri/tests/fail/both_borrows/aliasing_mut4.rs @@ -1,8 +1,15 @@ +//@revisions: stack tree +//@[tree]compile-flags: -Zmiri-tree-borrows +//@[tree]error-in-other-file: /write access through .* is forbidden/ use std::cell::Cell; use std::mem; // Make sure &mut UnsafeCell also is exclusive -pub fn safe(_x: &i32, _y: &mut Cell) {} //~ ERROR: protect +pub fn safe(x: &i32, y: &mut Cell) { + //~[stack]^ ERROR: protect + y.set(1); + let _ = *x; +} fn main() { let mut x = 0; diff --git a/src/tools/miri/tests/fail/stacked_borrows/aliasing_mut4.stderr b/src/tools/miri/tests/fail/both_borrows/aliasing_mut4.stack.stderr similarity index 78% rename from src/tools/miri/tests/fail/stacked_borrows/aliasing_mut4.stderr rename to src/tools/miri/tests/fail/both_borrows/aliasing_mut4.stack.stderr index ddf197bc63955..b53ae9bd5504b 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/aliasing_mut4.stderr +++ b/src/tools/miri/tests/fail/both_borrows/aliasing_mut4.stack.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: not granting access to tag because that would remove [SharedReadOnly for ] which is strongly protected because it is an argument of call ID --> $DIR/aliasing_mut4.rs:LL:CC | -LL | pub fn safe(_x: &i32, _y: &mut Cell) {} - | ^^ not granting access to tag because that would remove [SharedReadOnly for ] which is strongly protected because it is an argument of call ID +LL | pub fn safe(x: &i32, y: &mut Cell) { + | ^ not granting access to tag because that would remove [SharedReadOnly for ] which is strongly protected because it is an argument of call ID | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information @@ -14,8 +14,8 @@ LL | let xref = &mut x; help: is this argument --> $DIR/aliasing_mut4.rs:LL:CC | -LL | pub fn safe(_x: &i32, _y: &mut Cell) {} - | ^^ +LL | pub fn safe(x: &i32, y: &mut Cell) { + | ^ = note: BACKTRACE (of the first span): = note: inside `safe` at $DIR/aliasing_mut4.rs:LL:CC note: inside `main` diff --git a/src/tools/miri/tests/fail/both_borrows/aliasing_mut4.tree.stderr b/src/tools/miri/tests/fail/both_borrows/aliasing_mut4.tree.stderr new file mode 100644 index 0000000000000..f620d8cd5114c --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/aliasing_mut4.tree.stderr @@ -0,0 +1,39 @@ +error: Undefined Behavior: write access through is forbidden + --> RUSTLIB/core/src/mem/mod.rs:LL:CC + | +LL | ptr::write(dest, src); + | ^^^^^^^^^^^^^^^^^^^^^ write access through is forbidden + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: the accessed tag is foreign to the protected tag (i.e., it is not a child) + = help: the access would cause the protected tag to transition from Frozen to Disabled + = help: this is a loss of read permissions, which is not allowed for protected tags +help: the accessed tag was created here + --> $DIR/aliasing_mut4.rs:LL:CC + | +LL | y.set(1); + | ^^^^^^^^ +help: the protected tag was created here, in the initial state Frozen + --> $DIR/aliasing_mut4.rs:LL:CC + | +LL | pub fn safe(x: &i32, y: &mut Cell) { + | ^ + = note: BACKTRACE (of the first span): + = note: inside `std::mem::replace::` at RUSTLIB/core/src/mem/mod.rs:LL:CC + = note: inside `std::cell::Cell::::replace` at RUSTLIB/core/src/cell.rs:LL:CC + = note: inside `std::cell::Cell::::set` at RUSTLIB/core/src/cell.rs:LL:CC +note: inside `safe` + --> $DIR/aliasing_mut4.rs:LL:CC + | +LL | y.set(1); + | ^^^^^^^^ +note: inside `main` + --> $DIR/aliasing_mut4.rs:LL:CC + | +LL | safe_raw(xshr, xraw as *mut _); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/stacked_borrows/box_noalias_violation.rs b/src/tools/miri/tests/fail/both_borrows/box_noalias_violation.rs similarity index 61% rename from src/tools/miri/tests/fail/stacked_borrows/box_noalias_violation.rs rename to src/tools/miri/tests/fail/both_borrows/box_noalias_violation.rs index 2067149b6c87c..1d20b22b3ad88 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/box_noalias_violation.rs +++ b/src/tools/miri/tests/fail/both_borrows/box_noalias_violation.rs @@ -1,8 +1,13 @@ +//@revisions: stack tree +//@[tree]compile-flags: -Zmiri-tree-borrows + unsafe fn test(mut x: Box, y: *const i32) -> i32 { // We will call this in a way that x and y alias. *x = 5; std::mem::forget(x); - *y //~ERROR: weakly protected + *y + //~[stack]^ ERROR: weakly protected + //~[tree]| ERROR: /read access through .* is forbidden/ } fn main() { diff --git a/src/tools/miri/tests/fail/stacked_borrows/box_noalias_violation.stderr b/src/tools/miri/tests/fail/both_borrows/box_noalias_violation.stack.stderr similarity index 100% rename from src/tools/miri/tests/fail/stacked_borrows/box_noalias_violation.stderr rename to src/tools/miri/tests/fail/both_borrows/box_noalias_violation.stack.stderr diff --git a/src/tools/miri/tests/fail/both_borrows/box_noalias_violation.tree.stderr b/src/tools/miri/tests/fail/both_borrows/box_noalias_violation.tree.stderr new file mode 100644 index 0000000000000..3c842b44639ed --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/box_noalias_violation.tree.stderr @@ -0,0 +1,38 @@ +error: Undefined Behavior: read access through is forbidden + --> $DIR/box_noalias_violation.rs:LL:CC + | +LL | *y + | ^^ read access through is forbidden + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: the accessed tag is foreign to the protected tag (i.e., it is not a child) + = help: the access would cause the protected tag to transition from Active to Frozen + = help: this is a loss of write permissions, which is not allowed for protected tags +help: the accessed tag was created here + --> $DIR/box_noalias_violation.rs:LL:CC + | +LL | let ptr = &mut v as *mut i32; + | ^^^^^^ +help: the protected tag was created here, in the initial state Reserved + --> $DIR/box_noalias_violation.rs:LL:CC + | +LL | unsafe fn test(mut x: Box, y: *const i32) -> i32 { + | ^^^^^ +help: the protected tag later transitioned to Active due to a child write access at offsets [0x0..0x4] + --> $DIR/box_noalias_violation.rs:LL:CC + | +LL | *x = 5; + | ^^^^^^ + = help: this corresponds to the first write to a 2-phase borrowed mutable reference + = note: BACKTRACE (of the first span): + = note: inside `test` at $DIR/box_noalias_violation.rs:LL:CC +note: inside `main` + --> $DIR/box_noalias_violation.rs:LL:CC + | +LL | test(Box::from_raw(ptr), ptr); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/stacked_borrows/buggy_as_mut_slice.rs b/src/tools/miri/tests/fail/both_borrows/buggy_as_mut_slice.rs similarity index 52% rename from src/tools/miri/tests/fail/stacked_borrows/buggy_as_mut_slice.rs rename to src/tools/miri/tests/fail/both_borrows/buggy_as_mut_slice.rs index 8615a9a58ad96..6d535a14c0481 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/buggy_as_mut_slice.rs +++ b/src/tools/miri/tests/fail/both_borrows/buggy_as_mut_slice.rs @@ -1,3 +1,5 @@ +//@revisions: stack tree +//@[tree]compile-flags: -Zmiri-tree-borrows mod safe { use std::slice::from_raw_parts_mut; @@ -9,7 +11,9 @@ mod safe { fn main() { let v = vec![0, 1, 2]; let v1 = safe::as_mut_slice(&v); - let _v2 = safe::as_mut_slice(&v); + let v2 = safe::as_mut_slice(&v); v1[1] = 5; - //~^ ERROR: /write access .* tag does not exist in the borrow stack/ + //~[stack]^ ERROR: /write access .* tag does not exist in the borrow stack/ + v2[1] = 7; + //~[tree]^ ERROR: /write access through .* is forbidden/ } diff --git a/src/tools/miri/tests/fail/stacked_borrows/buggy_as_mut_slice.stderr b/src/tools/miri/tests/fail/both_borrows/buggy_as_mut_slice.stack.stderr similarity index 100% rename from src/tools/miri/tests/fail/stacked_borrows/buggy_as_mut_slice.stderr rename to src/tools/miri/tests/fail/both_borrows/buggy_as_mut_slice.stack.stderr diff --git a/src/tools/miri/tests/fail/both_borrows/buggy_as_mut_slice.tree.stderr b/src/tools/miri/tests/fail/both_borrows/buggy_as_mut_slice.tree.stderr new file mode 100644 index 0000000000000..d1d643f3fb50e --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/buggy_as_mut_slice.tree.stderr @@ -0,0 +1,32 @@ +error: Undefined Behavior: write access through is forbidden + --> $DIR/buggy_as_mut_slice.rs:LL:CC + | +LL | v2[1] = 7; + | ^^^^^^^^^ write access through is forbidden + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: the accessed tag is a child of the conflicting tag + = help: the conflicting tag has state Disabled which forbids child write accesses +help: the accessed tag was created here + --> $DIR/buggy_as_mut_slice.rs:LL:CC + | +LL | let v2 = safe::as_mut_slice(&v); + | ^^^^^^^^^^^^^^^^^^^^^^ +help: the conflicting tag was created here, in the initial state Reserved + --> $DIR/buggy_as_mut_slice.rs:LL:CC + | +LL | unsafe { from_raw_parts_mut(self_.as_ptr() as *mut T, self_.len()) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: the conflicting tag later transitioned to Disabled due to a foreign write access at offsets [0x4..0x8] + --> $DIR/buggy_as_mut_slice.rs:LL:CC + | +LL | v1[1] = 5; + | ^^^^^^^^^ + = help: this corresponds to a loss of read and write permissions + = note: BACKTRACE (of the first span): + = note: inside `main` at $DIR/buggy_as_mut_slice.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/stacked_borrows/buggy_split_at_mut.rs b/src/tools/miri/tests/fail/both_borrows/buggy_split_at_mut.rs similarity index 74% rename from src/tools/miri/tests/fail/stacked_borrows/buggy_split_at_mut.rs rename to src/tools/miri/tests/fail/both_borrows/buggy_split_at_mut.rs index 8a1ea86d63385..4dc6eaf7cd318 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/buggy_split_at_mut.rs +++ b/src/tools/miri/tests/fail/both_borrows/buggy_split_at_mut.rs @@ -1,3 +1,5 @@ +//@revisions: stack tree +//@[tree]compile-flags: -Zmiri-tree-borrows mod safe { use std::slice::from_raw_parts_mut; @@ -19,7 +21,8 @@ mod safe { fn main() { let mut array = [1, 2, 3, 4]; let (a, b) = safe::split_at_mut(&mut array, 0); - //~^ ERROR: /retag .* tag does not exist in the borrow stack/ + //~[stack]^ ERROR: /retag .* tag does not exist in the borrow stack/ a[1] = 5; b[1] = 6; + //~[tree]^ ERROR: /write access through .* is forbidden/ } diff --git a/src/tools/miri/tests/fail/stacked_borrows/buggy_split_at_mut.stderr b/src/tools/miri/tests/fail/both_borrows/buggy_split_at_mut.stack.stderr similarity index 100% rename from src/tools/miri/tests/fail/stacked_borrows/buggy_split_at_mut.stderr rename to src/tools/miri/tests/fail/both_borrows/buggy_split_at_mut.stack.stderr diff --git a/src/tools/miri/tests/fail/both_borrows/buggy_split_at_mut.tree.stderr b/src/tools/miri/tests/fail/both_borrows/buggy_split_at_mut.tree.stderr new file mode 100644 index 0000000000000..3c619fe316e30 --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/buggy_split_at_mut.tree.stderr @@ -0,0 +1,32 @@ +error: Undefined Behavior: write access through is forbidden + --> $DIR/buggy_split_at_mut.rs:LL:CC + | +LL | b[1] = 6; + | ^^^^^^^^ write access through is forbidden + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: the accessed tag is a child of the conflicting tag + = help: the conflicting tag has state Disabled which forbids child write accesses +help: the accessed tag was created here + --> $DIR/buggy_split_at_mut.rs:LL:CC + | +LL | let (a, b) = safe::split_at_mut(&mut array, 0); + | ^ +help: the conflicting tag was created here, in the initial state Reserved + --> $DIR/buggy_split_at_mut.rs:LL:CC + | +LL | from_raw_parts_mut(ptr.offset(mid as isize), len - mid), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: the conflicting tag later transitioned to Disabled due to a foreign write access at offsets [0x4..0x8] + --> $DIR/buggy_split_at_mut.rs:LL:CC + | +LL | a[1] = 5; + | ^^^^^^^^ + = help: this corresponds to a loss of read and write permissions + = note: BACKTRACE (of the first span): + = note: inside `main` at $DIR/buggy_split_at_mut.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/both_borrows/illegal_write1.rs b/src/tools/miri/tests/fail/both_borrows/illegal_write1.rs new file mode 100644 index 0000000000000..d3991949cc39e --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/illegal_write1.rs @@ -0,0 +1,14 @@ +//@revisions: stack tree +//@[tree]compile-flags: -Zmiri-tree-borrows + +fn main() { + let target = Box::new(42); // has an implicit raw + let xref = &*target; + { + let x: *mut u32 = xref as *const _ as *mut _; + unsafe { *x = 42 }; + //~[stack]^ ERROR: /write access .* tag only grants SharedReadOnly permission/ + //~[tree]| ERROR: /write access through .* is forbidden/ + } + let _x = *xref; +} diff --git a/src/tools/miri/tests/fail/stacked_borrows/illegal_write1.stderr b/src/tools/miri/tests/fail/both_borrows/illegal_write1.stack.stderr similarity index 100% rename from src/tools/miri/tests/fail/stacked_borrows/illegal_write1.stderr rename to src/tools/miri/tests/fail/both_borrows/illegal_write1.stack.stderr diff --git a/src/tools/miri/tests/fail/both_borrows/illegal_write1.tree.stderr b/src/tools/miri/tests/fail/both_borrows/illegal_write1.tree.stderr new file mode 100644 index 0000000000000..749fee28df0c8 --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/illegal_write1.tree.stderr @@ -0,0 +1,20 @@ +error: Undefined Behavior: write access through is forbidden + --> $DIR/illegal_write1.rs:LL:CC + | +LL | unsafe { *x = 42 }; + | ^^^^^^^ write access through is forbidden + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: the accessed tag has state Frozen which forbids child write accesses +help: the accessed tag was created here, in the initial state Frozen + --> $DIR/illegal_write1.rs:LL:CC + | +LL | let xref = &*target; + | ^^^^^^^^ + = note: BACKTRACE (of the first span): + = note: inside `main` at $DIR/illegal_write1.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/stacked_borrows/illegal_write5.rs b/src/tools/miri/tests/fail/both_borrows/illegal_write5.rs similarity index 66% rename from src/tools/miri/tests/fail/stacked_borrows/illegal_write5.rs rename to src/tools/miri/tests/fail/both_borrows/illegal_write5.rs index 1c655dc0a0fb4..5de63c0f0683f 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/illegal_write5.rs +++ b/src/tools/miri/tests/fail/both_borrows/illegal_write5.rs @@ -1,3 +1,6 @@ +//@revisions: stack tree +//@[tree]compile-flags: -Zmiri-tree-borrows + // A callee may not write to the destination of our `&mut` without us noticing. fn main() { @@ -8,7 +11,8 @@ fn main() { callee(xraw); // ... though any use of raw value will invalidate our ref. let _val = *xref; - //~^ ERROR: /read access .* tag does not exist in the borrow stack/ + //~[stack]^ ERROR: /read access .* tag does not exist in the borrow stack/ + //~[tree]| ERROR: /read access through .* is forbidden/ } fn callee(xraw: *mut i32) { diff --git a/src/tools/miri/tests/fail/stacked_borrows/illegal_write5.stderr b/src/tools/miri/tests/fail/both_borrows/illegal_write5.stack.stderr similarity index 100% rename from src/tools/miri/tests/fail/stacked_borrows/illegal_write5.stderr rename to src/tools/miri/tests/fail/both_borrows/illegal_write5.stack.stderr diff --git a/src/tools/miri/tests/fail/both_borrows/illegal_write5.tree.stderr b/src/tools/miri/tests/fail/both_borrows/illegal_write5.tree.stderr new file mode 100644 index 0000000000000..b94dc77c113f9 --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/illegal_write5.tree.stderr @@ -0,0 +1,32 @@ +error: Undefined Behavior: read access through is forbidden + --> $DIR/illegal_write5.rs:LL:CC + | +LL | let _val = *xref; + | ^^^^^ read access through is forbidden + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: the accessed tag is a child of the conflicting tag + = help: the conflicting tag has state Disabled which forbids child read accesses +help: the accessed tag was created here + --> $DIR/illegal_write5.rs:LL:CC + | +LL | let xref = unsafe { &mut *xraw }; + | ^^^^^^^^^^ +help: the conflicting tag was created here, in the initial state Reserved + --> $DIR/illegal_write5.rs:LL:CC + | +LL | let xref = unsafe { &mut *xraw }; + | ^^^^^^^^^^ +help: the conflicting tag later transitioned to Disabled due to a foreign write access at offsets [0x0..0x4] + --> $DIR/illegal_write5.rs:LL:CC + | +LL | unsafe { *xraw = 15 }; + | ^^^^^^^^^^ + = help: this corresponds to a loss of read and write permissions + = note: BACKTRACE (of the first span): + = note: inside `main` at $DIR/illegal_write5.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/both_borrows/illegal_write6.rs b/src/tools/miri/tests/fail/both_borrows/illegal_write6.rs new file mode 100644 index 0000000000000..5c2dfc48e5221 --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/illegal_write6.rs @@ -0,0 +1,17 @@ +//@revisions: stack tree +//@[tree]compile-flags: -Zmiri-tree-borrows + +fn main() { + let x = &mut 0u32; + let p = x as *mut u32; + foo(x, p); +} + +fn foo(a: &mut u32, y: *mut u32) -> u32 { + *a = 1; + let _b = &*a; + unsafe { *y = 2 }; + //~[stack]^ ERROR: /not granting access .* because that would remove .* which is strongly protected/ + //~[tree]| ERROR: /write access through .* is forbidden/ + return *a; +} diff --git a/src/tools/miri/tests/fail/stacked_borrows/illegal_write6.stderr b/src/tools/miri/tests/fail/both_borrows/illegal_write6.stack.stderr similarity index 100% rename from src/tools/miri/tests/fail/stacked_borrows/illegal_write6.stderr rename to src/tools/miri/tests/fail/both_borrows/illegal_write6.stack.stderr diff --git a/src/tools/miri/tests/fail/both_borrows/illegal_write6.tree.stderr b/src/tools/miri/tests/fail/both_borrows/illegal_write6.tree.stderr new file mode 100644 index 0000000000000..e808d4a0ae08f --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/illegal_write6.tree.stderr @@ -0,0 +1,38 @@ +error: Undefined Behavior: write access through is forbidden + --> $DIR/illegal_write6.rs:LL:CC + | +LL | unsafe { *y = 2 }; + | ^^^^^^ write access through is forbidden + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: the accessed tag is foreign to the protected tag (i.e., it is not a child) + = help: the access would cause the protected tag to transition from Active to Disabled + = help: this is a loss of read and write permissions, which is not allowed for protected tags +help: the accessed tag was created here + --> $DIR/illegal_write6.rs:LL:CC + | +LL | let x = &mut 0u32; + | ^^^^^^^^^ +help: the protected tag was created here, in the initial state Reserved + --> $DIR/illegal_write6.rs:LL:CC + | +LL | fn foo(a: &mut u32, y: *mut u32) -> u32 { + | ^ +help: the protected tag later transitioned to Active due to a child write access at offsets [0x0..0x4] + --> $DIR/illegal_write6.rs:LL:CC + | +LL | *a = 1; + | ^^^^^^ + = help: this corresponds to the first write to a 2-phase borrowed mutable reference + = note: BACKTRACE (of the first span): + = note: inside `foo` at $DIR/illegal_write6.rs:LL:CC +note: inside `main` + --> $DIR/illegal_write6.rs:LL:CC + | +LL | foo(x, p); + | ^^^^^^^^^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/stacked_borrows/invalidate_against_protector2.rs b/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector2.rs similarity index 66% rename from src/tools/miri/tests/fail/stacked_borrows/invalidate_against_protector2.rs rename to src/tools/miri/tests/fail/both_borrows/invalidate_against_protector2.rs index f4e767302fd00..0cec2d7c397b4 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/invalidate_against_protector2.rs +++ b/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector2.rs @@ -1,8 +1,13 @@ +//@revisions: stack tree +//@[tree]compile-flags: -Zmiri-tree-borrows + fn inner(x: *mut i32, _y: &i32) { // If `x` and `y` alias, retagging is fine with this... but we really // shouldn't be allowed to write to `x` at all because `y` was assumed to be // immutable for the duration of this call. - unsafe { *x = 0 }; //~ ERROR: protect + unsafe { *x = 0 }; + //~[stack]^ ERROR: protect + //~[tree]| ERROR: /write access through .* is forbidden/ } fn main() { diff --git a/src/tools/miri/tests/fail/stacked_borrows/invalidate_against_protector2.stderr b/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector2.stack.stderr similarity index 100% rename from src/tools/miri/tests/fail/stacked_borrows/invalidate_against_protector2.stderr rename to src/tools/miri/tests/fail/both_borrows/invalidate_against_protector2.stack.stderr diff --git a/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector2.tree.stderr b/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector2.tree.stderr new file mode 100644 index 0000000000000..b6744fcfa0e4c --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector2.tree.stderr @@ -0,0 +1,32 @@ +error: Undefined Behavior: write access through is forbidden + --> $DIR/invalidate_against_protector2.rs:LL:CC + | +LL | unsafe { *x = 0 }; + | ^^^^^^ write access through is forbidden + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: the accessed tag is foreign to the protected tag (i.e., it is not a child) + = help: the access would cause the protected tag to transition from Frozen to Disabled + = help: this is a loss of read permissions, which is not allowed for protected tags +help: the accessed tag was created here + --> $DIR/invalidate_against_protector2.rs:LL:CC + | +LL | let xraw = &mut x as *mut _; + | ^^^^^^ +help: the protected tag was created here, in the initial state Frozen + --> $DIR/invalidate_against_protector2.rs:LL:CC + | +LL | fn inner(x: *mut i32, _y: &i32) { + | ^^ + = note: BACKTRACE (of the first span): + = note: inside `inner` at $DIR/invalidate_against_protector2.rs:LL:CC +note: inside `main` + --> $DIR/invalidate_against_protector2.rs:LL:CC + | +LL | inner(xraw, xref); + | ^^^^^^^^^^^^^^^^^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/stacked_borrows/invalidate_against_protector3.rs b/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector3.rs similarity index 68% rename from src/tools/miri/tests/fail/stacked_borrows/invalidate_against_protector3.rs rename to src/tools/miri/tests/fail/both_borrows/invalidate_against_protector3.rs index 634eb97217c6c..170bcf9590a76 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/invalidate_against_protector3.rs +++ b/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector3.rs @@ -1,10 +1,15 @@ +//@revisions: stack tree +//@[tree]compile-flags: -Zmiri-tree-borrows + use std::alloc::{alloc, Layout}; fn inner(x: *mut i32, _y: &i32) { // If `x` and `y` alias, retagging is fine with this... but we really // shouldn't be allowed to write to `x` at all because `y` was assumed to be // immutable for the duration of this call. - unsafe { *x = 0 }; //~ ERROR: protect + unsafe { *x = 0 }; + //~[stack]^ ERROR: protect + //~[tree]| ERROR: /write access through .* is forbidden/ } fn main() { diff --git a/src/tools/miri/tests/fail/stacked_borrows/invalidate_against_protector3.stderr b/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector3.stack.stderr similarity index 100% rename from src/tools/miri/tests/fail/stacked_borrows/invalidate_against_protector3.stderr rename to src/tools/miri/tests/fail/both_borrows/invalidate_against_protector3.stack.stderr diff --git a/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector3.tree.stderr b/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector3.tree.stderr new file mode 100644 index 0000000000000..cfbe0463e20a1 --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector3.tree.stderr @@ -0,0 +1,32 @@ +error: Undefined Behavior: write access through (root of the allocation) is forbidden + --> $DIR/invalidate_against_protector3.rs:LL:CC + | +LL | unsafe { *x = 0 }; + | ^^^^^^ write access through (root of the allocation) is forbidden + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: the accessed tag (root of the allocation) is foreign to the protected tag (i.e., it is not a child) + = help: the access would cause the protected tag to transition from Frozen to Disabled + = help: this is a loss of read permissions, which is not allowed for protected tags +help: the accessed tag was created here + --> $DIR/invalidate_against_protector3.rs:LL:CC + | +LL | let ptr = alloc(Layout::for_value(&0i32)) as *mut i32; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: the protected tag was created here, in the initial state Frozen + --> $DIR/invalidate_against_protector3.rs:LL:CC + | +LL | fn inner(x: *mut i32, _y: &i32) { + | ^^ + = note: BACKTRACE (of the first span): + = note: inside `inner` at $DIR/invalidate_against_protector3.rs:LL:CC +note: inside `main` + --> $DIR/invalidate_against_protector3.rs:LL:CC + | +LL | inner(ptr, &*ptr); + | ^^^^^^^^^^^^^^^^^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/stacked_borrows/issue-miri-1050-1.rs b/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-1.rs similarity index 75% rename from src/tools/miri/tests/fail/stacked_borrows/issue-miri-1050-1.rs rename to src/tools/miri/tests/fail/both_borrows/issue-miri-1050-1.rs index 075efe494123d..424aace239a21 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/issue-miri-1050-1.rs +++ b/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-1.rs @@ -1,3 +1,5 @@ +//@revisions: stack tree +//@[tree]compile-flags: -Zmiri-tree-borrows //@error-in-other-file: pointer to 4 bytes starting at offset 0 is out-of-bounds fn main() { diff --git a/src/tools/miri/tests/fail/stacked_borrows/issue-miri-1050-1.stderr b/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-1.stack.stderr similarity index 100% rename from src/tools/miri/tests/fail/stacked_borrows/issue-miri-1050-1.stderr rename to src/tools/miri/tests/fail/both_borrows/issue-miri-1050-1.stack.stderr diff --git a/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-1.tree.stderr b/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-1.tree.stderr new file mode 100644 index 0000000000000..c69a3af293c13 --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-1.tree.stderr @@ -0,0 +1,21 @@ +error: Undefined Behavior: out-of-bounds pointer use: ALLOC has size 2, so pointer to 4 bytes starting at offset 0 is out-of-bounds + --> RUSTLIB/alloc/src/boxed.rs:LL:CC + | +LL | Box(unsafe { Unique::new_unchecked(raw) }, alloc) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: ALLOC has size 2, so pointer to 4 bytes starting at offset 0 is out-of-bounds + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `std::boxed::Box::::from_raw_in` at RUSTLIB/alloc/src/boxed.rs:LL:CC + = note: inside `std::boxed::Box::::from_raw` at RUSTLIB/alloc/src/boxed.rs:LL:CC +note: inside `main` + --> $DIR/issue-miri-1050-1.rs:LL:CC + | +LL | drop(Box::from_raw(ptr as *mut u32)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/stacked_borrows/issue-miri-1050-2.rs b/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-2.rs similarity index 73% rename from src/tools/miri/tests/fail/stacked_borrows/issue-miri-1050-2.rs rename to src/tools/miri/tests/fail/both_borrows/issue-miri-1050-2.rs index 1b43daa925389..5c947e6414258 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/issue-miri-1050-2.rs +++ b/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-2.rs @@ -1,3 +1,5 @@ +//@revisions: stack tree +//@[tree]compile-flags: -Zmiri-tree-borrows //@error-in-other-file: is a dangling pointer use std::ptr::NonNull; diff --git a/src/tools/miri/tests/fail/stacked_borrows/issue-miri-1050-2.stderr b/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-2.stack.stderr similarity index 100% rename from src/tools/miri/tests/fail/stacked_borrows/issue-miri-1050-2.stderr rename to src/tools/miri/tests/fail/both_borrows/issue-miri-1050-2.stack.stderr diff --git a/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-2.tree.stderr b/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-2.tree.stderr new file mode 100644 index 0000000000000..23d7fdcd03bc5 --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-2.tree.stderr @@ -0,0 +1,21 @@ +error: Undefined Behavior: out-of-bounds pointer use: 0x4[noalloc] is a dangling pointer (it has no provenance) + --> RUSTLIB/alloc/src/boxed.rs:LL:CC + | +LL | Box(unsafe { Unique::new_unchecked(raw) }, alloc) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: 0x4[noalloc] is a dangling pointer (it has no provenance) + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `std::boxed::Box::::from_raw_in` at RUSTLIB/alloc/src/boxed.rs:LL:CC + = note: inside `std::boxed::Box::::from_raw` at RUSTLIB/alloc/src/boxed.rs:LL:CC +note: inside `main` + --> $DIR/issue-miri-1050-2.rs:LL:CC + | +LL | drop(Box::from_raw(ptr.as_ptr())); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/stacked_borrows/load_invalid_shr.rs b/src/tools/miri/tests/fail/both_borrows/load_invalid_shr.rs similarity index 60% rename from src/tools/miri/tests/fail/stacked_borrows/load_invalid_shr.rs rename to src/tools/miri/tests/fail/both_borrows/load_invalid_shr.rs index 8f94cc07a24f7..9dc2bdac8573e 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/load_invalid_shr.rs +++ b/src/tools/miri/tests/fail/both_borrows/load_invalid_shr.rs @@ -1,3 +1,5 @@ +//@revisions: stack tree +//@[tree]compile-flags: -Zmiri-tree-borrows // Make sure we catch this even without validation //@compile-flags: -Zmiri-disable-validation @@ -8,5 +10,7 @@ fn main() { let xref = unsafe { &*xraw }; let xref_in_mem = Box::new(xref); unsafe { *xraw = 42 }; // unfreeze - let _val = *xref_in_mem; //~ ERROR: /retag .* tag does not exist in the borrow stack/ + let _val = *xref_in_mem; + //~[stack]^ ERROR: /retag .* tag does not exist in the borrow stack/ + //~[tree]| ERROR: /read access through .* is forbidden/ } diff --git a/src/tools/miri/tests/fail/stacked_borrows/load_invalid_shr.stderr b/src/tools/miri/tests/fail/both_borrows/load_invalid_shr.stack.stderr similarity index 100% rename from src/tools/miri/tests/fail/stacked_borrows/load_invalid_shr.stderr rename to src/tools/miri/tests/fail/both_borrows/load_invalid_shr.stack.stderr diff --git a/src/tools/miri/tests/fail/both_borrows/load_invalid_shr.tree.stderr b/src/tools/miri/tests/fail/both_borrows/load_invalid_shr.tree.stderr new file mode 100644 index 0000000000000..f68887f0597fa --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/load_invalid_shr.tree.stderr @@ -0,0 +1,32 @@ +error: Undefined Behavior: read access through is forbidden + --> $DIR/load_invalid_shr.rs:LL:CC + | +LL | let _val = *xref_in_mem; + | ^^^^^^^^^^^^ read access through is forbidden + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: the accessed tag is a child of the conflicting tag + = help: the conflicting tag has state Disabled which forbids child read accesses +help: the accessed tag was created here + --> $DIR/load_invalid_shr.rs:LL:CC + | +LL | let xref_in_mem = Box::new(xref); + | ^^^^^^^^^^^^^^ +help: the conflicting tag was created here, in the initial state Frozen + --> $DIR/load_invalid_shr.rs:LL:CC + | +LL | let xref = unsafe { &*xraw }; + | ^^^^^^ +help: the conflicting tag later transitioned to Disabled due to a foreign write access at offsets [0x0..0x4] + --> $DIR/load_invalid_shr.rs:LL:CC + | +LL | unsafe { *xraw = 42 }; // unfreeze + | ^^^^^^^^^^ + = help: this corresponds to a loss of read permissions + = note: BACKTRACE (of the first span): + = note: inside `main` at $DIR/load_invalid_shr.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/stacked_borrows/mut_exclusive_violation1.rs b/src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation1.rs similarity index 70% rename from src/tools/miri/tests/fail/stacked_borrows/mut_exclusive_violation1.rs rename to src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation1.rs index f6fcdf1acdd2a..1bca637ae3bdf 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/mut_exclusive_violation1.rs +++ b/src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation1.rs @@ -1,3 +1,6 @@ +//@revisions: stack tree +//@[tree]compile-flags: -Zmiri-tree-borrows + fn demo_mut_advanced_unique(our: &mut i32) -> i32 { unknown_code_1(&*our); @@ -24,7 +27,9 @@ fn unknown_code_1(x: &i32) { fn unknown_code_2() { unsafe { - *LEAK = 7; //~ ERROR: /write access .* tag does not exist in the borrow stack/ + *LEAK = 7; + //~[stack]^ ERROR: /write access .* tag does not exist in the borrow stack/ + //~[tree]| ERROR: /write access through .* is forbidden/ } } diff --git a/src/tools/miri/tests/fail/stacked_borrows/mut_exclusive_violation1.stderr b/src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation1.stack.stderr similarity index 100% rename from src/tools/miri/tests/fail/stacked_borrows/mut_exclusive_violation1.stderr rename to src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation1.stack.stderr diff --git a/src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation1.tree.stderr b/src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation1.tree.stderr new file mode 100644 index 0000000000000..d80cfbea54e00 --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation1.tree.stderr @@ -0,0 +1,42 @@ +error: Undefined Behavior: write access through is forbidden + --> $DIR/mut_exclusive_violation1.rs:LL:CC + | +LL | *LEAK = 7; + | ^^^^^^^^^ write access through is forbidden + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: the accessed tag is a child of the conflicting tag + = help: the conflicting tag has state Disabled which forbids child write accesses +help: the accessed tag was created here + --> $DIR/mut_exclusive_violation1.rs:LL:CC + | +LL | fn unknown_code_1(x: &i32) { + | ^ +help: the conflicting tag was created here, in the initial state Frozen + --> $DIR/mut_exclusive_violation1.rs:LL:CC + | +LL | unknown_code_1(&*our); + | ^^^^^ +help: the conflicting tag later transitioned to Disabled due to a foreign write access at offsets [0x0..0x4] + --> $DIR/mut_exclusive_violation1.rs:LL:CC + | +LL | *our = 5; + | ^^^^^^^^ + = help: this corresponds to a loss of read permissions + = note: BACKTRACE (of the first span): + = note: inside `unknown_code_2` at $DIR/mut_exclusive_violation1.rs:LL:CC +note: inside `demo_mut_advanced_unique` + --> $DIR/mut_exclusive_violation1.rs:LL:CC + | +LL | unknown_code_2(); + | ^^^^^^^^^^^^^^^^ +note: inside `main` + --> $DIR/mut_exclusive_violation1.rs:LL:CC + | +LL | demo_mut_advanced_unique(&mut 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation2.rs b/src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation2.rs new file mode 100644 index 0000000000000..43f8b9d950ca5 --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation2.rs @@ -0,0 +1,16 @@ +//@revisions: stack tree +//@[tree]compile-flags: -Zmiri-tree-borrows +use std::ptr::NonNull; + +fn main() { + unsafe { + let x = &mut 0; + let mut ptr1 = NonNull::from(x); + let mut ptr2 = ptr1.clone(); + let raw1 = ptr1.as_mut(); + let raw2 = ptr2.as_mut(); + let _val = *raw1; //~[stack] ERROR: /read access .* tag does not exist in the borrow stack/ + *raw2 = 2; + *raw1 = 3; //~[tree] ERROR: /write access through .* is forbidden/ + } +} diff --git a/src/tools/miri/tests/fail/stacked_borrows/mut_exclusive_violation2.stderr b/src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation2.stack.stderr similarity index 94% rename from src/tools/miri/tests/fail/stacked_borrows/mut_exclusive_violation2.stderr rename to src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation2.stack.stderr index 30ce698761f3d..258189f88783c 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/mut_exclusive_violation2.stderr +++ b/src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation2.stack.stderr @@ -17,8 +17,8 @@ LL | let raw1 = ptr1.as_mut(); help: was later invalidated at offsets [0x0..0x4] by a Unique retag --> $DIR/mut_exclusive_violation2.rs:LL:CC | -LL | let _raw2 = ptr2.as_mut(); - | ^^^^^^^^^^^^^ +LL | let raw2 = ptr2.as_mut(); + | ^^^^^^^^^^^^^ = note: BACKTRACE (of the first span): = note: inside `main` at $DIR/mut_exclusive_violation2.rs:LL:CC diff --git a/src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation2.tree.stderr b/src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation2.tree.stderr new file mode 100644 index 0000000000000..94ca9ffb544e3 --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation2.tree.stderr @@ -0,0 +1,32 @@ +error: Undefined Behavior: write access through is forbidden + --> $DIR/mut_exclusive_violation2.rs:LL:CC + | +LL | *raw1 = 3; + | ^^^^^^^^^ write access through is forbidden + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: the accessed tag is a child of the conflicting tag + = help: the conflicting tag has state Disabled which forbids child write accesses +help: the accessed tag was created here + --> $DIR/mut_exclusive_violation2.rs:LL:CC + | +LL | let raw1 = ptr1.as_mut(); + | ^^^^^^^^^^^^^ +help: the conflicting tag was created here, in the initial state Reserved + --> $DIR/mut_exclusive_violation2.rs:LL:CC + | +LL | let raw1 = ptr1.as_mut(); + | ^^^^^^^^^^^^^ +help: the conflicting tag later transitioned to Disabled due to a foreign write access at offsets [0x0..0x4] + --> $DIR/mut_exclusive_violation2.rs:LL:CC + | +LL | *raw2 = 2; + | ^^^^^^^^^ + = help: this corresponds to a loss of read and write permissions + = note: BACKTRACE (of the first span): + = note: inside `main` at $DIR/mut_exclusive_violation2.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/stacked_borrows/newtype_pair_retagging.rs b/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.rs similarity index 69% rename from src/tools/miri/tests/fail/stacked_borrows/newtype_pair_retagging.rs rename to src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.rs index 1ae6740924c50..013d722135f7f 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/newtype_pair_retagging.rs +++ b/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.rs @@ -1,4 +1,8 @@ -//@error-in-other-file: which is strongly protected +//@revisions: stack tree +//@[tree]compile-flags: -Zmiri-tree-borrows + +//@[stack]error-in-other-file: which is strongly protected +//@[tree]error-in-other-file: /write access through .* is forbidden/ struct Newtype<'a>(&'a mut i32, i32); fn dealloc_while_running(_n: Newtype<'_>, dealloc: impl FnOnce()) { diff --git a/src/tools/miri/tests/fail/stacked_borrows/newtype_pair_retagging.stderr b/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.stack.stderr similarity index 100% rename from src/tools/miri/tests/fail/stacked_borrows/newtype_pair_retagging.stderr rename to src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.stack.stderr diff --git a/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.tree.stderr b/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.tree.stderr new file mode 100644 index 0000000000000..11ac000da979e --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.tree.stderr @@ -0,0 +1,55 @@ +error: Undefined Behavior: write access through is forbidden + --> RUSTLIB/alloc/src/alloc.rs:LL:CC + | +LL | unsafe { __rust_dealloc(ptr, layout.size(), layout.align()) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ write access through is forbidden + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: the accessed tag is foreign to the protected tag (i.e., it is not a child) + = help: the access would cause the protected tag to transition from Frozen to Disabled + = help: this is a loss of read permissions, which is not allowed for protected tags +help: the accessed tag was created here + --> $DIR/newtype_pair_retagging.rs:LL:CC + | +LL | || drop(Box::from_raw(ptr)), + | ^^^^^^^^^^^^^^^^^^^^^^^^ +help: the protected tag was created here, in the initial state Reserved + --> $DIR/newtype_pair_retagging.rs:LL:CC + | +LL | fn dealloc_while_running(_n: Newtype<'_>, dealloc: impl FnOnce()) { + | ^^ +help: the protected tag later transitioned to Frozen due to a foreign read access at offsets [0x0..0x4] + --> $DIR/newtype_pair_retagging.rs:LL:CC + | +LL | || drop(Box::from_raw(ptr)), + | ^^^^^^^^^^^^^^^^^^ + = help: this corresponds to a loss of write permissions + = note: BACKTRACE (of the first span): + = note: inside `std::alloc::dealloc` at RUSTLIB/alloc/src/alloc.rs:LL:CC + = note: inside `::deallocate` at RUSTLIB/alloc/src/alloc.rs:LL:CC + = note: inside `alloc::alloc::box_free::` at RUSTLIB/alloc/src/alloc.rs:LL:CC + = note: inside `std::ptr::drop_in_place::> - shim(Some(std::boxed::Box))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC + = note: inside `std::mem::drop::>` at RUSTLIB/core/src/mem/mod.rs:LL:CC +note: inside closure + --> $DIR/newtype_pair_retagging.rs:LL:CC + | +LL | || drop(Box::from_raw(ptr)), + | ^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `dealloc_while_running::<[closure@$DIR/newtype_pair_retagging.rs:LL:CC]>` + --> $DIR/newtype_pair_retagging.rs:LL:CC + | +LL | dealloc(); + | ^^^^^^^^^ +note: inside `main` + --> $DIR/newtype_pair_retagging.rs:LL:CC + | +LL | / dealloc_while_running( +LL | | Newtype(&mut *ptr, 0), +LL | | || drop(Box::from_raw(ptr)), +LL | | ) + | |_________^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/stacked_borrows/newtype_retagging.rs b/src/tools/miri/tests/fail/both_borrows/newtype_retagging.rs similarity index 67% rename from src/tools/miri/tests/fail/stacked_borrows/newtype_retagging.rs rename to src/tools/miri/tests/fail/both_borrows/newtype_retagging.rs index f106274b8112e..c711e9ca9a14c 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/newtype_retagging.rs +++ b/src/tools/miri/tests/fail/both_borrows/newtype_retagging.rs @@ -1,4 +1,9 @@ -//@error-in-other-file: which is strongly protected +//@revisions: stack tree +//@[tree]compile-flags: -Zmiri-tree-borrows + +//@[stack]error-in-other-file: which is strongly protected +//@[tree]error-in-other-file: /write access through .* is forbidden/ + struct Newtype<'a>(&'a mut i32); fn dealloc_while_running(_n: Newtype<'_>, dealloc: impl FnOnce()) { diff --git a/src/tools/miri/tests/fail/stacked_borrows/newtype_retagging.stderr b/src/tools/miri/tests/fail/both_borrows/newtype_retagging.stack.stderr similarity index 100% rename from src/tools/miri/tests/fail/stacked_borrows/newtype_retagging.stderr rename to src/tools/miri/tests/fail/both_borrows/newtype_retagging.stack.stderr diff --git a/src/tools/miri/tests/fail/both_borrows/newtype_retagging.tree.stderr b/src/tools/miri/tests/fail/both_borrows/newtype_retagging.tree.stderr new file mode 100644 index 0000000000000..c442f398fc12f --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/newtype_retagging.tree.stderr @@ -0,0 +1,55 @@ +error: Undefined Behavior: write access through is forbidden + --> RUSTLIB/alloc/src/alloc.rs:LL:CC + | +LL | unsafe { __rust_dealloc(ptr, layout.size(), layout.align()) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ write access through is forbidden + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: the accessed tag is foreign to the protected tag (i.e., it is not a child) + = help: the access would cause the protected tag to transition from Frozen to Disabled + = help: this is a loss of read permissions, which is not allowed for protected tags +help: the accessed tag was created here + --> $DIR/newtype_retagging.rs:LL:CC + | +LL | || drop(Box::from_raw(ptr)), + | ^^^^^^^^^^^^^^^^^^^^^^^^ +help: the protected tag was created here, in the initial state Reserved + --> $DIR/newtype_retagging.rs:LL:CC + | +LL | fn dealloc_while_running(_n: Newtype<'_>, dealloc: impl FnOnce()) { + | ^^ +help: the protected tag later transitioned to Frozen due to a foreign read access at offsets [0x0..0x4] + --> $DIR/newtype_retagging.rs:LL:CC + | +LL | || drop(Box::from_raw(ptr)), + | ^^^^^^^^^^^^^^^^^^ + = help: this corresponds to a loss of write permissions + = note: BACKTRACE (of the first span): + = note: inside `std::alloc::dealloc` at RUSTLIB/alloc/src/alloc.rs:LL:CC + = note: inside `::deallocate` at RUSTLIB/alloc/src/alloc.rs:LL:CC + = note: inside `alloc::alloc::box_free::` at RUSTLIB/alloc/src/alloc.rs:LL:CC + = note: inside `std::ptr::drop_in_place::> - shim(Some(std::boxed::Box))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC + = note: inside `std::mem::drop::>` at RUSTLIB/core/src/mem/mod.rs:LL:CC +note: inside closure + --> $DIR/newtype_retagging.rs:LL:CC + | +LL | || drop(Box::from_raw(ptr)), + | ^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `dealloc_while_running::<[closure@$DIR/newtype_retagging.rs:LL:CC]>` + --> $DIR/newtype_retagging.rs:LL:CC + | +LL | dealloc(); + | ^^^^^^^^^ +note: inside `main` + --> $DIR/newtype_retagging.rs:LL:CC + | +LL | / dealloc_while_running( +LL | | Newtype(&mut *ptr), +LL | | || drop(Box::from_raw(ptr)), +LL | | ) + | |_________^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/both_borrows/outdated_local.rs b/src/tools/miri/tests/fail/both_borrows/outdated_local.rs new file mode 100644 index 0000000000000..1330496bbe931 --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/outdated_local.rs @@ -0,0 +1,14 @@ +//@revisions: stack tree +//@[tree]compile-flags: -Zmiri-tree-borrows + +fn main() { + let mut x = 0; + let y: *const i32 = &x; + x = 1; // this invalidates y by reactivating the lowermost uniq borrow for this local + + assert_eq!(unsafe { *y }, 1); + //~[stack]^ ERROR: /read access .* tag does not exist in the borrow stack/ + //~[tree]| ERROR: /read access through .* is forbidden/ + + assert_eq!(x, 1); +} diff --git a/src/tools/miri/tests/fail/stacked_borrows/outdated_local.stderr b/src/tools/miri/tests/fail/both_borrows/outdated_local.stack.stderr similarity index 100% rename from src/tools/miri/tests/fail/stacked_borrows/outdated_local.stderr rename to src/tools/miri/tests/fail/both_borrows/outdated_local.stack.stderr diff --git a/src/tools/miri/tests/fail/both_borrows/outdated_local.tree.stderr b/src/tools/miri/tests/fail/both_borrows/outdated_local.tree.stderr new file mode 100644 index 0000000000000..6d0087bb8303c --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/outdated_local.tree.stderr @@ -0,0 +1,26 @@ +error: Undefined Behavior: read access through is forbidden + --> $DIR/outdated_local.rs:LL:CC + | +LL | assert_eq!(unsafe { *y }, 1); + | ^^ read access through is forbidden + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: the accessed tag has state Disabled which forbids child read accesses +help: the accessed tag was created here, in the initial state Frozen + --> $DIR/outdated_local.rs:LL:CC + | +LL | let y: *const i32 = &x; + | ^^ +help: the accessed tag later transitioned to Disabled due to a foreign write access at offsets [0x0..0x4] + --> $DIR/outdated_local.rs:LL:CC + | +LL | x = 1; // this invalidates y by reactivating the lowermost uniq borrow for this local + | ^^^^^ + = help: this corresponds to a loss of read permissions + = note: BACKTRACE (of the first span): + = note: inside `main` at $DIR/outdated_local.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/stacked_borrows/pass_invalid_shr.rs b/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr.rs similarity index 52% rename from src/tools/miri/tests/fail/stacked_borrows/pass_invalid_shr.rs rename to src/tools/miri/tests/fail/both_borrows/pass_invalid_shr.rs index 903c2733107bb..a49f622f69230 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/pass_invalid_shr.rs +++ b/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr.rs @@ -1,3 +1,6 @@ +//@revisions: stack tree +//@[tree]compile-flags: -Zmiri-tree-borrows + // Make sure that we cannot pass by argument a `&` that got already invalidated. fn foo(_: &i32) {} @@ -6,5 +9,7 @@ fn main() { let xraw = x as *mut _; let xref = unsafe { &*xraw }; unsafe { *xraw = 42 }; // unfreeze - foo(xref); //~ ERROR: /retag .* tag does not exist in the borrow stack/ + foo(xref); + //~[stack]^ ERROR: /retag .* tag does not exist in the borrow stack/ + //~[tree]| ERROR: /read access through .* is forbidden/ } diff --git a/src/tools/miri/tests/fail/stacked_borrows/pass_invalid_shr.stderr b/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr.stack.stderr similarity index 100% rename from src/tools/miri/tests/fail/stacked_borrows/pass_invalid_shr.stderr rename to src/tools/miri/tests/fail/both_borrows/pass_invalid_shr.stack.stderr diff --git a/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr.tree.stderr b/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr.tree.stderr new file mode 100644 index 0000000000000..c94e6c021bdfb --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr.tree.stderr @@ -0,0 +1,26 @@ +error: Undefined Behavior: read access through is forbidden + --> $DIR/pass_invalid_shr.rs:LL:CC + | +LL | foo(xref); + | ^^^^ read access through is forbidden + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: the accessed tag has state Disabled which forbids child read accesses +help: the accessed tag was created here, in the initial state Frozen + --> $DIR/pass_invalid_shr.rs:LL:CC + | +LL | let xref = unsafe { &*xraw }; + | ^^^^^^ +help: the accessed tag later transitioned to Disabled due to a foreign write access at offsets [0x0..0x4] + --> $DIR/pass_invalid_shr.rs:LL:CC + | +LL | unsafe { *xraw = 42 }; // unfreeze + | ^^^^^^^^^^ + = help: this corresponds to a loss of read permissions + = note: BACKTRACE (of the first span): + = note: inside `main` at $DIR/pass_invalid_shr.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr_option.rs b/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr_option.rs new file mode 100644 index 0000000000000..0ac6f98fbc185 --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr_option.rs @@ -0,0 +1,15 @@ +//@revisions: stack tree +//@[tree]compile-flags: -Zmiri-tree-borrows + +// Make sure that we cannot pass by argument a `&` that got already invalidated. +fn foo(_: Option<&i32>) {} + +fn main() { + let x = &mut 42; + let xraw = x as *mut _; + let some_xref = unsafe { Some(&*xraw) }; + unsafe { *xraw = 42 }; // unfreeze + foo(some_xref); + //~[stack]^ ERROR: /retag .* tag does not exist in the borrow stack/ + //~[tree]| ERROR: /read access through .* is forbidden/ +} diff --git a/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr_option.stack.stderr b/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr_option.stack.stderr new file mode 100644 index 0000000000000..e35d7918c03cf --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr_option.stack.stderr @@ -0,0 +1,28 @@ +error: Undefined Behavior: trying to retag from for SharedReadOnly permission at ALLOC[0x0], but that tag does not exist in the borrow stack for this location + --> $DIR/pass_invalid_shr_option.rs:LL:CC + | +LL | foo(some_xref); + | ^^^^^^^^^ + | | + | trying to retag from for SharedReadOnly permission at ALLOC[0x0], but that tag does not exist in the borrow stack for this location + | this error occurs as part of retag at ALLOC[0x0..0x4] + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental + = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information +help: was created by a SharedReadOnly retag at offsets [0x0..0x4] + --> $DIR/pass_invalid_shr_option.rs:LL:CC + | +LL | let some_xref = unsafe { Some(&*xraw) }; + | ^^^^^^^^^^^^ +help: was later invalidated at offsets [0x0..0x4] by a write access + --> $DIR/pass_invalid_shr_option.rs:LL:CC + | +LL | unsafe { *xraw = 42 }; // unfreeze + | ^^^^^^^^^^ + = note: BACKTRACE (of the first span): + = note: inside `main` at $DIR/pass_invalid_shr_option.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr_option.tree.stderr b/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr_option.tree.stderr new file mode 100644 index 0000000000000..87b4fcba4d51f --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr_option.tree.stderr @@ -0,0 +1,32 @@ +error: Undefined Behavior: read access through is forbidden + --> $DIR/pass_invalid_shr_option.rs:LL:CC + | +LL | foo(some_xref); + | ^^^^^^^^^ read access through is forbidden + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: the accessed tag is a child of the conflicting tag + = help: the conflicting tag has state Disabled which forbids child read accesses +help: the accessed tag was created here + --> $DIR/pass_invalid_shr_option.rs:LL:CC + | +LL | let some_xref = unsafe { Some(&*xraw) }; + | ^^^^^^^^^^^^ +help: the conflicting tag was created here, in the initial state Frozen + --> $DIR/pass_invalid_shr_option.rs:LL:CC + | +LL | let some_xref = unsafe { Some(&*xraw) }; + | ^^^^^^ +help: the conflicting tag later transitioned to Disabled due to a foreign write access at offsets [0x0..0x4] + --> $DIR/pass_invalid_shr_option.rs:LL:CC + | +LL | unsafe { *xraw = 42 }; // unfreeze + | ^^^^^^^^^^ + = help: this corresponds to a loss of read permissions + = note: BACKTRACE (of the first span): + = note: inside `main` at $DIR/pass_invalid_shr_option.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr_tuple.rs b/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr_tuple.rs new file mode 100644 index 0000000000000..d22c0f6e8e16c --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr_tuple.rs @@ -0,0 +1,16 @@ +//@revisions: stack tree +//@[tree]compile-flags: -Zmiri-tree-borrows + +// Make sure that we cannot pass by argument a `&` that got already invalidated. +fn foo(_: (&i32, &i32)) {} + +fn main() { + let x = &mut (42i32, 31i32); + let xraw0 = &mut x.0 as *mut _; + let xraw1 = &mut x.1 as *mut _; + let pair_xref = unsafe { (&*xraw0, &*xraw1) }; + unsafe { *xraw0 = 42 }; // unfreeze + foo(pair_xref); + //~[stack]^ ERROR: /retag .* tag does not exist in the borrow stack/ + //~[tree]| ERROR: /read access through .* is forbidden/ +} diff --git a/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr_tuple.stack.stderr b/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr_tuple.stack.stderr new file mode 100644 index 0000000000000..10c566d061216 --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr_tuple.stack.stderr @@ -0,0 +1,28 @@ +error: Undefined Behavior: trying to retag from for SharedReadOnly permission at ALLOC[0x0], but that tag does not exist in the borrow stack for this location + --> $DIR/pass_invalid_shr_tuple.rs:LL:CC + | +LL | foo(pair_xref); + | ^^^^^^^^^ + | | + | trying to retag from for SharedReadOnly permission at ALLOC[0x0], but that tag does not exist in the borrow stack for this location + | this error occurs as part of retag at ALLOC[0x0..0x4] + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental + = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information +help: was created by a SharedReadOnly retag at offsets [0x0..0x4] + --> $DIR/pass_invalid_shr_tuple.rs:LL:CC + | +LL | let pair_xref = unsafe { (&*xraw0, &*xraw1) }; + | ^^^^^^^^^^^^^^^^^^ +help: was later invalidated at offsets [0x0..0x4] by a write access + --> $DIR/pass_invalid_shr_tuple.rs:LL:CC + | +LL | unsafe { *xraw0 = 42 }; // unfreeze + | ^^^^^^^^^^^ + = note: BACKTRACE (of the first span): + = note: inside `main` at $DIR/pass_invalid_shr_tuple.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr_tuple.tree.stderr b/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr_tuple.tree.stderr new file mode 100644 index 0000000000000..605120e59dbb5 --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/pass_invalid_shr_tuple.tree.stderr @@ -0,0 +1,32 @@ +error: Undefined Behavior: read access through is forbidden + --> $DIR/pass_invalid_shr_tuple.rs:LL:CC + | +LL | foo(pair_xref); + | ^^^^^^^^^ read access through is forbidden + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: the accessed tag is a child of the conflicting tag + = help: the conflicting tag has state Disabled which forbids child read accesses +help: the accessed tag was created here + --> $DIR/pass_invalid_shr_tuple.rs:LL:CC + | +LL | let pair_xref = unsafe { (&*xraw0, &*xraw1) }; + | ^^^^^^^^^^^^^^^^^^ +help: the conflicting tag was created here, in the initial state Frozen + --> $DIR/pass_invalid_shr_tuple.rs:LL:CC + | +LL | let pair_xref = unsafe { (&*xraw0, &*xraw1) }; + | ^^^^^^^ +help: the conflicting tag later transitioned to Disabled due to a foreign write access at offsets [0x0..0x4] + --> $DIR/pass_invalid_shr_tuple.rs:LL:CC + | +LL | unsafe { *xraw0 = 42 }; // unfreeze + | ^^^^^^^^^^^ + = help: this corresponds to a loss of read permissions + = note: BACKTRACE (of the first span): + = note: inside `main` at $DIR/pass_invalid_shr_tuple.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr.rs b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr.rs similarity index 55% rename from src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr.rs rename to src/tools/miri/tests/fail/both_borrows/return_invalid_shr.rs index 45526498dadf5..99945e5699239 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr.rs +++ b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr.rs @@ -1,9 +1,14 @@ +//@revisions: stack tree +//@[tree]compile-flags: -Zmiri-tree-borrows + // Make sure that we cannot return a `&` that got already invalidated. fn foo(x: &mut (i32, i32)) -> &i32 { let xraw = x as *mut (i32, i32); let ret = unsafe { &(*xraw).1 }; unsafe { *xraw = (42, 23) }; // unfreeze - ret //~ ERROR: /retag .* tag does not exist in the borrow stack/ + ret + //~[stack]^ ERROR: /retag .* tag does not exist in the borrow stack/ + //~[tree]| ERROR: /read access through .* is forbidden/ } fn main() { diff --git a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr.stderr b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr.stack.stderr similarity index 100% rename from src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr.stderr rename to src/tools/miri/tests/fail/both_borrows/return_invalid_shr.stack.stderr diff --git a/src/tools/miri/tests/fail/both_borrows/return_invalid_shr.tree.stderr b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr.tree.stderr new file mode 100644 index 0000000000000..1b3a5bfbd12f9 --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr.tree.stderr @@ -0,0 +1,31 @@ +error: Undefined Behavior: read access through is forbidden + --> $DIR/return_invalid_shr.rs:LL:CC + | +LL | ret + | ^^^ read access through is forbidden + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: the accessed tag has state Disabled which forbids child read accesses +help: the accessed tag was created here, in the initial state Frozen + --> $DIR/return_invalid_shr.rs:LL:CC + | +LL | let ret = unsafe { &(*xraw).1 }; + | ^^^^^^^^^^ +help: the accessed tag later transitioned to Disabled due to a foreign write access at offsets [0x0..0x8] + --> $DIR/return_invalid_shr.rs:LL:CC + | +LL | unsafe { *xraw = (42, 23) }; // unfreeze + | ^^^^^^^^^^^^^^^^ + = help: this corresponds to a loss of read permissions + = note: BACKTRACE (of the first span): + = note: inside `foo` at $DIR/return_invalid_shr.rs:LL:CC +note: inside `main` + --> $DIR/return_invalid_shr.rs:LL:CC + | +LL | foo(&mut (1, 2)); + | ^^^^^^^^^^^^^^^^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr_option.rs b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_option.rs similarity index 63% rename from src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr_option.rs rename to src/tools/miri/tests/fail/both_borrows/return_invalid_shr_option.rs index 094ce33b9c1f7..e735ce9bedabb 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr_option.rs +++ b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_option.rs @@ -1,9 +1,14 @@ +//@revisions: stack tree +//@[tree]compile-flags: -Zmiri-tree-borrows + // Make sure that we cannot return a `&` that got already invalidated, not even in an `Option`. fn foo(x: &mut (i32, i32)) -> Option<&i32> { let xraw = x as *mut (i32, i32); let ret = Some(unsafe { &(*xraw).1 }); unsafe { *xraw = (42, 23) }; // unfreeze - ret //~ ERROR: /retag .* tag does not exist in the borrow stack/ + ret + //~[stack]^ ERROR: /retag .* tag does not exist in the borrow stack/ + //~[tree]| ERROR: /read access through .* is forbidden/ } fn main() { diff --git a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr_option.stderr b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_option.stack.stderr similarity index 100% rename from src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr_option.stderr rename to src/tools/miri/tests/fail/both_borrows/return_invalid_shr_option.stack.stderr diff --git a/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_option.tree.stderr b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_option.tree.stderr new file mode 100644 index 0000000000000..4e920b34d7b6a --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_option.tree.stderr @@ -0,0 +1,37 @@ +error: Undefined Behavior: read access through is forbidden + --> $DIR/return_invalid_shr_option.rs:LL:CC + | +LL | ret + | ^^^ read access through is forbidden + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: the accessed tag is a child of the conflicting tag + = help: the conflicting tag has state Disabled which forbids child read accesses +help: the accessed tag was created here + --> $DIR/return_invalid_shr_option.rs:LL:CC + | +LL | let ret = Some(unsafe { &(*xraw).1 }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: the conflicting tag was created here, in the initial state Frozen + --> $DIR/return_invalid_shr_option.rs:LL:CC + | +LL | let ret = Some(unsafe { &(*xraw).1 }); + | ^^^^^^^^^^ +help: the conflicting tag later transitioned to Disabled due to a foreign write access at offsets [0x0..0x8] + --> $DIR/return_invalid_shr_option.rs:LL:CC + | +LL | unsafe { *xraw = (42, 23) }; // unfreeze + | ^^^^^^^^^^^^^^^^ + = help: this corresponds to a loss of read permissions + = note: BACKTRACE (of the first span): + = note: inside `foo` at $DIR/return_invalid_shr_option.rs:LL:CC +note: inside `main` + --> $DIR/return_invalid_shr_option.rs:LL:CC + | +LL | match foo(&mut (1, 2)) { + | ^^^^^^^^^^^^^^^^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr_tuple.rs b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_tuple.rs similarity index 58% rename from src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr_tuple.rs rename to src/tools/miri/tests/fail/both_borrows/return_invalid_shr_tuple.rs index d0fd53e06aa26..90a40215022b7 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr_tuple.rs +++ b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_tuple.rs @@ -1,9 +1,14 @@ +//@revisions: stack tree +//@[tree]compile-flags: -Zmiri-tree-borrows + // Make sure that we cannot return a `&` that got already invalidated, not even in a tuple. fn foo(x: &mut (i32, i32)) -> (&i32,) { let xraw = x as *mut (i32, i32); let ret = (unsafe { &(*xraw).1 },); unsafe { *xraw = (42, 23) }; // unfreeze - ret //~ ERROR: /retag .* tag does not exist in the borrow stack/ + ret + //~[stack]^ ERROR: /retag .* tag does not exist in the borrow stack/ + //~[tree]| ERROR: /read access through .* is forbidden/ } fn main() { diff --git a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr_tuple.stderr b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_tuple.stack.stderr similarity index 100% rename from src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr_tuple.stderr rename to src/tools/miri/tests/fail/both_borrows/return_invalid_shr_tuple.stack.stderr diff --git a/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_tuple.tree.stderr b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_tuple.tree.stderr new file mode 100644 index 0000000000000..b60614e98fad4 --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_tuple.tree.stderr @@ -0,0 +1,37 @@ +error: Undefined Behavior: read access through is forbidden + --> $DIR/return_invalid_shr_tuple.rs:LL:CC + | +LL | ret + | ^^^ read access through is forbidden + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: the accessed tag is a child of the conflicting tag + = help: the conflicting tag has state Disabled which forbids child read accesses +help: the accessed tag was created here + --> $DIR/return_invalid_shr_tuple.rs:LL:CC + | +LL | let ret = (unsafe { &(*xraw).1 },); + | ^^^^^^^^^^^^^^^^^^^^^^^^ +help: the conflicting tag was created here, in the initial state Frozen + --> $DIR/return_invalid_shr_tuple.rs:LL:CC + | +LL | let ret = (unsafe { &(*xraw).1 },); + | ^^^^^^^^^^ +help: the conflicting tag later transitioned to Disabled due to a foreign write access at offsets [0x0..0x8] + --> $DIR/return_invalid_shr_tuple.rs:LL:CC + | +LL | unsafe { *xraw = (42, 23) }; // unfreeze + | ^^^^^^^^^^^^^^^^ + = help: this corresponds to a loss of read permissions + = note: BACKTRACE (of the first span): + = note: inside `foo` at $DIR/return_invalid_shr_tuple.rs:LL:CC +note: inside `main` + --> $DIR/return_invalid_shr_tuple.rs:LL:CC + | +LL | foo(&mut (1, 2)).0; + | ^^^^^^^^^^^^^^^^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation1.rs b/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation1.rs new file mode 100644 index 0000000000000..1edd7748cde11 --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation1.rs @@ -0,0 +1,22 @@ +//@revisions: stack tree +//@[tree]compile-flags: -Zmiri-tree-borrows + +#![allow(cast_ref_to_mut)] + +fn foo(x: &mut i32) -> i32 { + *x = 5; + unknown_code(&*x); + *x // must return 5 +} + +fn main() { + println!("{}", foo(&mut 0)); +} + +fn unknown_code(x: &i32) { + unsafe { + *(x as *const i32 as *mut i32) = 7; + //~[stack]^ ERROR: /write access .* only grants SharedReadOnly permission/ + //~[tree]| ERROR: /write access through .* is forbidden/ + } +} diff --git a/src/tools/miri/tests/fail/stacked_borrows/shr_frozen_violation1.stderr b/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation1.stack.stderr similarity index 100% rename from src/tools/miri/tests/fail/stacked_borrows/shr_frozen_violation1.stderr rename to src/tools/miri/tests/fail/both_borrows/shr_frozen_violation1.stack.stderr diff --git a/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation1.tree.stderr b/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation1.tree.stderr new file mode 100644 index 0000000000000..893e38f5b6c12 --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation1.tree.stderr @@ -0,0 +1,36 @@ +error: Undefined Behavior: write access through is forbidden + --> $DIR/shr_frozen_violation1.rs:LL:CC + | +LL | *(x as *const i32 as *mut i32) = 7; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ write access through is forbidden + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: the accessed tag is a child of the conflicting tag + = help: the conflicting tag has state Frozen which forbids child write accesses +help: the accessed tag was created here + --> $DIR/shr_frozen_violation1.rs:LL:CC + | +LL | fn unknown_code(x: &i32) { + | ^ +help: the conflicting tag was created here, in the initial state Frozen + --> $DIR/shr_frozen_violation1.rs:LL:CC + | +LL | unknown_code(&*x); + | ^^^ + = note: BACKTRACE (of the first span): + = note: inside `unknown_code` at $DIR/shr_frozen_violation1.rs:LL:CC +note: inside `foo` + --> $DIR/shr_frozen_violation1.rs:LL:CC + | +LL | unknown_code(&*x); + | ^^^^^^^^^^^^^^^^^ +note: inside `main` + --> $DIR/shr_frozen_violation1.rs:LL:CC + | +LL | println!("{}", foo(&mut 0)); + | ^^^^^^^^^^^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation2.rs b/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation2.rs new file mode 100644 index 0000000000000..7b2b63ef215e6 --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation2.rs @@ -0,0 +1,15 @@ +//@revisions: stack tree +//@[tree]compile-flags: -Zmiri-tree-borrows +fn main() { + unsafe { + let mut x = 0; + let ptr = std::ptr::addr_of_mut!(x); + let frozen = &*ptr; + let _val = *frozen; + x = 1; + let _val = *frozen; + //~[stack]^ ERROR: /read access .* tag does not exist in the borrow stack/ + //~[tree]| ERROR: /read access through .* is forbidden/ + let _val = x; // silence warning + } +} diff --git a/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation2.stack.stderr b/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation2.stack.stderr new file mode 100644 index 0000000000000..0f09359007dba --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation2.stack.stderr @@ -0,0 +1,28 @@ +error: Undefined Behavior: attempting a read access using at ALLOC[0x0], but that tag does not exist in the borrow stack for this location + --> $DIR/shr_frozen_violation2.rs:LL:CC + | +LL | let _val = *frozen; + | ^^^^^^^ + | | + | attempting a read access using at ALLOC[0x0], but that tag does not exist in the borrow stack for this location + | this error occurs as part of an access at ALLOC[0x0..0x4] + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental + = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information +help: was created by a SharedReadOnly retag at offsets [0x0..0x4] + --> $DIR/shr_frozen_violation2.rs:LL:CC + | +LL | let frozen = &*ptr; + | ^^^^^ +help: was later invalidated at offsets [0x0..0x4] by a write access + --> $DIR/shr_frozen_violation2.rs:LL:CC + | +LL | x = 1; + | ^^^^^ + = note: BACKTRACE (of the first span): + = note: inside `main` at $DIR/shr_frozen_violation2.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation2.tree.stderr b/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation2.tree.stderr new file mode 100644 index 0000000000000..5fd5ba2fe3639 --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation2.tree.stderr @@ -0,0 +1,26 @@ +error: Undefined Behavior: read access through is forbidden + --> $DIR/shr_frozen_violation2.rs:LL:CC + | +LL | let _val = *frozen; + | ^^^^^^^ read access through is forbidden + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: the accessed tag has state Disabled which forbids child read accesses +help: the accessed tag was created here, in the initial state Frozen + --> $DIR/shr_frozen_violation2.rs:LL:CC + | +LL | let frozen = &*ptr; + | ^^^^^ +help: the accessed tag later transitioned to Disabled due to a foreign write access at offsets [0x0..0x4] + --> $DIR/shr_frozen_violation2.rs:LL:CC + | +LL | x = 1; + | ^^^^^ + = help: this corresponds to a loss of read permissions + = note: BACKTRACE (of the first span): + = note: inside `main` at $DIR/shr_frozen_violation2.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/stacked_borrows/illegal_write1.rs b/src/tools/miri/tests/fail/stacked_borrows/illegal_write1.rs deleted file mode 100644 index f28401938a925..0000000000000 --- a/src/tools/miri/tests/fail/stacked_borrows/illegal_write1.rs +++ /dev/null @@ -1,9 +0,0 @@ -fn main() { - let target = Box::new(42); // has an implicit raw - let xref = &*target; - { - let x: *mut u32 = xref as *const _ as *mut _; - unsafe { *x = 42 }; //~ ERROR: /write access .* tag only grants SharedReadOnly permission/ - } - let _x = *xref; -} diff --git a/src/tools/miri/tests/fail/stacked_borrows/illegal_write6.rs b/src/tools/miri/tests/fail/stacked_borrows/illegal_write6.rs deleted file mode 100644 index 7983b30ea1822..0000000000000 --- a/src/tools/miri/tests/fail/stacked_borrows/illegal_write6.rs +++ /dev/null @@ -1,12 +0,0 @@ -fn main() { - let x = &mut 0u32; - let p = x as *mut u32; - foo(x, p); -} - -fn foo(a: &mut u32, y: *mut u32) -> u32 { - *a = 1; - let _b = &*a; - unsafe { *y = 2 }; //~ ERROR: /not granting access .* because that would remove .* which is strongly protected/ - return *a; -} diff --git a/src/tools/miri/tests/fail/stacked_borrows/mut_exclusive_violation2.rs b/src/tools/miri/tests/fail/stacked_borrows/mut_exclusive_violation2.rs deleted file mode 100644 index 2305ce746512a..0000000000000 --- a/src/tools/miri/tests/fail/stacked_borrows/mut_exclusive_violation2.rs +++ /dev/null @@ -1,12 +0,0 @@ -use std::ptr::NonNull; - -fn main() { - unsafe { - let x = &mut 0; - let mut ptr1 = NonNull::from(x); - let mut ptr2 = ptr1.clone(); - let raw1 = ptr1.as_mut(); - let _raw2 = ptr2.as_mut(); - let _val = *raw1; //~ ERROR: /read access .* tag does not exist in the borrow stack/ - } -} diff --git a/src/tools/miri/tests/fail/stacked_borrows/outdated_local.rs b/src/tools/miri/tests/fail/stacked_borrows/outdated_local.rs deleted file mode 100644 index 4262157d1e3df..0000000000000 --- a/src/tools/miri/tests/fail/stacked_borrows/outdated_local.rs +++ /dev/null @@ -1,9 +0,0 @@ -fn main() { - let mut x = 0; - let y: *const i32 = &x; - x = 1; // this invalidates y by reactivating the lowermost uniq borrow for this local - - assert_eq!(unsafe { *y }, 1); //~ ERROR: /read access .* tag does not exist in the borrow stack/ - - assert_eq!(x, 1); -} diff --git a/src/tools/miri/tests/fail/stacked_borrows/shr_frozen_violation1.rs b/src/tools/miri/tests/fail/stacked_borrows/shr_frozen_violation1.rs deleted file mode 100644 index 8cd59b3550dc9..0000000000000 --- a/src/tools/miri/tests/fail/stacked_borrows/shr_frozen_violation1.rs +++ /dev/null @@ -1,17 +0,0 @@ -#![allow(cast_ref_to_mut)] - -fn foo(x: &mut i32) -> i32 { - *x = 5; - unknown_code(&*x); - *x // must return 5 -} - -fn main() { - println!("{}", foo(&mut 0)); -} - -fn unknown_code(x: &i32) { - unsafe { - *(x as *const i32 as *mut i32) = 7; //~ ERROR: /write access .* only grants SharedReadOnly permission/ - } -} diff --git a/src/tools/miri/tests/fail/tree-borrows/alternate-read-write.rs b/src/tools/miri/tests/fail/tree_borrows/alternate-read-write.rs similarity index 100% rename from src/tools/miri/tests/fail/tree-borrows/alternate-read-write.rs rename to src/tools/miri/tests/fail/tree_borrows/alternate-read-write.rs diff --git a/src/tools/miri/tests/fail/tree-borrows/alternate-read-write.stderr b/src/tools/miri/tests/fail/tree_borrows/alternate-read-write.stderr similarity index 100% rename from src/tools/miri/tests/fail/tree-borrows/alternate-read-write.stderr rename to src/tools/miri/tests/fail/tree_borrows/alternate-read-write.stderr diff --git a/src/tools/miri/tests/fail/tree-borrows/error-range.rs b/src/tools/miri/tests/fail/tree_borrows/error-range.rs similarity index 100% rename from src/tools/miri/tests/fail/tree-borrows/error-range.rs rename to src/tools/miri/tests/fail/tree_borrows/error-range.rs diff --git a/src/tools/miri/tests/fail/tree-borrows/error-range.stderr b/src/tools/miri/tests/fail/tree_borrows/error-range.stderr similarity index 100% rename from src/tools/miri/tests/fail/tree-borrows/error-range.stderr rename to src/tools/miri/tests/fail/tree_borrows/error-range.stderr diff --git a/src/tools/miri/tests/fail/tree_borrows/fnentry_invalidation.rs b/src/tools/miri/tests/fail/tree_borrows/fnentry_invalidation.rs new file mode 100644 index 0000000000000..a21cbab6a9fc1 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/fnentry_invalidation.rs @@ -0,0 +1,29 @@ +//@compile-flags: -Zmiri-tree-borrows +// This test is the TB counterpart to fail/stacked_borrows/fnentry_invalidation, +// but the SB version passes TB without error. +// An additional write access is inserted so that this test properly fails. + +// Test that spans displayed in diagnostics identify the function call, not the function +// definition, as the location of invalidation due to FnEntry retag. Technically the FnEntry retag +// occurs inside the function, but what the user wants to know is which call produced the +// invalidation. + +fn main() { + let mut x = 0i32; + let z = &mut x as *mut i32; + unsafe { + *z = 1; + } + x.do_bad(); + unsafe { + *z = 2; //~ ERROR: /write access through .* is forbidden/ + } +} + +trait Bad { + fn do_bad(&mut self) { + // who knows + } +} + +impl Bad for i32 {} diff --git a/src/tools/miri/tests/fail/tree_borrows/fnentry_invalidation.stderr b/src/tools/miri/tests/fail/tree_borrows/fnentry_invalidation.stderr new file mode 100644 index 0000000000000..dacd27f0d3852 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/fnentry_invalidation.stderr @@ -0,0 +1,32 @@ +error: Undefined Behavior: write access through is forbidden + --> $DIR/fnentry_invalidation.rs:LL:CC + | +LL | *z = 2; + | ^^^^^^ write access through is forbidden + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: the accessed tag has state Frozen which forbids child write accesses +help: the accessed tag was created here, in the initial state Reserved + --> $DIR/fnentry_invalidation.rs:LL:CC + | +LL | let z = &mut x as *mut i32; + | ^^^^^^ +help: the accessed tag later transitioned to Active due to a child write access at offsets [0x0..0x4] + --> $DIR/fnentry_invalidation.rs:LL:CC + | +LL | *z = 1; + | ^^^^^^ + = help: this corresponds to the first write to a 2-phase borrowed mutable reference +help: the accessed tag later transitioned to Frozen due to a foreign read access at offsets [0x0..0x4] + --> $DIR/fnentry_invalidation.rs:LL:CC + | +LL | x.do_bad(); + | ^^^^^^^^^^ + = help: this corresponds to a loss of write permissions + = note: BACKTRACE (of the first span): + = note: inside `main` at $DIR/fnentry_invalidation.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/tree-borrows/fragile-data-race.rs b/src/tools/miri/tests/fail/tree_borrows/fragile-data-race.rs similarity index 100% rename from src/tools/miri/tests/fail/tree-borrows/fragile-data-race.rs rename to src/tools/miri/tests/fail/tree_borrows/fragile-data-race.rs diff --git a/src/tools/miri/tests/fail/tree-borrows/fragile-data-race.stderr b/src/tools/miri/tests/fail/tree_borrows/fragile-data-race.stderr similarity index 100% rename from src/tools/miri/tests/fail/tree-borrows/fragile-data-race.stderr rename to src/tools/miri/tests/fail/tree_borrows/fragile-data-race.stderr diff --git a/src/tools/miri/tests/fail/tree-borrows/outside-range.rs b/src/tools/miri/tests/fail/tree_borrows/outside-range.rs similarity index 100% rename from src/tools/miri/tests/fail/tree-borrows/outside-range.rs rename to src/tools/miri/tests/fail/tree_borrows/outside-range.rs diff --git a/src/tools/miri/tests/fail/tree-borrows/outside-range.stderr b/src/tools/miri/tests/fail/tree_borrows/outside-range.stderr similarity index 100% rename from src/tools/miri/tests/fail/tree-borrows/outside-range.stderr rename to src/tools/miri/tests/fail/tree_borrows/outside-range.stderr diff --git a/src/tools/miri/tests/fail/tree-borrows/read-to-local.rs b/src/tools/miri/tests/fail/tree_borrows/parent_read_freezes_raw_mut.rs similarity index 69% rename from src/tools/miri/tests/fail/tree-borrows/read-to-local.rs rename to src/tools/miri/tests/fail/tree_borrows/parent_read_freezes_raw_mut.rs index 025b7ad22dc34..303c9ee0c0e72 100644 --- a/src/tools/miri/tests/fail/tree-borrows/read-to-local.rs +++ b/src/tools/miri/tests/fail/tree_borrows/parent_read_freezes_raw_mut.rs @@ -1,7 +1,7 @@ //@compile-flags: -Zmiri-tree-borrows -// Read to local variable kills reborrows *and* raw pointers derived from them. -// This test would succeed under Stacked Borrows. +// Read from local variable kills reborrows *and* raw pointers derived from them. +// This test would be accepted under Stacked Borrows. fn main() { unsafe { let mut root = 6u8; diff --git a/src/tools/miri/tests/fail/tree-borrows/read-to-local.stderr b/src/tools/miri/tests/fail/tree_borrows/parent_read_freezes_raw_mut.stderr similarity index 83% rename from src/tools/miri/tests/fail/tree-borrows/read-to-local.stderr rename to src/tools/miri/tests/fail/tree_borrows/parent_read_freezes_raw_mut.stderr index 6deb4b43f6a03..cc7ed97b388d7 100644 --- a/src/tools/miri/tests/fail/tree-borrows/read-to-local.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/parent_read_freezes_raw_mut.stderr @@ -1,5 +1,5 @@ error: Undefined Behavior: write access through is forbidden - --> $DIR/read-to-local.rs:LL:CC + --> $DIR/parent_read_freezes_raw_mut.rs:LL:CC | LL | *ptr = 0; | ^^^^^^^^ write access through is forbidden @@ -7,24 +7,24 @@ LL | *ptr = 0; = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental = help: the accessed tag has state Frozen which forbids child write accesses help: the accessed tag was created here, in the initial state Reserved - --> $DIR/read-to-local.rs:LL:CC + --> $DIR/parent_read_freezes_raw_mut.rs:LL:CC | LL | let mref = &mut root; | ^^^^^^^^^ help: the accessed tag later transitioned to Active due to a child write access at offsets [0x0..0x1] - --> $DIR/read-to-local.rs:LL:CC + --> $DIR/parent_read_freezes_raw_mut.rs:LL:CC | LL | *ptr = 0; // Write | ^^^^^^^^ = help: this corresponds to the first write to a 2-phase borrowed mutable reference help: the accessed tag later transitioned to Frozen due to a foreign read access at offsets [0x0..0x1] - --> $DIR/read-to-local.rs:LL:CC + --> $DIR/parent_read_freezes_raw_mut.rs:LL:CC | LL | assert_eq!(root, 0); // Parent Read | ^^^^^^^^^^^^^^^^^^^ = help: this corresponds to a loss of write permissions = note: BACKTRACE (of the first span): - = note: inside `main` at $DIR/read-to-local.rs:LL:CC + = note: inside `main` at $DIR/parent_read_freezes_raw_mut.rs:LL:CC = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tree_borrows/pass_invalid_mut.rs b/src/tools/miri/tests/fail/tree_borrows/pass_invalid_mut.rs new file mode 100644 index 0000000000000..a22e3118341a1 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/pass_invalid_mut.rs @@ -0,0 +1,20 @@ +//@compile-flags: -Zmiri-tree-borrows +// This test is the TB counterpart to fail/stacked_borrows/pass_invalid_mut, +// but the SB version passes TB without error. +// An additional write access is inserted so that this test properly fails. + +// Make sure that we cannot use a `&mut` whose parent got invalidated. +// fail/both_borrows/pass_invalid_shr is already checking a forbidden read, +// so the new thing that this tests is a forbidden write. +fn foo(nope: &mut i32) { + *nope = 31; //~ ERROR: /write access through .* is forbidden/ +} + +fn main() { + let x = &mut 42; + let xraw = x as *mut _; + let xref = unsafe { &mut *xraw }; + *xref = 18; // activate xref + let _val = unsafe { *xraw }; // invalidate xref for writing + foo(xref); +} diff --git a/src/tools/miri/tests/fail/tree_borrows/pass_invalid_mut.stderr b/src/tools/miri/tests/fail/tree_borrows/pass_invalid_mut.stderr new file mode 100644 index 0000000000000..4e5657f8b7b1a --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/pass_invalid_mut.stderr @@ -0,0 +1,43 @@ +error: Undefined Behavior: write access through is forbidden + --> $DIR/pass_invalid_mut.rs:LL:CC + | +LL | *nope = 31; + | ^^^^^^^^^^ write access through is forbidden + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: the accessed tag is a child of the conflicting tag + = help: the conflicting tag has state Frozen which forbids child write accesses +help: the accessed tag was created here + --> $DIR/pass_invalid_mut.rs:LL:CC + | +LL | fn foo(nope: &mut i32) { + | ^^^^ +help: the conflicting tag was created here, in the initial state Reserved + --> $DIR/pass_invalid_mut.rs:LL:CC + | +LL | let xref = unsafe { &mut *xraw }; + | ^^^^^^^^^^ +help: the conflicting tag later transitioned to Active due to a child write access at offsets [0x0..0x4] + --> $DIR/pass_invalid_mut.rs:LL:CC + | +LL | *xref = 18; // activate xref + | ^^^^^^^^^^ + = help: this corresponds to the first write to a 2-phase borrowed mutable reference +help: the conflicting tag later transitioned to Frozen due to a foreign read access at offsets [0x0..0x4] + --> $DIR/pass_invalid_mut.rs:LL:CC + | +LL | let _val = unsafe { *xraw }; // invalidate xref for writing + | ^^^^^ + = help: this corresponds to a loss of write permissions + = note: BACKTRACE (of the first span): + = note: inside `foo` at $DIR/pass_invalid_mut.rs:LL:CC +note: inside `main` + --> $DIR/pass_invalid_mut.rs:LL:CC + | +LL | foo(xref); + | ^^^^^^^^^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/tree-borrows/reserved/cell-protected-write.rs b/src/tools/miri/tests/fail/tree_borrows/reserved/cell-protected-write.rs similarity index 100% rename from src/tools/miri/tests/fail/tree-borrows/reserved/cell-protected-write.rs rename to src/tools/miri/tests/fail/tree_borrows/reserved/cell-protected-write.rs diff --git a/src/tools/miri/tests/fail/tree-borrows/reserved/cell-protected-write.stderr b/src/tools/miri/tests/fail/tree_borrows/reserved/cell-protected-write.stderr similarity index 100% rename from src/tools/miri/tests/fail/tree-borrows/reserved/cell-protected-write.stderr rename to src/tools/miri/tests/fail/tree_borrows/reserved/cell-protected-write.stderr diff --git a/src/tools/miri/tests/fail/tree-borrows/reserved/int-protected-write.rs b/src/tools/miri/tests/fail/tree_borrows/reserved/int-protected-write.rs similarity index 100% rename from src/tools/miri/tests/fail/tree-borrows/reserved/int-protected-write.rs rename to src/tools/miri/tests/fail/tree_borrows/reserved/int-protected-write.rs diff --git a/src/tools/miri/tests/fail/tree-borrows/reserved/int-protected-write.stderr b/src/tools/miri/tests/fail/tree_borrows/reserved/int-protected-write.stderr similarity index 100% rename from src/tools/miri/tests/fail/tree-borrows/reserved/int-protected-write.stderr rename to src/tools/miri/tests/fail/tree_borrows/reserved/int-protected-write.stderr diff --git a/src/tools/miri/tests/fail/tree-borrows/retag-data-race.rs b/src/tools/miri/tests/fail/tree_borrows/retag-data-race.rs similarity index 100% rename from src/tools/miri/tests/fail/tree-borrows/retag-data-race.rs rename to src/tools/miri/tests/fail/tree_borrows/retag-data-race.rs diff --git a/src/tools/miri/tests/fail/tree-borrows/retag-data-race.stderr b/src/tools/miri/tests/fail/tree_borrows/retag-data-race.stderr similarity index 100% rename from src/tools/miri/tests/fail/tree-borrows/retag-data-race.stderr rename to src/tools/miri/tests/fail/tree_borrows/retag-data-race.stderr diff --git a/src/tools/miri/tests/fail/tree_borrows/return_invalid_mut.rs b/src/tools/miri/tests/fail/tree_borrows/return_invalid_mut.rs new file mode 100644 index 0000000000000..869e48bea56c9 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/return_invalid_mut.rs @@ -0,0 +1,22 @@ +//@compile-flags: -Zmiri-tree-borrows +// This test is the TB counterpart to fail/stacked_borrows/return_invalid_mut, +// but the SB version passes TB without error. +// An additional write access is inserted so that this test properly fails. + +// Make sure that we cannot use a returned `&mut` that got already invalidated. +// fail/both_borrows/return_invalid_shr is already testing that we cannot return +// a reference invalidated for reading, so the new thing that we test here +// is the case where the return value cannot be used for writing. +fn foo(x: &mut (i32, i32)) -> &mut i32 { + let xraw = x as *mut (i32, i32); + let ret = unsafe { &mut (*xraw).1 }; + *ret = *ret; // activate + let _val = unsafe { *xraw }; // invalidate xref for writing + ret +} + +fn main() { + let arg = &mut (1, 2); + let ret = foo(arg); + *ret = 3; //~ ERROR: /write access through .* is forbidden/ +} diff --git a/src/tools/miri/tests/fail/tree_borrows/return_invalid_mut.stderr b/src/tools/miri/tests/fail/tree_borrows/return_invalid_mut.stderr new file mode 100644 index 0000000000000..3d050d209c81d --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/return_invalid_mut.stderr @@ -0,0 +1,38 @@ +error: Undefined Behavior: write access through is forbidden + --> $DIR/return_invalid_mut.rs:LL:CC + | +LL | *ret = 3; + | ^^^^^^^^ write access through is forbidden + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: the accessed tag is a child of the conflicting tag + = help: the conflicting tag has state Frozen which forbids child write accesses +help: the accessed tag was created here + --> $DIR/return_invalid_mut.rs:LL:CC + | +LL | let ret = foo(arg); + | ^^^^^^^^ +help: the conflicting tag was created here, in the initial state Reserved + --> $DIR/return_invalid_mut.rs:LL:CC + | +LL | let ret = unsafe { &mut (*xraw).1 }; + | ^^^^^^^^^^^^^^ +help: the conflicting tag later transitioned to Active due to a child write access at offsets [0x4..0x8] + --> $DIR/return_invalid_mut.rs:LL:CC + | +LL | *ret = *ret; // activate + | ^^^^^^^^^^^ + = help: this corresponds to the first write to a 2-phase borrowed mutable reference +help: the conflicting tag later transitioned to Frozen due to a foreign read access at offsets [0x0..0x8] + --> $DIR/return_invalid_mut.rs:LL:CC + | +LL | let _val = unsafe { *xraw }; // invalidate xref for writing + | ^^^^^ + = help: this corresponds to a loss of write permissions + = note: BACKTRACE (of the first span): + = note: inside `main` at $DIR/return_invalid_mut.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/tree-borrows/strongly-protected.rs b/src/tools/miri/tests/fail/tree_borrows/strongly-protected.rs similarity index 100% rename from src/tools/miri/tests/fail/tree-borrows/strongly-protected.rs rename to src/tools/miri/tests/fail/tree_borrows/strongly-protected.rs diff --git a/src/tools/miri/tests/fail/tree-borrows/strongly-protected.stderr b/src/tools/miri/tests/fail/tree_borrows/strongly-protected.stderr similarity index 100% rename from src/tools/miri/tests/fail/tree-borrows/strongly-protected.stderr rename to src/tools/miri/tests/fail/tree_borrows/strongly-protected.stderr 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 similarity index 100% rename from src/tools/miri/tests/fail/tree-borrows/write-during-2phase.rs rename to src/tools/miri/tests/fail/tree_borrows/write-during-2phase.rs diff --git a/src/tools/miri/tests/fail/tree-borrows/write-during-2phase.stderr b/src/tools/miri/tests/fail/tree_borrows/write-during-2phase.stderr similarity index 100% rename from src/tools/miri/tests/fail/tree-borrows/write-during-2phase.stderr rename to src/tools/miri/tests/fail/tree_borrows/write-during-2phase.stderr diff --git a/src/tools/miri/tests/fail/tree_borrows/write_to_shr.stderr b/src/tools/miri/tests/fail/tree_borrows/write_to_shr.stderr new file mode 100644 index 0000000000000..0e2002c34f12f --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/write_to_shr.stderr @@ -0,0 +1,26 @@ +error: Undefined Behavior: write access through is forbidden + --> $DIR/write_to_shr.rs:LL:CC + | +LL | *xmut = 31; + | ^^^^^^^^^^ write access through is forbidden + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: the accessed tag is a child of the conflicting tag + = help: the conflicting tag has state Frozen which forbids child write accesses +help: the accessed tag was created here + --> $DIR/write_to_shr.rs:LL:CC + | +LL | let xmut = unsafe { &mut *(xref as *const u64 as *mut u64) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: the conflicting tag was created here, in the initial state Frozen + --> $DIR/write_to_shr.rs:LL:CC + | +LL | let xref = unsafe { &*(x as *mut u64) }; + | ^^^^^^^^^^^^^^^^^ + = note: BACKTRACE (of the first span): + = note: inside `main` at $DIR/write_to_shr.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/pass/tree-borrows/transmute-unsafecell.rs b/src/tools/miri/tests/pass/tree-borrows/transmute-unsafecell.rs deleted file mode 100644 index e1a9334ab5410..0000000000000 --- a/src/tools/miri/tests/pass/tree-borrows/transmute-unsafecell.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@compile-flags: -Zmiri-tree-borrows - -use core::cell::UnsafeCell; -use core::mem; - -fn main() { - unsafe { - let x = &0i32; - // As long as we only read, transmuting this to UnsafeCell should be fine. - let cell_x: &UnsafeCell = mem::transmute(&x); - let _val = *cell_x.get(); - } -} diff --git a/src/tools/miri/tests/pass/tree-borrows/2phase-interiormut.rs b/src/tools/miri/tests/pass/tree_borrows/2phase-interiormut.rs similarity index 100% rename from src/tools/miri/tests/pass/tree-borrows/2phase-interiormut.rs rename to src/tools/miri/tests/pass/tree_borrows/2phase-interiormut.rs diff --git a/src/tools/miri/tests/pass/tree-borrows/cell-alternate-writes.rs b/src/tools/miri/tests/pass/tree_borrows/cell-alternate-writes.rs similarity index 100% rename from src/tools/miri/tests/pass/tree-borrows/cell-alternate-writes.rs rename to src/tools/miri/tests/pass/tree_borrows/cell-alternate-writes.rs diff --git a/src/tools/miri/tests/pass/tree-borrows/cell-alternate-writes.stderr b/src/tools/miri/tests/pass/tree_borrows/cell-alternate-writes.stderr similarity index 100% rename from src/tools/miri/tests/pass/tree-borrows/cell-alternate-writes.stderr rename to src/tools/miri/tests/pass/tree_borrows/cell-alternate-writes.stderr diff --git a/src/tools/miri/tests/pass/tree-borrows/copy-nonoverlapping.rs b/src/tools/miri/tests/pass/tree_borrows/copy-nonoverlapping.rs similarity index 100% rename from src/tools/miri/tests/pass/tree-borrows/copy-nonoverlapping.rs rename to src/tools/miri/tests/pass/tree_borrows/copy-nonoverlapping.rs diff --git a/src/tools/miri/tests/pass/tree-borrows/end-of-protector.rs b/src/tools/miri/tests/pass/tree_borrows/end-of-protector.rs similarity index 100% rename from src/tools/miri/tests/pass/tree-borrows/end-of-protector.rs rename to src/tools/miri/tests/pass/tree_borrows/end-of-protector.rs diff --git a/src/tools/miri/tests/pass/tree-borrows/end-of-protector.stderr b/src/tools/miri/tests/pass/tree_borrows/end-of-protector.stderr similarity index 100% rename from src/tools/miri/tests/pass/tree-borrows/end-of-protector.stderr rename to src/tools/miri/tests/pass/tree_borrows/end-of-protector.stderr diff --git a/src/tools/miri/tests/pass/tree-borrows/formatting.rs b/src/tools/miri/tests/pass/tree_borrows/formatting.rs similarity index 100% rename from src/tools/miri/tests/pass/tree-borrows/formatting.rs rename to src/tools/miri/tests/pass/tree_borrows/formatting.rs diff --git a/src/tools/miri/tests/pass/tree-borrows/formatting.stderr b/src/tools/miri/tests/pass/tree_borrows/formatting.stderr similarity index 100% rename from src/tools/miri/tests/pass/tree-borrows/formatting.stderr rename to src/tools/miri/tests/pass/tree_borrows/formatting.stderr diff --git a/src/tools/miri/tests/pass/tree-borrows/reborrow-is-read.rs b/src/tools/miri/tests/pass/tree_borrows/reborrow-is-read.rs similarity index 100% rename from src/tools/miri/tests/pass/tree-borrows/reborrow-is-read.rs rename to src/tools/miri/tests/pass/tree_borrows/reborrow-is-read.rs diff --git a/src/tools/miri/tests/pass/tree-borrows/reborrow-is-read.stderr b/src/tools/miri/tests/pass/tree_borrows/reborrow-is-read.stderr similarity index 100% rename from src/tools/miri/tests/pass/tree-borrows/reborrow-is-read.stderr rename to src/tools/miri/tests/pass/tree_borrows/reborrow-is-read.stderr diff --git a/src/tools/miri/tests/pass/tree-borrows/reserved.rs b/src/tools/miri/tests/pass/tree_borrows/reserved.rs similarity index 100% rename from src/tools/miri/tests/pass/tree-borrows/reserved.rs rename to src/tools/miri/tests/pass/tree_borrows/reserved.rs diff --git a/src/tools/miri/tests/pass/tree-borrows/reserved.stderr b/src/tools/miri/tests/pass/tree_borrows/reserved.stderr similarity index 100% rename from src/tools/miri/tests/pass/tree-borrows/reserved.stderr rename to src/tools/miri/tests/pass/tree_borrows/reserved.stderr diff --git a/src/tools/miri/tests/pass/tree_borrows/sb_fails.rs b/src/tools/miri/tests/pass/tree_borrows/sb_fails.rs new file mode 100644 index 0000000000000..5973ef01ead08 --- /dev/null +++ b/src/tools/miri/tests/pass/tree_borrows/sb_fails.rs @@ -0,0 +1,81 @@ +//@compile-flags: -Zmiri-tree-borrows + +// These tests fail Stacked Borrows, but pass Tree Borrows. +// A modified version of each is also available that fails Tree Borrows. +// They all have in common that in SB a mutable reborrow is enough to produce +// write access errors, but in TB an actual write is needed. + +mod fnentry_invalidation { + // Copied directly from fail/stacked_borrows/fnentry_invalidation.rs + // Version that fails TB: fail/tree_borrows/fnentry_invalidation.rs + pub fn main() { + let mut x = 0i32; + let z = &mut x as *mut i32; + x.do_bad(); + unsafe { + let _oof = *z; + // In SB this is an error, but in TB the mutable reborrow did + // not invalidate z for reading. + } + } + + trait Bad { + fn do_bad(&mut self) { + // who knows + } + } + + impl Bad for i32 {} +} + +mod pass_invalid_mut { + // Copied directly from fail/stacked_borrows/pass_invalid_mut.rs + // Version that fails TB: fail/tree_borrows/pass_invalid_mut.rs + fn foo(_: &mut i32) {} + + pub fn main() { + let x = &mut 42; + let xraw = x as *mut _; + let xref = unsafe { &mut *xraw }; + let _val = unsafe { *xraw }; // In SB this invalidates xref... + foo(xref); // ...which then cannot be reborrowed here. + // But in TB xref is Reserved and thus still writeable. + } +} + +mod return_invalid_mut { + // Copied directly from fail/stacked_borrows/return_invalid_mut.rs + // Version that fails TB: fail/tree_borrows/return_invalid_mut.rs + fn foo(x: &mut (i32, i32)) -> &mut i32 { + let xraw = x as *mut (i32, i32); + let ret = unsafe { &mut (*xraw).1 }; + let _val = unsafe { *xraw }; // In SB this invalidates ret... + ret // ...which then cannot be reborrowed here. + // But in TB ret is Reserved and thus still writeable. + } + + pub fn main() { + foo(&mut (1, 2)); + } +} + +mod static_memory_modification { + // Copied directly from fail/stacked_borrows/static_memory_modification.rs + // Version that fails TB: fail/tree_borrows/static_memory_modification.rs + static X: usize = 5; + + #[allow(mutable_transmutes)] + pub fn main() { + let _x = unsafe { + std::mem::transmute::<&usize, &mut usize>(&X) // In SB this mutable reborrow fails. + // But in TB we are allowed to transmute as long as we don't write. + }; + } +} + +fn main() { + fnentry_invalidation::main(); + pass_invalid_mut::main(); + return_invalid_mut::main(); + static_memory_modification::main(); +} diff --git a/src/tools/miri/tests/pass/tree_borrows/transmute-unsafecell.rs b/src/tools/miri/tests/pass/tree_borrows/transmute-unsafecell.rs new file mode 100644 index 0000000000000..1df0636e1e5d2 --- /dev/null +++ b/src/tools/miri/tests/pass/tree_borrows/transmute-unsafecell.rs @@ -0,0 +1,32 @@ +//@compile-flags: -Zmiri-tree-borrows + +//! Testing `mem::transmute` between types with and without interior mutability. +//! All transmutations should work, as long as we don't do any actual accesses +//! that violate immutability. + +use core::cell::UnsafeCell; +use core::mem; + +fn main() { + unsafe { + ref_to_cell(); + cell_to_ref(); + } +} + +// Pretend that the reference has interior mutability. +// Don't actually mutate it though, it will fail because it has a Frozen parent. +unsafe fn ref_to_cell() { + let x = &42i32; + let cell_x: &UnsafeCell = mem::transmute(x); + let val = *cell_x.get(); + assert_eq!(val, 42); +} + +// Forget about the interior mutability of a cell. +unsafe fn cell_to_ref() { + let x = &UnsafeCell::new(42); + let ref_x: &i32 = mem::transmute(x); + let val = *ref_x; + assert_eq!(val, 42); +} diff --git a/src/tools/miri/tests/pass/tree-borrows/tree-borrows.rs b/src/tools/miri/tests/pass/tree_borrows/tree-borrows.rs similarity index 100% rename from src/tools/miri/tests/pass/tree-borrows/tree-borrows.rs rename to src/tools/miri/tests/pass/tree_borrows/tree-borrows.rs