summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXinchen Hui <laruence@gmail.com>2019-01-08 19:17:46 +0800
committerXinchen Hui <laruence@gmail.com>2019-01-08 19:19:01 +0800
commitcd49db9d47fa979c308ef25b43123b08be0a5ab0 (patch)
tree6c7fe0f3c00052e0d1dab47d870fd9402dc80e96
parent76c687feaf86d305f8ba510a7319ccc1b66a8901 (diff)
downloadphp-git-cd49db9d47fa979c308ef25b43123b08be0a5ab0.tar.gz
Fixed bug #77266 (Assertion failed in dce_live_ranges)
-rw-r--r--NEWS1
-rw-r--r--ext/opcache/Optimizer/zend_optimizer.c40
-rw-r--r--ext/opcache/tests/bug77266.phpt33
3 files changed, 73 insertions, 1 deletions
diff --git a/NEWS b/NEWS
index 050c222fca..48566bb357 100644
--- a/NEWS
+++ b/NEWS
@@ -43,6 +43,7 @@ PHP NEWS
no external visibility). (Anatol)
- Opcache:
+ . Fixed bug #77266 (Assertion failed in dce_live_ranges). (Laruence)
. Fixed bug #77257 (value of variable assigned in a switch() construct gets
lost). (Nikita)
diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c
index 5d34525af9..cb6cdf61d9 100644
--- a/ext/opcache/Optimizer/zend_optimizer.c
+++ b/ext/opcache/Optimizer/zend_optimizer.c
@@ -621,6 +621,39 @@ void zend_optimizer_remove_live_range(zend_op_array *op_array, uint32_t var)
}
}
+static uint32_t zend_determine_constructor_call(zend_op_array *op_array, uint32_t start) {
+ int call = 0;
+ while (start++ < op_array->last) {
+ switch (op_array->opcodes[start].opcode) {
+ case ZEND_INIT_FCALL_BY_NAME:
+ case ZEND_INIT_NS_FCALL_BY_NAME:
+ case ZEND_INIT_STATIC_METHOD_CALL:
+ case ZEND_INIT_METHOD_CALL:
+ case ZEND_INIT_FCALL:
+ case ZEND_NEW:
+ case ZEND_INIT_DYNAMIC_CALL:
+ case ZEND_INIT_USER_CALL:
+ call++;
+ break;
+ case ZEND_DO_FCALL:
+ if (call == 0) {
+ return start;
+ }
+ /* break missing intentionally */
+ case ZEND_DO_ICALL:
+ case ZEND_DO_UCALL:
+ case ZEND_DO_FCALL_BY_NAME:
+ call--;
+ break;
+ default:
+ break;
+ }
+ }
+
+ ZEND_ASSERT(0);
+ return -1;
+}
+
void zend_optimizer_remove_live_range_ex(zend_op_array *op_array, uint32_t var, uint32_t start)
{
uint32_t i = 0;
@@ -638,7 +671,12 @@ void zend_optimizer_remove_live_range_ex(zend_op_array *op_array, uint32_t var,
case ZEND_FE_RESET_R:
case ZEND_FE_RESET_RW:
var |= ZEND_LIVE_LOOP;
- /* break missing intentionally */
+ start++;
+ break;
+ case ZEND_NEW:
+ start = zend_determine_constructor_call(op_array, start);
+ start++;
+ break;
default:
start++;
}
diff --git a/ext/opcache/tests/bug77266.phpt b/ext/opcache/tests/bug77266.phpt
new file mode 100644
index 0000000000..8e225b8480
--- /dev/null
+++ b/ext/opcache/tests/bug77266.phpt
@@ -0,0 +1,33 @@
+--TEST--
+Bug #77266 (Assertion failed in dce_live_ranges)
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.optimization_level=-1
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+final class Lock
+{
+ private static function clearOrphanedLocks()
+ {
+ $lockList = [];
+
+ $serverMonitors = array();
+ $listCount = count($lockList);
+ if ( is_array($lockList) && $listCount > 0 ) {
+ $v = explode(':', $value);
+ if (!$serverMonitors[$v[0]]['m']) {
+ $serverMonitors[$v[0]]['m'] = new ServerMonitor($v[0]);
+ }
+
+ }
+
+ }
+
+}
+?>
+okey
+--EXPECT--
+okey