From e8579365181d8e61c00968715ed8be5ec151002d Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 11 Sep 2020 22:36:41 +0200 Subject: Fixed bug #80805 Handle missing result_var in binary_op_result_type. (cherry picked from commit 8446e2827585c37d0739f8d44fa8d359cbbb6551) --- NEWS | 3 +++ ext/opcache/Optimizer/zend_inference.c | 11 +++++++---- ext/opcache/tests/bug80805.phpt | 26 ++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 ext/opcache/tests/bug80805.phpt diff --git a/NEWS b/NEWS index 46aa23e007..f2bd80397e 100644 --- a/NEWS +++ b/NEWS @@ -15,6 +15,9 @@ PHP NEWS . Fixed bug #80713 (SegFault when disabling ATTR_EMULATE_PREPARES and MySQL 8.0). (Nikita) +- opcache: + . Fixed bug #80805 (create simple class and get error in opcache.so). (Nikita) + - phpdbg: . Fixed bug #80757 (Exit code is 0 when could not open file). (Felipe) diff --git a/ext/opcache/Optimizer/zend_inference.c b/ext/opcache/Optimizer/zend_inference.c index 368f68108d..bd3dad34ad 100644 --- a/ext/opcache/Optimizer/zend_inference.c +++ b/ext/opcache/Optimizer/zend_inference.c @@ -2141,7 +2141,7 @@ static uint32_t assign_dim_result_type( /* For binary ops that have compound assignment operators */ static uint32_t binary_op_result_type( - zend_ssa *ssa, zend_uchar opcode, uint32_t t1, uint32_t t2, uint32_t result_var, + zend_ssa *ssa, zend_uchar opcode, uint32_t t1, uint32_t t2, int result_var, zend_long optimization_level) { uint32_t tmp = 0; uint32_t t1_type = (t1 & MAY_BE_ANY) | (t1 & MAY_BE_UNDEF ? MAY_BE_NULL : 0); @@ -2159,7 +2159,8 @@ static uint32_t binary_op_result_type( switch (opcode) { case ZEND_ADD: if (t1_type == MAY_BE_LONG && t2_type == MAY_BE_LONG) { - if (!ssa->var_info[result_var].has_range || + if (result_var < 0 || + !ssa->var_info[result_var].has_range || ssa->var_info[result_var].range.underflow || ssa->var_info[result_var].range.overflow) { /* may overflow */ @@ -2185,7 +2186,8 @@ static uint32_t binary_op_result_type( case ZEND_SUB: case ZEND_MUL: if (t1_type == MAY_BE_LONG && t2_type == MAY_BE_LONG) { - if (!ssa->var_info[result_var].has_range || + if (result_var < 0 || + !ssa->var_info[result_var].has_range || ssa->var_info[result_var].range.underflow || ssa->var_info[result_var].range.overflow) { /* may overflow */ @@ -2627,7 +2629,8 @@ static int zend_update_type_info(const zend_op_array *op_array, } tmp |= binary_op_result_type( - ssa, opline->extended_value, t1, t2, ssa_ops[i].op1_def, optimization_level); + ssa, opline->extended_value, t1, t2, + opline->opcode == ZEND_ASSIGN_OP ? ssa_ops[i].op1_def : -1, optimization_level); if (tmp & (MAY_BE_STRING|MAY_BE_ARRAY)) { tmp |= MAY_BE_RC1; } diff --git a/ext/opcache/tests/bug80805.phpt b/ext/opcache/tests/bug80805.phpt new file mode 100644 index 0000000000..65e4748e57 --- /dev/null +++ b/ext/opcache/tests/bug80805.phpt @@ -0,0 +1,26 @@ +--TEST-- +Bug #80805: create simple class and get error in opcache.so +--FILE-- +foo = 2; + } + public function inc(): int + { + return $this->foo += 2; + } +} + +$test = new Test(); +var_dump($test->foo); +$test->inc(); +var_dump($test->foo); + +?> +--EXPECT-- +int(2) +int(4) -- cgit v1.2.1