com php-src: Fix return from by-ref generators: Zend/tests/gene rators/return_from_by_ref_generator.phpt Zend/zend _compile.c
| From: | Nikita Popov | Date: | Thu, 14 Jul 2016 13:44:04 +0000 |
| Subject: | com php-src: Fix return from by-ref generators: Zend/tests/gene rators/return_from_by_ref_generator.phpt Zend/zend _compile.c | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-93013@lists.php.net to get a copy of this message | ||
Commit: e3e400c983d91af84e57c5c8402260ac84ec5459
Author: Nikita Popov <nikic@php.net> Thu, 14 Jul 2016 15:44:04 +0200
Parents: 918e40366df1bc25a8bfebcbbd8b65ea397d9ae4
Branches: master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=e3e400c983d91af84e57c5c8402260ac84ec5459
Log:
Fix return from by-ref generators
Changed paths:
A Zend/tests/generators/return_from_by_ref_generator.phpt
M Zend/zend_compile.c
Diff:
diff --git a/Zend/tests/generators/return_from_by_ref_generator.phpt
b/Zend/tests/generators/return_from_by_ref_generator.phpt
new file mode 100644
index 0000000..32bebfb
--- /dev/null
+++ b/Zend/tests/generators/return_from_by_ref_generator.phpt
@@ -0,0 +1,20 @@
+--TEST--
+Return from by-ref generator
+--FILE--
+<?php
+
+function &gen() {
+ yield;
+ $arr = [42];
+ return $arr[0];
+}
+
+function gen2() {
+ var_dump(yield from gen());
+}
+
+gen2()->next();
+
+?>
+--EXPECT--
+int(42)
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 9a4ff33..ec95fd0 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -4120,11 +4120,17 @@ static int zend_has_finally(void) /* {{{ */
void zend_compile_return(zend_ast *ast) /* {{{ */
{
zend_ast *expr_ast = ast->child[0];
+ zend_bool is_generator = (CG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) != 0;
zend_bool by_ref = (CG(active_op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0;
znode expr_node;
zend_op *opline;
+ if (is_generator) {
+ /* For generators the by-ref flag refers to yields, not returns */
+ by_ref = 0;
+ }
+
if (!expr_ast) {
expr_node.op_type = IS_CONST;
ZVAL_NULL(&expr_node.u.constant);
@@ -4146,7 +4152,7 @@ void zend_compile_return(zend_ast *ast) /* {{{ */
}
/* Generator return types are handled separately */
- if (!(CG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) &&
CG(active_op_array)->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+ if (!is_generator && CG(active_op_array)->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
zend_emit_return_type_check(
expr_ast ? &expr_node : NULL, CG(active_op_array)->arg_info - 1, 0);
}
@@ -4156,10 +4162,10 @@ void zend_compile_return(zend_ast *ast) /* {{{ */
opline = zend_emit_op(NULL, by_ref ? ZEND_RETURN_BY_REF : ZEND_RETURN,
&expr_node, NULL);
- if (expr_ast) {
+ if (by_ref && expr_ast) {
if (zend_is_call(expr_ast)) {
opline->extended_value = ZEND_RETURNS_FUNCTION;
- } else if (by_ref && !zend_is_variable(expr_ast)) {
+ } else if (!zend_is_variable(expr_ast)) {
opline->extended_value = ZEND_RETURNS_VALUE;
}
}