Skip to content

Commit

Permalink
Merge branch 'PHP-8.1'
Browse files Browse the repository at this point in the history
* PHP-8.1:
  Fix self-assign evaluation order for ASSIGN_DIM_OP
  • Loading branch information
nikic committed Nov 1, 2021
2 parents 54ef4f7 + 55aadc6 commit a899dc9
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 30 deletions.
19 changes: 19 additions & 0 deletions Zend/tests/assign_dim_op_same_var.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
--TEST--
Compound array assignment with same variable
--FILE--
<?php
function test() {
$ary = [[]];
$ary[0] += $ary;
foreach ($ary as $v) {
var_dump($v);
}
}
test();
?>
--EXPECT--
array(1) {
[0]=>
array(0) {
}
}
46 changes: 20 additions & 26 deletions Zend/zend_compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -3090,6 +3090,22 @@ static bool zend_is_assign_to_self(zend_ast *var_ast, zend_ast *expr_ast) /* {{{
}
/* }}} */

static void zend_compile_expr_with_potential_assign_to_self(
znode *expr_node, zend_ast *expr_ast, zend_ast *var_ast) {
if (zend_is_assign_to_self(var_ast, expr_ast) && !is_this_fetch(expr_ast)) {
/* $a[0] = $a should evaluate the right $a first */
znode cv_node;

if (zend_try_compile_cv(&cv_node, expr_ast) == FAILURE) {
zend_compile_simple_var_no_cv(expr_node, expr_ast, BP_VAR_R, 0);
} else {
zend_emit_op_tmp(expr_node, ZEND_QM_ASSIGN, &cv_node, NULL);
}
} else {
zend_compile_expr(expr_node, expr_ast);
}
}

static void zend_compile_assign(znode *result, zend_ast *ast) /* {{{ */
{
zend_ast *var_ast = ast->child[0];
Expand Down Expand Up @@ -3130,20 +3146,7 @@ static void zend_compile_assign(znode *result, zend_ast *ast) /* {{{ */
case ZEND_AST_DIM:
offset = zend_delayed_compile_begin();
zend_delayed_compile_dim(result, var_ast, BP_VAR_W, /* by_ref */ false);

if (zend_is_assign_to_self(var_ast, expr_ast)
&& !is_this_fetch(expr_ast)) {
/* $a[0] = $a should evaluate the right $a first */
znode cv_node;

if (zend_try_compile_cv(&cv_node, expr_ast) == FAILURE) {
zend_compile_simple_var_no_cv(&expr_node, expr_ast, BP_VAR_R, 0);
} else {
zend_emit_op_tmp(&expr_node, ZEND_QM_ASSIGN, &cv_node, NULL);
}
} else {
zend_compile_expr(&expr_node, expr_ast);
}
zend_compile_expr_with_potential_assign_to_self(&expr_node, expr_ast, var_ast);

opline = zend_delayed_compile_end(offset);
opline->opcode = ZEND_ASSIGN_DIM;
Expand Down Expand Up @@ -3313,7 +3316,7 @@ static void zend_compile_compound_assign(znode *result, zend_ast *ast) /* {{{ */
case ZEND_AST_DIM:
offset = zend_delayed_compile_begin();
zend_delayed_compile_dim(result, var_ast, BP_VAR_RW, /* by_ref */ false);
zend_compile_expr(&expr_node, expr_ast);
zend_compile_expr_with_potential_assign_to_self(&expr_node, expr_ast, var_ast);

opline = zend_delayed_compile_end(offset);
opline->opcode = ZEND_ASSIGN_DIM_OP;
Expand Down Expand Up @@ -8902,17 +8905,8 @@ static void zend_compile_assign_coalesce(znode *result, zend_ast *ast) /* {{{ */
zend_emit_op_tmp(result, ZEND_COALESCE, &var_node_is, NULL);

CG(memoize_mode) = ZEND_MEMOIZE_NONE;
if (var_ast->kind == ZEND_AST_DIM
&& zend_is_assign_to_self(var_ast, default_ast)
&& !is_this_fetch(default_ast)) {
/* $a[0] = $a should evaluate the right $a first */
znode cv_node;

if (zend_try_compile_cv(&cv_node, default_ast) == FAILURE) {
zend_compile_simple_var_no_cv(&default_node, default_ast, BP_VAR_R, 0);
} else {
zend_emit_op_tmp(&default_node, ZEND_QM_ASSIGN, &cv_node, NULL);
}
if (var_ast->kind == ZEND_AST_DIM) {
zend_compile_expr_with_potential_assign_to_self(&default_node, default_ast, var_ast);
} else {
zend_compile_expr(&default_node, default_ast);
}
Expand Down
6 changes: 2 additions & 4 deletions ext/opcache/tests/jit/assign_dim_op_004.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,8 @@ $a = null;
$a[] .= $a;
var_dump($a);
?>
--EXPECTF--
Warning: Array to string conversion in %sassign_dim_op_004.php on line 3
--EXPECT--
array(1) {
[0]=>
string(5) "Array"
string(0) ""
}

0 comments on commit a899dc9

Please sign in to comment.