com php-src: Remove reference restrictions from foreach: Zend/tests/errmsg_043.phpt Zend/tests/foreach_tem p_array_expr_with_refs.phpt
Zend/tests/generators/y ield_by_reference.phpt Zend/zend_compile.c Zend/z end_language_parser.y tests/lang/foreachLoop.00 8.phpt
| From: | Gustavo André dos Santos Lopes | Date: | Sun, 22 Jul 2012 12:33:25 +0000 |
| Subject: | com php-src: Remove reference restrictions from foreach: Zend/tests/errmsg_043.phpt Zend/tests/foreach_tem p_array_expr_with_refs.phpt Zend/tests/generators/y ield_by_reference.phpt Zend/zend_compile.c Zend/z end_language_parser.y tests/lang/foreachLoop.00 8.phpt |
||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-70037@lists.php.net to get a copy of this message | ||
Commit: de80e3ce4b5b7a9ec0cfdd0778e77027a7ebfcc2
Author: Nikita Popov <nikic@php.net> Sun, 22 Jul 2012 14:33:25 +0200
Parents: 80748631aa1c4193cbc68f8854d82e7a57817fe2
Branches: master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=de80e3ce4b5b7a9ec0cfdd0778e77027a7ebfcc2
Log:
Remove reference restrictions from foreach
foreach only allowed variables to be traversed by reference. This never
really made sense because
a) Expressions like array(&$a, &$b) can be meaningfully iterated by-ref
b) Function calls can return by-ref (so they can also be meaningfully
iterated)
c) Iterators could at least in theory also be iterated by-ref (not
sure if any iterator makes use of this)
With by-ref generators the restriction makes even less sense, so I removed
it altogether.
Changed paths:
D Zend/tests/errmsg_043.phpt
A Zend/tests/foreach_temp_array_expr_with_refs.phpt
M Zend/tests/generators/yield_by_reference.phpt
M Zend/zend_compile.c
M Zend/zend_language_parser.y
D tests/lang/foreachLoop.008.phpt
Diff:
diff --git a/Zend/tests/errmsg_043.phpt b/Zend/tests/errmsg_043.phpt
deleted file mode 100644
index 3de8bc2..0000000
--- a/Zend/tests/errmsg_043.phpt
+++ /dev/null
@@ -1,12 +0,0 @@
---TEST--
-errmsg: cannot create references to temp array
---FILE--
-<?php
-
-foreach (array(1,2,3) as $k=>&$v) {
-}
-
-echo "Done\n";
-?>
---EXPECTF--
-Fatal error: Cannot create references to elements of a temporary array expression in %s on line %d
diff --git a/Zend/tests/foreach_temp_array_expr_with_refs.phpt
b/Zend/tests/foreach_temp_array_expr_with_refs.phpt
new file mode 100644
index 0000000..8978b7b
--- /dev/null
+++ b/Zend/tests/foreach_temp_array_expr_with_refs.phpt
@@ -0,0 +1,18 @@
+--TEST--
+Temporary array expressions can be iterated by reference
+--FILE--
+<?php
+
+$a = 'a';
+$b = 'b';
+
+foreach ([&$a, &$b] as &$value) {
+ $value .= '-foo';
+}
+
+var_dump($a, $b);
+
+?>
+--EXPECT--
+string(5) "a-foo"
+string(5) "b-foo"
diff --git a/Zend/tests/generators/yield_by_reference.phpt
b/Zend/tests/generators/yield_by_reference.phpt
index 5a6c169..dba0791 100644
--- a/Zend/tests/generators/yield_by_reference.phpt
+++ b/Zend/tests/generators/yield_by_reference.phpt
@@ -9,24 +9,34 @@ function &iter(array &$array) {
}
}
-$array = [1, 2, 3, 4, 5];
+$array = [1, 2, 3];
$iter = iter($array);
foreach ($iter as &$value) {
$value *= -1;
}
var_dump($array);
+$array = [1, 2, 3];
+foreach (iter($array) as &$value) {
+ $value *= -1;
+}
+var_dump($array);
+
?>
--EXPECT--
-array(5) {
+array(3) {
+ [0]=>
+ int(-1)
+ [1]=>
+ int(-2)
+ [2]=>
+ &int(-3)
+}
+array(3) {
[0]=>
int(-1)
[1]=>
int(-2)
[2]=>
- int(-3)
- [3]=>
- int(-4)
- [4]=>
- &int(-5)
+ &int(-3)
}
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 51fc8c3...f0648a2 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -6317,9 +6317,7 @@ void zend_do_foreach_cont(znode *foreach_token, const znode
*open_brackets_token
if (value->EA & ZEND_PARSED_REFERENCE_VARIABLE) {
assign_by_ref = 1;
- if (!(opline-1)->extended_value) {
- zend_error(E_COMPILE_ERROR, "Cannot create references to elements of a temporary array
expression");
- }
+
/* Mark extended_value for assign-by-reference */
opline->extended_value |= ZEND_FE_FETCH_BYREF;
CG(active_op_array)->opcodes[foreach_token->u.op.opline_num].extended_value |=
ZEND_FE_RESET_REFERENCE;
diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y
index e5f31b5..4221752 100644
--- a/Zend/zend_language_parser.y
+++ b/Zend/zend_language_parser.y
@@ -312,7 +312,7 @@ unticked_statement:
foreach_statement { zend_do_foreach_end(&$1, &$4 TSRMLS_CC); }
| T_FOREACH '(' expr_without_variable T_AS
{ zend_do_foreach_begin(&$1, &$2, &$3, &$4, 0 TSRMLS_CC); }
- variable foreach_optional_arg ')' { zend_check_writable_variable(&$6);
zend_do_foreach_cont(&$1, &$2, &$4, &$6, &$7 TSRMLS_CC); }
+ foreach_variable foreach_optional_arg ')' { zend_do_foreach_cont(&$1, &$2,
&$4, &$6, &$7 TSRMLS_CC); }
foreach_statement { zend_do_foreach_end(&$1, &$4 TSRMLS_CC); }
| T_DECLARE { $1.u.op.opline_num = get_next_op_number(CG(active_op_array));
zend_do_declare_begin(TSRMLS_C); } '(' declare_list ')' declare_statement {
zend_do_declare_end(&$1 TSRMLS_CC); }
| ';' /* empty statement */
diff --git a/tests/lang/foreachLoop.008.phpt b/tests/lang/foreachLoop.008.phpt
deleted file mode 100644
index 787f43b..0000000
--- a/tests/lang/foreachLoop.008.phpt
+++ /dev/null
@@ -1,10 +0,0 @@
---TEST--
-Foreach loop tests - error case: reference to constant array, with key.
---FILE--
-<?php
-foreach (array(1,2) as $k=>&$v) {
- var_dump($v);
-}
-?>
---EXPECTF--
-Fatal error: Cannot create references to elements of a temporary array expression in %s on line 2