summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS3
-rw-r--r--ext/opcache/Optimizer/zend_inference.c9
-rw-r--r--ext/opcache/tests/bug77058.phpt20
3 files changed, 29 insertions, 3 deletions
diff --git a/NEWS b/NEWS
index fc017b96f6..aa12469b6a 100644
--- a/NEWS
+++ b/NEWS
@@ -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