Skip to content

Commit

Permalink
fix(ssa refactor): Ignore array out of bounds errors when enable_side…
Browse files Browse the repository at this point in the history
…_effects is false (#1797)

* Fix im::Vector out of bounds error

* Merge master

* Use all zeroes as default value instead
  • Loading branch information
jfecher authored Jun 22, 2023
1 parent 2992915 commit 7b7682a
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,14 @@ impl AcirContext {
self.add_data(var_data)
}

/// True if the given AcirVar refers to a constant one value
pub(crate) fn is_constant_one(&self, var: &AcirVar) -> bool {
match self.vars[var] {
AcirVarData::Const(field) => field.is_one(),
_ => false,
}
}

/// Adds a new Variable to context whose value will
/// be constrained to be the negation of `var`.
///
Expand Down
31 changes: 30 additions & 1 deletion crates/noirc_evaluator/src/ssa_refactor/acir_gen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,18 @@ impl Context {
}

fn convert_ssa_block_param(&mut self, param_type: &Type) -> AcirValue {
self.create_value_from_type(param_type, |this, typ| this.add_numeric_input_var(&typ))
}

fn create_value_from_type(
&mut self,
param_type: &Type,
mut make_var: impl FnMut(&mut Self, NumericType) -> AcirVar,
) -> AcirValue {
match param_type {
Type::Numeric(numeric_type) => {
let typ = AcirType::new(*numeric_type);
AcirValue::Var(self.add_numeric_input_var(numeric_type), typ)
AcirValue::Var(make_var(self, *numeric_type), typ)
}
Type::Array(element_types, length) => {
let mut elements = im::Vector::new();
Expand Down Expand Up @@ -284,6 +292,20 @@ impl Context {
.try_to_u64()
.expect("Expected array index to fit into a u64") as usize;

if index >= array.len() {
// Ignore the error if side effects are disabled.
if let Some(var) = self.current_side_effects_enabled_var {
if self.acir_context.is_constant_one(&var) {
// TODO: Can we save a source Location for this error?
panic!("Index {} is out of bounds for array of length {}", index, array.len());
}
}
let result_type = dfg.type_of_value(dfg.instruction_results(instruction)[0]);
let value = self.create_default_value(&result_type);
self.define_result(dfg, instruction, value);
return;
}

let value = match store_value {
Some(store_value) => {
let store_value = self.convert_value(store_value, dfg);
Expand Down Expand Up @@ -680,6 +702,13 @@ impl Context {
}
}
}

/// Creates a default, meaningless value meant only to be a valid value of the given type.
fn create_default_value(&mut self, param_type: &Type) -> AcirValue {
self.create_value_from_type(param_type, |this, _| {
this.acir_context.add_constant(FieldElement::zero())
})
}
}

#[cfg(test)]
Expand Down

0 comments on commit 7b7682a

Please sign in to comment.