diff --git a/filetests/verifier/unreachable_code.cton b/filetests/verifier/unreachable_code.cton new file mode 100644 index 0000000000..474eaec6b4 --- /dev/null +++ b/filetests/verifier/unreachable_code.cton @@ -0,0 +1,23 @@ +test verifier + +function %test() -> i32 { ; Ok +ebb0: + v0 = iconst.i32 0 + v1 = iconst.i32 0 + jump ebb2 + +ebb2: + jump ebb4 + +ebb4: + jump ebb2 + +ebb3(v2: i32): + v4 = iadd.i32 v1, v2 + jump ebb9(v4) + +ebb9(v7: i32): + v9 = iadd.i32 v2, v7 + return v9 + +} diff --git a/lib/cretonne/src/verifier/mod.rs b/lib/cretonne/src/verifier/mod.rs index 08aeb9249f..2f817d1a48 100644 --- a/lib/cretonne/src/verifier/mod.rs +++ b/lib/cretonne/src/verifier/mod.rs @@ -363,7 +363,8 @@ impl<'a> Verifier<'a> { def_inst); } // Defining instruction dominates the instruction that uses the value. - if !self.domtree + if self.domtree.is_reachable(self.func.layout.pp_ebb(loc_inst)) && + !self.domtree .dominates(def_inst, loc_inst, &self.func.layout) { return err!(loc_inst, "uses value from non-dominating {}", def_inst); } @@ -381,7 +382,8 @@ impl<'a> Verifier<'a> { ebb); } // The defining EBB dominates the instruction using this value. - if !self.domtree.dominates(ebb, loc_inst, &self.func.layout) { + if self.domtree.is_reachable(ebb) && + !self.domtree.dominates(ebb, loc_inst, &self.func.layout) { return err!(loc_inst, "uses value arg from non-dominating {}", ebb); } }