make call_successors safe

For recursive functions, it could enter an infinite recursion.
This commit is contained in:
Folkert 2020-03-04 21:59:58 +01:00
parent f265651ee6
commit 429ba6ed06

View file

@ -707,17 +707,24 @@ fn call_successors<'a>(
call_symbol: Symbol, call_symbol: Symbol,
closures: &'a MutMap<Symbol, References>, closures: &'a MutMap<Symbol, References>,
) -> ImSet<Symbol> { ) -> ImSet<Symbol> {
// TODO (this comment should be moved to a GH issue) this may cause an infinite loop if 2 definitions reference each other; may need to track visited definitions! let mut answer = im_rc::hashset::HashSet::default();
match closures.get(&call_symbol) { let mut seen = MutSet::default();
Some(references) => { let mut queue = vec![call_symbol];
let mut answer = local_successors(&references, closures);
answer.insert(call_symbol.clone()); while let Some(symbol) = queue.pop() {
if seen.contains(&symbol) {
continue;
}
if let Some(references) = closures.get(&symbol) {
answer.extend(references.lookups.iter().copied());
queue.extend(references.calls.iter().copied());
seen.insert(symbol);
}
}
answer answer
}
None => ImSet::default(),
}
} }
pub fn references_from_local<'a, T>( pub fn references_from_local<'a, T>(