diff options
| author | Ralf Jung <post@ralfj.de> | 2022-12-27 12:46:08 +0100 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2023-02-06 11:46:37 +0100 |
| commit | ea541bc2ee00c955e3f7eb3ddd5c3ab80146ab71 (patch) | |
| tree | 90de52aa5460cb560bdc7ff4400f1c19b36db07f /src | |
| parent | 201ae7387245caa4591d4c8db4c35c170c64faf0 (diff) | |
| download | rust-ea541bc2ee00c955e3f7eb3ddd5c3ab80146ab71.tar.gz rust-ea541bc2ee00c955e3f7eb3ddd5c3ab80146ab71.zip | |
make &mut !Unpin not dereferenceable
See https://github.com/rust-lang/unsafe-code-guidelines/issues/381 for discussion.
Diffstat (limited to 'src')
4 files changed, 24 insertions, 60 deletions
diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs index ec555ba2895..3b3a41c2f03 100644 --- a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs @@ -81,21 +81,18 @@ impl NewPermission { protector: None, } } else if pointee.is_unpin(*cx.tcx, cx.param_env()) { - // A regular full mutable reference. + // A regular full mutable reference. On `FnEntry` this is `noalias` and `dereferenceable`. NewPermission::Uniform { perm: Permission::Unique, access: Some(AccessKind::Write), protector, } } else { + // `!Unpin` dereferences do not get `noalias` nor `dereferenceable`. NewPermission::Uniform { perm: Permission::SharedReadWrite, - // FIXME: We emit `dereferenceable` for `!Unpin` mutable references, so we - // should do fake accesses here. But then we run into - // <https://github.com/rust-lang/unsafe-code-guidelines/issues/381>, so for now - // we don't do that. access: None, - protector, + protector: None, } } } @@ -109,6 +106,7 @@ impl NewPermission { } } ty::Ref(_, _pointee, Mutability::Not) => { + // Shared references. If frozen, these get `noalias` and `dereferenceable`; otherwise neither. NewPermission::FreezeSensitive { freeze_perm: Permission::SharedReadOnly, freeze_access: Some(AccessKind::Read), diff --git a/src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector2.rs b/src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector2.rs deleted file mode 100644 index fd67dccd14d..00000000000 --- a/src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector2.rs +++ /dev/null @@ -1,16 +0,0 @@ -//@error-pattern: /deallocating while item \[SharedReadWrite for .*\] is strongly protected/ -use std::marker::PhantomPinned; - -pub struct NotUnpin(i32, PhantomPinned); - -fn inner(x: &mut NotUnpin, f: fn(&mut NotUnpin)) { - // `f` may mutate, but it may not deallocate! - f(x) -} - -fn main() { - inner(Box::leak(Box::new(NotUnpin(0, PhantomPinned))), |x| { - let raw = x as *mut _; - drop(unsafe { Box::from_raw(raw) }); - }); -} diff --git a/src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector2.stderr b/src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector2.stderr deleted file mode 100644 index 47cfa0de725..00000000000 --- a/src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector2.stderr +++ /dev/null @@ -1,38 +0,0 @@ -error: Undefined Behavior: deallocating while item [SharedReadWrite for <TAG>] is strongly protected by call ID - --> RUSTLIB/alloc/src/alloc.rs:LL:CC - | -LL | unsafe { __rust_dealloc(ptr, layout.size(), layout.align()) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ deallocating while item [SharedReadWrite for <TAG>] is strongly protected by call ID - | - = 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 - = note: BACKTRACE: - = note: inside `std::alloc::dealloc` at RUSTLIB/alloc/src/alloc.rs:LL:CC - = note: inside `<std::alloc::Global as std::alloc::Allocator>::deallocate` at RUSTLIB/alloc/src/alloc.rs:LL:CC - = note: inside `alloc::alloc::box_free::<NotUnpin, std::alloc::Global>` at RUSTLIB/alloc/src/alloc.rs:LL:CC - = note: inside `std::ptr::drop_in_place::<std::boxed::Box<NotUnpin>> - shim(Some(std::boxed::Box<NotUnpin>))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC - = note: inside `std::mem::drop::<std::boxed::Box<NotUnpin>>` at RUSTLIB/core/src/mem/mod.rs:LL:CC -note: inside closure - --> $DIR/deallocate_against_protector2.rs:LL:CC - | -LL | drop(unsafe { Box::from_raw(raw) }); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: inside `<[closure@$DIR/deallocate_against_protector2.rs:LL:CC] as std::ops::FnOnce<(&mut NotUnpin,)>>::call_once - shim` at RUSTLIB/core/src/ops/function.rs:LL:CC -note: inside `inner` - --> $DIR/deallocate_against_protector2.rs:LL:CC - | -LL | f(x) - | ^^^^ -note: inside `main` - --> $DIR/deallocate_against_protector2.rs:LL:CC - | -LL | / inner(Box::leak(Box::new(NotUnpin(0, PhantomPinned))), |x| { -LL | | let raw = x as *mut _; -LL | | drop(unsafe { Box::from_raw(raw) }); -LL | | }); - | |______^ - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to previous error - 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 ef6eb346c17..8e78efa73c7 100644 --- a/src/tools/miri/tests/pass/stacked-borrows/stacked-borrows.rs +++ b/src/tools/miri/tests/pass/stacked-borrows/stacked-borrows.rs @@ -19,6 +19,7 @@ fn main() { array_casts(); mut_below_shr(); wide_raw_ptr_in_tuple(); + not_unpin_not_protected(); } // Make sure that reading from an `&mut` does, like reborrowing to `&`, @@ -219,3 +220,22 @@ fn wide_raw_ptr_in_tuple() { // Make sure the fn ptr part of the vtable is still fine. r.type_id(); } + +fn not_unpin_not_protected() { + // `&mut !Unpin`, at least for now, does not get `noalias` nor `dereferenceable`, so we also + // don't add protectors. (We could, but until we have a better idea for where we want to go with + // the self-referntial-generator situation, it does not seem worth the potential trouble.) + use std::marker::PhantomPinned; + + pub struct NotUnpin(i32, PhantomPinned); + + fn inner(x: &mut NotUnpin, f: fn(&mut NotUnpin)) { + // `f` may mutate, but it may not deallocate! + f(x) + } + + inner(Box::leak(Box::new(NotUnpin(0, PhantomPinned))), |x| { + let raw = x as *mut _; + drop(unsafe { Box::from_raw(raw) }); + }); +} |
