This commit is contained in:
committed by
Andrew Brown
parent
20c67f243e
commit
1e74d01111
@@ -1838,12 +1838,51 @@ impl<'a> Verifier<'a> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn typecheck_function_signature(&self, errors: &mut VerifierErrors) -> VerifierStepResult<()> {
|
||||
self.func
|
||||
.signature
|
||||
.params
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|(_, ¶m)| param.value_type == types::INVALID)
|
||||
.for_each(|(i, _)| {
|
||||
report!(
|
||||
errors,
|
||||
AnyEntity::Function,
|
||||
"Parameter at position {} has an invalid type",
|
||||
i
|
||||
);
|
||||
});
|
||||
|
||||
self.func
|
||||
.signature
|
||||
.returns
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|(_, &ret)| ret.value_type == types::INVALID)
|
||||
.for_each(|(i, _)| {
|
||||
report!(
|
||||
errors,
|
||||
AnyEntity::Function,
|
||||
"Return value at position {} has an invalid type",
|
||||
i
|
||||
)
|
||||
});
|
||||
|
||||
if errors.has_error() {
|
||||
Err(())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run(&self, errors: &mut VerifierErrors) -> VerifierStepResult<()> {
|
||||
self.verify_global_values(errors)?;
|
||||
self.verify_heaps(errors)?;
|
||||
self.verify_tables(errors)?;
|
||||
self.verify_jump_tables(errors)?;
|
||||
self.typecheck_entry_block_params(errors)?;
|
||||
self.typecheck_function_signature(errors)?;
|
||||
|
||||
for ebb in self.func.layout.ebbs() {
|
||||
for inst in self.func.layout.ebb_insts(ebb) {
|
||||
@@ -1870,7 +1909,7 @@ mod tests {
|
||||
use super::{Verifier, VerifierError, VerifierErrors};
|
||||
use crate::entity::EntityList;
|
||||
use crate::ir::instructions::{InstructionData, Opcode};
|
||||
use crate::ir::Function;
|
||||
use crate::ir::{types, AbiParam, Function};
|
||||
use crate::settings;
|
||||
|
||||
macro_rules! assert_err_with_msg {
|
||||
@@ -1929,4 +1968,30 @@ mod tests {
|
||||
|
||||
assert_err_with_msg!(errors, "instruction format");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_function_invalid_param() {
|
||||
let mut func = Function::new();
|
||||
func.signature.params.push(AbiParam::new(types::INVALID));
|
||||
|
||||
let mut errors = VerifierErrors::default();
|
||||
let flags = &settings::Flags::new(settings::builder());
|
||||
let verifier = Verifier::new(&func, flags.into());
|
||||
|
||||
let _ = verifier.typecheck_function_signature(&mut errors);
|
||||
assert_err_with_msg!(errors, "Parameter at position 0 has an invalid type");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_function_invalid_return_value() {
|
||||
let mut func = Function::new();
|
||||
func.signature.returns.push(AbiParam::new(types::INVALID));
|
||||
|
||||
let mut errors = VerifierErrors::default();
|
||||
let flags = &settings::Flags::new(settings::builder());
|
||||
let verifier = Verifier::new(&func, flags.into());
|
||||
|
||||
let _ = verifier.typecheck_function_signature(&mut errors);
|
||||
assert_err_with_msg!(errors, "Return value at position 0 has an invalid type");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user