@@ -316,11 +316,22 @@ impl<'tcx> Stack {
316
316
alloc_history : & mut AllocHistory ,
317
317
threads : & ThreadManager < ' _ , ' tcx > ,
318
318
) -> InterpResult < ' tcx > {
319
- if global. tracked_pointer_tags . contains ( & item. tag ( ) ) {
320
- register_diagnostic ( NonHaltingDiagnostic :: PoppedPointerTag (
321
- * item,
322
- provoking_access. map ( |( tag, _alloc_range, _size, access) | ( tag, access) ) ,
323
- ) ) ;
319
+ if !global. tracked_pointer_tags . is_empty ( ) {
320
+ check_tracked ( item, & provoking_access, global) ;
321
+
322
+ #[ inline( never) ] // cold path
323
+ fn check_tracked (
324
+ item : & Item ,
325
+ provoking_access : & Option < ( SbTagExtra , AllocRange , Size , AccessKind ) > ,
326
+ global : & GlobalStateInner ,
327
+ ) {
328
+ if global. tracked_pointer_tags . contains ( & item. tag ( ) ) {
329
+ register_diagnostic ( NonHaltingDiagnostic :: PoppedPointerTag (
330
+ * item,
331
+ provoking_access. map ( |( tag, _alloc_range, _size, access) | ( tag, access) ) ,
332
+ ) ) ;
333
+ }
334
+ }
324
335
}
325
336
326
337
if !item. protected ( ) {
@@ -341,40 +352,52 @@ impl<'tcx> Stack {
341
352
// which ends up about linear in the number of protected tags in the program into a
342
353
// constant time check (and a slow linear, because the tags in the frames aren't contiguous).
343
354
if global. protected_tags . contains ( & item. tag ( ) ) {
344
- // This path is cold because it is fatal to the program. So here it is fine to do the
345
- // more expensive search to figure out which call is responsible for protecting this
346
- // tag.
347
- let call_id = threads
348
- . all_stacks ( )
349
- . flatten ( )
350
- . map ( |frame| {
351
- frame
352
- . extra
353
- . stacked_borrows
354
- . as_ref ( )
355
- . expect ( "we should have Stacked Borrows data" )
356
- } )
357
- . find ( |frame| frame. protected_tags . contains ( & item. tag ( ) ) )
358
- . map ( |frame| frame. call_id )
359
- . unwrap ( ) ; // FIXME: Surely we should find something, but a panic seems wrong here?
360
- if let Some ( ( tag, _alloc_range, _offset, _access) ) = provoking_access {
361
- Err ( err_sb_ub (
362
- format ! (
363
- "not granting access to tag {:?} because incompatible item {:?} is protected by call {:?}" ,
364
- tag, item, call_id
365
- ) ,
366
- None ,
367
- tag. and_then ( |tag| alloc_history. get_logs_relevant_to ( tag, Some ( item. tag ( ) ) ) ) ,
368
- ) ) ?
369
- } else {
370
- Err ( err_sb_ub (
371
- format ! (
372
- "deallocating while item {:?} is protected by call {:?}" ,
373
- item, call_id
374
- ) ,
375
- None ,
376
- None ,
377
- ) ) ?
355
+ return Err ( protector_error ( item, & provoking_access, alloc_history, threads) ) ;
356
+
357
+ #[ inline( never) ] // cold path
358
+ fn protector_error < ' tcx > (
359
+ item : & Item ,
360
+ provoking_access : & Option < ( SbTagExtra , AllocRange , Size , AccessKind ) > ,
361
+ alloc_history : & mut AllocHistory ,
362
+ threads : & ThreadManager < ' _ , ' tcx > ,
363
+ ) -> InterpErrorInfo < ' tcx > {
364
+ // This path is cold because it is fatal to the program. So here it is fine to do the
365
+ // more expensive search to figure out which call is responsible for protecting this
366
+ // tag.
367
+ let call_id = threads
368
+ . all_stacks ( )
369
+ . flatten ( )
370
+ . map ( |frame| {
371
+ frame
372
+ . extra
373
+ . stacked_borrows
374
+ . as_ref ( )
375
+ . expect ( "we should have Stacked Borrows data" )
376
+ } )
377
+ . find ( |frame| frame. protected_tags . contains ( & item. tag ( ) ) )
378
+ . map ( |frame| frame. call_id )
379
+ . unwrap ( ) ; // FIXME: Surely we should find something, but a panic seems wrong here?
380
+ if let Some ( ( tag, _alloc_range, _offset, _access) ) = provoking_access {
381
+ err_sb_ub (
382
+ format ! (
383
+ "not granting access to tag {:?} because incompatible item {:?} is protected by call {:?}" ,
384
+ tag, item, call_id
385
+ ) ,
386
+ None ,
387
+ tag. and_then ( |tag| {
388
+ alloc_history. get_logs_relevant_to ( tag, Some ( item. tag ( ) ) )
389
+ } ) ,
390
+ )
391
+ } else {
392
+ err_sb_ub (
393
+ format ! (
394
+ "deallocating while item {:?} is protected by call {:?}" ,
395
+ item, call_id
396
+ ) ,
397
+ None ,
398
+ None ,
399
+ )
400
+ } . into ( )
378
401
}
379
402
}
380
403
Ok ( ( ) )
0 commit comments