diff options
| author | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2024-04-17 00:00:24 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-04-17 00:00:24 +0200 |
| commit | 51cfa95668c8a0ce5c87bd5fe649d577a040cce7 (patch) | |
| tree | 10832ecbb349f38659db87f336e723e17c1df8c1 /src | |
| parent | 4764dceb0f6f9a51c389c9b318cc1e189c89e3da (diff) | |
| parent | 8606efa5d24b1aeefa14b285920a0291953149fa (diff) | |
| download | rust-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')
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)); +} } |
