about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-07-26 12:52:57 +0000
committerbors <bors@rust-lang.org>2024-07-26 12:52:57 +0000
commitbf4d4c035d350e13cbdb93fdbbbd3eb3880ee295 (patch)
treeff3be865beacbcd2cf6dba81b1bd3374d71fce44
parentf98fdfc8a449bf535602b971e8eb12fd282de305 (diff)
parent5e1f8e2d07d2a32a1f234cf80efcb703aa87a989 (diff)
downloadrust-bf4d4c035d350e13cbdb93fdbbbd3eb3880ee295.tar.gz
rust-bf4d4c035d350e13cbdb93fdbbbd3eb3880ee295.zip
Auto merge of #3766 - RalfJung:tree-borrows-int2ptr, r=RalfJung
better diagnostics for Tree Borrows + int2ptr casts

- Entirely reject `-Zmiri-permissive-provenance -Zmiri-tree-borrows` since that combination just doesn't work
- In the int2ptr cast warning, when Tree Borrows is enabled, do not recommend `-Zmiri-permissive-provenance`, instead note that Tree Borrows does not support int2ptr casts

Fixes https://github.com/rust-lang/miri/issues/3764
-rw-r--r--src/tools/miri/src/bin/miri.rs8
-rw-r--r--src/tools/miri/src/borrow_tracker/mod.rs4
-rw-r--r--src/tools/miri/src/diagnostics.rs142
-rw-r--r--src/tools/miri/tests/pass/adjacent-allocs.rs2
-rw-r--r--src/tools/miri/tests/pass/box.rs3
-rw-r--r--src/tools/miri/tests/pass/box.stack.stderr33
-rw-r--r--src/tools/miri/tests/pass/box.stdout (renamed from src/tools/miri/tests/pass/box.stack.stdout)0
-rw-r--r--src/tools/miri/tests/pass/box.tree.stdout3
-rw-r--r--src/tools/miri/tests/pass/extern_types.rs8
-rw-r--r--src/tools/miri/tests/pass/extern_types.stack.stderr18
-rw-r--r--src/tools/miri/tests/pass/intptrcast.rs2
-rw-r--r--src/tools/miri/tests/pass/pointers.rs2
-rw-r--r--src/tools/miri/tests/pass/ptr_int_casts.rs3
-rw-r--r--src/tools/miri/tests/pass/ptr_int_casts.tree.stderr89
-rw-r--r--src/tools/miri/tests/pass/ptr_int_from_exposed.rs3
-rw-r--r--src/tools/miri/tests/pass/ptr_int_from_exposed.tree.stderr19
16 files changed, 201 insertions, 138 deletions
diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs
index 9f3fa075f38..25b154a8206 100644
--- a/src/tools/miri/src/bin/miri.rs
+++ b/src/tools/miri/src/bin/miri.rs
@@ -620,6 +620,14 @@ fn main() {
             "-Zmiri-unique-is-unique only has an effect when -Zmiri-tree-borrows is also used"
         );
     }
+    // Tree Borrows + permissive provenance does not work.
+    if miri_config.provenance_mode == ProvenanceMode::Permissive
+        && matches!(miri_config.borrow_tracker, Some(BorrowTrackerMethod::TreeBorrows))
+    {
+        show_error!(
+            "Tree Borrows does not support integer-to-pointer casts, and is hence not compatible with permissive provenance"
+        );
+    }
 
     debug!("rustc arguments: {:?}", rustc_args);
     debug!("crate arguments: {:?}", miri_config.args);
diff --git a/src/tools/miri/src/borrow_tracker/mod.rs b/src/tools/miri/src/borrow_tracker/mod.rs
index c9e7e300593..d537a7fbc17 100644
--- a/src/tools/miri/src/borrow_tracker/mod.rs
+++ b/src/tools/miri/src/borrow_tracker/mod.rs
@@ -232,6 +232,10 @@ impl GlobalStateInner {
     pub fn remove_unreachable_allocs(&mut self, allocs: &LiveAllocs<'_, '_>) {
         self.root_ptr_tags.retain(|id, _| allocs.is_live(*id));
     }
+
+    pub fn borrow_tracker_method(&self) -> BorrowTrackerMethod {
+        self.borrow_tracker_method
+    }
 }
 
 /// Which borrow tracking method to use
diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs
index 45a8a54bc29..1bed55743d4 100644
--- a/src/tools/miri/src/diagnostics.rs
+++ b/src/tools/miri/src/diagnostics.rs
@@ -140,6 +140,15 @@ pub enum DiagLevel {
     Note,
 }
 
+/// Generate a note/help text without a span.
+macro_rules! note {
+    ($($tt:tt)*) => { (None, format!($($tt)*)) };
+}
+/// Generate a note/help text with a span.
+macro_rules! note_span {
+    ($span:expr, $($tt:tt)*) => { (Some($span), format!($($tt)*)) };
+}
+
 /// Attempts to prune a stacktrace to omit the Rust runtime, and returns a bool indicating if any
 /// frames were pruned. If the stacktrace does not have any local frames, we conclude that it must
 /// be pointing to a problem in the Rust runtime itself, and do not prune it at all.
@@ -228,38 +237,38 @@ pub fn report_error<'tcx>(
         let helps = match info {
             UnsupportedInIsolation(_) =>
                 vec![
-                    (None, format!("set `MIRIFLAGS=-Zmiri-disable-isolation` to disable isolation;")),
-                    (None, format!("or set `MIRIFLAGS=-Zmiri-isolation-error=warn` to make Miri return an error code from isolated operations (if supported for that operation) and continue with a warning")),
+                    note!("set `MIRIFLAGS=-Zmiri-disable-isolation` to disable isolation;"),
+                    note!("or set `MIRIFLAGS=-Zmiri-isolation-error=warn` to make Miri return an error code from isolated operations (if supported for that operation) and continue with a warning"),
                 ],
             UnsupportedForeignItem(_) => {
                 vec![
-                    (None, format!("if this is a basic API commonly used on this target, please report an issue with Miri")),
-                    (None, format!("however, note that Miri does not aim to support every FFI function out there; for instance, we will not support APIs for things such as GUIs, scripting languages, or databases")),
+                    note!("if this is a basic API commonly used on this target, please report an issue with Miri"),
+                    note!("however, note that Miri does not aim to support every FFI function out there; for instance, we will not support APIs for things such as GUIs, scripting languages, or databases"),
                 ]
             }
             StackedBorrowsUb { help, history, .. } => {
                 msg.extend(help.clone());
                 let mut helps = vec![
-                    (None, format!("this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental")),
-                    (None, format!("see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information")),
+                    note!("this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental"),
+                    note!("see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information"),
                 ];
                 if let Some(TagHistory {created, invalidated, protected}) = history.clone() {
                     helps.push((Some(created.1), created.0));
                     if let Some((msg, span)) = invalidated {
-                        helps.push((Some(span), msg));
+                        helps.push(note_span!(span, "{msg}"));
                     }
                     if let Some((protector_msg, protector_span)) = protected {
-                        helps.push((Some(protector_span), protector_msg));
+                        helps.push(note_span!(protector_span, "{protector_msg}"));
                     }
                 }
                 helps
             },
             TreeBorrowsUb { title: _, details, history } => {
                 let mut helps = vec![
-                    (None, format!("this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental"))
+                    note!("this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental")
                 ];
                 for m in details {
-                    helps.push((None, m.clone()));
+                    helps.push(note!("{m}"));
                 }
                 for event in history.events.clone() {
                     helps.push(event);
@@ -268,26 +277,26 @@ pub fn report_error<'tcx>(
             }
             MultipleSymbolDefinitions { first, first_crate, second, second_crate, .. } =>
                 vec![
-                    (Some(*first), format!("it's first defined here, in crate `{first_crate}`")),
-                    (Some(*second), format!("then it's defined here again, in crate `{second_crate}`")),
+                    note_span!(*first, "it's first defined here, in crate `{first_crate}`"),
+                    note_span!(*second, "then it's defined here again, in crate `{second_crate}`"),
                 ],
             SymbolShimClashing { link_name, span } =>
-                vec![(Some(*span), format!("the `{link_name}` symbol is defined here"))],
+                vec![note_span!(*span, "the `{link_name}` symbol is defined here")],
             Int2PtrWithStrictProvenance =>
-                vec![(None, format!("use Strict Provenance APIs (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance, https://crates.io/crates/sptr) instead"))],
+                vec![note!("use Strict Provenance APIs (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance, https://crates.io/crates/sptr) instead")],
             DataRace { op1, extra, retag_explain, .. } => {
-                let mut helps = vec![(Some(op1.span), format!("and (1) occurred earlier here"))];
+                let mut helps = vec![note_span!(op1.span, "and (1) occurred earlier here")];
                 if let Some(extra) = extra {
-                    helps.push((None, format!("{extra}")));
-                    helps.push((None, format!("see https://doc.rust-lang.org/nightly/std/sync/atomic/index.html#memory-model-for-atomic-accesses for more information about the Rust memory model")));
+                    helps.push(note!("{extra}"));
+                    helps.push(note!("see https://doc.rust-lang.org/nightly/std/sync/atomic/index.html#memory-model-for-atomic-accesses for more information about the Rust memory model"));
                 }
                 if *retag_explain {
-                    helps.push((None, "retags occur on all (re)borrows and as well as when references are copied or moved".to_owned()));
-                    helps.push((None, "retags permit optimizations that insert speculative reads or writes".to_owned()));
-                    helps.push((None, "therefore from the perspective of data races, a retag has the same implications as a read or write".to_owned()));
+                    helps.push(note!("retags occur on all (re)borrows and as well as when references are copied or moved"));
+                    helps.push(note!("retags permit optimizations that insert speculative reads or writes"));
+                    helps.push(note!("therefore from the perspective of data races, a retag has the same implications as a read or write"));
                 }
-                helps.push((None, format!("this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior")));
-                helps.push((None, format!("see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information")));
+                helps.push(note!("this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior"));
+                helps.push(note!("see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information"));
                 helps
             }
                 ,
@@ -332,32 +341,32 @@ pub fn report_error<'tcx>(
         let helps = match e.kind() {
             Unsupported(_) =>
                 vec![
-                    (None, format!("this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support")),
+                    note!("this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support"),
                 ],
             UndefinedBehavior(AlignmentCheckFailed { .. })
                 if ecx.machine.check_alignment == AlignmentCheck::Symbolic
             =>
                 vec![
-                    (None, format!("this usually indicates that your program performed an invalid operation and caused Undefined Behavior")),
-                    (None, format!("but due to `-Zmiri-symbolic-alignment-check`, alignment errors can also be false positives")),
+                    note!("this usually indicates that your program performed an invalid operation and caused Undefined Behavior"),
+                    note!("but due to `-Zmiri-symbolic-alignment-check`, alignment errors can also be false positives"),
                 ],
             UndefinedBehavior(info) => {
                 let mut helps = vec![
-                    (None, format!("this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior")),
-                    (None, format!("see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information")),
+                    note!("this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior"),
+                    note!("see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information"),
                 ];
                 match info {
                     PointerUseAfterFree(alloc_id, _) | PointerOutOfBounds { alloc_id, .. } => {
                         if let Some(span) = ecx.machine.allocated_span(*alloc_id) {
-                            helps.push((Some(span), format!("{:?} was allocated here:", alloc_id)));
+                            helps.push(note_span!(span, "{:?} was allocated here:", alloc_id));
                         }
                         if let Some(span) = ecx.machine.deallocated_span(*alloc_id) {
-                            helps.push((Some(span), format!("{:?} was deallocated here:", alloc_id)));
+                            helps.push(note_span!(span, "{:?} was deallocated here:", alloc_id));
                         }
                     }
                     AbiMismatchArgument { .. } | AbiMismatchReturn { .. } => {
-                        helps.push((None, format!("this means these two types are not *guaranteed* to be ABI-compatible across all targets")));
-                        helps.push((None, format!("if you think this code should be accepted anyway, please report an issue with Miri")));
+                        helps.push(note!("this means these two types are not *guaranteed* to be ABI-compatible across all targets"));
+                        helps.push(note!("if you think this code should be accepted anyway, please report an issue with Miri"));
                     }
                     _ => {},
                 }
@@ -639,60 +648,47 @@ impl<'tcx> MiriMachine<'tcx> {
 
         let notes = match &e {
             ProgressReport { block_count } => {
-                // It is important that each progress report is slightly different, since
-                // identical diagnostics are being deduplicated.
-                vec![(None, format!("so far, {block_count} basic blocks have been executed"))]
+                vec![note!("so far, {block_count} basic blocks have been executed")]
             }
             _ => vec![],
         };
 
         let helps = match &e {
-            Int2Ptr { details: true } =>
-                vec![
-                    (
-                        None,
-                        format!(
-                            "this program is using integer-to-pointer casts or (equivalently) `ptr::with_exposed_provenance`, which means that Miri might miss pointer bugs in this program"
-                        ),
-                    ),
-                    (
-                        None,
-                        format!(
-                            "see https://doc.rust-lang.org/nightly/std/ptr/fn.with_exposed_provenance.html for more details on that operation"
-                        ),
+            Int2Ptr { details: true } => {
+                let mut v = vec![
+                    note!(
+                        "this program is using integer-to-pointer casts or (equivalently) `ptr::with_exposed_provenance`, which means that Miri might miss pointer bugs in this program"
                     ),
-                    (
-                        None,
-                        format!(
-                            "to ensure that Miri does not miss bugs in your program, use Strict Provenance APIs (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance, https://crates.io/crates/sptr) instead"
-                        ),
+                    note!(
+                        "see https://doc.rust-lang.org/nightly/std/ptr/fn.with_exposed_provenance.html for more details on that operation"
                     ),
-                    (
-                        None,
-                        format!(
-                            "you can then set `MIRIFLAGS=-Zmiri-strict-provenance` to ensure you are not relying on `with_exposed_provenance` semantics"
-                        ),
+                    note!(
+                        "to ensure that Miri does not miss bugs in your program, use Strict Provenance APIs (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance, https://crates.io/crates/sptr) instead"
                     ),
-                    (
-                        None,
-                        format!(
-                            "alternatively, `MIRIFLAGS=-Zmiri-permissive-provenance` disables this warning"
-                        ),
+                    note!(
+                        "you can then set `MIRIFLAGS=-Zmiri-strict-provenance` to ensure you are not relying on `with_exposed_provenance` semantics"
                     ),
-                ],
+                ];
+                if self.borrow_tracker.as_ref().is_some_and(|b| {
+                    matches!(b.borrow().borrow_tracker_method(), BorrowTrackerMethod::TreeBorrows)
+                }) {
+                    v.push(
+                        note!("Tree Borrows does not support integer-to-pointer casts, so the program is likely to go wrong when this pointer gets used")
+                    );
+                } else {
+                    v.push(
+                        note!("alternatively, `MIRIFLAGS=-Zmiri-permissive-provenance` disables this warning")
+                    );
+                }
+                v
+            }
             ExternTypeReborrow => {
                 vec![
-                    (
-                        None,
-                        format!(
-                            "`extern type` are not compatible with the Stacked Borrows aliasing model implemented by Miri; Miri may miss bugs in this code"
-                        ),
+                    note!(
+                        "`extern type` are not compatible with the Stacked Borrows aliasing model implemented by Miri; Miri may miss bugs in this code"
                     ),
-                    (
-                        None,
-                        format!(
-                            "try running with `MIRIFLAGS=-Zmiri-tree-borrows` to use the more permissive but also even more experimental Tree Borrows aliasing checks instead"
-                        ),
+                    note!(
+                        "try running with `MIRIFLAGS=-Zmiri-tree-borrows` to use the more permissive but also even more experimental Tree Borrows aliasing checks instead"
                     ),
                 ]
             }
diff --git a/src/tools/miri/tests/pass/adjacent-allocs.rs b/src/tools/miri/tests/pass/adjacent-allocs.rs
index 8be4bdac7e1..711c54fd68a 100644
--- a/src/tools/miri/tests/pass/adjacent-allocs.rs
+++ b/src/tools/miri/tests/pass/adjacent-allocs.rs
@@ -1,5 +1,3 @@
-//@revisions: stack tree
-//@[tree]compile-flags: -Zmiri-tree-borrows
 //@compile-flags: -Zmiri-permissive-provenance
 
 fn ensure_allocs_can_be_adjacent() {
diff --git a/src/tools/miri/tests/pass/box.rs b/src/tools/miri/tests/pass/box.rs
index 174bf8be30b..693209c0456 100644
--- a/src/tools/miri/tests/pass/box.rs
+++ b/src/tools/miri/tests/pass/box.rs
@@ -1,5 +1,4 @@
-//@revisions: stack tree
-//@[tree]compile-flags: -Zmiri-tree-borrows -Zmiri-permissive-provenance
+//@compile-flags: -Zmiri-permissive-provenance
 #![feature(ptr_internals)]
 
 fn main() {
diff --git a/src/tools/miri/tests/pass/box.stack.stderr b/src/tools/miri/tests/pass/box.stack.stderr
deleted file mode 100644
index f2d01b518fc..00000000000
--- a/src/tools/miri/tests/pass/box.stack.stderr
+++ /dev/null
@@ -1,33 +0,0 @@
-warning: integer-to-pointer cast
-  --> $DIR/box.rs:LL:CC
-   |
-LL |         let r2 = ((r as usize) + 0) as *mut i32;
-   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ integer-to-pointer cast
-   |
-   = help: this program is using integer-to-pointer casts or (equivalently) `ptr::with_exposed_provenance`, which means that Miri might miss pointer bugs in this program
-   = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.with_exposed_provenance.html for more details on that operation
-   = help: to ensure that Miri does not miss bugs in your program, use Strict Provenance APIs (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance, https://crates.io/crates/sptr) instead
-   = help: you can then set `MIRIFLAGS=-Zmiri-strict-provenance` to ensure you are not relying on `with_exposed_provenance` semantics
-   = help: alternatively, `MIRIFLAGS=-Zmiri-permissive-provenance` disables this warning
-   = note: BACKTRACE:
-   = note: inside `into_raw` at $DIR/box.rs:LL:CC
-note: inside `main`
-  --> $DIR/box.rs:LL:CC
-   |
-LL |     into_raw();
-   |     ^^^^^^^^^^
-
-warning: integer-to-pointer cast
-  --> $DIR/box.rs:LL:CC
-   |
-LL |         let r = ((u.as_ptr() as usize) + 0) as *mut i32;
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ integer-to-pointer cast
-   |
-   = note: BACKTRACE:
-   = note: inside `into_unique` at $DIR/box.rs:LL:CC
-note: inside `main`
-  --> $DIR/box.rs:LL:CC
-   |
-LL |     into_unique();
-   |     ^^^^^^^^^^^^^
-
diff --git a/src/tools/miri/tests/pass/box.stack.stdout b/src/tools/miri/tests/pass/box.stdout
index 230ef368da6..230ef368da6 100644
--- a/src/tools/miri/tests/pass/box.stack.stdout
+++ b/src/tools/miri/tests/pass/box.stdout
diff --git a/src/tools/miri/tests/pass/box.tree.stdout b/src/tools/miri/tests/pass/box.tree.stdout
deleted file mode 100644
index 230ef368da6..00000000000
--- a/src/tools/miri/tests/pass/box.tree.stdout
+++ /dev/null
@@ -1,3 +0,0 @@
-pair_foo = PairFoo { fst: Foo(42), snd: Foo(1337) }
-foo #0 = Foo(42)
-foo #1 = Foo(1337)
diff --git a/src/tools/miri/tests/pass/extern_types.rs b/src/tools/miri/tests/pass/extern_types.rs
index 7ac93577f0c..eade5c6ac08 100644
--- a/src/tools/miri/tests/pass/extern_types.rs
+++ b/src/tools/miri/tests/pass/extern_types.rs
@@ -1,12 +1,14 @@
 //@revisions: stack tree
-//@[tree]compile-flags: -Zmiri-tree-borrows -Zmiri-permissive-provenance
-#![feature(extern_types)]
+//@[tree]compile-flags: -Zmiri-tree-borrows
+#![feature(extern_types, strict_provenance)]
+
+use std::ptr;
 
 extern "C" {
     type Foo;
 }
 
 fn main() {
-    let x: &Foo = unsafe { &*(16 as *const Foo) };
+    let x: &Foo = unsafe { &*(ptr::without_provenance::<()>(16) as *const Foo) };
     let _y: &Foo = &*x;
 }
diff --git a/src/tools/miri/tests/pass/extern_types.stack.stderr b/src/tools/miri/tests/pass/extern_types.stack.stderr
index 9b6f632eb5a..2c9fc0192af 100644
--- a/src/tools/miri/tests/pass/extern_types.stack.stderr
+++ b/src/tools/miri/tests/pass/extern_types.stack.stderr
@@ -1,22 +1,8 @@
-warning: integer-to-pointer cast
-  --> $DIR/extern_types.rs:LL:CC
-   |
-LL |     let x: &Foo = unsafe { &*(16 as *const Foo) };
-   |                              ^^^^^^^^^^^^^^^^^^ integer-to-pointer cast
-   |
-   = help: this program is using integer-to-pointer casts or (equivalently) `ptr::with_exposed_provenance`, which means that Miri might miss pointer bugs in this program
-   = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.with_exposed_provenance.html for more details on that operation
-   = help: to ensure that Miri does not miss bugs in your program, use Strict Provenance APIs (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance, https://crates.io/crates/sptr) instead
-   = help: you can then set `MIRIFLAGS=-Zmiri-strict-provenance` to ensure you are not relying on `with_exposed_provenance` semantics
-   = help: alternatively, `MIRIFLAGS=-Zmiri-permissive-provenance` disables this warning
-   = note: BACKTRACE:
-   = note: inside `main` at $DIR/extern_types.rs:LL:CC
-
 warning: reborrow of reference to `extern type`
   --> $DIR/extern_types.rs:LL:CC
    |
-LL |     let x: &Foo = unsafe { &*(16 as *const Foo) };
-   |                            ^^^^^^^^^^^^^^^^^^^^ reborrow of a reference to `extern type` is not properly supported
+LL |     let x: &Foo = unsafe { &*(ptr::without_provenance::<()>(16) as *const Foo) };
+   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reborrow of a reference to `extern type` is not properly supported
    |
    = help: `extern type` are not compatible with the Stacked Borrows aliasing model implemented by Miri; Miri may miss bugs in this code
    = help: try running with `MIRIFLAGS=-Zmiri-tree-borrows` to use the more permissive but also even more experimental Tree Borrows aliasing checks instead
diff --git a/src/tools/miri/tests/pass/intptrcast.rs b/src/tools/miri/tests/pass/intptrcast.rs
index fb1a1dfae5d..a304f2751bd 100644
--- a/src/tools/miri/tests/pass/intptrcast.rs
+++ b/src/tools/miri/tests/pass/intptrcast.rs
@@ -1,5 +1,3 @@
-//@revisions: stack tree
-//@[tree]compile-flags: -Zmiri-tree-borrows
 //@compile-flags: -Zmiri-permissive-provenance
 
 use std::mem;
diff --git a/src/tools/miri/tests/pass/pointers.rs b/src/tools/miri/tests/pass/pointers.rs
index c7b720dafa2..280a815abc4 100644
--- a/src/tools/miri/tests/pass/pointers.rs
+++ b/src/tools/miri/tests/pass/pointers.rs
@@ -1,5 +1,3 @@
-//@revisions: stack tree
-//@[tree]compile-flags: -Zmiri-tree-borrows
 //@compile-flags: -Zmiri-permissive-provenance
 #![feature(ptr_metadata, const_raw_ptr_comparison)]
 #![allow(ambiguous_wide_pointer_comparisons)]
diff --git a/src/tools/miri/tests/pass/ptr_int_casts.rs b/src/tools/miri/tests/pass/ptr_int_casts.rs
index a2fcd098107..684e8f6ec7b 100644
--- a/src/tools/miri/tests/pass/ptr_int_casts.rs
+++ b/src/tools/miri/tests/pass/ptr_int_casts.rs
@@ -1,6 +1,7 @@
 //@revisions: stack tree
+// Tree Borrows doesn't support int2ptr casts, but let's make sure we don't immediately crash either.
 //@[tree]compile-flags: -Zmiri-tree-borrows
-//@compile-flags: -Zmiri-permissive-provenance
+//@[stack]compile-flags: -Zmiri-permissive-provenance
 use std::mem;
 use std::ptr;
 
diff --git a/src/tools/miri/tests/pass/ptr_int_casts.tree.stderr b/src/tools/miri/tests/pass/ptr_int_casts.tree.stderr
new file mode 100644
index 00000000000..a34474ee0d6
--- /dev/null
+++ b/src/tools/miri/tests/pass/ptr_int_casts.tree.stderr
@@ -0,0 +1,89 @@
+warning: integer-to-pointer cast
+  --> $DIR/ptr_int_casts.rs:LL:CC
+   |
+LL |     assert_eq!(1 as *const i32 as usize, 1);
+   |                ^^^^^^^^^^^^^^^ integer-to-pointer cast
+   |
+   = help: this program is using integer-to-pointer casts or (equivalently) `ptr::with_exposed_provenance`, which means that Miri might miss pointer bugs in this program
+   = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.with_exposed_provenance.html for more details on that operation
+   = help: to ensure that Miri does not miss bugs in your program, use Strict Provenance APIs (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance, https://crates.io/crates/sptr) instead
+   = help: you can then set `MIRIFLAGS=-Zmiri-strict-provenance` to ensure you are not relying on `with_exposed_provenance` semantics
+   = help: Tree Borrows does not support integer-to-pointer casts, so the program is likely to go wrong when this pointer gets used
+   = note: BACKTRACE:
+   = note: inside `ptr_int_casts` at $DIR/ptr_int_casts.rs:LL:CC
+note: inside `main`
+  --> $DIR/ptr_int_casts.rs:LL:CC
+   |
+LL |     ptr_int_casts();
+   |     ^^^^^^^^^^^^^^^
+
+warning: integer-to-pointer cast
+  --> $DIR/ptr_int_casts.rs:LL:CC
+   |
+LL |     assert_eq!((1 as *const i32).wrapping_offset(4) as usize, 1 + 4 * 4);
+   |                ^^^^^^^^^^^^^^^^^ integer-to-pointer cast
+   |
+   = note: BACKTRACE:
+   = note: inside `ptr_int_casts` at $DIR/ptr_int_casts.rs:LL:CC
+note: inside `main`
+  --> $DIR/ptr_int_casts.rs:LL:CC
+   |
+LL |     ptr_int_casts();
+   |     ^^^^^^^^^^^^^^^
+
+warning: integer-to-pointer cast
+  --> $DIR/ptr_int_casts.rs:LL:CC
+   |
+LL |     *val = (1 as *const u8).wrapping_offset(-4);
+   |            ^^^^^^^^^^^^^^^^ integer-to-pointer cast
+   |
+   = note: BACKTRACE:
+   = note: inside `ptr_int_casts` at $DIR/ptr_int_casts.rs:LL:CC
+note: inside `main`
+  --> $DIR/ptr_int_casts.rs:LL:CC
+   |
+LL |     ptr_int_casts();
+   |     ^^^^^^^^^^^^^^^
+
+warning: integer-to-pointer cast
+  --> $DIR/ptr_int_casts.rs:LL:CC
+   |
+LL |         let y = y as *const _;
+   |                 ^^^^^^^^^^^^^ integer-to-pointer cast
+   |
+   = note: BACKTRACE:
+   = note: inside `ptr_int_casts` at $DIR/ptr_int_casts.rs:LL:CC
+note: inside `main`
+  --> $DIR/ptr_int_casts.rs:LL:CC
+   |
+LL |     ptr_int_casts();
+   |     ^^^^^^^^^^^^^^^
+
+warning: integer-to-pointer cast
+  --> $DIR/ptr_int_casts.rs:LL:CC
+   |
+LL |         let x: fn() -> i32 = unsafe { mem::transmute(y as *mut u8) };
+   |                                                      ^^^^^^^^^^^^ integer-to-pointer cast
+   |
+   = note: BACKTRACE:
+   = note: inside `ptr_int_casts` at $DIR/ptr_int_casts.rs:LL:CC
+note: inside `main`
+  --> $DIR/ptr_int_casts.rs:LL:CC
+   |
+LL |     ptr_int_casts();
+   |     ^^^^^^^^^^^^^^^
+
+warning: integer-to-pointer cast
+  --> $DIR/ptr_int_casts.rs:LL:CC
+   |
+LL |     assert_eq!((-1i32) as usize as *const i32 as usize, (-1i32) as usize);
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ integer-to-pointer cast
+   |
+   = note: BACKTRACE:
+   = note: inside `ptr_int_casts` at $DIR/ptr_int_casts.rs:LL:CC
+note: inside `main`
+  --> $DIR/ptr_int_casts.rs:LL:CC
+   |
+LL |     ptr_int_casts();
+   |     ^^^^^^^^^^^^^^^
+
diff --git a/src/tools/miri/tests/pass/ptr_int_from_exposed.rs b/src/tools/miri/tests/pass/ptr_int_from_exposed.rs
index 5690d7865bb..f6ebf0632a1 100644
--- a/src/tools/miri/tests/pass/ptr_int_from_exposed.rs
+++ b/src/tools/miri/tests/pass/ptr_int_from_exposed.rs
@@ -1,6 +1,7 @@
 //@revisions: stack tree
+// Tree Borrows doesn't support int2ptr casts, but let's make sure we don't immediately crash either.
 //@[tree]compile-flags: -Zmiri-tree-borrows
-//@compile-flags: -Zmiri-permissive-provenance
+//@[stack]compile-flags: -Zmiri-permissive-provenance
 #![feature(strict_provenance, exposed_provenance)]
 
 use std::ptr;
diff --git a/src/tools/miri/tests/pass/ptr_int_from_exposed.tree.stderr b/src/tools/miri/tests/pass/ptr_int_from_exposed.tree.stderr
new file mode 100644
index 00000000000..614b0d26a63
--- /dev/null
+++ b/src/tools/miri/tests/pass/ptr_int_from_exposed.tree.stderr
@@ -0,0 +1,19 @@
+warning: integer-to-pointer cast
+  --> $DIR/ptr_int_from_exposed.rs:LL:CC
+   |
+LL |     let ptr = ptr::with_exposed_provenance::<i32>(x_usize).wrapping_offset(-128);
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ integer-to-pointer cast
+   |
+   = help: this program is using integer-to-pointer casts or (equivalently) `ptr::with_exposed_provenance`, which means that Miri might miss pointer bugs in this program
+   = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.with_exposed_provenance.html for more details on that operation
+   = help: to ensure that Miri does not miss bugs in your program, use Strict Provenance APIs (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance, https://crates.io/crates/sptr) instead
+   = help: you can then set `MIRIFLAGS=-Zmiri-strict-provenance` to ensure you are not relying on `with_exposed_provenance` semantics
+   = help: Tree Borrows does not support integer-to-pointer casts, so the program is likely to go wrong when this pointer gets used
+   = note: BACKTRACE:
+   = note: inside `ptr_roundtrip_out_of_bounds` at $DIR/ptr_int_from_exposed.rs:LL:CC
+note: inside `main`
+  --> $DIR/ptr_int_from_exposed.rs:LL:CC
+   |
+LL |     ptr_roundtrip_out_of_bounds();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+