1
0
Fork 0
mirror of synced 2025-09-24 04:40:05 +00:00

div by zero

This commit is contained in:
dark64 2021-08-17 18:44:25 +02:00
parent 934d36078e
commit 6ea4cfbe84
2 changed files with 33 additions and 3 deletions

View file

@ -0,0 +1,3 @@
def main(field input) -> field:
field divisor = if true then 0 else 1 fi
return input / divisor

View file

@ -14,6 +14,7 @@ type Constants<'ast, T> = HashMap<Identifier<'ast>, ZirExpression<'ast, T>>;
#[derive(Debug, PartialEq)]
pub enum Error {
OutOfBounds(u128, u128),
DivisionByZero,
}
impl fmt::Display for Error {
@ -24,6 +25,9 @@ impl fmt::Display for Error {
"Out of bounds index ({} >= {}) found in zir during static analysis",
index, size
),
Error::DivisionByZero => {
write!(f, "Division by zero detected in zir during static analysis",)
}
}
}
}
@ -105,7 +109,7 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ZirPropagator<'ast, T> {
UExpressionInner::Value(v) => e
.get(v as usize)
.cloned()
.ok_or(Error::OutOfBounds(v, e.len() as u128)),
.ok_or_else(|| Error::OutOfBounds(v, e.len() as u128)),
i => Ok(FieldElementExpression::Select(
e,
box i.annotate(UBitwidth::B32),
@ -169,6 +173,9 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ZirPropagator<'ast, T> {
self.fold_field_expression(e1)?,
self.fold_field_expression(e2)?,
) {
(_, FieldElementExpression::Number(n)) if n == T::from(0) => {
Err(Error::DivisionByZero)
}
(e, FieldElementExpression::Number(n)) if n == T::from(1) => Ok(e),
(FieldElementExpression::Number(n1), FieldElementExpression::Number(n2)) => {
Ok(FieldElementExpression::Number(n1 / n2))
@ -234,7 +241,7 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ZirPropagator<'ast, T> {
UExpressionInner::Value(v) => e
.get(*v as usize)
.cloned()
.ok_or(Error::OutOfBounds(*v, e.len() as u128)),
.ok_or_else(|| Error::OutOfBounds(*v, e.len() as u128)),
_ => Ok(BooleanExpression::Select(e, box index)),
}
}
@ -453,7 +460,7 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ZirPropagator<'ast, T> {
UExpressionInner::Value(v) => e
.get(v as usize)
.cloned()
.ok_or(Error::OutOfBounds(v, e.len() as u128))
.ok_or_else(|| Error::OutOfBounds(v, e.len() as u128))
.map(|e| e.into_inner()),
i => Ok(UExpressionInner::Select(e, box i.annotate(bitwidth))),
}
@ -513,6 +520,7 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ZirPropagator<'ast, T> {
let e2 = self.fold_uint_expression(e2)?;
match (e1.into_inner(), e2.into_inner()) {
(_, UExpressionInner::Value(n)) if n == 0 => Err(Error::DivisionByZero),
(e, UExpressionInner::Value(n)) if n == 1 => Ok(e),
(UExpressionInner::Value(n1), UExpressionInner::Value(n2)) => Ok(
UExpressionInner::Value((n1 / n2) % 2_u128.pow(bitwidth.to_usize() as u32)),
@ -806,6 +814,14 @@ mod tests {
)),
Ok(FieldElementExpression::Identifier("a".into()))
);
assert_eq!(
propagator.fold_field_expression(FieldElementExpression::Div(
box FieldElementExpression::Identifier("a".into()),
box FieldElementExpression::Number(Bn128Field::from(0)),
)),
Err(Error::DivisionByZero)
);
}
#[test]
@ -1402,6 +1418,17 @@ mod tests {
),
Ok(UExpressionInner::Identifier("a".into()))
);
assert_eq!(
propagator.fold_uint_expression_inner(
UBitwidth::B32,
UExpressionInner::Div(
box UExpressionInner::Identifier("a".into()).annotate(UBitwidth::B32),
box UExpressionInner::Value(0).annotate(UBitwidth::B32),
)
),
Err(Error::DivisionByZero)
);
}
#[test]