@@ -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,16 @@ impl GlobalState {
258269 tag
259270 }
260271
261- fn add_creation ( & mut self , tag : SbTag , alloc : AllocId , range : AllocRange ) {
272+ fn add_creation (
273+ & mut self ,
274+ parent : Option < SbTag > ,
275+ tag : SbTag ,
276+ alloc : AllocId ,
277+ range : AllocRange ,
278+ ) {
262279 let mut extras = self . extras . entry ( alloc) . or_default ( ) ;
263280 extras. creations . push ( Event {
281+ parent,
264282 tag,
265283 range,
266284 span : self . current_span ,
@@ -272,6 +290,7 @@ impl GlobalState {
272290 fn add_invalidation ( & mut self , tag : SbTag , alloc : AllocId , range : AllocRange ) {
273291 let mut extras = self . extras . entry ( alloc) . or_default ( ) ;
274292 extras. invalidations . push ( Event {
293+ parent : None ,
275294 tag,
276295 range,
277296 span : self . current_span ,
@@ -280,14 +299,40 @@ impl GlobalState {
280299 extras. current_time += 1 ;
281300 }
282301
302+ fn add_protector ( & mut self , orig_tag : SbTag , tag : SbTag , alloc : AllocId ) {
303+ let mut extras = self . extras . entry ( alloc) . or_default ( ) ;
304+ extras. protectors . push ( Protection { orig_tag, tag, span : self . current_span } ) ;
305+ extras. current_time += 1 ;
306+ }
307+
283308 fn get_stack_history (
284309 & self ,
285310 tag : SbTag ,
286311 alloc : AllocId ,
287312 alloc_range : AllocRange ,
288313 offset : Size ,
314+ protector_tag : Option < SbTag > ,
289315 ) -> Option < TagHistory > {
290316 let extras = self . extras . get ( & alloc) ?;
317+ let protected = protector_tag
318+ . and_then ( |protector| {
319+ extras. protectors . iter ( ) . find_map ( |protection| {
320+ if protection. tag == protector {
321+ Some ( ( protection. orig_tag , protection. span . data ( ) ) )
322+ } else {
323+ None
324+ }
325+ } )
326+ } )
327+ . and_then ( |( tag, call_span) | {
328+ extras. creations . iter ( ) . rev ( ) . find_map ( |event| {
329+ if event. tag == tag {
330+ Some ( ( event. parent ?, event. span . data ( ) , call_span) )
331+ } else {
332+ None
333+ }
334+ } )
335+ } ) ;
291336 if let SbTag :: Tagged ( _) = tag {
292337 let get_matching = |events : & [ Event ] | {
293338 events. iter ( ) . rev ( ) . find_map ( |event| {
@@ -296,8 +341,9 @@ impl GlobalState {
296341 } ;
297342 Some ( TagHistory :: Tagged {
298343 tag,
299- created : get_matching ( & extras. creations ) . unwrap ( ) ,
344+ created : get_matching ( & extras. creations ) ? ,
300345 invalidated : get_matching ( & extras. invalidations ) ,
346+ protected,
301347 } )
302348 } else {
303349 let mut created_time = 0 ;
@@ -348,7 +394,12 @@ impl GlobalState {
348394 } else {
349395 None
350396 } ;
351- Some ( TagHistory :: Untagged { recently_created, matching_created, recently_invalidated } )
397+ Some ( TagHistory :: Untagged {
398+ recently_created,
399+ matching_created,
400+ recently_invalidated,
401+ protected,
402+ } )
352403 }
353404 }
354405}
@@ -446,27 +497,33 @@ impl<'tcx> Stack {
446497 /// `None` during a deallocation.
447498 fn check_protector (
448499 item : & Item ,
449- provoking_access : Option < ( SbTag , AccessKind ) > ,
500+ provoking_access : Option < ( SbTag , AllocId , AllocRange , Size ) > , // just for debug printing amd error messages
450501 global : & GlobalState ,
451502 ) -> InterpResult < ' tcx > {
452503 if let SbTag :: Tagged ( id) = item. tag {
453504 if Some ( id) == global. tracked_pointer_tag {
454505 register_diagnostic ( NonHaltingDiagnostic :: PoppedPointerTag (
455506 item. clone ( ) ,
456- provoking_access ,
507+ None , // FIXME
457508 ) ) ;
458509 }
459510 }
460511 if let Some ( call) = item. protector {
461512 if global. is_active ( call) {
462- if let Some ( ( tag, _ ) ) = provoking_access {
513+ if let Some ( ( tag, alloc_id , alloc_range , offset ) ) = provoking_access {
463514 Err ( err_sb_ub (
464515 format ! (
465516 "not granting access to tag {:?} because incompatible item is protected: {:?}" ,
466517 tag, item
467518 ) ,
468519 None ,
469- None ,
520+ global. get_stack_history (
521+ tag,
522+ alloc_id,
523+ alloc_range,
524+ offset,
525+ Some ( item. tag ) ,
526+ ) ,
470527 ) ) ?
471528 } else {
472529 Err ( err_sb_ub (
@@ -506,7 +563,7 @@ impl<'tcx> Stack {
506563 let first_incompatible_idx = self . find_first_write_incompatible ( granting_idx) ;
507564 for item in self . borrows . drain ( first_incompatible_idx..) . rev ( ) {
508565 trace ! ( "access: popping item {:?}" , item) ;
509- Stack :: check_protector ( & item, Some ( ( tag, access ) ) , global) ?;
566+ Stack :: check_protector ( & item, Some ( ( tag, alloc_id , alloc_range , offset ) ) , global) ?;
510567 global. add_invalidation ( item. tag , alloc_id, alloc_range) ;
511568 }
512569 } else {
@@ -522,7 +579,11 @@ impl<'tcx> Stack {
522579 let item = & mut self . borrows [ idx] ;
523580 if item. perm == Permission :: Unique {
524581 trace ! ( "access: disabling item {:?}" , item) ;
525- Stack :: check_protector ( item, Some ( ( tag, access) ) , global) ?;
582+ Stack :: check_protector (
583+ item,
584+ Some ( ( tag, alloc_id, alloc_range, offset) ) ,
585+ global,
586+ ) ?;
526587 item. perm = Permission :: Disabled ;
527588 global. add_invalidation ( item. tag , alloc_id, alloc_range) ;
528589 }
@@ -548,7 +609,7 @@ impl<'tcx> Stack {
548609 tag, alloc_id,
549610 ) ,
550611 None ,
551- global. get_stack_history ( tag, alloc_id, alloc_range, offset) ,
612+ global. get_stack_history ( tag, alloc_id, alloc_range, offset, None ) ,
552613 )
553614 } ) ?;
554615
@@ -640,7 +701,7 @@ impl<'tcx> Stack {
640701 err_sb_ub (
641702 format ! ( "{}{}" , action, self . error_cause( derived_from) ) ,
642703 Some ( Self :: operation_summary ( "a reborrow" , alloc_id, alloc_range) ) ,
643- global. get_stack_history ( derived_from, alloc_id, alloc_range, error_offset) ,
704+ global. get_stack_history ( derived_from, alloc_id, alloc_range, error_offset, None ) ,
644705 )
645706 }
646707
@@ -664,7 +725,7 @@ impl<'tcx> Stack {
664725 err_sb_ub (
665726 format ! ( "{}{}" , action, self . error_cause( tag) ) ,
666727 Some ( Self :: operation_summary ( "an access" , alloc_id, alloc_range) ) ,
667- global. get_stack_history ( tag, alloc_id, alloc_range, error_offset) ,
728+ global. get_stack_history ( tag, alloc_id, alloc_range, error_offset, None ) ,
668729 )
669730 }
670731
@@ -768,7 +829,7 @@ impl Stacks {
768829 ( tag, Permission :: SharedReadWrite )
769830 }
770831 } ;
771- extra. add_creation ( base_tag, id, alloc_range ( Size :: ZERO , size) ) ;
832+ extra. add_creation ( None , base_tag, id, alloc_range ( Size :: ZERO , size) ) ;
772833 Stacks :: new ( size, perm, base_tag)
773834 }
774835
@@ -857,6 +918,17 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
857918 let ( alloc_id, base_offset, ptr) = this. memory . ptr_get_alloc ( place. ptr ) ?;
858919 let orig_tag = ptr. provenance . sb ;
859920
921+ let mem_extra = this. memory . extra . stacked_borrows . as_mut ( ) . unwrap ( ) . get_mut ( ) ;
922+ mem_extra. add_creation (
923+ Some ( orig_tag) ,
924+ new_tag,
925+ alloc_id,
926+ alloc_range ( base_offset, base_offset + size) ,
927+ ) ;
928+ if protect {
929+ mem_extra. add_protector ( orig_tag, new_tag, alloc_id) ;
930+ }
931+
860932 // Ensure we bail out if the pointer goes out-of-bounds (see miri#1050).
861933 let ( alloc_size, _) =
862934 this. memory . get_size_and_align ( alloc_id, AllocCheck :: Dereferenceable ) ?;
@@ -959,9 +1031,6 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
9591031 None => return Ok ( * val) ,
9601032 } ;
9611033
962- // May return Err for retags of size 0
963- let alloc = this. memory . ptr_get_alloc ( place. ptr ) ;
964-
9651034 // Compute new borrow.
9661035 let mem_extra = this. memory . extra . stacked_borrows . as_mut ( ) . unwrap ( ) . get_mut ( ) ;
9671036 let new_tag = match kind {
@@ -971,10 +1040,6 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
9711040 _ => SbTag :: Tagged ( mem_extra. new_ptr ( ) ) ,
9721041 } ;
9731042
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-
9781043 // Reborrow.
9791044 this. reborrow ( & place, size, kind, new_tag, protect) ?;
9801045
0 commit comments