From cd49db9d47fa979c308ef25b43123b08be0a5ab0 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Tue, 8 Jan 2019 19:17:46 +0800 Subject: [PATCH] Fixed bug #77266 (Assertion failed in dce_live_ranges) --- NEWS | 1 + ext/opcache/Optimizer/zend_optimizer.c | 40 +++++++++++++++++++++++++- ext/opcache/tests/bug77266.phpt | 33 +++++++++++++++++++++ 3 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 ext/opcache/tests/bug77266.phpt 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-- + +--FILE-- + 0 ) { + $v = explode(':', $value); + if (!$serverMonitors[$v[0]]['m']) { + $serverMonitors[$v[0]]['m'] = new ServerMonitor($v[0]); + } + + } + + } + +} +?> +okey +--EXPECT-- +okey -- 2.40.0