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::{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}