Skip to content

Commit 77b1f16

Browse files
committed
Add extra error when compile-time integer is out of bounds of array
1 parent 7e29427 commit 77b1f16

File tree

4 files changed

+1562
-0
lines changed

4 files changed

+1562
-0
lines changed

src/instantiation/final_checks.rs

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//! After instantiation, we preform a few final checks of each module.
2+
3+
use num::BigInt;
4+
5+
use crate::{typing::concrete_type::ConcreteType, value::Value};
6+
7+
use super::{InstantiationContext, RealWireDataSource, RealWirePathElem};
8+
impl InstantiationContext<'_, '_> {
9+
fn check_array_accesses_in(&self, path: &[RealWirePathElem], mut arr_typ: &ConcreteType) {
10+
for elem in path {
11+
match elem {
12+
RealWirePathElem::ArrayAccess { span, idx_wire } => {
13+
let ConcreteType::Array(arr) = arr_typ else {
14+
break;
15+
}; // May still contain unknowns
16+
let ConcreteType::Value(Value::Integer(arr_sz)) = &arr.1 else {
17+
break;
18+
}; // May still contain unknowns
19+
arr_typ = &arr.0;
20+
21+
let idx_wire_wire = &self.wires[*idx_wire];
22+
if let RealWireDataSource::Constant { value } = &idx_wire_wire.source {
23+
// Constant access into array! We can check.
24+
let integer_value = value.unwrap_integer();
25+
if integer_value >= arr_sz || integer_value < &BigInt::ZERO {
26+
self.errors
27+
.error(span.inner_span(), format!("Index out of bounds. Array is of size {arr_sz}, but the index is {integer_value}."));
28+
}
29+
}
30+
}
31+
}
32+
}
33+
}
34+
pub fn check_array_accesses(&self) {
35+
for (_id, w) in &self.wires {
36+
match &w.source {
37+
RealWireDataSource::Select { root, path } => {
38+
let from = &self.wires[*root];
39+
self.check_array_accesses_in(path, &from.typ);
40+
}
41+
RealWireDataSource::Multiplexer {
42+
is_state: _,
43+
sources,
44+
} => {
45+
for s in sources {
46+
self.check_array_accesses_in(&s.to_path, &w.typ);
47+
}
48+
}
49+
_ => {}
50+
}
51+
}
52+
}
53+
}

src/instantiation/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
mod concrete_typecheck;
22
mod execute;
3+
mod final_checks;
34
mod unique_names;
45

56
use unique_names::UniqueNames;
@@ -419,5 +420,8 @@ fn perform_instantiation(
419420
println!("Latency Counting {}", md.link_info.name);
420421
context.compute_latencies();
421422

423+
println!("Checking array accesses {}", md.link_info.name);
424+
context.check_array_accesses();
425+
422426
context.extract()
423427
}

0 commit comments

Comments
 (0)