@@ -59,7 +59,7 @@ impl fmt::Debug for BorTag {
59
59
#[ derive( Debug ) ]
60
60
pub struct FrameState {
61
61
/// The ID of the call this frame corresponds to.
62
- pub call_id : CallId ,
62
+ call_id : CallId ,
63
63
64
64
/// If this frame is protecting any tags, they are listed here. We use this list to do
65
65
/// incremental updates of the global list of protected tags stored in the
@@ -72,7 +72,7 @@ pub struct FrameState {
72
72
///
73
73
/// This will contain one tag per reference passed to the function, so
74
74
/// 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 ] > ,
76
76
}
77
77
78
78
impl VisitTags for FrameState {
@@ -85,29 +85,29 @@ impl VisitTags for FrameState {
85
85
#[ derive( Debug ) ]
86
86
pub struct GlobalStateInner {
87
87
/// Borrow tracker method currently in use.
88
- pub borrow_tracker_method : BorrowTrackerMethod ,
88
+ borrow_tracker_method : BorrowTrackerMethod ,
89
89
/// Next unused pointer ID (tag).
90
- pub next_ptr_tag : BorTag ,
90
+ next_ptr_tag : BorTag ,
91
91
/// Table storing the "base" tag for each allocation.
92
92
/// The base tag is the one used for the initial pointer.
93
93
/// 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 > ,
95
95
/// Next unused call ID (for protectors).
96
- pub next_call_id : CallId ,
96
+ next_call_id : CallId ,
97
97
/// All currently protected tags.
98
98
/// An item is protected if its tag is in this set, *and* it has the "protected" bit set.
99
99
/// We add tags to this when they are created with a protector in `reborrow`, and
100
100
/// we remove tags from this when the call which is protecting them returns, in
101
101
/// `GlobalStateInner::end_call`. See `Stack::item_popped` for more details.
102
- pub protected_tags : FxHashMap < BorTag , ProtectorKind > ,
102
+ protected_tags : FxHashMap < BorTag , ProtectorKind > ,
103
103
/// The pointer ids to trace
104
- pub tracked_pointer_tags : FxHashSet < BorTag > ,
104
+ tracked_pointer_tags : FxHashSet < BorTag > ,
105
105
/// The call ids to trace
106
- pub tracked_call_ids : FxHashSet < CallId > ,
106
+ tracked_call_ids : FxHashSet < CallId > ,
107
107
/// Whether to recurse into datatypes when searching for pointers to retag.
108
- pub retag_fields : RetagFields ,
108
+ retag_fields : RetagFields ,
109
109
/// Whether `core::ptr::Unique` gets special (`Box`-like) handling.
110
- pub unique_is_unique : bool ,
110
+ unique_is_unique : bool ,
111
111
}
112
112
113
113
impl VisitTags for GlobalStateInner {
@@ -194,7 +194,7 @@ impl GlobalStateInner {
194
194
}
195
195
196
196
/// 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 {
198
198
let id = self . next_ptr_tag ;
199
199
self . next_ptr_tag = id. succ ( ) . unwrap ( ) ;
200
200
id
@@ -210,7 +210,7 @@ impl GlobalStateInner {
210
210
FrameState { call_id, protected_tags : SmallVec :: new ( ) }
211
211
}
212
212
213
- pub fn end_call ( & mut self , frame : & machine:: FrameExtra < ' _ > ) {
213
+ fn end_call ( & mut self , frame : & machine:: FrameExtra < ' _ > ) {
214
214
for ( _, tag) in & frame
215
215
. borrow_tracker
216
216
. as_ref ( )
@@ -355,6 +355,38 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
355
355
BorrowTrackerMethod :: TreeBorrows => this. print_tree ( alloc_id, show_unnamed) ,
356
356
}
357
357
}
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
+ }
358
390
}
359
391
360
392
/// Extra per-allocation data for borrow tracking
0 commit comments