Skip to content

Commit 8c4a7f2

Browse files
committed
Fix COPY_TMP live range construction with optimization
The use may be optimized away, leaving us only with the free use. Also fix off-by-one error in the other optimization case.
1 parent 6491577 commit 8c4a7f2

File tree

2 files changed

+11
-0
lines changed

2 files changed

+11
-0
lines changed

Zend/tests/coalesce_assign_optimization.phpt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,13 @@ function test() {
66
$a[X] ??= Y;
77
var_dump($a);
88
}
9+
function test2(string $b, int $c) {
10+
$a[~$b] ??= $c;
11+
}
912
define('X', 1);
1013
define('Y', 2);
1114
test();
15+
test2("", 0);
1216
?>
1317
--EXPECT--
1418
array(1) {

Zend/zend_opcode.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,7 @@ static void emit_live_range(
729729
if (use_opline->opcode != ZEND_FREE) {
730730
/* This can happen if one branch of the coalesce has been optimized away.
731731
* In this case we should emit a normal live-range instead. */
732+
start++;
732733
break;
733734
}
734735

@@ -744,6 +745,12 @@ static void emit_live_range(
744745

745746
do {
746747
use_opline--;
748+
749+
/* The use might have been optimized away, in which case we will hit the def
750+
* instead. */
751+
if (use_opline->opcode == ZEND_COPY_TMP && use_opline->result.var == rt_var_num) {
752+
return;
753+
}
747754
} while (!(
748755
((use_opline->op1_type & (IS_TMP_VAR|IS_VAR)) && use_opline->op1.var == rt_var_num) ||
749756
((use_opline->op2_type & (IS_TMP_VAR|IS_VAR)) && use_opline->op2.var == rt_var_num)

0 commit comments

Comments
 (0)