rapx/check/safedrop/
drop.rs1use super::checks;
2use super::graph::*;
3
4#[derive(Debug, Copy, Clone, PartialEq, Eq)]
5pub struct LocalSpot {
6 pub bb: Option<usize>,
7 pub local: Option<usize>,
8}
9
10impl LocalSpot {
11 pub fn new(bb: usize, local: usize) -> Self {
12 LocalSpot {
13 bb: Some(bb),
14 local: Some(local),
15 }
16 }
17 pub fn from_local(local: usize) -> Self {
18 LocalSpot {
19 bb: None,
20 local: Some(local),
21 }
22 }
23 pub fn default() -> Self {
24 LocalSpot {
25 bb: None,
26 local: None,
27 }
28 }
29}
30
31#[derive(Debug, Clone)]
32pub struct DropRecord {
33 pub value_index: usize,
34 pub is_dropped: bool,
35 pub drop_spot: LocalSpot,
36 pub prop_chain: Vec<usize>,
37 pub has_dropped_field: bool,
38}
39
40impl DropRecord {
41 pub fn new(value_index: usize, is_dropped: bool, drop_spot: LocalSpot) -> Self {
42 DropRecord {
43 value_index,
44 is_dropped,
45 drop_spot,
46 prop_chain: Vec::new(),
47 has_dropped_field: false,
48 }
49 }
50 pub fn false_record(value_index: usize) -> Self {
51 DropRecord {
52 value_index,
53 is_dropped: false,
54 drop_spot: LocalSpot::default(),
55 prop_chain: Vec::new(),
56 has_dropped_field: false,
57 }
58 }
59 pub fn from(value_index: usize, record: &DropRecord) -> Self {
60 DropRecord {
61 value_index,
62 is_dropped: record.is_dropped,
63 drop_spot: record.drop_spot.clone(),
64 prop_chain: record.prop_chain.clone(),
65 has_dropped_field: record.has_dropped_field,
66 }
67 }
68 pub fn clear(&mut self) {
69 self.is_dropped = false;
70 self.drop_spot = LocalSpot::default();
71 self.prop_chain.clear();
72 self.has_dropped_field = false;
73 }
74}
75
76impl<'tcx> SafeDropGraph<'tcx> {
77 pub fn add_to_drop_record(
82 &mut self,
83 value_idx: usize, bb_idx: usize, flag_cleanup: bool,
86 ) {
87 rap_debug!(
88 "add_to_drop_record: value_idx = {}, bb_idx = {}",
89 value_idx,
90 bb_idx
91 );
92 if self.alias_graph.value_to_slot_idx(value_idx)
93 .map_or(false, |si| self.alias_graph.pts_graph.slot_is_ref_count(si)) {
94 return;
95 }
96 if self.df_check(value_idx, bb_idx, self.alias_graph.span(), flag_cleanup) {
97 return;
98 }
99 if !self.drop_record[value_idx].is_dropped {
100 let local = self.alias_graph.value_to_slot_idx(value_idx)
101 .and_then(|si| self.alias_graph.pts_graph.get_slot(si))
102 .map(|s| s.local)
103 .unwrap_or(value_idx);
104 let drop_spot = LocalSpot::new(bb_idx, local);
105 self.drop_record[value_idx] = DropRecord::new(value_idx, true, drop_spot);
106 rap_debug!("{:?}", self.drop_record[value_idx]);
107 checks::push_drop_info(&self.alias_graph, &mut self.drop_record, value_idx, drop_spot);
108 }
109 }
110}