Skip to content

Commit 624f9bd

Browse files
authored
Rollup merge of #128333 - RalfJung:miri-sync, r=RalfJung
Miri subtree update r? `@ghost`
2 parents 43c50bc + a6796c1 commit 624f9bd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+807
-204
lines changed

src/tools/miri/rust-version

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
99b7134389e9766462601a2fc4013840b9d31745
1+
a526d7ce45fd2284e0e7c7556ccba2425b9d25e5

src/tools/miri/src/bin/miri.rs

+8
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,14 @@ fn main() {
620620
"-Zmiri-unique-is-unique only has an effect when -Zmiri-tree-borrows is also used"
621621
);
622622
}
623+
// Tree Borrows + permissive provenance does not work.
624+
if miri_config.provenance_mode == ProvenanceMode::Permissive
625+
&& matches!(miri_config.borrow_tracker, Some(BorrowTrackerMethod::TreeBorrows))
626+
{
627+
show_error!(
628+
"Tree Borrows does not support integer-to-pointer casts, and is hence not compatible with permissive provenance"
629+
);
630+
}
623631

624632
debug!("rustc arguments: {:?}", rustc_args);
625633
debug!("crate arguments: {:?}", miri_config.args);

src/tools/miri/src/borrow_tracker/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,10 @@ impl GlobalStateInner {
232232
pub fn remove_unreachable_allocs(&mut self, allocs: &LiveAllocs<'_, '_>) {
233233
self.root_ptr_tags.retain(|id, _| allocs.is_live(*id));
234234
}
235+
236+
pub fn borrow_tracker_method(&self) -> BorrowTrackerMethod {
237+
self.borrow_tracker_method
238+
}
235239
}
236240

237241
/// Which borrow tracking method to use

src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ pub mod diagnostics;
55
mod item;
66
mod stack;
77

8+
use std::cell::RefCell;
89
use std::cmp;
910
use std::fmt::Write;
1011
use std::mem;
@@ -820,7 +821,19 @@ trait EvalContextPrivExt<'tcx, 'ecx>: crate::MiriInterpCxExt<'tcx> {
820821
// See https://github.com/rust-lang/unsafe-code-guidelines/issues/276.
821822
let size = match size {
822823
Some(size) => size,
823-
None => return Ok(place.clone()),
824+
None => {
825+
// The first time this happens, show a warning.
826+
thread_local! { static WARNING_SHOWN: RefCell<bool> = const { RefCell::new(false) }; }
827+
WARNING_SHOWN.with_borrow_mut(|shown| {
828+
if *shown {
829+
return;
830+
}
831+
// Not yet shown. Show it!
832+
*shown = true;
833+
this.emit_diagnostic(NonHaltingDiagnostic::ExternTypeReborrow);
834+
});
835+
return Ok(place.clone());
836+
}
824837
};
825838

826839
// Compute new borrow.

src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,15 @@ impl<'tcx> NewPermission {
141141
) -> Option<Self> {
142142
let ty_is_freeze = pointee.is_freeze(*cx.tcx, cx.param_env());
143143
let ty_is_unpin = pointee.is_unpin(*cx.tcx, cx.param_env());
144+
let is_protected = kind == RetagKind::FnEntry;
145+
// As demonstrated by `tests/fail/tree_borrows/reservedim_spurious_write.rs`,
146+
// interior mutability and protectors interact poorly.
147+
// To eliminate the case of Protected Reserved IM we override interior mutability
148+
// in the case of a protected reference: protected references are always considered
149+
// "freeze".
144150
let initial_state = match mutability {
145-
Mutability::Mut if ty_is_unpin => Permission::new_reserved(ty_is_freeze),
151+
Mutability::Mut if ty_is_unpin =>
152+
Permission::new_reserved(ty_is_freeze || is_protected),
146153
Mutability::Not if ty_is_freeze => Permission::new_frozen(),
147154
// Raw pointers never enter this function so they are not handled.
148155
// However raw pointers are not the only pointers that take the parent
@@ -151,7 +158,7 @@ impl<'tcx> NewPermission {
151158
_ => return None,
152159
};
153160

154-
let protector = (kind == RetagKind::FnEntry).then_some(ProtectorKind::StrongProtector);
161+
let protector = is_protected.then_some(ProtectorKind::StrongProtector);
155162
Some(Self { zero_size: false, initial_state, protector })
156163
}
157164

src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs

+11
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ enum PermissionPriv {
2222
/// - foreign-read then child-write is UB due to `conflicted`,
2323
/// - child-write then foreign-read is UB since child-write will activate and then
2424
/// foreign-read disables a protected `Active`, which is UB.
25+
///
26+
/// Note: since the discovery of `tests/fail/tree_borrows/reservedim_spurious_write.rs`,
27+
/// `ty_is_freeze` does not strictly mean that the type has no interior mutability,
28+
/// it could be an interior mutable type that lost its interior mutability privileges
29+
/// when retagged with a protector.
2530
Reserved { ty_is_freeze: bool, conflicted: bool },
2631
/// represents: a unique pointer;
2732
/// allows: child reads, child writes;
@@ -141,6 +146,12 @@ mod transition {
141146
/// non-protected interior mutable `Reserved` which stay the same.
142147
fn foreign_write(state: PermissionPriv, protected: bool) -> Option<PermissionPriv> {
143148
Some(match state {
149+
// FIXME: since the fix related to reservedim_spurious_write, it is now possible
150+
// to express these transitions of the state machine without an explicit dependency
151+
// on `protected`: because `ty_is_freeze: false` implies `!protected` then
152+
// the line handling `Reserved { .. } if protected` could be deleted.
153+
// This will however require optimizations to the exhaustive tests because
154+
// fewer initial conditions are valid.
144155
Reserved { .. } if protected => Disabled,
145156
res @ Reserved { ty_is_freeze: false, .. } => res,
146157
_ => Disabled,

0 commit comments

Comments
 (0)