@@ -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
0 commit comments