rapx/analysis/safedrop/
mod.rs

1pub mod alias;
2pub mod bug_records;
3pub mod check_bugs;
4pub mod corner_handle;
5pub mod graph;
6pub mod safedrop;
7
8use rustc_hir::def_id::DefId;
9use rustc_middle::ty::TyCtxt;
10
11use crate::analysis::{
12    core::{
13        alias_analysis::default::{AliasAnalyzer, MopAAResultMap},
14        ownedheap_analysis::{OHAResultMap, OwnedHeapAnalysis, default::OwnedHeapAnalyzer},
15    },
16    graphs::scc::Scc,
17};
18use graph::SafeDropGraph;
19use safedrop::*;
20
21use super::Analysis;
22
23pub struct SafeDrop<'tcx> {
24    pub tcx: TyCtxt<'tcx>,
25}
26
27impl<'tcx> SafeDrop<'tcx> {
28    pub fn new(tcx: TyCtxt<'tcx>) -> Self {
29        Self { tcx }
30    }
31    pub fn start(&self) {
32        let mut mop = AliasAnalyzer::new(self.tcx);
33        mop.run();
34        let fn_map = mop.get_all_fn_alias_raw();
35
36        let mut heap = OwnedHeapAnalyzer::new(self.tcx);
37        heap.run();
38        let adt_owner = heap.get_all_items();
39
40        let mir_keys = self.tcx.mir_keys(());
41        for local_def_id in mir_keys {
42            query_safedrop(
43                self.tcx,
44                &fn_map,
45                local_def_id.to_def_id(),
46                adt_owner.clone(),
47            );
48        }
49    }
50}
51
52pub fn query_safedrop(
53    tcx: TyCtxt,
54    fn_map: &MopAAResultMap,
55    def_id: DefId,
56    adt_owner: OHAResultMap,
57) {
58    /* filter const mir */
59    if let Some(_other) = tcx.hir_body_const_context(def_id.expect_local()) {
60        return;
61    }
62    if tcx.is_mir_available(def_id) {
63        let mut safedrop_graph = SafeDropGraph::new(tcx, def_id, adt_owner);
64        rap_debug!("safedrop grah (raw): {}", safedrop_graph);
65        safedrop_graph.mop_graph.find_scc();
66        rap_debug!("safedrop graph (scc): {}", safedrop_graph);
67        safedrop_graph.check(0, tcx, fn_map);
68        if safedrop_graph.mop_graph.visit_times <= VISIT_LIMIT {
69            safedrop_graph.report_bugs();
70        }
71    }
72}