Skip to main content

rapx/check/opt/data_collection/initialization/
vec_init.rs

1use annotate_snippets::Level;
2
3use rustc_middle::ty::TyCtxt;
4use rustc_span::Span;
5
6use crate::{analysis::dataflow::*, check::opt::OptCheck};
7
8use crate::check::opt::report::OptReport;
9
10crate::def_paths! {
11    vec_from_elem: "std::vec::from_elem",
12}
13
14pub struct VecInitCheck {
15    record: Vec<Span>,
16}
17
18impl OptCheck for VecInitCheck {
19    fn new() -> Self {
20        Self { record: Vec::new() }
21    }
22
23    fn check(&mut self, graph: &Graph, tcx: &TyCtxt) {
24        let def_paths = &DEFPATHS.get_or_init(|| DefPaths::new(tcx));
25        for node in graph.nodes.iter() {
26            for op in node.ops.iter() {
27                if let NodeOp::Call(def_id) = op {
28                    if *def_id == def_paths.vec_from_elem.last_def_id() {
29                        self.record.push(node.span);
30                    }
31                }
32            }
33        }
34    }
35
36    fn report(&self, graph: &Graph) {
37        for span in self.record.iter() {
38            report_vec_init(graph, *span);
39        }
40    }
41
42    fn cnt(&self) -> usize {
43        self.record.len()
44    }
45}
46
47fn report_vec_init(graph: &Graph, span: Span) {
48    OptReport::from_graph(graph)
49        .file_name(span)
50        .title("Unnecessary data collection initialization detected")
51        .annotate(Level::Error, span, "Initialization happens here")
52        .footer("Use unsafe APIs to skip initialization.")
53        .emit();
54}