@@ -650,7 +650,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
650650 allocs_to_print : & mut VecDeque < AllocId > ,
651651 alloc : & Allocation < Tag , Extra > ,
652652 ) {
653- for & ( _, ( _ , target_id) ) in alloc. relocations ( ) . iter ( ) {
653+ for & ( _, target_id) in alloc. relocations ( ) . values ( ) {
654654 if allocs_seen. insert ( target_id) {
655655 allocs_to_print. push_back ( target_id) ;
656656 }
@@ -713,12 +713,31 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
713713 }
714714
715715 pub fn leak_report ( & self ) -> usize {
716- let leaks: Vec < _ > = self
717- . alloc_map
718- . filter_map_collect ( |& id, & ( kind, _) | if kind. may_leak ( ) { None } else { Some ( id) } ) ;
716+ // Collect the set of allocations that are *reachable* from `Global` allocations.
717+ let reachable = {
718+ let mut reachable = FxHashSet :: default ( ) ;
719+ let global_kind = M :: GLOBAL_KIND . map ( MemoryKind :: Machine ) ;
720+ let mut todo: Vec < _ > = self . alloc_map . filter_map_collect ( move |& id, & ( kind, _) | {
721+ if Some ( kind) == global_kind { Some ( id) } else { None }
722+ } ) ;
723+ while let Some ( id) = todo. pop ( ) {
724+ if reachable. insert ( id) {
725+ if let Some ( ( _, alloc) ) = self . alloc_map . get ( id) {
726+ // This is a new allocation, add its relocations to `todo`.
727+ todo. extend ( alloc. relocations ( ) . values ( ) . map ( |& ( _, target_id) | target_id) ) ;
728+ }
729+ }
730+ }
731+ reachable
732+ } ;
733+
734+ // All allocations that are *not* `reachable` and *not* `may_leak` are considered leaking.
735+ let leaks: Vec < _ > = self . alloc_map . filter_map_collect ( |& id, & ( kind, _) | {
736+ if kind. may_leak ( ) || reachable. contains ( & id) { None } else { Some ( id) }
737+ } ) ;
719738 let n = leaks. len ( ) ;
720739 if n > 0 {
721- eprintln ! ( "### LEAK REPORT ### " ) ;
740+ eprintln ! ( "The following memory was leaked: " ) ;
722741 self . dump_allocs ( leaks) ;
723742 }
724743 n
0 commit comments