summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXinchen Hui <laruence@gmail.com>2017-02-23 12:33:17 +0800
committerXinchen Hui <laruence@gmail.com>2017-02-23 12:33:17 +0800
commit330a7b62c3558aa987ee80e12f1914347d3a9eee (patch)
treeface7436918d38e11cc6ffe9e62f51e66037ede5
parent1d4eead995ed8bd437aec578568aaee0075d17b0 (diff)
downloadphp-git-330a7b62c3558aa987ee80e12f1914347d3a9eee.tar.gz
Fixed bug #74152 (if statement says true to a null variable)
-rw-r--r--NEWS1
-rw-r--r--ext/opcache/Optimizer/block_pass.c14
-rw-r--r--ext/opcache/tests/bug74152.phpt27
3 files changed, 40 insertions, 2 deletions
diff --git a/NEWS b/NEWS
index f5ae82bcfb..d3a832895f 100644
--- a/NEWS
+++ b/NEWS
@@ -43,6 +43,7 @@ PHP NEWS
(Andrew Nester, Nikita)
- Opcache:
+ . Fixed bug #74152 (if statement says true to a null variable). (Laruence)
. Fixed bug #74019 (Segfault with list). (Laruence)
- OpenSSL:
diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c
index 862dfaf144..f69199b24e 100644
--- a/ext/opcache/Optimizer/block_pass.c
+++ b/ext/opcache/Optimizer/block_pass.c
@@ -561,6 +561,17 @@ static void zend_rebuild_access_path(zend_cfg *cfg, zend_op_array *op_array, int
convert_to_string((v)); \
}
+static int is_predecessor_smart_branch(zend_op *start, zend_op *predecessor) {
+ do {
+ if (predecessor == start) {
+ return 0;
+ }
+ predecessor--;
+ } while (predecessor->opcode == ZEND_NOP);
+
+ return zend_is_smart_branch(predecessor);
+}
+
static void strip_nop(zend_code_block *block, zend_op_array *op_array, zend_optimizer_ctx *ctx)
{
zend_op *opline = block->start_opline;
@@ -602,8 +613,7 @@ static void strip_nop(zend_code_block *block, zend_op_array *op_array, zend_opti
&& ((opline + 1)->opcode == ZEND_JMPZ
|| (opline + 1)->opcode == ZEND_JMPNZ)
&& (opline + 1)->op1_type & (IS_CV|IS_CONST)
- && opline > op_array->opcodes
- && zend_is_smart_branch(opline - 1)) {
+ && is_predecessor_smart_branch(op_array->opcodes, opline)) {
/* don't remove NOP, that splits incorrect smart branch */
opline++;
break;
diff --git a/ext/opcache/tests/bug74152.phpt b/ext/opcache/tests/bug74152.phpt
new file mode 100644
index 0000000000..f51c26b621
--- /dev/null
+++ b/ext/opcache/tests/bug74152.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Bug #74152 (if statement says true to a null variable)
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.optimization_level=-1
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$foo = 'foo';
+
+$bar = null;
+
+switch ($foo) {
+default:
+case 'foo':
+ if ($bar) {
+ echo 'true';
+ } else {
+ echo 'false';
+ }
+}
+?>
+--EXPECT--
+false