about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2023-10-09 08:31:03 +0200
committerRalf Jung <post@ralfj.de>2023-10-09 08:59:38 +0200
commitfc4aa4e2f2b8764b6b3482bf99d9dad10fdf6a51 (patch)
tree4186b56a2b9f53db9a386bb03a171be96a1c3426 /src
parenta04b7a374458b640960798dffe83e614f7907562 (diff)
downloadrust-fc4aa4e2f2b8764b6b3482bf99d9dad10fdf6a51.tar.gz
rust-fc4aa4e2f2b8764b6b3482bf99d9dad10fdf6a51.zip
add test for self-assignment on call through reference
Diffstat (limited to 'src')
-rw-r--r--src/tools/miri/tests/pass/calls.rs16
1 files changed, 16 insertions, 0 deletions
diff --git a/src/tools/miri/tests/pass/calls.rs b/src/tools/miri/tests/pass/calls.rs
index 014d1d3acab..8db3d3590cc 100644
--- a/src/tools/miri/tests/pass/calls.rs
+++ b/src/tools/miri/tests/pass/calls.rs
@@ -34,10 +34,26 @@ fn const_fn_call() -> i64 {
     x
 }
 
+fn call_return_into_passed_reference() {
+    pub fn func<T>(v: &mut T, f: fn(&T) -> T) {
+        // MIR building will introduce a temporary, so this becomes
+        // `let temp = f(v); *v = temp;`.
+        // If this got optimized to `*v = f(v)` on the MIR level we'd have UB
+        // since the return place may not be observed while the function runs!
+        *v = f(v);
+    }
+
+    let mut x = 0;
+    func(&mut x, |v| v + 1);
+    assert_eq!(x, 1);
+}
+
 fn main() {
     assert_eq!(call(), 2);
     assert_eq!(factorial_recursive(), 3628800);
     assert_eq!(call_generic(), (42, true));
     assert_eq!(cross_crate_fn_call(), 1);
     assert_eq!(const_fn_call(), 11);
+
+    call_return_into_passed_reference();
 }