Skip to content

Commit

Permalink
Rollup merge of #128333 - RalfJung:miri-sync, r=RalfJung
Browse files Browse the repository at this point in the history
Miri subtree update

r? `@ghost`
  • Loading branch information
matthiaskrgr committed Jul 29, 2024
2 parents 43c50bc + a6796c1 commit 624f9bd
Show file tree
Hide file tree
Showing 45 changed files with 807 additions and 204 deletions.
2 changes: 1 addition & 1 deletion src/tools/miri/rust-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
99b7134389e9766462601a2fc4013840b9d31745
a526d7ce45fd2284e0e7c7556ccba2425b9d25e5
8 changes: 8 additions & 0 deletions src/tools/miri/src/bin/miri.rs
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,14 @@ fn main() {
"-Zmiri-unique-is-unique only has an effect when -Zmiri-tree-borrows is also used"
);
}
// Tree Borrows + permissive provenance does not work.
if miri_config.provenance_mode == ProvenanceMode::Permissive
&& matches!(miri_config.borrow_tracker, Some(BorrowTrackerMethod::TreeBorrows))
{
show_error!(
"Tree Borrows does not support integer-to-pointer casts, and is hence not compatible with permissive provenance"
);
}

debug!("rustc arguments: {:?}", rustc_args);
debug!("crate arguments: {:?}", miri_config.args);
Expand Down
4 changes: 4 additions & 0 deletions src/tools/miri/src/borrow_tracker/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,10 @@ impl GlobalStateInner {
pub fn remove_unreachable_allocs(&mut self, allocs: &LiveAllocs<'_, '_>) {
self.root_ptr_tags.retain(|id, _| allocs.is_live(*id));
}

pub fn borrow_tracker_method(&self) -> BorrowTrackerMethod {
self.borrow_tracker_method
}
}

/// Which borrow tracking method to use
Expand Down
15 changes: 14 additions & 1 deletion src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub mod diagnostics;
mod item;
mod stack;

use std::cell::RefCell;
use std::cmp;
use std::fmt::Write;
use std::mem;
Expand Down Expand Up @@ -820,7 +821,19 @@ trait EvalContextPrivExt<'tcx, 'ecx>: crate::MiriInterpCxExt<'tcx> {
// See https://github.com/rust-lang/unsafe-code-guidelines/issues/276.
let size = match size {
Some(size) => size,
None => return Ok(place.clone()),
None => {
// The first time this happens, show a warning.
thread_local! { static WARNING_SHOWN: RefCell<bool> = const { RefCell::new(false) }; }
WARNING_SHOWN.with_borrow_mut(|shown| {
if *shown {
return;
}
// Not yet shown. Show it!
*shown = true;
this.emit_diagnostic(NonHaltingDiagnostic::ExternTypeReborrow);
});
return Ok(place.clone());
}
};

// Compute new borrow.
Expand Down
11 changes: 9 additions & 2 deletions src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,15 @@ impl<'tcx> NewPermission {
) -> Option<Self> {
let ty_is_freeze = pointee.is_freeze(*cx.tcx, cx.param_env());
let ty_is_unpin = pointee.is_unpin(*cx.tcx, cx.param_env());
let is_protected = kind == RetagKind::FnEntry;
// As demonstrated by `tests/fail/tree_borrows/reservedim_spurious_write.rs`,
// interior mutability and protectors interact poorly.
// To eliminate the case of Protected Reserved IM we override interior mutability
// in the case of a protected reference: protected references are always considered
// "freeze".
let initial_state = match mutability {
Mutability::Mut if ty_is_unpin => Permission::new_reserved(ty_is_freeze),
Mutability::Mut if ty_is_unpin =>
Permission::new_reserved(ty_is_freeze || is_protected),
Mutability::Not if ty_is_freeze => Permission::new_frozen(),
// Raw pointers never enter this function so they are not handled.
// However raw pointers are not the only pointers that take the parent
Expand All @@ -151,7 +158,7 @@ impl<'tcx> NewPermission {
_ => return None,
};

let protector = (kind == RetagKind::FnEntry).then_some(ProtectorKind::StrongProtector);
let protector = is_protected.then_some(ProtectorKind::StrongProtector);
Some(Self { zero_size: false, initial_state, protector })
}

Expand Down
11 changes: 11 additions & 0 deletions src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ enum PermissionPriv {
/// - foreign-read then child-write is UB due to `conflicted`,
/// - child-write then foreign-read is UB since child-write will activate and then
/// foreign-read disables a protected `Active`, which is UB.
///
/// Note: since the discovery of `tests/fail/tree_borrows/reservedim_spurious_write.rs`,
/// `ty_is_freeze` does not strictly mean that the type has no interior mutability,
/// it could be an interior mutable type that lost its interior mutability privileges
/// when retagged with a protector.
Reserved { ty_is_freeze: bool, conflicted: bool },
/// represents: a unique pointer;
/// allows: child reads, child writes;
Expand Down Expand Up @@ -141,6 +146,12 @@ mod transition {
/// non-protected interior mutable `Reserved` which stay the same.
fn foreign_write(state: PermissionPriv, protected: bool) -> Option<PermissionPriv> {
Some(match state {
// FIXME: since the fix related to reservedim_spurious_write, it is now possible
// to express these transitions of the state machine without an explicit dependency
// on `protected`: because `ty_is_freeze: false` implies `!protected` then
// the line handling `Reserved { .. } if protected` could be deleted.
// This will however require optimizations to the exhaustive tests because
// fewer initial conditions are valid.
Reserved { .. } if protected => Disabled,
res @ Reserved { ty_is_freeze: false, .. } => res,
_ => Disabled,
Expand Down
Loading

0 comments on commit 624f9bd

Please sign in to comment.