Skip to content

Commit

Permalink
[valid] check local variable initializer is const
Browse files Browse the repository at this point in the history
  • Loading branch information
teoxoy authored and jimblandy committed Oct 12, 2023
1 parent a0e0242 commit 61d91eb
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 2 deletions.
8 changes: 7 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -978,7 +978,13 @@ pub struct LocalVariable {
pub name: Option<String>,
/// The type of this variable.
pub ty: Handle<Type>,
/// Initial value for this variable. Must be a const-expression.
/// Initial value for this variable.
///
/// This handle refers to this `LocalVariable`'s function's
/// [`expressions`] arena, but it is required to be an evaluated
/// constant expression.
///
/// [`expressions`]: Function::expressions
pub init: Option<Handle<Expression>>,
}

Expand Down
13 changes: 12 additions & 1 deletion src/valid/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ pub enum LocalVariableError {
InvalidType(Handle<crate::Type>),
#[error("Initializer doesn't match the variable type")]
InitializerType,
#[error("Initializer is not const")]
NonConstInitializer,
}

#[derive(Clone, Debug, thiserror::Error)]
Expand Down Expand Up @@ -942,6 +944,7 @@ impl super::Validator {
var: &crate::LocalVariable,
gctx: crate::proc::GlobalCtx,
fun_info: &FunctionInfo,
expression_constness: &crate::proc::ExpressionConstnessTracker,
) -> Result<(), LocalVariableError> {
log::debug!("var {:?}", var);
let type_info = self
Expand All @@ -958,6 +961,10 @@ impl super::Validator {
if !decl_ty.equivalent(init_ty, gctx.types) {
return Err(LocalVariableError::InitializerType);
}

if !expression_constness.is_const(init) {
return Err(LocalVariableError::NonConstInitializer);
}
}

Ok(())
Expand All @@ -973,9 +980,13 @@ impl super::Validator {
#[cfg_attr(not(feature = "validate"), allow(unused_mut))]
let mut info = mod_info.process_function(fun, module, self.flags, self.capabilities)?;

#[cfg(feature = "validate")]
let expression_constness =
crate::proc::ExpressionConstnessTracker::from_arena(&fun.expressions);

#[cfg(feature = "validate")]
for (var_handle, var) in fun.local_variables.iter() {
self.validate_local_var(var, module.to_ctx(), &info)
self.validate_local_var(var, module.to_ctx(), &info, &expression_constness)
.map_err(|source| {
FunctionError::LocalVariable {
handle: var_handle,
Expand Down

0 comments on commit 61d91eb

Please sign in to comment.