Skip to content

Commit 6738d19

Browse files
committed
Fix bug #76281
Make sure we keep the smart-branch inhibiting NOP even if there are multiple NOPs in sequence.
1 parent 279ba58 commit 6738d19

File tree

3 files changed

+34
-3
lines changed

3 files changed

+34
-3
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ PHP NEWS
99
- Opcache:
1010
. Fixed bug #76275 (Assertion failure in file cache when unserializing empty
1111
try_catch_array). (Nikita)
12+
. Fixed bug #76281 (Opcache causes incorrect "undefined variable" errors).
13+
(Nikita)
1214

1315
- Reflection:
1416
. Fixed arginfo for array_replace(_recursive) and array_merge(_recursive).

ext/opcache/Optimizer/dfa_pass.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,12 +144,13 @@ static void zend_ssa_remove_nops(zend_op_array *op_array, zend_ssa *ssa)
144144
while (i < end) {
145145
shiftlist[i] = i - target;
146146
if (EXPECTED(op_array->opcodes[i].opcode != ZEND_NOP) ||
147-
/*keep NOP to support ZEND_VM_SMART_BRANCH */
148-
(i > 0 &&
147+
/* Keep NOP to support ZEND_VM_SMART_BRANCH. Using "target-1" instead of
148+
* "i-1" here to check the last non-NOP instruction. */
149+
(target > 0 &&
149150
i + 1 < op_array->last &&
150151
(op_array->opcodes[i+1].opcode == ZEND_JMPZ ||
151152
op_array->opcodes[i+1].opcode == ZEND_JMPNZ) &&
152-
zend_is_smart_branch(op_array->opcodes + i - 1))) {
153+
zend_is_smart_branch(op_array->opcodes + target - 1))) {
153154
if (i != target) {
154155
op_array->opcodes[target] = op_array->opcodes[i];
155156
ssa->ops[target] = ssa->ops[i];

ext/opcache/tests/bug76281.phpt

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
--TEST--
2+
Bug #76281: Opcache causes incorrect "undefined variable" errors
3+
--FILE--
4+
<?php
5+
6+
function test($r, $action) {
7+
$user_sub_resource = in_array($action, array('get_securityquestions', 'get_status', 'get_groupstats'));
8+
9+
$user_id = null;
10+
if ($user_sub_resource && isset($r['user_id'])) {
11+
$user_id = $r['user_id'];
12+
}
13+
else if (isset($r['id'])) {
14+
$user_id = $r['id'];
15+
}
16+
17+
if ($user_sub_resource) {
18+
return 'foo';
19+
}
20+
21+
return 'bar';
22+
}
23+
24+
var_dump(test(['user_id' => 1, 'id' => 2], 'foo'));
25+
26+
?>
27+
--EXPECT--
28+
string(3) "bar"

0 commit comments

Comments
 (0)