rapx/check/safedrop/
mod.rs1pub 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 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}