summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2020-10-05 15:23:31 +0200
committerNikita Popov <nikita.ppv@gmail.com>2020-10-05 15:24:51 +0200
commit6ea870f5fb94c251cf201fb2955a93ba70edaa89 (patch)
treea6d3caeedbd8cb717863a4bac1017dd19416af45
parent4982964224c0a1ba19c8c87931442483693b83ea (diff)
downloadphp-git-6ea870f5fb94c251cf201fb2955a93ba70edaa89.tar.gz
Fix bug #80184
-rw-r--r--NEWS4
-rw-r--r--Zend/tests/bug80184.phpt20
-rw-r--r--ext/opcache/Optimizer/block_pass.c1
3 files changed, 25 insertions, 0 deletions
diff --git a/NEWS b/NEWS
index b0e4d74d28..00f463c491 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,10 @@ PHP NEWS
. Fixed bug #80121 (Null pointer deref if CurlHandle directly instantiated).
(Nikita)
+- Opcache:
+ . Fixed bug #80184 (Complex expression in while / if statements resolves to
+ false incorrectly). (Nikita)
+
- SPL:
. Fixed bug #65387 (Circular references in SPL iterators are not garbage
collected). (Nikita)
diff --git a/Zend/tests/bug80184.phpt b/Zend/tests/bug80184.phpt
new file mode 100644
index 0000000000..1d12799f0c
--- /dev/null
+++ b/Zend/tests/bug80184.phpt
@@ -0,0 +1,20 @@
+--TEST--
+Bug #80184: Complex expression in while / if statements resolves to false incorrectly
+--FILE--
+<?php
+
+$callbacks = [
+ function () { echo "First item!\n"; },
+ function () { echo "Second item!\n"; },
+ function () { echo "Third item!\n"; },
+ function () { echo "Fourth item!\n"; },
+];
+
+while ($callback = array_shift($callbacks) and ($callback() || true));
+
+?>
+--EXPECT--
+First item!
+Second item!
+Third item!
+Fourth item!
diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c
index 7b9fb2afca..d8a0e419f1 100644
--- a/ext/opcache/Optimizer/block_pass.c
+++ b/ext/opcache/Optimizer/block_pass.c
@@ -1371,6 +1371,7 @@ static void zend_jmp_optimization(zend_basic_block *block, zend_op_array *op_arr
MAKE_NOP(last_op);
block->len--;
}
+ block->successors[0] = follow_block - cfg->blocks;
block->successors_count = 1;
++(*opt_count);
break;