]> granicus.if.org Git - php/commitdiff
Fixed bug #69419
authorNikita Popov <nikic@php.net>
Tue, 14 Apr 2015 14:35:23 +0000 (16:35 +0200)
committerNikita Popov <nikic@php.net>
Tue, 14 Apr 2015 14:35:23 +0000 (16:35 +0200)
NEWS
Zend/tests/generators/bug69419.phpt [new file with mode: 0644]
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

diff --git a/NEWS b/NEWS
index 800393842dd3287ec72d98fe61440161fe25b20a..a71c3fca5b5c1be792215e858097b786c38e7599 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,8 @@ PHP                                                                        NEWS
   . Fixed bug #67314 (Segmentation fault in gc_remove_zval_from_buffer).
     (Dmitry)
   . Fixed bug #68652 (segmentation fault in destructor). (Dmitry)
+  . Fixed bug #69419 (Returning compatible sub generator produces a warning).
+    (Nikita)
 
 - cURL:
   . Fixed bug #68739 (Missing break / control flow). (Laruence)
diff --git a/Zend/tests/generators/bug69419.phpt b/Zend/tests/generators/bug69419.phpt
new file mode 100644 (file)
index 0000000..dce08ed
--- /dev/null
@@ -0,0 +1,22 @@
+--TEST--
+Bug #69419: Returning compatible sub generator produces a warning
+--FILE--
+<?php
+
+function & genRefInner() {
+    $var = 1;
+    yield $var;
+}
+
+function & genRefOuter() {
+    return genRefInner();
+}
+
+foreach(genRefOuter() as $i) {
+    var_dump($i);
+}
+
+?>
+--EXPECTF--
+Notice: Only variable references should be returned by reference in %s on line %d
+int(1)
index 66758d47fab6ca73f5c41c96df97084095809c0f..9e68290a9e6c9a8a1b628b115c7c1f5ded84ec8a 100644 (file)
@@ -1996,13 +1996,12 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
                        EX_T(opline->result.var).var.ptr = NULL;
                }
        } else if (fbc->type == ZEND_USER_FUNCTION) {
+               temp_variable *ret = &EX_T(opline->result.var);
                EX(original_return_value) = EG(return_value_ptr_ptr);
                EG(active_symbol_table) = NULL;
                EG(active_op_array) = &fbc->op_array;
                EG(return_value_ptr_ptr) = NULL;
                if (RETURN_VALUE_USED(opline)) {
-                       temp_variable *ret = &EX_T(opline->result.var);
-
                        ret->var.ptr = NULL;
                        EG(return_value_ptr_ptr) = &ret->var.ptr;
                        ret->var.ptr_ptr = &ret->var.ptr;
@@ -2011,7 +2010,8 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
 
                if (UNEXPECTED((EG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) != 0)) {
                        if (RETURN_VALUE_USED(opline)) {
-                               EX_T(opline->result.var).var.ptr = zend_generator_create_zval(EG(active_op_array) TSRMLS_CC);
+                               ret->var.ptr = zend_generator_create_zval(EG(active_op_array) TSRMLS_CC);
+                               ret->var.fcall_returned_reference = 0;
                        }
                } else if (EXPECTED(zend_execute_ex == execute_ex)) {
                        if (EXPECTED(EG(exception) == NULL)) {
index 58ca552b82c81d5c8987c8d2050b57120d43ed06..706d00b1b416318b56c9325b6f0309b7aec584fa 100644 (file)
@@ -559,13 +559,12 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR
                        EX_T(opline->result.var).var.ptr = NULL;
                }
        } else if (fbc->type == ZEND_USER_FUNCTION) {
+               temp_variable *ret = &EX_T(opline->result.var);
                EX(original_return_value) = EG(return_value_ptr_ptr);
                EG(active_symbol_table) = NULL;
                EG(active_op_array) = &fbc->op_array;
                EG(return_value_ptr_ptr) = NULL;
                if (RETURN_VALUE_USED(opline)) {
-                       temp_variable *ret = &EX_T(opline->result.var);
-
                        ret->var.ptr = NULL;
                        EG(return_value_ptr_ptr) = &ret->var.ptr;
                        ret->var.ptr_ptr = &ret->var.ptr;
@@ -574,7 +573,8 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR
 
                if (UNEXPECTED((EG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) != 0)) {
                        if (RETURN_VALUE_USED(opline)) {
-                               EX_T(opline->result.var).var.ptr = zend_generator_create_zval(EG(active_op_array) TSRMLS_CC);
+                               ret->var.ptr = zend_generator_create_zval(EG(active_op_array) TSRMLS_CC);
+                               ret->var.fcall_returned_reference = 0;
                        }
                } else if (EXPECTED(zend_execute_ex == execute_ex)) {
                        if (EXPECTED(EG(exception) == NULL)) {