pedant_core/ir/semantic/
function_summary.rs1use super::super::facts::DataFlowFact;
9use super::common::{FnContext, LockAcquisition};
10
11#[derive(Clone, Copy)]
17pub(super) struct FlowRange {
18 start: u32,
19 end: u32,
20}
21
22impl FlowRange {
23 pub(super) fn new(start: usize, end: usize) -> Self {
26 Self {
27 start: start as u32,
28 end: end as u32,
29 }
30 }
31
32 pub(super) fn slice<'a>(&self, flows: &'a [DataFlowFact]) -> &'a [DataFlowFact] {
34 &flows[self.start as usize..self.end as usize]
35 }
36}
37
38pub(super) struct FunctionSummaryData {
44 pub(super) lock_acquisitions: Box<[LockAcquisition]>,
45 pub(super) taint: FlowRange,
46 pub(super) quality: FlowRange,
47 pub(super) performance: FlowRange,
48 pub(super) concurrency: FlowRange,
49}
50
51pub(super) struct DetectorRanges {
53 taint: FlowRange,
54 quality: FlowRange,
55 performance: FlowRange,
56 concurrency: FlowRange,
57}
58
59impl DetectorRanges {
60 pub(super) fn into_summary(
62 self,
63 lock_acquisitions: Box<[LockAcquisition]>,
64 ) -> FunctionSummaryData {
65 FunctionSummaryData {
66 lock_acquisitions,
67 taint: self.taint,
68 quality: self.quality,
69 performance: self.performance,
70 concurrency: self.concurrency,
71 }
72 }
73}
74
75pub(super) fn run_detectors(
78 ctx: &FnContext<'_, '_>,
79 all_flows: &mut Vec<DataFlowFact>,
80) -> DetectorRanges {
81 let taint = super::taint::detect(ctx);
82 let quality = super::quality::detect(ctx);
83 let performance = super::perf::detect(ctx);
84 let concurrency = super::concurrency::detect(ctx);
85
86 DetectorRanges {
87 taint: append_flows(all_flows, taint),
88 quality: append_flows(all_flows, quality),
89 performance: append_flows(all_flows, performance),
90 concurrency: append_flows(all_flows, concurrency),
91 }
92}
93
94fn append_flows(all: &mut Vec<DataFlowFact>, facts: Box<[DataFlowFact]>) -> FlowRange {
95 let start = all.len();
96 all.extend(facts.into_vec());
97 FlowRange::new(start, all.len())
98}
99
100pub struct FunctionAnalysisSummary<'a> {
105 data: &'a FunctionSummaryData,
106 flows: &'a [DataFlowFact],
107}
108
109impl<'a> FunctionAnalysisSummary<'a> {
110 pub(super) fn new(data: &'a FunctionSummaryData, flows: &'a [DataFlowFact]) -> Self {
112 Self { data, flows }
113 }
114
115 pub fn quality_issues(&self) -> &[DataFlowFact] {
118 self.data.quality.slice(self.flows)
119 }
120
121 pub fn performance_issues(&self) -> &[DataFlowFact] {
124 self.data.performance.slice(self.flows)
125 }
126
127 pub fn concurrency_issues(&self) -> &[DataFlowFact] {
130 self.data.concurrency.slice(self.flows)
131 }
132
133 pub fn taint_flows(&self) -> &[DataFlowFact] {
135 self.data.taint.slice(self.flows)
136 }
137}