From 5e094034d45b341bc426f97f4fd321134085cc00 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Tue, 9 Jan 2018 10:45:47 -0800 Subject: [PATCH] Fix verifier bug in unreachable code. We want to disable dominance checks in unreachable code. The is_reachable() check for EBB parameter values was checking if the defining EBB was reachable, not the EBB using the value. This bug showed up in fuzzing and in #213. --- .../filetests/verifier/unreachable_code.cton | 22 +++++++++++++++++++ lib/cretonne/src/verifier/mod.rs | 8 +++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/cranelift/filetests/verifier/unreachable_code.cton b/cranelift/filetests/verifier/unreachable_code.cton index 474eaec6b4..7ea7dd49b0 100644 --- a/cranelift/filetests/verifier/unreachable_code.cton +++ b/cranelift/filetests/verifier/unreachable_code.cton @@ -21,3 +21,25 @@ ebb9(v7: i32): return v9 } + +; Using a function argument in an unreachable block is ok. +function %arg(i32) -> i32 { +ebb0(v0: i32): + v1 = iadd_imm v0, 1 + return v1 + +ebb1: + v10 = iadd_imm v0, 10 + return v10 +} + +; Using an EBB argument from an unreachable block is not ok. +function %arg2(i32) -> i32 { +ebb0(v0: i32): + v1 = iadd v0, v10 ; error: uses value arg from non-dominating + return v1 + +ebb1(v10: i32): + v11 = iadd v0, v10 + return v11 +} diff --git a/lib/cretonne/src/verifier/mod.rs b/lib/cretonne/src/verifier/mod.rs index affd8a3ec6..1860fecbbf 100644 --- a/lib/cretonne/src/verifier/mod.rs +++ b/lib/cretonne/src/verifier/mod.rs @@ -443,6 +443,8 @@ impl<'a> Verifier<'a> { if !dfg.value_is_valid(v) { return err!(loc_inst, "invalid value reference {}", v); } + let loc_ebb = self.func.layout.pp_ebb(loc_inst); + let is_reachable = self.expected_domtree.is_reachable(loc_ebb); // SSA form match dfg.value_def(v) { @@ -466,9 +468,7 @@ impl<'a> Verifier<'a> { ); } // Defining instruction dominates the instruction that uses the value. - if self.expected_domtree.is_reachable( - self.func.layout.pp_ebb(loc_inst), - ) && + if is_reachable && !self.expected_domtree.dominates( def_inst, loc_inst, @@ -493,7 +493,7 @@ impl<'a> Verifier<'a> { ); } // The defining EBB dominates the instruction using this value. - if self.expected_domtree.is_reachable(ebb) && + if is_reachable && !self.expected_domtree.dominates( ebb, loc_inst,