diff --git a/ext/opcache/Optimizer/zend_inference.c b/ext/opcache/Optimizer/zend_inference.c index a130a7fba0d..9f9925e181b 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/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c index d3f30392fb2..602627df7ed 100644 --- a/ext/opcache/Optimizer/zend_optimizer.c +++ b/ext/opcache/Optimizer/zend_optimizer.c @@ -1481,8 +1481,11 @@ int zend_optimize_script(zend_script *script, zend_long optimization_level, zend for (i = 0; i < call_graph.op_arrays_count; i++) { func_info = ZEND_FUNC_INFO(call_graph.op_arrays[i]); if (func_info) { - zend_dfa_analyze_op_array(call_graph.op_arrays[i], &ctx, &func_info->ssa); - func_info->flags = func_info->ssa.cfg.flags; + if (zend_dfa_analyze_op_array(call_graph.op_arrays[i], &ctx, &func_info->ssa) == SUCCESS) { + func_info->flags = func_info->ssa.cfg.flags; + } else { + ZEND_SET_FUNC_INFO(call_graph.op_arrays[i], NULL); + } } } diff --git a/ext/opcache/tests/bug77058.phpt b/ext/opcache/tests/bug77058.phpt new file mode 100644 index 00000000000..6a5a83cef7a --- /dev/null +++ b/ext/opcache/tests/bug77058.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #77058: Type inference in opcache causes side effects +--FILE-- += 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