about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2024-04-17 00:00:24 +0200
committerGitHub <noreply@github.com>2024-04-17 00:00:24 +0200
commit51cfa95668c8a0ce5c87bd5fe649d577a040cce7 (patch)
tree10832ecbb349f38659db87f336e723e17c1df8c1 /src
parent4764dceb0f6f9a51c389c9b318cc1e189c89e3da (diff)
parent8606efa5d24b1aeefa14b285920a0291953149fa (diff)
downloadrust-51cfa95668c8a0ce5c87bd5fe649d577a040cce7.tar.gz
rust-51cfa95668c8a0ce5c87bd5fe649d577a040cce7.zip
Rollup merge of #124013 - RalfJung:box-to-raw, r=oli-obk
Box::into_raw: make Miri understand that this is a box-to-raw cast

Turns out https://github.com/rust-lang/rust/pull/122647 went a bit too far in cleaning up `Box`... we still need a hack in `Box::into_raw`. The nicer fix would be to make Stacked Borrows not care about reference-to-raw-pointer casts, but it's unclear whether that will ever be possible without going to full Tree Borrows.

Fixes https://github.com/rust-lang/miri/issues/3473.
Diffstat (limited to 'src')
-rw-r--r--src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.stack.stderr2
-rw-r--r--src/tools/miri/tests/fail/both_borrows/newtype_retagging.stack.stderr2
-rw-r--r--src/tools/miri/tests/pass/issues/issue-miri-3473.rs28
-rw-r--r--src/tools/miri/tests/pass/stacked-borrows/stacked-borrows.rs12
4 files changed, 42 insertions, 2 deletions
diff --git a/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.stack.stderr b/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.stack.stderr
index 867907e98e6..c26c7f397b0 100644
--- a/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.stack.stderr
+++ b/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.stack.stderr
@@ -6,7 +6,7 @@ LL |         Box(unsafe { Unique::new_unchecked(raw) }, alloc)
    |
    = 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 by a Unique retag at offsets [0x0..0x4]
+help: <TAG> was created by a SharedReadWrite retag at offsets [0x0..0x4]
   --> $DIR/newtype_pair_retagging.rs:LL:CC
    |
 LL |     let ptr = Box::into_raw(Box::new(0i32));
diff --git a/src/tools/miri/tests/fail/both_borrows/newtype_retagging.stack.stderr b/src/tools/miri/tests/fail/both_borrows/newtype_retagging.stack.stderr
index 56715938e97..ae54da70fe2 100644
--- a/src/tools/miri/tests/fail/both_borrows/newtype_retagging.stack.stderr
+++ b/src/tools/miri/tests/fail/both_borrows/newtype_retagging.stack.stderr
@@ -6,7 +6,7 @@ LL |         Box(unsafe { Unique::new_unchecked(raw) }, alloc)
    |
    = 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 by a Unique retag at offsets [0x0..0x4]
+help: <TAG> was created by a SharedReadWrite retag at offsets [0x0..0x4]
   --> $DIR/newtype_retagging.rs:LL:CC
    |
 LL |     let ptr = Box::into_raw(Box::new(0i32));
diff --git a/src/tools/miri/tests/pass/issues/issue-miri-3473.rs b/src/tools/miri/tests/pass/issues/issue-miri-3473.rs
new file mode 100644
index 00000000000..77b960c1cdc
--- /dev/null
+++ b/src/tools/miri/tests/pass/issues/issue-miri-3473.rs
@@ -0,0 +1,28 @@
+//@revisions: stack tree
+//@[tree]compile-flags: -Zmiri-tree-borrows
+use std::cell::UnsafeCell;
+
+#[repr(C)]
+#[derive(Default)]
+struct Node {
+    _meta: UnsafeCell<usize>,
+    value: usize,
+}
+
+impl Node {
+    fn value(&self) -> &usize {
+        &self.value
+    }
+}
+
+/// This used to cause Stacked Borrows errors because of trouble around conversion
+/// from Box to raw pointer.
+fn main() {
+    unsafe {
+        let a = Box::into_raw(Box::new(Node::default()));
+        let ptr = &*a;
+        *UnsafeCell::raw_get(a.cast::<UnsafeCell<usize>>()) = 2;
+        assert_eq!(*ptr.value(), 0);
+        drop(Box::from_raw(a));
+    }
+}
diff --git a/src/tools/miri/tests/pass/stacked-borrows/stacked-borrows.rs b/src/tools/miri/tests/pass/stacked-borrows/stacked-borrows.rs
index 734411ccc72..43ba490d5bb 100644
--- a/src/tools/miri/tests/pass/stacked-borrows/stacked-borrows.rs
+++ b/src/tools/miri/tests/pass/stacked-borrows/stacked-borrows.rs
@@ -20,6 +20,7 @@ fn main() {
     wide_raw_ptr_in_tuple();
     not_unpin_not_protected();
     write_does_not_invalidate_all_aliases();
+    box_into_raw_allows_interior_mutable_alias();
 }
 
 // Make sure that reading from an `&mut` does, like reborrowing to `&`,
@@ -263,3 +264,14 @@ fn write_does_not_invalidate_all_aliases() {
     other::lib2();
     assert_eq!(*x, 1337); // oops, the value changed! I guess not all pointers were invalidated
 }
+
+fn box_into_raw_allows_interior_mutable_alias() { unsafe {
+    let b = Box::new(std::cell::Cell::new(42));
+    let raw = Box::into_raw(b);
+    let c = &*raw;
+    let d = raw.cast::<i32>(); // bypassing `Cell` -- only okay in Miri tests
+    // `c` and `d` should permit arbitrary aliasing with each other now.
+    *d = 1;
+    c.set(2);
+    drop(Box::from_raw(raw));
+} }