@@ -11,7 +11,7 @@ use log::trace;
11
11
use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
12
12
use rustc_middle:: mir:: RetagKind ;
13
13
use rustc_middle:: ty;
14
- use rustc_target:: abi:: Size ;
14
+ use rustc_target:: abi:: { LayoutOf , Size } ;
15
15
use rustc_hir:: Mutability ;
16
16
17
17
use crate :: * ;
@@ -645,4 +645,34 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
645
645
646
646
Ok ( ( ) )
647
647
}
648
+
649
+ /// After a stack frame got pushed, retag the return place so that we are sure
650
+ /// it does not alias with anything.
651
+ fn retag_return_place ( & mut self ) -> InterpResult < ' tcx > {
652
+ let this = self . eval_context_mut ( ) ;
653
+ let return_place = if let Some ( return_place) = this. frame_mut ( ) . return_place {
654
+ return_place
655
+ } else {
656
+ // No return place, nothing to do.
657
+ return Ok ( ( ) ) ;
658
+ } ;
659
+ if return_place. layout . is_zst ( ) {
660
+ // There may not be any memory here, nothing to do.
661
+ return Ok ( ( ) ) ;
662
+ }
663
+ // We need this to be in-memory to use tagged pointers.
664
+ let return_place = this. force_allocation ( return_place) ?;
665
+
666
+ // We have to turn the place into a reference to use the existing code.
667
+ let ptr_layout = this. layout_of ( this. tcx . mk_mut_ptr ( return_place. layout . ty ) ) ?;
668
+ let val = ImmTy :: from_immediate ( return_place. to_ref ( ) , ptr_layout) ;
669
+ // Reborrow it, then make it back into an `ImmTy`.
670
+ let val = this. retag_reference ( val, RefKind :: Unique { two_phase : false } , /*protector*/ true ) ?;
671
+ let val = ImmTy :: from_immediate ( val, ptr_layout) ;
672
+ // And use reborrowed pointer for return place.
673
+ let return_place = this. ref_to_mplace ( val) ?;
674
+ this. frame_mut ( ) . return_place = Some ( return_place. into ( ) ) ;
675
+
676
+ Ok ( ( ) )
677
+ }
648
678
}
0 commit comments