summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-07-29 13:02:01 +0200
committerChristoph M. Becker <cmbecker69@gmx.de>2019-07-29 14:44:23 +0200
commitd561a998c9313749ad2b488685e5c2bec661bc69 (patch)
tree2f409450b20d60bb94b81ec7288168626feafb48
parent63f1def36799ecb375ee6b11ec6143ab624b3092 (diff)
downloadphp-git-d561a998c9313749ad2b488685e5c2bec661bc69.tar.gz
Fixed bug #78341
The smart branch logic assumed b->start refers to the old offsets, while b->start was already adjusted to the new offsets at this point. Delay the change until later. (cherry picked from commit 8e63bb5e465620f27de93dea82e0d84be72da7f3)
-rw-r--r--NEWS3
-rw-r--r--ext/opcache/Optimizer/dfa_pass.c14
-rw-r--r--ext/opcache/tests/bug78341.phpt21
3 files changed, 31 insertions, 7 deletions
diff --git a/NEWS b/NEWS
index 76e8f830a0..6dba5974ed 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,9 @@ PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? ????, PHP 7.3.8
+- OPcache:
+ . Fixed bug #78341 (Failure to detect smart branch in DFA pass). (Nikita)
+
- Phpdbg:
. Fixed bug #78297 (Include unexistent file memory leak). (Nikita)
diff --git a/ext/opcache/Optimizer/dfa_pass.c b/ext/opcache/Optimizer/dfa_pass.c
index 55b9597850..ecf3038b6b 100644
--- a/ext/opcache/Optimizer/dfa_pass.c
+++ b/ext/opcache/Optimizer/dfa_pass.c
@@ -181,9 +181,8 @@ static void zend_ssa_remove_nops(zend_op_array *op_array, zend_ssa *ssa, zend_op
for (b = blocks; b < blocks_end; b++) {
if (b->flags & (ZEND_BB_REACHABLE|ZEND_BB_UNREACHABLE_FREE)) {
- uint32_t end;
-
if (b->len) {
+ uint32_t new_start, old_end;
while (i < b->start) {
shiftlist[i] = i - target;
i++;
@@ -196,9 +195,9 @@ static void zend_ssa_remove_nops(zend_op_array *op_array, zend_ssa *ssa, zend_op
b->len = 1;
}
- end = b->start + b->len;
- b->start = target;
- while (i < end) {
+ new_start = target;
+ old_end = b->start + b->len;
+ while (i < old_end) {
shiftlist[i] = i - target;
if (EXPECTED(op_array->opcodes[i].opcode != ZEND_NOP) ||
is_smart_branch_inhibiting_nop(op_array, target, i, b, blocks_end)) {
@@ -211,12 +210,13 @@ static void zend_ssa_remove_nops(zend_op_array *op_array, zend_ssa *ssa, zend_op
}
i++;
}
- if (target != end) {
+ b->start = new_start;
+ if (target != old_end) {
zend_op *opline;
zend_op *new_opline;
b->len = target - b->start;
- opline = op_array->opcodes + end - 1;
+ opline = op_array->opcodes + old_end - 1;
if (opline->opcode == ZEND_NOP) {
continue;
}
diff --git a/ext/opcache/tests/bug78341.phpt b/ext/opcache/tests/bug78341.phpt
new file mode 100644
index 0000000000..8b10125068
--- /dev/null
+++ b/ext/opcache/tests/bug78341.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Bug #78341: Failure to detect smart branch in DFA pass
+--FILE--
+<?php
+
+function test($a) {
+ // Just some dead code...
+ if (strpos("foo", "foo") !== 0) {
+ echo "Foo";
+ }
+
+ $x = $a === null;
+ if ($x) {
+ var_dump($x);
+ }
+}
+test(null);
+
+?>
+--EXPECT--
+bool(true)