diff options
author | Nikita Popov <nikic@php.net> | 2014-09-20 21:58:06 +0200 |
---|---|---|
committer | Nikita Popov <nikic@php.net> | 2014-09-20 21:58:06 +0200 |
commit | 6219a4e844e82f8eacd9ad6d24bb92739dcd6ff6 (patch) | |
tree | 2c1adab8272d1629669a2fa1365a745bf7f44846 | |
parent | 2fc1a1dce557875d029f16d58bd3d4cd22af54fb (diff) | |
parent | 308c0a727ec496ff551f67052b0835de3c152c11 (diff) | |
download | php-git-6219a4e844e82f8eacd9ad6d24bb92739dcd6ff6.tar.gz |
Merge branch 'PHP-5.6'
Conflicts:
Zend/zend_compile.c
-rw-r--r-- | Zend/tests/bug67633.phpt | 44 | ||||
-rw-r--r-- | Zend/zend_compile.c | 4 |
2 files changed, 48 insertions, 0 deletions
diff --git a/Zend/tests/bug67633.phpt b/Zend/tests/bug67633.phpt new file mode 100644 index 0000000000..a9e05d10ab --- /dev/null +++ b/Zend/tests/bug67633.phpt @@ -0,0 +1,44 @@ +--TEST-- +Bug #67633: A foreach on an array returned from a function not doing copy-on-write +--FILE-- +<?php + +function id($x) { + return $x; +} + +function &ref_id(&$x) { + return $x; +} + +$c = 'c'; +$array = ['a', 'b', $c]; + +foreach(id($array) as &$v) { + $v .= 'q'; +} +var_dump($array); + +foreach(ref_id($array) as &$v) { + $v .= 'q'; +} +var_dump($array); + +?> +--EXPECT-- +array(3) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" +} +array(3) { + [0]=> + string(2) "aq" + [1]=> + string(2) "bq" + [2]=> + &string(2) "cq" +} diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index c5337595c5..15902256db 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -3413,6 +3413,10 @@ void zend_compile_foreach(zend_ast *ast TSRMLS_DC) /* {{{ */ zend_compile_expr(&expr_node, expr_ast TSRMLS_CC); } + if (by_ref) { + zend_separate_if_call_and_write(&expr_node, expr_ast, BP_VAR_W TSRMLS_CC); + } + opnum_reset = get_next_op_number(CG(active_op_array)); opline = zend_emit_op(&reset_node, ZEND_FE_RESET, &expr_node, NULL TSRMLS_CC); if (by_ref && is_variable) { |