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