Skip to content

Commit 6eb153a

Browse files
authored
Merge branch 'master' into partially-invalidate-mut
2 parents 04794c4 + 17d0851 commit 6eb153a

File tree

2 files changed

+7
-33
lines changed

2 files changed

+7
-33
lines changed

src/stacked_borrows.rs

+7-30
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,10 @@ impl<'tcx> Stack {
151151
/// Returns the index of the item we matched, `None` if it was the frozen one.
152152
/// `kind` indicates which kind of reference is being dereferenced.
153153
fn deref(&self, bor: Borrow, kind: RefKind) -> Result<Option<usize>, String> {
154+
// Exclude unique ref with frozen tag.
155+
if let (RefKind::Unique, Borrow::Shr(Some(_))) = (kind, bor) {
156+
return Err(format!("Encountered mutable reference with frozen tag ({:?})", bor));
157+
}
154158
// Checks related to freezing
155159
match bor {
156160
Borrow::Shr(Some(bor_t)) if kind == RefKind::Frozen => {
@@ -490,36 +494,9 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for MiriEvalContext<'a, 'mir, 'tcx> {
490494
if let Some(mutability) = mutability { format!("{:?}", mutability) } else { format!("raw") },
491495
place.ptr, place.layout.ty);
492496
let ptr = place.ptr.to_ptr()?;
493-
// In principle we should not have to do anything here. However, with transmutes involved,
494-
// it can happen that the tag of `ptr` does not actually match `mutability`, and we
495-
// should adjust for that.
496-
// Notably, the compiler can introduce such transmutes by optimizing away `&[mut]*`.
497-
// That can transmute a raw ptr to a (shared/mut) ref, and a mut ref to a shared one.
498-
match (mutability, ptr.tag) {
499-
(None, _) => {
500-
// No further validation on raw accesses.
501-
return Ok(());
502-
}
503-
(Some(MutMutable), Borrow::Uniq(_)) |
504-
(Some(MutImmutable), Borrow::Shr(_)) => {
505-
// Expected combinations. Nothing to do.
506-
}
507-
(Some(MutMutable), Borrow::Shr(None)) => {
508-
// Raw transmuted to mut ref. This is something real unsafe code does.
509-
// We cannot reborrow here because we do not want to mutate state on a deref.
510-
}
511-
(Some(MutImmutable), Borrow::Uniq(_)) => {
512-
// A mut got transmuted to shr. Can happen even from compiler transformations:
513-
// `&*x` gets optimized to `x` even when `x` is a `&mut`.
514-
}
515-
(Some(MutMutable), Borrow::Shr(Some(_))) => {
516-
// This is just invalid: A shr got transmuted to a mut.
517-
// If we ever allow this, we have to consider what we do when a turn a
518-
// `Raw`-tagged `&mut` into a raw pointer pointing to a frozen location.
519-
// We probably do not want to allow that, but we have to allow
520-
// turning a `Raw`-tagged `&` into a raw ptr to a frozen location.
521-
return err!(MachineError(format!("Encountered mutable reference with frozen tag {:?}", ptr.tag)))
522-
}
497+
if mutability.is_none() {
498+
// No further checks on raw derefs -- only the access itself will be checked.
499+
return Ok(());
523500
}
524501

525502
// Get the allocation

tests/compile-fail-fullmir/stacked_borrows/static_memory_modification.rs

-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
// FIXME still considering whether we are okay with this not being an error
2-
// ignore-test
3-
41
static X: usize = 5;
52

63
#[allow(mutable_transmutes)]

0 commit comments

Comments
 (0)