rapx/check/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::core::{
13        alias_analysis::default::{AliasAnalyzer, MopFnAliasMap},
14        ownedheap_analysis::{OHAResultMap, OwnedHeapAnalysis, default::OwnedHeapAnalyzer},
15    },
16    utils::{scc::Scc, source::get_fn_name},
17};
18use graph::SafeDropGraph;
19use safedrop::*;
20
21use crate::analysis::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        rap_info!("================================");
36        rap_info!("Aliases found: {:?}", fn_map);
37
38        let mut heap = OwnedHeapAnalyzer::new(self.tcx);
39        heap.run();
40        let adt_owner = heap.get_all_items();
41
42        let mir_keys = self.tcx.mir_keys(());
43        for local_def_id in mir_keys {
44            query_safedrop(
45                self.tcx,
46                &fn_map,
47                local_def_id.to_def_id(),
48                adt_owner.clone(),
49            );
50        }
51    }
52}
53
54pub fn query_safedrop(tcx: TyCtxt, fn_map: &MopFnAliasMap, def_id: DefId, adt_owner: OHAResultMap) {
55    let fn_name = get_fn_name(tcx, def_id);
56    if fn_name
57        .as_ref()
58        .map_or(false, |s| s.contains("__raw_ptr_deref_dummy"))
59    {
60        return;
61    }
62    rap_trace!("query_safedrop: {:?}", fn_name);
63    /* filter const mir */
64
65    /* filter const mir */
66    if let Some(_other) = tcx.hir_body_const_context(def_id.expect_local()) {
67        return;
68    }
69    if tcx.is_mir_available(def_id) {
70        let mut safedrop_graph = SafeDropGraph::new(tcx, def_id, adt_owner);
71        rap_debug!("safedrop grah (raw): {}", safedrop_graph);
72        safedrop_graph.mop_graph.find_scc();
73        rap_debug!("safedrop graph (scc): {}", safedrop_graph);
74        safedrop_graph.check(0, fn_map);
75        if safedrop_graph.mop_graph.visit_times <= VISIT_LIMIT {
76            safedrop_graph.report_bugs();
77        }
78    }
79}