From 64878757be97a6938b4cd7f3e0a0937f5f73e48e Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 1 Nov 2021 11:01:29 +0100 Subject: [PATCH] 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. --- Zend/Optimizer/scdf.c | 14 +++++++++----- Zend/tests/match/match_of_phi_optimization.phpt | 14 ++++++++++++++ 2 files changed, 23 insertions(+), 5 deletions(-) create mode 100644 Zend/tests/match/match_of_phi_optimization.phpt diff --git a/Zend/Optimizer/scdf.c b/Zend/Optimizer/scdf.c index a07f1857244..0e0a66c1086 100644 --- a/Zend/Optimizer/scdf.c +++ b/Zend/Optimizer/scdf.c @@ -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); } diff --git a/Zend/tests/match/match_of_phi_optimization.phpt b/Zend/tests/match/match_of_phi_optimization.phpt new file mode 100644 index 00000000000..57edf3783e4 --- /dev/null +++ b/Zend/tests/match/match_of_phi_optimization.phpt @@ -0,0 +1,14 @@ +--TEST-- +Unreachable code elimination when match argument is a phi node +--FILE-- + $x +}; +?> +--EXPECTF-- +Fatal error: Uncaught UnhandledMatchError: Unhandled match case true in %s:%d +Stack trace: +#0 {main} + thrown in %s on line %d