diff options
author | Xinchen Hui <laruence@gmail.com> | 2019-01-08 19:17:46 +0800 |
---|---|---|
committer | Xinchen Hui <laruence@gmail.com> | 2019-01-08 19:19:01 +0800 |
commit | cd49db9d47fa979c308ef25b43123b08be0a5ab0 (patch) | |
tree | 6c7fe0f3c00052e0d1dab47d870fd9402dc80e96 | |
parent | 76c687feaf86d305f8ba510a7319ccc1b66a8901 (diff) | |
download | php-git-cd49db9d47fa979c308ef25b43123b08be0a5ab0.tar.gz |
Fixed bug #77266 (Assertion failed in dce_live_ranges)
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | ext/opcache/Optimizer/zend_optimizer.c | 40 | ||||
-rw-r--r-- | ext/opcache/tests/bug77266.phpt | 33 |
3 files changed, 73 insertions, 1 deletions
@@ -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 |