about summary refs log tree commit diff
path: root/src/tools/miri/tests
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2025-08-22 09:22:02 +0200
committerRalf Jung <post@ralfj.de>2025-08-22 10:21:33 +0200
commit78bdd86c676a4e08849677c351591db3564d87e8 (patch)
treef8e5c85d1bafc44c868995ab15db2199b0c9315e /src/tools/miri/tests
parentd127901d940d96209fd2ae8ff6769ad2788099fb (diff)
downloadrust-78bdd86c676a4e08849677c351591db3564d87e8.tar.gz
rust-78bdd86c676a4e08849677c351591db3564d87e8.zip
miri: also detect aliasing of in-place argument and return place
Diffstat (limited to 'src/tools/miri/tests')
-rw-r--r--src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias.rs2
-rw-r--r--src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias_ret.rs34
-rw-r--r--src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias_ret.stack.stderr25
-rw-r--r--src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias_ret.tree.stderr34
4 files changed, 95 insertions, 0 deletions
diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias.rs b/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias.rs
index b91a41d7650..744d64b9b1e 100644
--- a/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias.rs
+++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias.rs
@@ -1,3 +1,5 @@
+//! Ensure we detect aliasing of two in-place arguments for the tricky case where they do not
+//! live in memory.
 //@revisions: stack tree
 //@[tree]compile-flags: -Zmiri-tree-borrows
 // Validation forces more things into memory, which we can't have here.
diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias_ret.rs b/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias_ret.rs
new file mode 100644
index 00000000000..dff724f8d96
--- /dev/null
+++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias_ret.rs
@@ -0,0 +1,34 @@
+//! Ensure we detect aliasing of a in-place argument with the return place for the tricky case where
+//! they do not live in memory.
+//@revisions: stack tree
+//@[tree]compile-flags: -Zmiri-tree-borrows
+// Validation forces more things into memory, which we can't have here.
+//@compile-flags: -Zmiri-disable-validation
+#![feature(custom_mir, core_intrinsics)]
+use std::intrinsics::mir::*;
+
+#[allow(unused)]
+pub struct S(i32);
+
+#[custom_mir(dialect = "runtime", phase = "optimized")]
+fn main() {
+    mir! {
+        let _unit: ();
+        {
+            let staging = S(42); // This forces `staging` into memory...
+            let _non_copy = staging; // ... so we move it to a non-inmemory local here.
+            // This specifically uses a type with scalar representation to tempt Miri to use the
+            // efficient way of storing local variables (outside adressable memory).
+            Call(_non_copy = callee(Move(_non_copy)), ReturnTo(after_call), UnwindContinue())
+            //~[stack]^ ERROR: not granting access
+            //~[tree]| ERROR: /reborrow .* forbidden/
+        }
+        after_call = {
+            Return()
+        }
+    }
+}
+
+pub fn callee(x: S) -> S {
+    x
+}
diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias_ret.stack.stderr b/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias_ret.stack.stderr
new file mode 100644
index 00000000000..fcd5b8752e7
--- /dev/null
+++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias_ret.stack.stderr
@@ -0,0 +1,25 @@
+error: Undefined Behavior: not granting access to tag <TAG> because that would remove [Unique for <TAG>] which is strongly protected
+  --> tests/fail/function_calls/arg_inplace_locals_alias_ret.rs:LL:CC
+   |
+LL |             Call(_non_copy = callee(Move(_non_copy)), ReturnTo(after_call), UnwindContinue())
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
+   |
+   = 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: <TAG> was created here, as the root tag for ALLOC
+  --> tests/fail/function_calls/arg_inplace_locals_alias_ret.rs:LL:CC
+   |
+LL |             Call(_non_copy = callee(Move(_non_copy)), ReturnTo(after_call), UnwindContinue())
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: <TAG> is this argument
+  --> tests/fail/function_calls/arg_inplace_locals_alias_ret.rs:LL:CC
+   |
+LL |     x
+   |     ^
+   = note: BACKTRACE (of the first span):
+   = note: inside `main` at tests/fail/function_calls/arg_inplace_locals_alias_ret.rs:LL:CC
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias_ret.tree.stderr b/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias_ret.tree.stderr
new file mode 100644
index 00000000000..b7f514de0af
--- /dev/null
+++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_locals_alias_ret.tree.stderr
@@ -0,0 +1,34 @@
+error: Undefined Behavior: reborrow through <TAG> (root of the allocation) at ALLOC[0x0] is forbidden
+  --> tests/fail/function_calls/arg_inplace_locals_alias_ret.rs:LL:CC
+   |
+LL |             Call(_non_copy = callee(Move(_non_copy)), ReturnTo(after_call), UnwindContinue())
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
+   |
+   = 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: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/tree-borrows.md for further information
+   = help: the accessed tag <TAG> (root of the allocation) is foreign to the protected tag <TAG> (i.e., it is not a child)
+   = help: this reborrow (acting as a foreign read access) would cause the protected tag <TAG> (currently Active) to become Disabled
+   = help: protected tags must never be Disabled
+help: the accessed tag <TAG> was created here
+  --> tests/fail/function_calls/arg_inplace_locals_alias_ret.rs:LL:CC
+   |
+LL |             Call(_non_copy = callee(Move(_non_copy)), ReturnTo(after_call), UnwindContinue())
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: the protected tag <TAG> was created here, in the initial state Reserved
+  --> tests/fail/function_calls/arg_inplace_locals_alias_ret.rs:LL:CC
+   |
+LL |     x
+   |     ^
+help: the protected tag <TAG> later transitioned to Active due to a child write access at offsets [0x0..0x4]
+  --> tests/fail/function_calls/arg_inplace_locals_alias_ret.rs:LL:CC
+   |
+LL |     x
+   |     ^
+   = help: this transition corresponds to the first write to a 2-phase borrowed mutable reference
+   = note: BACKTRACE (of the first span):
+   = note: inside `main` at tests/fail/function_calls/arg_inplace_locals_alias_ret.rs:LL:CC
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to 1 previous error
+