@@ -126,11 +126,20 @@ struct AllocHistory {
126126 current_time : usize ,
127127 creations : Vec < Event > ,
128128 invalidations : Vec < Event > ,
129+ protectors : Vec < Protection > ,
130+ }
131+
132+ #[ derive( Debug ) ]
133+ struct Protection {
134+ orig_tag : SbTag ,
135+ tag : SbTag ,
136+ span : Span ,
129137}
130138
131139#[ derive( Debug ) ]
132140struct Event {
133141 time : usize ,
142+ parent : Option < SbTag > ,
134143 tag : SbTag ,
135144 range : AllocRange ,
136145 span : Span ,
@@ -141,11 +150,13 @@ pub enum TagHistory {
141150 tag : SbTag ,
142151 created : ( AllocRange , SpanData ) ,
143152 invalidated : Option < ( AllocRange , SpanData ) > ,
153+ protected : Option < ( SbTag , SpanData , SpanData ) > ,
144154 } ,
145155 Untagged {
146156 recently_created : Option < ( AllocRange , SpanData ) > ,
147157 recently_invalidated : Option < ( AllocRange , SpanData ) > ,
148158 matching_created : Option < ( AllocRange , SpanData ) > ,
159+ protected : Option < ( SbTag , SpanData , SpanData ) > ,
149160 } ,
150161}
151162
@@ -258,9 +269,10 @@ impl GlobalState {
258269 tag
259270 }
260271
261- fn add_creation ( & mut self , tag : SbTag , alloc : AllocId , range : AllocRange ) {
272+ fn add_creation ( & mut self , parent : Option < SbTag > , tag : SbTag , alloc : AllocId , range : AllocRange ) {
262273 let mut extras = self . extras . entry ( alloc) . or_default ( ) ;
263274 extras. creations . push ( Event {
275+ parent,
264276 tag,
265277 range,
266278 span : self . current_span ,
@@ -272,6 +284,7 @@ impl GlobalState {
272284 fn add_invalidation ( & mut self , tag : SbTag , alloc : AllocId , range : AllocRange ) {
273285 let mut extras = self . extras . entry ( alloc) . or_default ( ) ;
274286 extras. invalidations . push ( Event {
287+ parent : None ,
275288 tag,
276289 range,
277290 span : self . current_span ,
@@ -280,14 +293,32 @@ impl GlobalState {
280293 extras. current_time += 1 ;
281294 }
282295
296+ fn add_protector ( & mut self , orig_tag : SbTag , tag : SbTag , alloc : AllocId ) {
297+ let mut extras = self . extras . entry ( alloc) . or_default ( ) ;
298+ extras. protectors . push ( Protection { orig_tag, tag, span : self . current_span } ) ;
299+ extras. current_time += 1 ;
300+ }
301+
283302 fn get_stack_history (
284303 & self ,
285304 tag : SbTag ,
286305 alloc : AllocId ,
287306 alloc_range : AllocRange ,
288307 offset : Size ,
308+ protector_tag : Option < SbTag > ,
289309 ) -> Option < TagHistory > {
290310 let extras = self . extras . get ( & alloc) ?;
311+ let protected = protector_tag
312+ . and_then ( |protector| {
313+ extras. protectors . iter ( ) . find_map ( |protection| {
314+ if protection. tag == protector { Some ( ( protection. orig_tag , protection. span . data ( ) ) ) } else { None }
315+ } )
316+ } )
317+ . and_then ( |( tag, call_span) | {
318+ extras. creations . iter ( ) . rev ( ) . find_map ( |event| {
319+ if event. tag == tag { Some ( ( event. parent . unwrap ( ) , event. span . data ( ) , call_span) ) } else { None }
320+ } )
321+ } ) ;
291322 if let SbTag :: Tagged ( _) = tag {
292323 let get_matching = |events : & [ Event ] | {
293324 events. iter ( ) . rev ( ) . find_map ( |event| {
@@ -298,6 +329,7 @@ impl GlobalState {
298329 tag,
299330 created : get_matching ( & extras. creations ) . unwrap ( ) ,
300331 invalidated : get_matching ( & extras. invalidations ) ,
332+ protected,
301333 } )
302334 } else {
303335 let mut created_time = 0 ;
@@ -348,7 +380,12 @@ impl GlobalState {
348380 } else {
349381 None
350382 } ;
351- Some ( TagHistory :: Untagged { recently_created, matching_created, recently_invalidated } )
383+ Some ( TagHistory :: Untagged {
384+ recently_created,
385+ matching_created,
386+ recently_invalidated,
387+ protected,
388+ } )
352389 }
353390 }
354391}
@@ -446,27 +483,33 @@ impl<'tcx> Stack {
446483 /// `None` during a deallocation.
447484 fn check_protector (
448485 item : & Item ,
449- provoking_access : Option < ( SbTag , AccessKind ) > ,
486+ provoking_access : Option < ( SbTag , AllocId , AllocRange , Size ) > , // just for debug printing amd error messages
450487 global : & GlobalState ,
451488 ) -> InterpResult < ' tcx > {
452489 if let SbTag :: Tagged ( id) = item. tag {
453490 if Some ( id) == global. tracked_pointer_tag {
454491 register_diagnostic ( NonHaltingDiagnostic :: PoppedPointerTag (
455492 item. clone ( ) ,
456- provoking_access ,
493+ None , // FIXME
457494 ) ) ;
458495 }
459496 }
460497 if let Some ( call) = item. protector {
461498 if global. is_active ( call) {
462- if let Some ( ( tag, _ ) ) = provoking_access {
499+ if let Some ( ( tag, alloc_id , alloc_range , offset ) ) = provoking_access {
463500 Err ( err_sb_ub (
464501 format ! (
465502 "not granting access to tag {:?} because incompatible item is protected: {:?}" ,
466503 tag, item
467504 ) ,
468505 None ,
469- None ,
506+ global. get_stack_history (
507+ tag,
508+ alloc_id,
509+ alloc_range,
510+ offset,
511+ Some ( item. tag ) ,
512+ ) ,
470513 ) ) ?
471514 } else {
472515 Err ( err_sb_ub (
@@ -506,7 +549,7 @@ impl<'tcx> Stack {
506549 let first_incompatible_idx = self . find_first_write_incompatible ( granting_idx) ;
507550 for item in self . borrows . drain ( first_incompatible_idx..) . rev ( ) {
508551 trace ! ( "access: popping item {:?}" , item) ;
509- Stack :: check_protector ( & item, Some ( ( tag, access ) ) , global) ?;
552+ Stack :: check_protector ( & item, Some ( ( tag, alloc_id , alloc_range , offset ) ) , global) ?;
510553 global. add_invalidation ( item. tag , alloc_id, alloc_range) ;
511554 }
512555 } else {
@@ -522,7 +565,11 @@ impl<'tcx> Stack {
522565 let item = & mut self . borrows [ idx] ;
523566 if item. perm == Permission :: Unique {
524567 trace ! ( "access: disabling item {:?}" , item) ;
525- Stack :: check_protector ( item, Some ( ( tag, access) ) , global) ?;
568+ Stack :: check_protector (
569+ item,
570+ Some ( ( tag, alloc_id, alloc_range, offset) ) ,
571+ global,
572+ ) ?;
526573 item. perm = Permission :: Disabled ;
527574 global. add_invalidation ( item. tag , alloc_id, alloc_range) ;
528575 }
@@ -548,7 +595,7 @@ impl<'tcx> Stack {
548595 tag, alloc_id,
549596 ) ,
550597 None ,
551- global. get_stack_history ( tag, alloc_id, alloc_range, offset) ,
598+ global. get_stack_history ( tag, alloc_id, alloc_range, offset, None ) ,
552599 )
553600 } ) ?;
554601
@@ -640,7 +687,7 @@ impl<'tcx> Stack {
640687 err_sb_ub (
641688 format ! ( "{}{}" , action, self . error_cause( derived_from) ) ,
642689 Some ( Self :: operation_summary ( "a reborrow" , alloc_id, alloc_range) ) ,
643- global. get_stack_history ( derived_from, alloc_id, alloc_range, error_offset) ,
690+ global. get_stack_history ( derived_from, alloc_id, alloc_range, error_offset, None ) ,
644691 )
645692 }
646693
@@ -664,7 +711,7 @@ impl<'tcx> Stack {
664711 err_sb_ub (
665712 format ! ( "{}{}" , action, self . error_cause( tag) ) ,
666713 Some ( Self :: operation_summary ( "an access" , alloc_id, alloc_range) ) ,
667- global. get_stack_history ( tag, alloc_id, alloc_range, error_offset) ,
714+ global. get_stack_history ( tag, alloc_id, alloc_range, error_offset, None ) ,
668715 )
669716 }
670717
@@ -768,7 +815,7 @@ impl Stacks {
768815 ( tag, Permission :: SharedReadWrite )
769816 }
770817 } ;
771- extra. add_creation ( base_tag, id, alloc_range ( Size :: ZERO , size) ) ;
818+ extra. add_creation ( None , base_tag, id, alloc_range ( Size :: ZERO , size) ) ;
772819 Stacks :: new ( size, perm, base_tag)
773820 }
774821
@@ -857,6 +904,12 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
857904 let ( alloc_id, base_offset, ptr) = this. memory . ptr_get_alloc ( place. ptr ) ?;
858905 let orig_tag = ptr. provenance . sb ;
859906
907+ let mem_extra = this. memory . extra . stacked_borrows . as_mut ( ) . unwrap ( ) . get_mut ( ) ;
908+ mem_extra. add_creation ( Some ( orig_tag) , new_tag, alloc_id, alloc_range ( base_offset, base_offset + size) ) ;
909+ if protect {
910+ mem_extra. add_protector ( orig_tag, new_tag, alloc_id) ;
911+ }
912+
860913 // Ensure we bail out if the pointer goes out-of-bounds (see miri#1050).
861914 let ( alloc_size, _) =
862915 this. memory . get_size_and_align ( alloc_id, AllocCheck :: Dereferenceable ) ?;
@@ -959,9 +1012,6 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
9591012 None => return Ok ( * val) ,
9601013 } ;
9611014
962- // May return Err for retags of size 0
963- let alloc = this. memory . ptr_get_alloc ( place. ptr ) ;
964-
9651015 // Compute new borrow.
9661016 let mem_extra = this. memory . extra . stacked_borrows . as_mut ( ) . unwrap ( ) . get_mut ( ) ;
9671017 let new_tag = match kind {
@@ -971,10 +1021,6 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
9711021 _ => SbTag :: Tagged ( mem_extra. new_ptr ( ) ) ,
9721022 } ;
9731023
974- if let Ok ( ( alloc_id, base_offset, _ptr) ) = alloc {
975- mem_extra. add_creation ( new_tag, alloc_id, alloc_range ( base_offset, base_offset + size) ) ;
976- }
977-
9781024 // Reborrow.
9791025 this. reborrow ( & place, size, kind, new_tag, protect) ?;
9801026
0 commit comments