From bbd3f714d7a39b11b876ffca0b37520abadbef89 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 5 Oct 2021 11:26:32 +0200 Subject: [PATCH] Fix COPY_TMP live range construction after optimization If we optimize the FREE away, we should switch to constructing a normal live range, rather than a split live range. Fixes oss-fuzz #39548. --- Zend/tests/coalesce_assign_optimization.phpt | 17 +++++++++++++++++ Zend/zend_opcode.c | 11 ++++++++--- 2 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 Zend/tests/coalesce_assign_optimization.phpt diff --git a/Zend/tests/coalesce_assign_optimization.phpt b/Zend/tests/coalesce_assign_optimization.phpt new file mode 100644 index 00000000000..ff076b03e0a --- /dev/null +++ b/Zend/tests/coalesce_assign_optimization.phpt @@ -0,0 +1,17 @@ +--TEST-- +Live range construction should not break if colesce assign branch is optimized away +--FILE-- + +--EXPECT-- +array(1) { + [1]=> + int(2) +} diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index 78c4adf82d5..d99500ab258 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -721,17 +721,22 @@ static void emit_live_range( * "null" branch, and another from the start of the "non-null" branch to the * FREE opcode. */ uint32_t rt_var_num = EX_NUM_TO_VAR(op_array->last_var + var_num); - zend_op *block_start_op = use_opline; - if (needs_live_range && !needs_live_range(op_array, orig_def_opline)) { return; } + kind = ZEND_LIVE_TMPVAR; + if (use_opline->opcode != ZEND_FREE) { + /* This can happen if one branch of the coalesce has been optimized away. + * In this case we should emit a normal live-range instead. */ + break; + } + + zend_op *block_start_op = use_opline; while ((block_start_op-1)->opcode == ZEND_FREE) { block_start_op--; } - kind = ZEND_LIVE_TMPVAR; start = block_start_op - op_array->opcodes; if (start != end) { emit_live_range_raw(op_array, var_num, kind, start, end);