From 52acbf85f575889289e087a60fec98137fe60744 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Sun, 13 Oct 2024 16:57:11 +0200 Subject: [PATCH] Add test for NonEmpty block pass --- crates/verifier/src/pass.rs | 2 +- crates/verifier/src/passes/block/non_empty.rs | 79 +++++++++++++++++++ 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/crates/verifier/src/pass.rs b/crates/verifier/src/pass.rs index 84bfe89..24270ba 100644 --- a/crates/verifier/src/pass.rs +++ b/crates/verifier/src/pass.rs @@ -6,7 +6,7 @@ pub trait VerificationPass { fn run(&mut self, ctx: &mut VerificationCtx) -> VerificationResult; } -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] pub enum VerificationResult { Pass, Fail, diff --git a/crates/verifier/src/passes/block/non_empty.rs b/crates/verifier/src/passes/block/non_empty.rs index de66f50..41dace8 100644 --- a/crates/verifier/src/passes/block/non_empty.rs +++ b/crates/verifier/src/passes/block/non_empty.rs @@ -31,3 +31,82 @@ impl VerificationPass for NonEmpty { VerificationResult::Pass } } + +#[cfg(test)] +mod tests { + use std::fmt::Write; + + use sonatina_ir::{ + builder::test_util::test_func_builder, + inst::control_flow::{Jump, Return}, + isa::Isa, + Type, + }; + + use super::*; + + #[test] + fn non_empty_block() { + let (evm, mut builder) = test_func_builder(&[], Type::Unit); + let is = evm.inst_set(); + + let b0 = builder.append_block(); + let _b1 = builder.append_block(); // empty + let b2 = builder.append_block(); + let b3 = builder.append_block(); + let _b4 = builder.append_block(); // empty + let _b5 = builder.append_block(); // empty + let b6 = builder.append_block(); + + builder.switch_to_block(b0); + builder.insert_inst_no_result_with(|| Jump::new(is, b2)); + + builder.switch_to_block(b2); + builder.insert_inst_no_result_with(|| Jump::new(is, b3)); + + builder.switch_to_block(b3); + builder.insert_inst_no_result_with(|| Jump::new(is, b6)); + + builder.switch_to_block(b6); + builder.insert_inst_no_result_with(|| Return::new(is, None)); + + builder.seal_all(); + + let module = builder.finish().build(); + let func_ref = module.iter_functions().next().unwrap(); + let func = &module.funcs[func_ref]; + + let mut ctx = VerificationCtx::new(func_ref, func); + let res = NonEmpty.run(&mut ctx); + assert_eq!(res, VerificationResult::Fail); + + let mut err_msgs = String::new(); + + let errs = ctx + .error_stack + .into_errs_iter(func, func_ref) + .into_iter() + .collect::>(); + + for e in errs { + write!(&mut err_msgs, "{}\n", e).unwrap(); + } + + assert_eq!( + "empty block, block1 +trace_info: +0: block1 +1: func public %test_func() -> unit +empty block, block4 +trace_info: +0: block4 +1: func public %test_func() -> unit +empty block, block5 +trace_info: +0: block5 +1: func public %test_func() -> unit +", + err_msgs + ); + } +}