Skip to content

Commit 965dafe

Browse files
committed
Fix too aggressive DCE that leads to memory leak
Fixes oss-fuzz #43738
1 parent 464e725 commit 965dafe

File tree

2 files changed

+32
-9
lines changed

2 files changed

+32
-9
lines changed

ext/opcache/Optimizer/sccp.c

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2275,21 +2275,31 @@ static int try_remove_definition(sccp_ctx *ctx, int var_num, zend_ssa_var *var,
22752275
zend_optimizer_update_op1_const(ctx->scdf.op_array, opline, value);
22762276
}
22772277
return 0;
2278-
} else {
2279-
zend_ssa_remove_result_def(ssa, ssa_op);
2280-
if (opline->opcode == ZEND_DO_ICALL) {
2281-
removed_ops = remove_call(ctx, opline, ssa_op);
2282-
} else if (opline->opcode == ZEND_TYPE_CHECK
2283-
&& (opline->op1_type & (IS_VAR|IS_TMP_VAR))
2284-
&& (!value_known(&ctx->values[ssa_op->op1_use])
2285-
|| IS_PARTIAL_ARRAY(&ctx->values[ssa_op->op1_use])
2286-
|| IS_PARTIAL_OBJECT(&ctx->values[ssa_op->op1_use]))) {
2278+
} else if ((opline->op2_type & (IS_VAR|IS_TMP_VAR))
2279+
&& (!value_known(&ctx->values[ssa_op->op2_use])
2280+
|| IS_PARTIAL_ARRAY(&ctx->values[ssa_op->op2_use])
2281+
|| IS_PARTIAL_OBJECT(&ctx->values[ssa_op->op2_use]))) {
2282+
return 0;
2283+
} else if ((opline->op1_type & (IS_VAR|IS_TMP_VAR))
2284+
&& (!value_known(&ctx->values[ssa_op->op1_use])
2285+
|| IS_PARTIAL_ARRAY(&ctx->values[ssa_op->op1_use])
2286+
|| IS_PARTIAL_OBJECT(&ctx->values[ssa_op->op1_use]))) {
2287+
if (opline->opcode == ZEND_TYPE_CHECK
2288+
|| opline->opcode == ZEND_BOOL) {
2289+
zend_ssa_remove_result_def(ssa, ssa_op);
22872290
/* For TYPE_CHECK we may compute the result value without knowing the
22882291
* operand, based on type inference information. Make sure the operand is
22892292
* freed and leave further cleanup to DCE. */
22902293
opline->opcode = ZEND_FREE;
22912294
opline->result_type = IS_UNUSED;
22922295
removed_ops++;
2296+
} else {
2297+
return 0;
2298+
}
2299+
} else {
2300+
zend_ssa_remove_result_def(ssa, ssa_op);
2301+
if (opline->opcode == ZEND_DO_ICALL) {
2302+
removed_ops = remove_call(ctx, opline, ssa_op);
22932303
} else {
22942304
zend_ssa_remove_instr(ssa, opline, ssa_op);
22952305
removed_ops++;

ext/opcache/tests/opt/sccp_037.phpt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
--TEST--
2+
SCCP 037: Memory leak
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.optimization_level=-1
7+
--FILE--
8+
<?php
9+
[!![[new ERROR]]];
10+
?>
11+
DONE
12+
--EXPECT--
13+
DONE

0 commit comments

Comments
 (0)