@@ -59,7 +59,7 @@ impl fmt::Debug for BorTag {
5959#[ derive( Debug ) ]
6060pub struct FrameState {
6161 /// The ID of the call this frame corresponds to.
62- pub call_id : CallId ,
62+ call_id : CallId ,
6363
6464 /// If this frame is protecting any tags, they are listed here. We use this list to do
6565 /// incremental updates of the global list of protected tags stored in the
@@ -72,7 +72,7 @@ pub struct FrameState {
7272 ///
7373 /// This will contain one tag per reference passed to the function, so
7474 /// a size of 2 is enough for the vast majority of functions.
75- pub protected_tags : SmallVec < [ ( AllocId , BorTag ) ; 2 ] > ,
75+ protected_tags : SmallVec < [ ( AllocId , BorTag ) ; 2 ] > ,
7676}
7777
7878impl VisitTags for FrameState {
@@ -85,29 +85,29 @@ impl VisitTags for FrameState {
8585#[ derive( Debug ) ]
8686pub struct GlobalStateInner {
8787 /// Borrow tracker method currently in use.
88- pub borrow_tracker_method : BorrowTrackerMethod ,
88+ borrow_tracker_method : BorrowTrackerMethod ,
8989 /// Next unused pointer ID (tag).
90- pub next_ptr_tag : BorTag ,
90+ next_ptr_tag : BorTag ,
9191 /// Table storing the "base" tag for each allocation.
9292 /// The base tag is the one used for the initial pointer.
9393 /// We need this in a separate table to handle cyclic statics.
94- pub base_ptr_tags : FxHashMap < AllocId , BorTag > ,
94+ base_ptr_tags : FxHashMap < AllocId , BorTag > ,
9595 /// Next unused call ID (for protectors).
96- pub next_call_id : CallId ,
96+ next_call_id : CallId ,
9797 /// All currently protected tags.
9898 /// An item is protected if its tag is in this set, *and* it has the "protected" bit set.
9999 /// We add tags to this when they are created with a protector in `reborrow`, and
100100 /// we remove tags from this when the call which is protecting them returns, in
101101 /// `GlobalStateInner::end_call`. See `Stack::item_popped` for more details.
102- pub protected_tags : FxHashMap < BorTag , ProtectorKind > ,
102+ protected_tags : FxHashMap < BorTag , ProtectorKind > ,
103103 /// The pointer ids to trace
104- pub tracked_pointer_tags : FxHashSet < BorTag > ,
104+ tracked_pointer_tags : FxHashSet < BorTag > ,
105105 /// The call ids to trace
106- pub tracked_call_ids : FxHashSet < CallId > ,
106+ tracked_call_ids : FxHashSet < CallId > ,
107107 /// Whether to recurse into datatypes when searching for pointers to retag.
108- pub retag_fields : RetagFields ,
108+ retag_fields : RetagFields ,
109109 /// Whether `core::ptr::Unique` gets special (`Box`-like) handling.
110- pub unique_is_unique : bool ,
110+ unique_is_unique : bool ,
111111}
112112
113113impl VisitTags for GlobalStateInner {
@@ -194,7 +194,7 @@ impl GlobalStateInner {
194194 }
195195
196196 /// Generates a new pointer tag. Remember to also check track_pointer_tags and log its creation!
197- pub fn new_ptr ( & mut self ) -> BorTag {
197+ fn new_ptr ( & mut self ) -> BorTag {
198198 let id = self . next_ptr_tag ;
199199 self . next_ptr_tag = id. succ ( ) . unwrap ( ) ;
200200 id
@@ -210,7 +210,7 @@ impl GlobalStateInner {
210210 FrameState { call_id, protected_tags : SmallVec :: new ( ) }
211211 }
212212
213- pub fn end_call ( & mut self , frame : & machine:: FrameExtra < ' _ > ) {
213+ fn end_call ( & mut self , frame : & machine:: FrameExtra < ' _ > ) {
214214 for ( _, tag) in & frame
215215 . borrow_tracker
216216 . as_ref ( )
@@ -355,6 +355,38 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
355355 BorrowTrackerMethod :: TreeBorrows => this. print_tree ( alloc_id, show_unnamed) ,
356356 }
357357 }
358+
359+ fn on_stack_pop (
360+ & self ,
361+ frame : & Frame < ' mir , ' tcx , Provenance , FrameExtra < ' tcx > > ,
362+ ) -> InterpResult < ' tcx > {
363+ let this = self . eval_context_ref ( ) ;
364+ let borrow_tracker = this. machine . borrow_tracker . as_ref ( ) . unwrap ( ) ;
365+ // The body of this loop needs `borrow_tracker` immutably
366+ // so we can't move this code inside the following `end_call`.
367+ for ( alloc_id, tag) in & frame
368+ . extra
369+ . borrow_tracker
370+ . as_ref ( )
371+ . expect ( "we should have borrow tracking data" )
372+ . protected_tags
373+ {
374+ // Just because the tag is protected doesn't guarantee that
375+ // the allocation still exists (weak protectors allow deallocations)
376+ // so we must check that the allocation exists.
377+ // If it does exist, then we have the guarantee that the
378+ // pointer is readable, and the implicit read access inserted
379+ // will never cause UB on the pointer itself.
380+ let ( _, _, kind) = this. get_alloc_info ( * alloc_id) ;
381+ if matches ! ( kind, AllocKind :: LiveData ) {
382+ let alloc_extra = this. get_alloc_extra ( * alloc_id) . unwrap ( ) ;
383+ let alloc_borrow_tracker = & alloc_extra. borrow_tracker . as_ref ( ) . unwrap ( ) ;
384+ alloc_borrow_tracker. release_protector ( & this. machine , borrow_tracker, * tag) ?;
385+ }
386+ }
387+ borrow_tracker. borrow_mut ( ) . end_call ( & frame. extra ) ;
388+ Ok ( ( ) )
389+ }
358390}
359391
360392/// Extra per-allocation data for borrow tracking
0 commit comments