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.
This commit is contained in:
Jakob Stoklund Olesen
2018-01-09 10:45:47 -08:00
parent af89006b09
commit 5e094034d4
2 changed files with 26 additions and 4 deletions

View File

@@ -21,3 +21,25 @@ ebb9(v7: i32):
return v9 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
}

View File

@@ -443,6 +443,8 @@ impl<'a> Verifier<'a> {
if !dfg.value_is_valid(v) { if !dfg.value_is_valid(v) {
return err!(loc_inst, "invalid value reference {}", 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 // SSA form
match dfg.value_def(v) { match dfg.value_def(v) {
@@ -466,9 +468,7 @@ impl<'a> Verifier<'a> {
); );
} }
// Defining instruction dominates the instruction that uses the value. // Defining instruction dominates the instruction that uses the value.
if self.expected_domtree.is_reachable( if is_reachable &&
self.func.layout.pp_ebb(loc_inst),
) &&
!self.expected_domtree.dominates( !self.expected_domtree.dominates(
def_inst, def_inst,
loc_inst, loc_inst,
@@ -493,7 +493,7 @@ impl<'a> Verifier<'a> {
); );
} }
// The defining EBB dominates the instruction using this value. // The defining EBB dominates the instruction using this value.
if self.expected_domtree.is_reachable(ebb) && if is_reachable &&
!self.expected_domtree.dominates( !self.expected_domtree.dominates(
ebb, ebb,
loc_inst, loc_inst,