From be7eab3202567a1acf0158d281362c20d5051767 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 30 Jan 2020 14:23:46 +0100 Subject: Fix live range calculation for FE_FETCH Op2 is def here, not a use, so treat it accordingly. --- Zend/tests/fe_fetch_op2_live_range.phpt | 12 ++++++++++++ Zend/zend_opcode.c | 12 +++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 Zend/tests/fe_fetch_op2_live_range.phpt diff --git a/Zend/tests/fe_fetch_op2_live_range.phpt b/Zend/tests/fe_fetch_op2_live_range.phpt new file mode 100644 index 0000000000..c601e43120 --- /dev/null +++ b/Zend/tests/fe_fetch_op2_live_range.phpt @@ -0,0 +1,12 @@ +--TEST-- +FE_FETCH op2 is a def and needs special live range handling +--FILE-- + func()[]) {} +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECT-- +Call to undefined function func() diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index a128f9436e..d0d49934fe 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -817,7 +817,17 @@ static void zend_calc_live_ranges( } if (opline->op2_type & (IS_TMP_VAR|IS_VAR)) { uint32_t var_num = EX_VAR_TO_NUM(opline->op2.var) - var_offset; - if (EXPECTED(last_use[var_num] == (uint32_t) -1)) { + if (UNEXPECTED(opline->opcode == ZEND_FE_FETCH_R + || opline->opcode == ZEND_FE_FETCH_RW)) { + /* OP2 of FE_FETCH is actually a def, not a use. */ + if (last_use[var_num] != (uint32_t) -1) { + if (opnum + 1 != last_use[var_num]) { + emit_live_range( + op_array, var_num, opnum, last_use[var_num], needs_live_range); + } + last_use[var_num] = (uint32_t) -1; + } + } else if (EXPECTED(last_use[var_num] == (uint32_t) -1)) { #if 1 /* OP_DATA uses only op1 operand */ ZEND_ASSERT(opline->opcode != ZEND_OP_DATA); -- cgit v1.2.1