Skip to content

Commit be7eab3

Browse files
committed
Fix live range calculation for FE_FETCH
Op2 is def here, not a use, so treat it accordingly.
1 parent 01d30f8 commit be7eab3

File tree

2 files changed

+23
-1
lines changed

2 files changed

+23
-1
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--TEST--
2+
FE_FETCH op2 is a def and needs special live range handling
3+
--FILE--
4+
<?php
5+
try {
6+
foreach (["test"] as $k => func()[]) {}
7+
} catch (Error $e) {
8+
echo $e->getMessage(), "\n";
9+
}
10+
?>
11+
--EXPECT--
12+
Call to undefined function func()

Zend/zend_opcode.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -817,7 +817,17 @@ static void zend_calc_live_ranges(
817817
}
818818
if (opline->op2_type & (IS_TMP_VAR|IS_VAR)) {
819819
uint32_t var_num = EX_VAR_TO_NUM(opline->op2.var) - var_offset;
820-
if (EXPECTED(last_use[var_num] == (uint32_t) -1)) {
820+
if (UNEXPECTED(opline->opcode == ZEND_FE_FETCH_R
821+
|| opline->opcode == ZEND_FE_FETCH_RW)) {
822+
/* OP2 of FE_FETCH is actually a def, not a use. */
823+
if (last_use[var_num] != (uint32_t) -1) {
824+
if (opnum + 1 != last_use[var_num]) {
825+
emit_live_range(
826+
op_array, var_num, opnum, last_use[var_num], needs_live_range);
827+
}
828+
last_use[var_num] = (uint32_t) -1;
829+
}
830+
} else if (EXPECTED(last_use[var_num] == (uint32_t) -1)) {
821831
#if 1
822832
/* OP_DATA uses only op1 operand */
823833
ZEND_ASSERT(opline->opcode != ZEND_OP_DATA);

0 commit comments

Comments
 (0)