Skip to content

Commit

Permalink
Reject constant/initializer cycles in handle validation.
Browse files Browse the repository at this point in the history
  • Loading branch information
jimblandy committed Jul 4, 2023
1 parent df3cbf1 commit 51af0f6
Showing 1 changed file with 49 additions and 0 deletions.
49 changes: 49 additions & 0 deletions src/valid/handles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ impl super::Validator {
crate::Expression::Literal(_) => {}
crate::Expression::Constant(constant) => {
validate_constant(constant)?;
handle.check_dep(constants[constant].init)?;
}
crate::Expression::ZeroValue(ty) => {
validate_type(ty)?;
Expand Down Expand Up @@ -661,3 +662,51 @@ impl<T> crate::arena::Range<T> {
arena.check_contains_range(self)
}
}

#[test]
#[cfg(feature = "validate")]
fn constant_deps() {
use crate::{Constant, Expression, Literal, Span, Type, TypeInner};

let nowhere = Span::default();

let mut types = UniqueArena::new();
let mut const_exprs = Arena::new();
let mut fun_exprs = Arena::new();
let mut constants = Arena::new();

let i32_handle = types.insert(
Type {
name: None,
inner: TypeInner::Scalar {
kind: crate::ScalarKind::Sint,
width: 4,
},
},
nowhere,
);

// Construct a self-referential constant by misusing a handle to
// fun_exprs as a constant initializer.
let fun_expr = fun_exprs.append(Expression::Literal(Literal::I32(42)), nowhere);
let self_referential_const = constants.append(
Constant {
name: None,
r#override: crate::Override::None,
ty: i32_handle,
init: fun_expr,
},
nowhere,
);
let _self_referential_expr =
const_exprs.append(Expression::Constant(self_referential_const), nowhere);

for handle_and_expr in const_exprs.iter() {
assert!(super::Validator::validate_const_expression_handles(
handle_and_expr,
&constants,
&types,
)
.is_err());
}
}

0 comments on commit 51af0f6

Please sign in to comment.