Skip to content

Commit 2c9d857

Browse files
committed
Miri leak_report: do not report leaks of allocations that are reachable from globals
1 parent 6050e52 commit 2c9d857

File tree

1 file changed

+24
-5
lines changed

1 file changed

+24
-5
lines changed

src/librustc_mir/interpret/memory.rs

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)