@@ -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,17 @@ 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
+ Rust | Miri | C | Mmap => true ,
144
+ Machine | Global | ExternStatic | Tls | WinHeap | Runtime => false ,
145
+ }
146
+ }
147
+ }
148
+
138
149
impl fmt:: Display for MiriMemoryKind {
139
150
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
140
151
use self :: MiriMemoryKind :: * ;
@@ -497,6 +508,10 @@ pub struct MiriMachine<'mir, 'tcx> {
497
508
498
509
/// Whether to collect a backtrace when each allocation is created, just in case it leaks.
499
510
pub ( crate ) collect_leak_backtraces : bool ,
511
+
512
+ /// The spans we will use to report where an allocation was created and deallocated in
513
+ /// diagnostics.
514
+ pub ( crate ) allocation_spans : RefCell < FxHashMap < AllocId , ( Option < Span > , Option < Span > ) > > ,
500
515
}
501
516
502
517
impl < ' mir , ' tcx > MiriMachine < ' mir , ' tcx > {
@@ -621,6 +636,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
621
636
stack_addr,
622
637
stack_size,
623
638
collect_leak_backtraces : config. collect_leak_backtraces ,
639
+ allocation_spans : RefCell :: new ( FxHashMap :: default ( ) ) ,
624
640
}
625
641
}
626
642
@@ -742,6 +758,22 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
742
758
pub ( crate ) fn page_align ( & self ) -> Align {
743
759
Align :: from_bytes ( self . page_size ) . unwrap ( )
744
760
}
761
+
762
+ pub ( crate ) fn allocated_span ( & self , alloc_id : AllocId ) -> Option < SpanData > {
763
+ self . allocation_spans
764
+ . borrow ( )
765
+ . get ( & alloc_id)
766
+ . and_then ( |( allocated, _deallocated) | * allocated)
767
+ . map ( Span :: data)
768
+ }
769
+
770
+ pub ( crate ) fn deallocated_span ( & self , alloc_id : AllocId ) -> Option < SpanData > {
771
+ self . allocation_spans
772
+ . borrow ( )
773
+ . get ( & alloc_id)
774
+ . and_then ( |( _allocated, deallocated) | * deallocated)
775
+ . map ( Span :: data)
776
+ }
745
777
}
746
778
747
779
impl VisitTags for MiriMachine < ' _ , ' _ > {
@@ -791,6 +823,7 @@ impl VisitTags for MiriMachine<'_, '_> {
791
823
stack_addr : _,
792
824
stack_size : _,
793
825
collect_leak_backtraces : _,
826
+ allocation_spans : _,
794
827
} = self ;
795
828
796
829
threads. visit_tags ( visit) ;
@@ -1051,6 +1084,16 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
1051
1084
} ,
1052
1085
|ptr| ecx. global_base_pointer ( ptr) ,
1053
1086
) ?;
1087
+
1088
+ if let MemoryKind :: Machine ( kind) = kind {
1089
+ if kind. should_save_allocation_span ( ) {
1090
+ ecx. machine
1091
+ . allocation_spans
1092
+ . borrow_mut ( )
1093
+ . insert ( id, ( Some ( ecx. machine . current_span ( ) ) , None ) ) ;
1094
+ }
1095
+ }
1096
+
1054
1097
Ok ( Cow :: Owned ( alloc) )
1055
1098
}
1056
1099
@@ -1181,6 +1224,10 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
1181
1224
if let Some ( borrow_tracker) = & mut alloc_extra. borrow_tracker {
1182
1225
borrow_tracker. before_memory_deallocation ( alloc_id, prove_extra, range, machine) ?;
1183
1226
}
1227
+ if let Some ( ( _, deallocated_at) ) = machine. allocation_spans . borrow_mut ( ) . get_mut ( & alloc_id)
1228
+ {
1229
+ * deallocated_at = Some ( machine. current_span ( ) ) ;
1230
+ }
1184
1231
Ok ( ( ) )
1185
1232
}
1186
1233
0 commit comments