@@ -25,7 +25,7 @@ use rustc_middle::{
25
25
} ,
26
26
} ;
27
27
use rustc_span:: def_id:: { CrateNum , DefId } ;
28
- use rustc_span:: Symbol ;
28
+ use rustc_span:: { Span , SpanData , Symbol } ;
29
29
use rustc_target:: abi:: { Align , Size } ;
30
30
use rustc_target:: spec:: abi:: Abi ;
31
31
@@ -135,6 +135,19 @@ impl MayLeak for MiriMemoryKind {
135
135
}
136
136
}
137
137
138
+ impl MiriMemoryKind {
139
+ /// Whether we have a useful allocation span for an allocation of this kind.
140
+ fn should_save_allocation_span ( self ) -> bool {
141
+ use self :: MiriMemoryKind :: * ;
142
+ match self {
143
+ // Heap allocations are fine since the `Allocation` is created immediately.
144
+ Rust | Miri | C | WinHeap | Mmap => true ,
145
+ // Everything else is unclear, let's not show potentially confusing spans.
146
+ Machine | Global | ExternStatic | Tls | Runtime => false ,
147
+ }
148
+ }
149
+ }
150
+
138
151
impl fmt:: Display for MiriMemoryKind {
139
152
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
140
153
use self :: MiriMemoryKind :: * ;
@@ -497,6 +510,10 @@ pub struct MiriMachine<'mir, 'tcx> {
497
510
498
511
/// Whether to collect a backtrace when each allocation is created, just in case it leaks.
499
512
pub ( crate ) collect_leak_backtraces : bool ,
513
+
514
+ /// The spans we will use to report where an allocation was created and deallocated in
515
+ /// diagnostics.
516
+ pub ( crate ) allocation_spans : RefCell < FxHashMap < AllocId , ( Span , Option < Span > ) > > ,
500
517
}
501
518
502
519
impl < ' mir , ' tcx > MiriMachine < ' mir , ' tcx > {
@@ -621,6 +638,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
621
638
stack_addr,
622
639
stack_size,
623
640
collect_leak_backtraces : config. collect_leak_backtraces ,
641
+ allocation_spans : RefCell :: new ( FxHashMap :: default ( ) ) ,
624
642
}
625
643
}
626
644
@@ -742,6 +760,21 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
742
760
pub ( crate ) fn page_align ( & self ) -> Align {
743
761
Align :: from_bytes ( self . page_size ) . unwrap ( )
744
762
}
763
+
764
+ pub ( crate ) fn allocated_span ( & self , alloc_id : AllocId ) -> Option < SpanData > {
765
+ self . allocation_spans
766
+ . borrow ( )
767
+ . get ( & alloc_id)
768
+ . map ( |( allocated, _deallocated) | allocated. data ( ) )
769
+ }
770
+
771
+ pub ( crate ) fn deallocated_span ( & self , alloc_id : AllocId ) -> Option < SpanData > {
772
+ self . allocation_spans
773
+ . borrow ( )
774
+ . get ( & alloc_id)
775
+ . and_then ( |( _allocated, deallocated) | * deallocated)
776
+ . map ( Span :: data)
777
+ }
745
778
}
746
779
747
780
impl VisitTags for MiriMachine < ' _ , ' _ > {
@@ -791,6 +824,7 @@ impl VisitTags for MiriMachine<'_, '_> {
791
824
stack_addr : _,
792
825
stack_size : _,
793
826
collect_leak_backtraces : _,
827
+ allocation_spans : _,
794
828
} = self ;
795
829
796
830
threads. visit_tags ( visit) ;
@@ -1051,6 +1085,14 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
1051
1085
} ,
1052
1086
|ptr| ecx. global_base_pointer ( ptr) ,
1053
1087
) ?;
1088
+
1089
+ if matches ! ( kind, MemoryKind :: Machine ( kind) if kind. should_save_allocation_span( ) ) {
1090
+ ecx. machine
1091
+ . allocation_spans
1092
+ . borrow_mut ( )
1093
+ . insert ( id, ( ecx. machine . current_span ( ) , None ) ) ;
1094
+ }
1095
+
1054
1096
Ok ( Cow :: Owned ( alloc) )
1055
1097
}
1056
1098
@@ -1181,6 +1223,10 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
1181
1223
if let Some ( borrow_tracker) = & mut alloc_extra. borrow_tracker {
1182
1224
borrow_tracker. before_memory_deallocation ( alloc_id, prove_extra, range, machine) ?;
1183
1225
}
1226
+ if let Some ( ( _, deallocated_at) ) = machine. allocation_spans . borrow_mut ( ) . get_mut ( & alloc_id)
1227
+ {
1228
+ * deallocated_at = Some ( machine. current_span ( ) ) ;
1229
+ }
1184
1230
Ok ( ( ) )
1185
1231
}
1186
1232
0 commit comments