mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Don't treat expression exit as terminator
Same as with throw expressions, this may remove later temporary consuming instructions and thus eliminate live ranges, resulting in a memory leak. We make use of the same hack and don't consider exit a terminator if used in an expression context.
This commit is contained in:
parent
757c1277eb
commit
c9762be566
3 changed files with 14 additions and 6 deletions
|
@ -299,13 +299,13 @@ ZEND_API int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, u
|
|||
case ZEND_RETURN:
|
||||
case ZEND_RETURN_BY_REF:
|
||||
case ZEND_GENERATOR_RETURN:
|
||||
case ZEND_EXIT:
|
||||
case ZEND_MATCH_ERROR:
|
||||
case ZEND_VERIFY_NEVER_TYPE:
|
||||
if (i + 1 < op_array->last) {
|
||||
BB_START(i + 1);
|
||||
}
|
||||
break;
|
||||
case ZEND_EXIT:
|
||||
case ZEND_THROW:
|
||||
/* Don't treat THROW as terminator if it's used in expression context,
|
||||
* as we may lose live ranges when eliminating unreachable code. */
|
||||
|
|
|
@ -23,6 +23,9 @@ try {
|
|||
}
|
||||
var_dump(error_reporting());
|
||||
|
||||
// Exit also unwinds and thus has the same basic problem.
|
||||
new stdClass(exit);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
Caught
|
||||
|
|
|
@ -9045,18 +9045,22 @@ static void zend_compile_print(znode *result, zend_ast *ast) /* {{{ */
|
|||
static void zend_compile_exit(znode *result, zend_ast *ast) /* {{{ */
|
||||
{
|
||||
zend_ast *expr_ast = ast->child[0];
|
||||
znode expr_node;
|
||||
|
||||
if (expr_ast) {
|
||||
znode expr_node;
|
||||
zend_compile_expr(&expr_node, expr_ast);
|
||||
zend_emit_op(NULL, ZEND_EXIT, &expr_node, NULL);
|
||||
} else {
|
||||
zend_emit_op(NULL, ZEND_EXIT, NULL, NULL);
|
||||
expr_node.op_type = IS_UNUSED;
|
||||
}
|
||||
|
||||
zend_op *opline = zend_emit_op(NULL, ZEND_EXIT, &expr_node, NULL);
|
||||
if (result) {
|
||||
/* Mark this as an "expression throw" for opcache. */
|
||||
opline->extended_value = ZEND_THROW_IS_EXPR;
|
||||
result->op_type = IS_CONST;
|
||||
ZVAL_TRUE(&result->u.constant);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static void zend_compile_yield(znode *result, zend_ast *ast) /* {{{ */
|
||||
|
@ -9999,6 +10003,7 @@ static void zend_compile_stmt(zend_ast *ast) /* {{{ */
|
|||
zend_compile_halt_compiler(ast);
|
||||
break;
|
||||
case ZEND_AST_THROW:
|
||||
case ZEND_AST_EXIT:
|
||||
zend_compile_expr(NULL, ast);
|
||||
break;
|
||||
default:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue