Fix scdf loop var free check for phi vars

The variable may come from a phi node, in which case we should
take the defining block from it.

Fixes oss-fuzz #40453.
This commit is contained in:
Nikita Popov 2021-11-01 11:01:29 +01:00
parent 55aadc647b
commit 64878757be
2 changed files with 23 additions and 5 deletions

View File

@ -190,14 +190,18 @@ static bool is_live_loop_var_free(
return false;
}
int ssa_var = ssa_op->op1_use;
if (ssa_var < 0) {
int var = ssa_op->op1_use;
if (var < 0) {
return false;
}
int op_num = scdf->ssa->vars[ssa_var].definition;
ZEND_ASSERT(op_num >= 0);
uint32_t def_block = scdf->ssa->cfg.map[op_num];
zend_ssa_var *ssa_var = &scdf->ssa->vars[var];
uint32_t def_block;
if (ssa_var->definition >= 0) {
def_block = scdf->ssa->cfg.map[ssa_var->definition];
} else {
def_block = ssa_var->definition_phi->block;
}
return zend_bitset_in(scdf->executable_blocks, def_block);
}

View File

@ -0,0 +1,14 @@
--TEST--
Unreachable code elimination when match argument is a phi node
--FILE--
<?php
$x = true;
match ($x and true or true) {
false => $x
};
?>
--EXPECTF--
Fatal error: Uncaught UnhandledMatchError: Unhandled match case true in %s:%d
Stack trace:
#0 {main}
thrown in %s on line %d