Skip to main content

rapx/analysis/alias/default/
mop.rs

1use rustc_hir::def_id::DefId;
2
3use std::collections::HashSet;
4
5use crate::analysis::alias::observer::NoopAliasObserver;
6use crate::analysis::path::{PathNode, PathTree};
7
8use super::alias::ensure_fn_aliases_cached;
9use super::{graph::*, *};
10
11impl<'tcx> AliasGraph<'tcx> {
12    pub fn process_function_paths(
13        &mut self,
14        fn_map: &mut MopFnAliasMap,
15        recursion_set: &mut HashSet<DefId>,
16    ) {
17        self.process_function_paths_opt(None, fn_map, recursion_set)
18    }
19
20    pub fn process_function_paths_opt(
21        &mut self,
22        precomputed_paths: Option<PathTree>,
23        fn_map: &mut MopFnAliasMap,
24        recursion_set: &mut HashSet<DefId>,
25    ) {
26        self.init_pts_graph();
27
28        let paths = precomputed_paths.unwrap_or_else(|| self.enumerate_paths());
29        let Some(root) = paths.root() else { return; };
30
31        let mut path = Vec::new();
32        let _ = self.dfs_mop(root, &mut path, fn_map, recursion_set);
33    }
34
35    fn dfs_mop(
36        &mut self,
37        node: &PathNode,
38        path: &mut Vec<usize>,
39        fn_map: &mut MopFnAliasMap,
40        rec_set: &mut HashSet<DefId>,
41    ) -> Result<(), ()> {
42        path.push(node.block);
43        let mut obs = NoopAliasObserver;
44
45        self.alias_bb(node.block, &mut obs);
46        if let Some(target_id) = self.call_target_of(node.block) {
47            ensure_fn_aliases_cached(self.tcx(), target_id, fn_map, rec_set);
48        }
49        self.alias_bbcall(node.block, fn_map, &mut obs);
50
51        let saved_pts_graph = self.pts_graph.clone();
52        let saved_rec = rec_set.clone();
53
54        if node.is_path_end {
55            self.increment_visit_times();
56            if self.visit_times() > VISIT_LIMIT {
57                path.pop();
58                return Err(());
59            }
60            self.merge_results_pts();
61        }
62
63        for child in &node.children {
64            self.pts_graph = saved_pts_graph.clone();
65            *rec_set = saved_rec.clone();
66            self.dfs_mop(child, path, fn_map, rec_set)?;
67        }
68
69        path.pop();
70        Ok(())
71    }
72}