diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2019-07-29 13:02:01 +0200 |
---|---|---|
committer | Christoph M. Becker <cmbecker69@gmx.de> | 2019-07-29 14:44:23 +0200 |
commit | d561a998c9313749ad2b488685e5c2bec661bc69 (patch) | |
tree | 2f409450b20d60bb94b81ec7288168626feafb48 | |
parent | 63f1def36799ecb375ee6b11ec6143ab624b3092 (diff) | |
download | php-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-- | NEWS | 3 | ||||
-rw-r--r-- | ext/opcache/Optimizer/dfa_pass.c | 14 | ||||
-rw-r--r-- | ext/opcache/tests/bug78341.phpt | 21 |
3 files changed, 31 insertions, 7 deletions
@@ -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) |