This commit is contained in:
committed by
Andrew Brown
parent
20c67f243e
commit
1e74d01111
@@ -1838,12 +1838,51 @@ impl<'a> Verifier<'a> {
|
|||||||
Ok(())
|
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<()> {
|
pub fn run(&self, errors: &mut VerifierErrors) -> VerifierStepResult<()> {
|
||||||
self.verify_global_values(errors)?;
|
self.verify_global_values(errors)?;
|
||||||
self.verify_heaps(errors)?;
|
self.verify_heaps(errors)?;
|
||||||
self.verify_tables(errors)?;
|
self.verify_tables(errors)?;
|
||||||
self.verify_jump_tables(errors)?;
|
self.verify_jump_tables(errors)?;
|
||||||
self.typecheck_entry_block_params(errors)?;
|
self.typecheck_entry_block_params(errors)?;
|
||||||
|
self.typecheck_function_signature(errors)?;
|
||||||
|
|
||||||
for ebb in self.func.layout.ebbs() {
|
for ebb in self.func.layout.ebbs() {
|
||||||
for inst in self.func.layout.ebb_insts(ebb) {
|
for inst in self.func.layout.ebb_insts(ebb) {
|
||||||
@@ -1870,7 +1909,7 @@ mod tests {
|
|||||||
use super::{Verifier, VerifierError, VerifierErrors};
|
use super::{Verifier, VerifierError, VerifierErrors};
|
||||||
use crate::entity::EntityList;
|
use crate::entity::EntityList;
|
||||||
use crate::ir::instructions::{InstructionData, Opcode};
|
use crate::ir::instructions::{InstructionData, Opcode};
|
||||||
use crate::ir::Function;
|
use crate::ir::{types, AbiParam, Function};
|
||||||
use crate::settings;
|
use crate::settings;
|
||||||
|
|
||||||
macro_rules! assert_err_with_msg {
|
macro_rules! assert_err_with_msg {
|
||||||
@@ -1929,4 +1968,30 @@ mod tests {
|
|||||||
|
|
||||||
assert_err_with_msg!(errors, "instruction format");
|
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