rapx/analysis/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::{
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 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}