@@ -126,11 +126,20 @@ struct AllocHistory {
126
126
current_time : usize ,
127
127
creations : Vec < Event > ,
128
128
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 ,
129
137
}
130
138
131
139
#[ derive( Debug ) ]
132
140
struct Event {
133
141
time : usize ,
142
+ parent : Option < SbTag > ,
134
143
tag : SbTag ,
135
144
range : AllocRange ,
136
145
span : Span ,
@@ -141,11 +150,13 @@ pub enum TagHistory {
141
150
tag : SbTag ,
142
151
created : ( AllocRange , SpanData ) ,
143
152
invalidated : Option < ( AllocRange , SpanData ) > ,
153
+ protected : Option < ( SbTag , SpanData , SpanData ) > ,
144
154
} ,
145
155
Untagged {
146
156
recently_created : Option < ( AllocRange , SpanData ) > ,
147
157
recently_invalidated : Option < ( AllocRange , SpanData ) > ,
148
158
matching_created : Option < ( AllocRange , SpanData ) > ,
159
+ protected : Option < ( SbTag , SpanData , SpanData ) > ,
149
160
} ,
150
161
}
151
162
@@ -258,9 +269,10 @@ impl GlobalState {
258
269
tag
259
270
}
260
271
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 ) {
262
273
let mut extras = self . extras . entry ( alloc) . or_default ( ) ;
263
274
extras. creations . push ( Event {
275
+ parent,
264
276
tag,
265
277
range,
266
278
span : self . current_span ,
@@ -272,6 +284,7 @@ impl GlobalState {
272
284
fn add_invalidation ( & mut self , tag : SbTag , alloc : AllocId , range : AllocRange ) {
273
285
let mut extras = self . extras . entry ( alloc) . or_default ( ) ;
274
286
extras. invalidations . push ( Event {
287
+ parent : None ,
275
288
tag,
276
289
range,
277
290
span : self . current_span ,
@@ -280,14 +293,32 @@ impl GlobalState {
280
293
extras. current_time += 1 ;
281
294
}
282
295
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
+
283
302
fn get_stack_history (
284
303
& self ,
285
304
tag : SbTag ,
286
305
alloc : AllocId ,
287
306
alloc_range : AllocRange ,
288
307
offset : Size ,
308
+ protector_tag : Option < SbTag > ,
289
309
) -> Option < TagHistory > {
290
310
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
+ } ) ;
291
322
if let SbTag :: Tagged ( _) = tag {
292
323
let get_matching = |events : & [ Event ] | {
293
324
events. iter ( ) . rev ( ) . find_map ( |event| {
@@ -298,6 +329,7 @@ impl GlobalState {
298
329
tag,
299
330
created : get_matching ( & extras. creations ) . unwrap ( ) ,
300
331
invalidated : get_matching ( & extras. invalidations ) ,
332
+ protected,
301
333
} )
302
334
} else {
303
335
let mut created_time = 0 ;
@@ -348,7 +380,12 @@ impl GlobalState {
348
380
} else {
349
381
None
350
382
} ;
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
+ } )
352
389
}
353
390
}
354
391
}
@@ -446,27 +483,33 @@ impl<'tcx> Stack {
446
483
/// `None` during a deallocation.
447
484
fn check_protector (
448
485
item : & Item ,
449
- provoking_access : Option < ( SbTag , AccessKind ) > ,
486
+ provoking_access : Option < ( SbTag , AllocId , AllocRange , Size ) > , // just for debug printing amd error messages
450
487
global : & GlobalState ,
451
488
) -> InterpResult < ' tcx > {
452
489
if let SbTag :: Tagged ( id) = item. tag {
453
490
if Some ( id) == global. tracked_pointer_tag {
454
491
register_diagnostic ( NonHaltingDiagnostic :: PoppedPointerTag (
455
492
item. clone ( ) ,
456
- provoking_access ,
493
+ None , // FIXME
457
494
) ) ;
458
495
}
459
496
}
460
497
if let Some ( call) = item. protector {
461
498
if global. is_active ( call) {
462
- if let Some ( ( tag, _ ) ) = provoking_access {
499
+ if let Some ( ( tag, alloc_id , alloc_range , offset ) ) = provoking_access {
463
500
Err ( err_sb_ub (
464
501
format ! (
465
502
"not granting access to tag {:?} because incompatible item is protected: {:?}" ,
466
503
tag, item
467
504
) ,
468
505
None ,
469
- None ,
506
+ global. get_stack_history (
507
+ tag,
508
+ alloc_id,
509
+ alloc_range,
510
+ offset,
511
+ Some ( item. tag ) ,
512
+ ) ,
470
513
) ) ?
471
514
} else {
472
515
Err ( err_sb_ub (
@@ -506,7 +549,7 @@ impl<'tcx> Stack {
506
549
let first_incompatible_idx = self . find_first_write_incompatible ( granting_idx) ;
507
550
for item in self . borrows . drain ( first_incompatible_idx..) . rev ( ) {
508
551
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) ?;
510
553
global. add_invalidation ( item. tag , alloc_id, alloc_range) ;
511
554
}
512
555
} else {
@@ -522,7 +565,11 @@ impl<'tcx> Stack {
522
565
let item = & mut self . borrows [ idx] ;
523
566
if item. perm == Permission :: Unique {
524
567
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
+ ) ?;
526
573
item. perm = Permission :: Disabled ;
527
574
global. add_invalidation ( item. tag , alloc_id, alloc_range) ;
528
575
}
@@ -548,7 +595,7 @@ impl<'tcx> Stack {
548
595
tag, alloc_id,
549
596
) ,
550
597
None ,
551
- global. get_stack_history ( tag, alloc_id, alloc_range, offset) ,
598
+ global. get_stack_history ( tag, alloc_id, alloc_range, offset, None ) ,
552
599
)
553
600
} ) ?;
554
601
@@ -640,7 +687,7 @@ impl<'tcx> Stack {
640
687
err_sb_ub (
641
688
format ! ( "{}{}" , action, self . error_cause( derived_from) ) ,
642
689
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 ) ,
644
691
)
645
692
}
646
693
@@ -664,7 +711,7 @@ impl<'tcx> Stack {
664
711
err_sb_ub (
665
712
format ! ( "{}{}" , action, self . error_cause( tag) ) ,
666
713
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 ) ,
668
715
)
669
716
}
670
717
@@ -768,7 +815,7 @@ impl Stacks {
768
815
( tag, Permission :: SharedReadWrite )
769
816
}
770
817
} ;
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) ) ;
772
819
Stacks :: new ( size, perm, base_tag)
773
820
}
774
821
@@ -857,6 +904,12 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
857
904
let ( alloc_id, base_offset, ptr) = this. memory . ptr_get_alloc ( place. ptr ) ?;
858
905
let orig_tag = ptr. provenance . sb ;
859
906
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
+
860
913
// Ensure we bail out if the pointer goes out-of-bounds (see miri#1050).
861
914
let ( alloc_size, _) =
862
915
this. memory . get_size_and_align ( alloc_id, AllocCheck :: Dereferenceable ) ?;
@@ -959,9 +1012,6 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
959
1012
None => return Ok ( * val) ,
960
1013
} ;
961
1014
962
- // May return Err for retags of size 0
963
- let alloc = this. memory . ptr_get_alloc ( place. ptr ) ;
964
-
965
1015
// Compute new borrow.
966
1016
let mem_extra = this. memory . extra . stacked_borrows . as_mut ( ) . unwrap ( ) . get_mut ( ) ;
967
1017
let new_tag = match kind {
@@ -971,10 +1021,6 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
971
1021
_ => SbTag :: Tagged ( mem_extra. new_ptr ( ) ) ,
972
1022
} ;
973
1023
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
-
978
1024
// Reborrow.
979
1025
this. reborrow ( & place, size, kind, new_tag, protect) ?;
980
1026
0 commit comments