From 61d91ebee1ac3dafa8a25ed7e156197e860e6d70 Mon Sep 17 00:00:00 2001 From: teoxoy <28601907+teoxoy@users.noreply.github.com> Date: Wed, 11 Oct 2023 14:07:20 +0200 Subject: [PATCH] [valid] check local variable initializer is const --- src/lib.rs | 8 +++++++- src/valid/function.rs | 13 ++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 80461e16ff..9d70190421 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -978,7 +978,13 @@ pub struct LocalVariable { pub name: Option, /// The type of this variable. pub ty: Handle, - /// 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>, } diff --git a/src/valid/function.rs b/src/valid/function.rs index a056a1d1f6..ca5877ba1e 100644 --- a/src/valid/function.rs +++ b/src/valid/function.rs @@ -58,6 +58,8 @@ pub enum LocalVariableError { InvalidType(Handle), #[error("Initializer doesn't match the variable type")] InitializerType, + #[error("Initializer is not const")] + NonConstInitializer, } #[derive(Clone, Debug, thiserror::Error)] @@ -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 @@ -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(()) @@ -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,