1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
use super::*;
use std::collections::BTreeMap;
impl AbstractObject {
/// Get all abstract IDs that the object may contain pointers to.
/// This yields an overapproximation of possible pointer targets.
pub fn get_referenced_ids_overapproximation(&self) -> &BTreeSet<AbstractIdentifier> {
&self.inner.pointer_targets
}
/// Get all abstract IDs for which the object contains pointers to.
/// This yields an underapproximation of pointer targets,
/// since the object may contain pointers that could not be tracked by the analysis.
pub fn get_referenced_ids_underapproximation(&self) -> BTreeSet<AbstractIdentifier> {
let mut referenced_ids = BTreeSet::new();
for data in self.inner.memory.values() {
referenced_ids.extend(data.referenced_ids().cloned())
}
referenced_ids
}
/// Remove the provided IDs from the target lists of all pointers in the memory object.
/// Also remove them from the pointer_targets list.
///
/// If this operation would produce an empty value, it replaces it with a `Top` value instead.
pub fn remove_ids(&mut self, ids_to_remove: &BTreeSet<AbstractIdentifier>) {
let inner = Arc::make_mut(&mut self.inner);
inner.pointer_targets = inner
.pointer_targets
.difference(ids_to_remove)
.cloned()
.collect();
for value in inner.memory.values_mut() {
value.remove_ids(ids_to_remove);
if value.is_empty() {
*value = value.top();
}
}
inner.memory.clear_top_values(); // In case the previous operation left *Top* values in the memory struct.
}
/// Replace all abstract IDs in `self` with the values given by the replacement map.
/// IDs not contained as keys in the replacement map are replaced by `Top` values.
pub fn replace_ids(&mut self, replacement_map: &BTreeMap<AbstractIdentifier, Data>) {
let inner = Arc::make_mut(&mut self.inner);
for elem in inner.memory.values_mut() {
elem.replace_all_ids(replacement_map);
}
inner.memory.clear_top_values();
let mut new_pointer_targets = BTreeSet::new();
for target in &inner.pointer_targets {
if let Some(replacement_value) = replacement_map.get(target) {
for new_target in replacement_value.referenced_ids() {
new_pointer_targets.insert(new_target.clone());
}
}
}
inner.pointer_targets = new_pointer_targets;
}
}