From be271f277eb5a9a3fc35f20bffb85b0d4957f4a6 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 24 Nov 2021 15:18:31 +0100 Subject: [PATCH] Fix bug #81652 We need to check not only for defs but also for uses of the variable. --- NEWS | 1 + Zend/tests/bug81652.phpt | 22 ++++++++++++++++++++++ ext/opcache/Optimizer/dfa_pass.c | 24 +++++++++++------------- 3 files changed, 34 insertions(+), 13 deletions(-) create mode 100644 Zend/tests/bug81652.phpt diff --git a/NEWS b/NEWS index 545529f5689..8af82b544a8 100644 --- a/NEWS +++ b/NEWS @@ -49,6 +49,7 @@ PHP NEWS - Opcache: . Fixed bug #81512 (Unexpected behavior with arrays and JIT). (Dmitry) + . Fixed bug #81652 (The value of error_reporting() gets overridden). (Nikita) - PCRE: . Fixed bug #81424 (PCRE2 10.35 JIT performance regression). (cmb) diff --git a/Zend/tests/bug81652.phpt b/Zend/tests/bug81652.phpt new file mode 100644 index 00000000000..d0fa78b23e1 --- /dev/null +++ b/Zend/tests/bug81652.phpt @@ -0,0 +1,22 @@ +--TEST-- +Bug #81652: The value of error_reporting() gets overridden +--FILE-- +a = true ? @random_int(0, 100) : false; + } +} + +var_dump(error_reporting()); +$c = new Foo(); +$c->bar(); +var_dump(error_reporting()); + +?> +--EXPECT-- +int(32767) +int(32767) diff --git a/ext/opcache/Optimizer/dfa_pass.c b/ext/opcache/Optimizer/dfa_pass.c index aff91f554f2..7a03c8ba02a 100644 --- a/ext/opcache/Optimizer/dfa_pass.c +++ b/ext/opcache/Optimizer/dfa_pass.c @@ -360,19 +360,17 @@ static zend_bool opline_supports_assign_contraction( return 1; } -static bool variable_redefined_in_range(zend_ssa *ssa, int var, int start, int end) +static bool variable_defined_or_used_in_range(zend_ssa *ssa, int var, int start, int end) { while (start < end) { - if (ssa->ops[start].op1_def >= 0 - && ssa->vars[ssa->ops[start].op1_def].var == var) { - return 1; - } - if (ssa->ops[start].op2_def >= 0 - && ssa->vars[ssa->ops[start].op2_def].var == var) { - return 1; - } - if (ssa->ops[start].result_def >= 0 - && ssa->vars[ssa->ops[start].result_def].var == var) { + const zend_ssa_op *ssa_op = &ssa->ops[start]; + if ((ssa_op->op1_def >= 0 && ssa->vars[ssa_op->op1_def].var == var) || + (ssa_op->op2_def >= 0 && ssa->vars[ssa_op->op2_def].var == var) || + (ssa_op->result_def >= 0 && ssa->vars[ssa_op->result_def].var == var) || + (ssa_op->op1_use >= 0 && ssa->vars[ssa_op->op1_use].var == var) || + (ssa_op->op2_use >= 0 && ssa->vars[ssa_op->op2_use].var == var) || + (ssa_op->result_use >= 0 && ssa->vars[ssa_op->result_use].var == var) + ) { return 1; } start++; @@ -1310,7 +1308,7 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx && opline_supports_assign_contraction( ssa, &op_array->opcodes[ssa->vars[src_var].definition], src_var, opline->result.var) - && !variable_redefined_in_range(ssa, EX_VAR_TO_NUM(opline->result.var), + && !variable_defined_or_used_in_range(ssa, EX_VAR_TO_NUM(opline->result.var), ssa->vars[src_var].definition+1, op_1) ) { @@ -1467,7 +1465,7 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx && opline_supports_assign_contraction( ssa, &op_array->opcodes[ssa->vars[src_var].definition], src_var, opline->op1.var) - && !variable_redefined_in_range(ssa, EX_VAR_TO_NUM(opline->op1.var), + && !variable_defined_or_used_in_range(ssa, EX_VAR_TO_NUM(opline->op1.var), ssa->vars[src_var].definition+1, op_1) ) {