rapx/check/safedrop/
mod.rs1pub mod bug_records;
2pub mod checks;
3pub mod corner_case;
4pub mod drop;
5pub mod graph;
6pub mod observer;
7pub mod safedrop;
8
9use rustc_hir::def_id::DefId;
10use rustc_middle::ty::TyCtxt;
11
12use crate::{
13 analysis::{
14 alias::default::{AliasAnalyzer, MopFnAliasMap},
15 owned_heap::{OHAResultMap, OwnedHeapAnalysis, default::OwnedHeapAnalyzer},
16 path::default::PathAnalyzer,
17 },
18 utils::source::get_fn_name,
19};
20use graph::SafeDropGraph;
21use safedrop::*;
22
23use crate::analysis::Analysis;
24
25pub struct SafeDrop<'tcx> {
26 pub tcx: TyCtxt<'tcx>,
27}
28
29impl<'tcx> SafeDrop<'tcx> {
30 pub fn new(tcx: TyCtxt<'tcx>) -> Self {
31 Self { tcx }
32 }
33 pub fn start(&self) {
34 let mut mop = AliasAnalyzer::new(self.tcx);
35 mop.run();
36 let fn_map = mop.get_all_fn_alias_raw();
37 let path_analyzer = mop.take_path_analyzer();
38 rap_info!("================================");
39 rap_debug!("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 &path_analyzer,
53 );
54 }
55 }
56}
57
58pub fn query_safedrop<'tcx>(
59 tcx: TyCtxt<'tcx>,
60 fn_map: &MopFnAliasMap,
61 def_id: DefId,
62 adt_owner: OHAResultMap,
63 path_analyzer: &PathAnalyzer<'tcx>,
64) {
65 let fn_name = get_fn_name(tcx, def_id);
66 if fn_name
67 .as_ref()
68 .map_or(false, |s| s.contains("__raw_ptr_deref_dummy"))
69 {
70 return;
71 }
72 rap_trace!("query_safedrop: {:?}", fn_name);
73 if let Some(_other) = tcx.hir_body_const_context(def_id.expect_local()) {
75 return;
76 }
77 if tcx.is_mir_available(def_id) {
78 let paths = path_analyzer.get_fn_paths(def_id);
79 let path_graph = path_analyzer
80 .graphs
81 .get(&def_id)
82 .cloned()
83 .unwrap_or_else(|| {
84 let mut g = crate::analysis::path::graph::PathGraph::new(tcx, def_id);
85 g.find_scc();
86 g
87 });
88 let mut safedrop_graph = SafeDropGraph::from_path_graph(tcx, def_id, path_graph, adt_owner);
89 rap_debug!("safedrop grah (raw): {}", safedrop_graph);
90 safedrop_graph.alias_graph.path_graph.find_scc();
91 rap_debug!("safedrop graph (scc): {}", safedrop_graph);
92 safedrop_graph.process_function_paths_opt(paths, fn_map);
93 let visit_times = safedrop_graph.alias_graph.visit_times();
94 if visit_times <= VISIT_LIMIT {
95 safedrop_graph.report_bugs();
96 } else if !safedrop_graph.bug_records.is_bug_free() {
97 safedrop_graph.report_bugs();
98 }
99 }
100}