rapx/check/safedrop/
alias.rs

1use 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}