diff options
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | ext/opcache/Optimizer/zend_inference.c | 9 | ||||
-rw-r--r-- | ext/opcache/tests/bug77058.phpt | 20 |
3 files changed, 29 insertions, 3 deletions
@@ -2,6 +2,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 7.3.0RC5 +- Opcache: + . Fixed bug #77058 (Type inference in opcache causes side effects). (Nikita) + - SOAP: . Fixed bug #50675 (SoapClient can't handle object references correctly). (Cameron Porter) diff --git a/ext/opcache/Optimizer/zend_inference.c b/ext/opcache/Optimizer/zend_inference.c index 46749b64c6..101ac9ecf8 100644 --- a/ext/opcache/Optimizer/zend_inference.c +++ b/ext/opcache/Optimizer/zend_inference.c @@ -2019,7 +2019,10 @@ static void handle_type_narrowing(const zend_op_array *op_array, zend_ssa *ssa, { if (1) { /* Right now, this is always a bug */ - zend_error(E_WARNING, "Narrowing occurred during type inference. Please file a bug report on bugs.php.net"); + int def_op_num = ssa->vars[var].definition; + const zend_op *def_opline = def_op_num >= 0 ? &op_array->opcodes[def_op_num] : NULL; + const char *def_op_name = def_opline ? zend_get_opcode_name(def_opline->opcode) : "PHI"; + zend_error(E_WARNING, "Narrowing occurred during type inference of %s. Please file a bug report on bugs.php.net", def_op_name); } else { /* if new_type set resets some bits from old_type set * We have completely recalculate types of some dependent SSA variables @@ -2555,7 +2558,7 @@ static int zend_update_type_info(const zend_op_array *op_array, tmp |= MAY_BE_RCN; } } - if ((t1 & MAY_BE_ANY) == MAY_BE_LONG) { + if ((t1 & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_LONG) { if (!ssa_var_info[ssa_ops[i].op1_use].has_range || (opline->opcode == ZEND_PRE_DEC && (ssa_var_info[ssa_ops[i].op1_use].range.underflow || @@ -2617,7 +2620,7 @@ static int zend_update_type_info(const zend_op_array *op_array, if (t1 & (MAY_BE_RC1|MAY_BE_RCN)) { tmp |= MAY_BE_RC1; } - if ((t1 & MAY_BE_ANY) == MAY_BE_LONG) { + if ((t1 & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_LONG) { if (!ssa_var_info[ssa_ops[i].op1_use].has_range || (opline->opcode == ZEND_PRE_DEC && (ssa_var_info[ssa_ops[i].op1_use].range.underflow || diff --git a/ext/opcache/tests/bug77058.phpt b/ext/opcache/tests/bug77058.phpt new file mode 100644 index 0000000000..6a5a83cef7 --- /dev/null +++ b/ext/opcache/tests/bug77058.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #77058: Type inference in opcache causes side effects +--FILE-- +<?php + +function myfunc(){ + $Nr = 0; + while(1){ + $x--; + $x++; + if( ++ $Nr >= 2 ) break; + } + echo "'$Nr' is expected to be 2", PHP_EOL; +} +myfunc(); + +?> +--EXPECTF-- +Notice: Undefined variable: x in %s on line %d +'2' is expected to be 2 |