rapx 0.7.31

A static analysis platform for Rust program analysis and verification
use rustc_hir::def_id::DefId;

use std::collections::HashSet;

use crate::analysis::alias::observer::NoopAliasObserver;
use crate::analysis::path::{PathNode, PathTree};

use super::alias::ensure_fn_aliases_cached;
use super::{graph::*, *};

impl<'tcx> AliasGraph<'tcx> {
    pub fn process_function_paths(
        &mut self,
        fn_map: &mut MopFnAliasMap,
        recursion_set: &mut HashSet<DefId>,
    ) {
        self.process_function_paths_opt(None, fn_map, recursion_set)
    }

    pub fn process_function_paths_opt(
        &mut self,
        precomputed_paths: Option<PathTree>,
        fn_map: &mut MopFnAliasMap,
        recursion_set: &mut HashSet<DefId>,
    ) {
        self.init_pts_graph();

        let paths = precomputed_paths.unwrap_or_else(|| self.enumerate_paths());
        let Some(root) = paths.root() else { return; };

        let mut path = Vec::new();
        let _ = self.dfs_mop(root, &mut path, fn_map, recursion_set);
    }

    fn dfs_mop(
        &mut self,
        node: &PathNode,
        path: &mut Vec<usize>,
        fn_map: &mut MopFnAliasMap,
        rec_set: &mut HashSet<DefId>,
    ) -> Result<(), ()> {
        path.push(node.block);
        let mut obs = NoopAliasObserver;

        self.alias_bb_pts(node.block, &mut obs);
        if let Some(target_id) = self.call_target_of(node.block) {
            ensure_fn_aliases_cached(self.tcx(), target_id, fn_map, rec_set);
        }
        self.alias_bbcall_pts(node.block, fn_map, &mut obs);

        let saved_pts_graph = self.pts_graph.clone();
        let saved_rec = rec_set.clone();

        if node.is_path_end {
            self.increment_visit_times();
            if self.visit_times() > VISIT_LIMIT {
                path.pop();
                return Err(());
            }
            self.merge_results_pts();
        }

        for child in &node.children {
            self.pts_graph = saved_pts_graph.clone();
            *rec_set = saved_rec.clone();
            self.dfs_mop(child, path, fn_map, rec_set)?;
        }

        path.pop();
        Ok(())
    }
}