rapx/check/safedrop/
alias.rs1use rustc_middle::{
2 mir::{Operand, TerminatorKind},
3 ty::{self},
4};
5
6use super::graph::*;
7use crate::analysis::alias_analysis::default::{MopFnAliasMap, alias::is_no_alias_intrinsic};
8
9impl<'tcx> SafeDropGraph<'tcx> {
10 pub fn alias_bb(&mut self, bb_index: usize) {
11 for constant in self.alias_graph.block_facts[bb_index].const_value.clone() {
12 self.alias_graph
13 .constants
14 .insert(constant.local, constant.value);
15 }
16 let block_facts = self.alias_graph.block_facts[bb_index].clone();
17 for assign in block_facts.assignments {
18 let lv_idx = self.alias_graph.projection(assign.lv);
19 let rv_idx = self.alias_graph.projection(assign.rv);
20 self.sync_drop_record();
21 self.uaf_check(rv_idx, bb_index, assign.span, false);
22 self.alias_graph.assign_alias(lv_idx, rv_idx);
23 self.sync_drop_record();
24 self.clear_drop_info(lv_idx);
25
26 rap_debug!("Alias sets: {:?}", self.alias_graph.alias_sets.clone());
27 }
28 }
29
30 pub fn alias_bbcall(&mut self, bb_index: usize, fn_map: &MopFnAliasMap) {
31 if let Some(terminator) = self.alias_graph.terminator(bb_index).cloned() {
32 if let TerminatorKind::Call {
33 func: Operand::Constant(ref constant),
34 ref args,
35 ref destination,
36 target: _,
37 unwind: _,
38 call_source: _,
39 fn_span: _,
40 } = terminator.kind
41 {
42 rap_debug!("alias_bbcall in {:?}: {:?}", bb_index, terminator);
43 let lv = self.alias_graph.projection(destination.clone());
44 self.sync_drop_record();
45 let mut merge_vec = Vec::new();
46 merge_vec.push(lv);
47 let mut may_drop_flag = 0;
48 if self.alias_graph.values[lv].may_drop {
49 may_drop_flag += 1;
50 }
51 for arg in args {
52 match arg.node {
53 Operand::Copy(ref p) | Operand::Move(ref p) => {
54 let rv = self.alias_graph.projection(p.clone());
55 self.sync_drop_record();
56 self.uaf_check(rv, bb_index, terminator.source_info.span, true);
57 merge_vec.push(rv);
58 if self.alias_graph.values[rv].may_drop {
59 may_drop_flag += 1;
60 }
61 }
62 Operand::Constant(_) => {
63 merge_vec.push(0);
64 }
65 #[cfg(rapx_rustc_ge_196)]
66 Operand::RuntimeChecks(_) => {}
67 }
68 }
69 if let ty::FnDef(target_id, _) = constant.const_.ty().kind() {
70 if may_drop_flag > 1 {
71 if is_no_alias_intrinsic(*target_id) {
72 return;
73 }
74 if self.alias_graph.tcx().is_mir_available(*target_id) {
75 rap_debug!("fn_map: {:?}", fn_map);
76 if fn_map.contains_key(&target_id) {
77 let fn_aliases = fn_map.get(&target_id).unwrap();
78 rap_debug!("aliases of the fn: {:?}", fn_aliases);
79 if fn_aliases.aliases().is_empty() {
80 if let Some(l_set_idx) = self.alias_graph.find_alias_set(lv) {
81 self.alias_graph.alias_sets[l_set_idx].remove(&lv);
82 }
83 }
84 for alias in fn_aliases.aliases().iter() {
85 if !alias.valuable() {
86 continue;
87 }
88 self.alias_graph.handle_fn_alias(alias, &merge_vec);
89 self.sync_drop_record();
90 }
91 }
92 } else {
93 if self.alias_graph.values[lv].may_drop {
94 for rv in &merge_vec {
95 if self.alias_graph.values[*rv].may_drop
96 && lv != *rv
97 && self.alias_graph.values[lv].is_ptr()
98 {
99 self.alias_graph.merge_alias(lv, *rv);
100 self.sync_drop_record();
101 self.clear_drop_info(lv);
102 }
103 }
104 }
105 }
106 }
107 }
108 }
109 }
110 }
111}