rapx/analysis/safedrop/
mod.rs

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