typifier: check local vars, global vars, and function arguments to exist

This commit is contained in:
Dzmitry Malyshau
2022-01-13 14:15:22 -05:00
parent 003ea29a3a
commit a4ea9ce68d
3 changed files with 25 additions and 13 deletions

View File

@@ -189,10 +189,14 @@ pub enum ResolveError {
FunctionNotDefined { name: String },
#[error("Function without return type")]
FunctionReturnsVoid,
#[error("Type is not found in the given immutable arena")]
TypeNotFound,
#[error("Incompatible operands: {0}")]
IncompatibleOperands(String),
#[error("Local var {0:?} doesn't exist")]
LocalVariableNotFound(Handle<crate::LocalVariable>),
#[error("Global var {0:?} doesn't exist")]
GlobalVariableNotFound(Handle<crate::GlobalVariable>),
#[error("Function argument {0} doesn't exist")]
FunctionArgumentNotFound(u32),
}
pub struct ResolveContext<'a> {
@@ -430,10 +434,17 @@ impl<'a> ResolveContext<'a> {
},
crate::Expression::Compose { ty, .. } => TypeResolution::Handle(ty),
crate::Expression::FunctionArgument(index) => {
TypeResolution::Handle(self.arguments[index as usize].ty)
let arg = self
.arguments
.get(index as usize)
.ok_or(ResolveError::FunctionArgumentNotFound(index))?;
TypeResolution::Handle(arg.ty)
}
crate::Expression::GlobalVariable(h) => {
let var = &self.global_vars[h];
let var = self
.global_vars
.try_get(h)
.ok_or(ResolveError::GlobalVariableNotFound(h))?;
if var.class == crate::StorageClass::Handle {
TypeResolution::Handle(var.ty)
} else {
@@ -444,7 +455,10 @@ impl<'a> ResolveContext<'a> {
}
}
crate::Expression::LocalVariable(h) => {
let var = &self.local_vars[h];
let var = self
.local_vars
.try_get(h)
.ok_or(ResolveError::LocalVariableNotFound(h))?;
TypeResolution::Value(Ti::Pointer {
base: var.ty,
class: crate::StorageClass::Function,

View File

@@ -819,13 +819,7 @@ impl super::Validator {
module: &crate::Module,
mod_info: &ModuleInfo,
) -> Result<FunctionInfo, WithSpan<FunctionError>> {
#[cfg(feature = "validate")]
let mut info = mod_info
.process_function(fun, module, self.flags)
.map_err(WithSpan::into_other)?;
#[cfg(not(feature = "validate"))]
let info = mod_info.process_function(fun, module, self.flags)?;
let mut info = mod_info.process_function(fun, module, self.flags)?;
#[cfg(feature = "validate")]
for (var_handle, var) in fun.local_variables.iter() {

View File

@@ -240,7 +240,11 @@ impl Validator {
}
}
crate::ConstantInner::Composite { ty, ref components } => {
match types.get_handle(ty).ok_or(ConstantError::InvalidType)?.inner {
match types
.get_handle(ty)
.ok_or(ConstantError::InvalidType)?
.inner
{
crate::TypeInner::Array {
size: crate::ArraySize::Constant(size_handle),
..