Skip to content

Commit 3f00c93

Browse files
committed
Fixed bug #77691
We cannot replace an op1_def opcode with an ASSIGN, if it also has a used res_def. Usually this doesn't happen because the res_def use can be eliminated first. The example is a case where operand replacement on the res_def use fails.
1 parent 2694953 commit 3f00c93

File tree

3 files changed

+36
-5
lines changed

3 files changed

+36
-5
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ PHP NEWS
2121
- MySQLi:
2222
. Fixed bug #77597 (mysqli_fetch_field hangs scripts). (Nikita)
2323

24+
- Opcache:
25+
. Fixed bug #77691 (Opcache passes wrong value for inline array push
26+
assignments). (Nikita)
27+
2428
- sodium:
2529
. Fixed bug #77646 (sign_detached() strings not terminated). (Frank)
2630

ext/opcache/Optimizer/sccp.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1581,7 +1581,10 @@ static int replace_constant_operands(sccp_ctx *ctx) {
15811581
zend_ssa_remove_instr(ssa, opline, ssa_op);
15821582
removed_ops++;
15831583
}
1584-
} else if (ssa_op->op1_def == i) {
1584+
} else if (ssa_op->op1_def == i &&
1585+
(ssa_op->result_def < 0 ||
1586+
(ssa->vars[ssa_op->result_def].use_chain < 0 &&
1587+
ssa->vars[ssa_op->result_def].phi_use_chain == NULL))) {
15851588
/* Compound assign or incdec -> convert to direct ASSIGN */
15861589

15871590
/* Destroy previous op2 */
@@ -1595,10 +1598,8 @@ static int replace_constant_operands(sccp_ctx *ctx) {
15951598
ssa_op->op2_use_chain = -1;
15961599
}
15971600

1598-
/* Mark result unused, if possible */
1599-
if (ssa_op->result_def >= 0
1600-
&& ssa->vars[ssa_op->result_def].use_chain < 0
1601-
&& ssa->vars[ssa_op->result_def].phi_use_chain == NULL) {
1601+
/* We checked that result has no uses, mark unused */
1602+
if (ssa_op->result_def >= 0) {
16021603
if (opline->result_type & (IS_TMP_VAR|IS_VAR)) {
16031604
zend_optimizer_remove_live_range_ex(op_array, opline->result.var, var->definition);
16041605
}

ext/opcache/tests/bug77691.phpt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
Bug #77691: Opcache passes wrong value for inline array push assignments
3+
--FILE--
4+
<?php
5+
6+
if (true) {
7+
function dump($str) {
8+
var_dump($str);
9+
}
10+
}
11+
12+
function test() {
13+
$array = [];
14+
dump($array[] = 'test');
15+
dump($array);
16+
}
17+
18+
test();
19+
20+
?>
21+
--EXPECT--
22+
string(4) "test"
23+
array(1) {
24+
[0]=>
25+
string(4) "test"
26+
}

0 commit comments

Comments
 (0)