about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/tools/miri/tests/fail/function_calls/return_pointer_on_unwind.rs55
-rw-r--r--src/tools/miri/tests/fail/function_calls/return_pointer_on_unwind.stderr19
2 files changed, 74 insertions, 0 deletions
diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_on_unwind.rs b/src/tools/miri/tests/fail/function_calls/return_pointer_on_unwind.rs
new file mode 100644
index 00000000000..79e29b79d6a
--- /dev/null
+++ b/src/tools/miri/tests/fail/function_calls/return_pointer_on_unwind.rs
@@ -0,0 +1,55 @@
+// Doesn't need an aliasing model.
+//@compile-flags: -Zmiri-disable-stacked-borrows
+#![feature(raw_ref_op)]
+#![feature(core_intrinsics)]
+#![feature(custom_mir)]
+
+use std::intrinsics::mir::*;
+use std::panic;
+
+#[repr(C)]
+struct S(i32, [u8; 128]);
+
+#[custom_mir(dialect = "runtime", phase = "optimized")]
+fn docall(out: &mut S) {
+    mir! {
+        {
+            Call(*out = callee(), after_call)
+        }
+
+        after_call = {
+            Return()
+        }
+    }
+}
+
+fn startpanic() -> () {
+    panic!()
+}
+
+#[custom_mir(dialect = "runtime", phase = "optimized")]
+fn callee() -> S {
+    mir! {
+        type RET = S;
+        let _unit: ();
+        {
+            // We test whether changes done to RET before unwinding
+            // become visible to the outside. In codegen we can see them
+            // but Miri should detect this as UB!
+            RET.0 = 42;
+            Call(_unit = startpanic(), after_call)
+        }
+
+        after_call = {
+            Return()
+        }
+    }
+}
+
+fn main() {
+    let mut x = S(0, [0; 128]);
+    panic::catch_unwind(panic::AssertUnwindSafe(|| docall(&mut x))).unwrap_err();
+    // The return place got de-initialized before the call and assigning to RET
+    // does not propagate if we do not reach the `Return`.
+    dbg!(x.0); //~ERROR: uninitialized
+}
diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_on_unwind.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_on_unwind.stderr
new file mode 100644
index 00000000000..ecd9a111840
--- /dev/null
+++ b/src/tools/miri/tests/fail/function_calls/return_pointer_on_unwind.stderr
@@ -0,0 +1,19 @@
+thread 'main' panicked at $DIR/return_pointer_on_unwind.rs:LL:CC:
+explicit panic
+note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
+error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory
+  --> $DIR/return_pointer_on_unwind.rs:LL:CC
+   |
+LL |     dbg!(x.0);
+   |     ^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
+   |
+   = 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 `main` at RUSTLIB/std/src/macros.rs:LL:CC
+   = note: this error originates in the macro `dbg` (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
+
+error: aborting due to previous error
+