From 6738d19fb80b8696f163cae4b9c114c247606daa Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 27 Apr 2018 22:17:59 +0200 Subject: Fix bug #76281 Make sure we keep the smart-branch inhibiting NOP even if there are multiple NOPs in sequence. --- NEWS | 2 ++ ext/opcache/Optimizer/dfa_pass.c | 7 ++++--- ext/opcache/tests/bug76281.phpt | 28 ++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 ext/opcache/tests/bug76281.phpt diff --git a/NEWS b/NEWS index c9b985012e..02a9367008 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,8 @@ PHP NEWS - Opcache: . Fixed bug #76275 (Assertion failure in file cache when unserializing empty try_catch_array). (Nikita) + . Fixed bug #76281 (Opcache causes incorrect "undefined variable" errors). + (Nikita) - Reflection: . Fixed arginfo for array_replace(_recursive) and array_merge(_recursive). diff --git a/ext/opcache/Optimizer/dfa_pass.c b/ext/opcache/Optimizer/dfa_pass.c index bb22665594..34d5de835a 100644 --- a/ext/opcache/Optimizer/dfa_pass.c +++ b/ext/opcache/Optimizer/dfa_pass.c @@ -144,12 +144,13 @@ static void zend_ssa_remove_nops(zend_op_array *op_array, zend_ssa *ssa) while (i < end) { shiftlist[i] = i - target; if (EXPECTED(op_array->opcodes[i].opcode != ZEND_NOP) || - /*keep NOP to support ZEND_VM_SMART_BRANCH */ - (i > 0 && + /* Keep NOP to support ZEND_VM_SMART_BRANCH. Using "target-1" instead of + * "i-1" here to check the last non-NOP instruction. */ + (target > 0 && i + 1 < op_array->last && (op_array->opcodes[i+1].opcode == ZEND_JMPZ || op_array->opcodes[i+1].opcode == ZEND_JMPNZ) && - zend_is_smart_branch(op_array->opcodes + i - 1))) { + zend_is_smart_branch(op_array->opcodes + target - 1))) { if (i != target) { op_array->opcodes[target] = op_array->opcodes[i]; ssa->ops[target] = ssa->ops[i]; diff --git a/ext/opcache/tests/bug76281.phpt b/ext/opcache/tests/bug76281.phpt new file mode 100644 index 0000000000..83c42f3a28 --- /dev/null +++ b/ext/opcache/tests/bug76281.phpt @@ -0,0 +1,28 @@ +--TEST-- +Bug #76281: Opcache causes incorrect "undefined variable" errors +--FILE-- + 1, 'id' => 2], 'foo')); + +?> +--EXPECT-- +string(3) "bar" -- cgit v1.2.1