Check that POST_INC/DEC has use in DFA optimization

We'd have usually converted it into a PRE_INC if there is no use,
but that's not guaranteed. If there is no use at this point, make
sure we don't try to use the sentinel value.
This commit is contained in:
Nikita Popov 2021-09-09 15:48:51 +02:00
parent 8c3d33a054
commit 5cae6b9b0d
2 changed files with 15 additions and 2 deletions

View File

@ -0,0 +1,13 @@
--TEST--
POST_INC without use during DFA optimization
--FILE--
<?php
function test($n) {
for ($i = 0; $i < $n; !$i++) {}
}
?>
===DONE===
--EXPECT--
===DONE===

View File

@ -1388,7 +1388,7 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx
&& (ssa->var_info[result_var].type & ((MAY_BE_ANY|MAY_BE_REF|MAY_BE_UNDEF) - (MAY_BE_LONG|MAY_BE_DOUBLE))) == 0) { && (ssa->var_info[result_var].type & ((MAY_BE_ANY|MAY_BE_REF|MAY_BE_UNDEF) - (MAY_BE_LONG|MAY_BE_DOUBLE))) == 0) {
int use = ssa->vars[result_var].use_chain; int use = ssa->vars[result_var].use_chain;
if (op_array->opcodes[use].opcode == ZEND_IS_SMALLER if (use >= 0 && op_array->opcodes[use].opcode == ZEND_IS_SMALLER
&& ssa->ops[use].op1_use == result_var && ssa->ops[use].op1_use == result_var
&& zend_dfa_try_to_replace_result(op_array, ssa, op_1, v)) { && zend_dfa_try_to_replace_result(op_array, ssa, op_1, v)) {
opline->opcode = ZEND_PRE_INC; opline->opcode = ZEND_PRE_INC;
@ -1402,7 +1402,7 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx
&& (ssa->var_info[result_var].type & ((MAY_BE_ANY|MAY_BE_REF|MAY_BE_UNDEF) - (MAY_BE_LONG|MAY_BE_DOUBLE))) == 0) { && (ssa->var_info[result_var].type & ((MAY_BE_ANY|MAY_BE_REF|MAY_BE_UNDEF) - (MAY_BE_LONG|MAY_BE_DOUBLE))) == 0) {
int use = ssa->vars[result_var].use_chain; int use = ssa->vars[result_var].use_chain;
if (op_array->opcodes[use].opcode == ZEND_IS_SMALLER if (use >= 0 && op_array->opcodes[use].opcode == ZEND_IS_SMALLER
&& ssa->ops[use].op2_use == result_var && ssa->ops[use].op2_use == result_var
&& zend_dfa_try_to_replace_result(op_array, ssa, op_1, v)) { && zend_dfa_try_to_replace_result(op_array, ssa, op_1, v)) {
opline->opcode = ZEND_PRE_DEC; opline->opcode = ZEND_PRE_DEC;