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