1
0
mirror of https://github.com/php/php-src.git synced 2026-04-08 16:43:44 +02:00

Mark ASSIGN result as UNUSED in SCCP

We can't drop the ASSIGN entirely, but we should mark the result
as UNUSED. Otherwise we'll replace uses of it in operands and
will not free the ASSIGN result value. This can happen with
non-interned strings, but possibly there's some other cases that
can trigger this as well.
This commit is contained in:
Nikita Popov
2021-09-14 13:14:54 +02:00
parent 260d2acdb4
commit fa3d603ba2

View File

@@ -2188,12 +2188,13 @@ static int try_remove_definition(sccp_ctx *ctx, int var_num, zend_ssa_var *var,
zend_op *opline = &op_array->opcodes[var->definition];
zend_ssa_op *ssa_op = &ssa->ops[var->definition];
if (opline->opcode == ZEND_ASSIGN) {
/* Leave assigns to DCE (due to dtor effects) */
return 0;
}
if (ssa_op->result_def == var_num) {
if (opline->opcode == ZEND_ASSIGN) {
/* We can't drop the ASSIGN, but we can remove the result. */
opline->result_type = IS_UNUSED;
zend_ssa_remove_result_def(ssa, ssa_op);
return 0;
}
if (ssa_op->op1_def >= 0
|| ssa_op->op2_def >= 0) {
/* we cannot remove instruction that defines other variables */
@@ -2257,6 +2258,11 @@ static int try_remove_definition(sccp_ctx *ctx, int var_num, zend_ssa_var *var,
}
}
} else if (ssa_op->op1_def == var_num) {
if (opline->opcode == ZEND_ASSIGN) {
/* Leave assigns to DCE (due to dtor effects) */
return 0;
}
/* Compound assign or incdec -> convert to direct ASSIGN */
if (!value) {