diff --git a/Zend/tests/coalesce_assign_optimization.phpt b/Zend/tests/coalesce_assign_optimization.phpt index ff076b03e0a..783af4cd1a0 100644 --- a/Zend/tests/coalesce_assign_optimization.phpt +++ b/Zend/tests/coalesce_assign_optimization.phpt @@ -6,9 +6,13 @@ function test() { $a[X] ??= Y; var_dump($a); } +function test2(string $b, int $c) { + $a[~$b] ??= $c; +} define('X', 1); define('Y', 2); test(); +test2("", 0); ?> --EXPECT-- array(1) { diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index d99500ab258..620d42dfc6e 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -729,6 +729,7 @@ static void emit_live_range( 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. */ + start++; break; } @@ -744,6 +745,12 @@ static void emit_live_range( do { use_opline--; + + /* The use might have been optimized away, in which case we will hit the def + * instead. */ + if (use_opline->opcode == ZEND_COPY_TMP && use_opline->result.var == rt_var_num) { + return; + } } while (!( ((use_opline->op1_type & (IS_TMP_VAR|IS_VAR)) && use_opline->op1.var == rt_var_num) || ((use_opline->op2_type & (IS_TMP_VAR|IS_VAR)) && use_opline->op2.var == rt_var_num)