]> granicus.if.org Git - php/commitdiff
Fixed bug #33558 (warning with nested calls to functions returning by reference)
authorDmitry Stogov <dmitry@php.net>
Mon, 18 Jul 2005 07:13:34 +0000 (07:13 +0000)
committerDmitry Stogov <dmitry@php.net>
Mon, 18 Jul 2005 07:13:34 +0000 (07:13 +0000)
NEWS
Zend/tests/bug33558.phpt [new file with mode: 0755]
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

diff --git a/NEWS b/NEWS
index f8dd061fb0b224d789b816abb376c62d48b819e6..7dbfdf27ce33b6363c8fe006867c948541c6f4c8 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,8 @@ PHP                                                                        NEWS
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 ?? ??? 2005, PHP 5.1
 - Fixed handling of HTTP requests with multiple Cookie headers. (Ilia)
+- Fixed bug #33558 (warning with nested calls to functions returning by
+  reference). (Dmitry)
 
 14 Jul 2005, PHP 5.1 Beta 3
 - Upgraded bundled SQLite library for PDO:SQLite to 3.2.2 (Ilia)
diff --git a/Zend/tests/bug33558.phpt b/Zend/tests/bug33558.phpt
new file mode 100755 (executable)
index 0000000..9c87fc6
--- /dev/null
@@ -0,0 +1,21 @@
+--TEST--
+Bug #33558 (warning with nested calls to functions returning by reference)
+--INI--
+error_reporting=4095
+--FILE--
+<?php
+function & foo() {
+    $var = 'ok';
+    return $var;
+}
+
+function & bar() {
+    return foo();
+}
+
+$a =& bar();
+echo "$a\n";
+?>
+--EXPECT--
+ok
+
index d4fb7b1a3f3c6fee430fba9c41489e1662d244fb..f0579e637d590aa62be0e0461bfcfe18378dc9af 100644 (file)
@@ -1991,8 +1991,9 @@ ZEND_VM_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY)
                }
 
                if (OP1_TYPE == IS_VAR && !(*retval_ptr_ptr)->is_ref) {
-                       if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr
-                               || (opline->extended_value == ZEND_RETURNS_FUNCTION && !EX_T(opline->op1.u.var).var.fcall_returned_reference)) {
+                       if (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+                           EX_T(opline->op1.u.var).var.fcall_returned_reference) {
+                       } else if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr) {
                                if (OP1_TYPE == IS_VAR && !OP1_FREE) {
                                        PZVAL_LOCK(*retval_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */
                                }
@@ -2169,7 +2170,7 @@ ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR|CV, ANY)
        }
        if ((opline->extended_value & ZEND_ARG_SEND_FUNCTION) &&
            !EX_T(opline->op1.u.var).var.fcall_returned_reference) {
-               zend_error(E_ERROR, "Only variables can be passed by reference");
+               zend_error_noreturn(E_ERROR, "Only variables can be passed by reference");
        } else {
                zval *varptr;
                zend_free_op free_op1;
index ee898636942d6825320002095f51397b43262432..cff24db0f2a0334327fa8d920d2c5d8e70f9d75a 100644 (file)
@@ -1601,8 +1601,9 @@ static int ZEND_RETURN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                }
 
                if (IS_CONST == IS_VAR && !(*retval_ptr_ptr)->is_ref) {
-                       if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr
-                               || (opline->extended_value == ZEND_RETURNS_FUNCTION && !EX_T(opline->op1.u.var).var.fcall_returned_reference)) {
+                       if (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+                           EX_T(opline->op1.u.var).var.fcall_returned_reference) {
+                       } else if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr) {
                                if (IS_CONST == IS_VAR && !0) {
                                        PZVAL_LOCK(*retval_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */
                                }
@@ -4010,8 +4011,9 @@ static int ZEND_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                }
 
                if (IS_TMP_VAR == IS_VAR && !(*retval_ptr_ptr)->is_ref) {
-                       if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr
-                               || (opline->extended_value == ZEND_RETURNS_FUNCTION && !EX_T(opline->op1.u.var).var.fcall_returned_reference)) {
+                       if (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+                           EX_T(opline->op1.u.var).var.fcall_returned_reference) {
+                       } else if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr) {
                                if (IS_TMP_VAR == IS_VAR && !1) {
                                        PZVAL_LOCK(*retval_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */
                                }
@@ -6940,8 +6942,9 @@ static int ZEND_RETURN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                }
 
                if (IS_VAR == IS_VAR && !(*retval_ptr_ptr)->is_ref) {
-                       if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr
-                               || (opline->extended_value == ZEND_RETURNS_FUNCTION && !EX_T(opline->op1.u.var).var.fcall_returned_reference)) {
+                       if (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+                           EX_T(opline->op1.u.var).var.fcall_returned_reference) {
+                       } else if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr) {
                                if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) {
                                        PZVAL_LOCK(*retval_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */
                                }
@@ -7090,7 +7093,7 @@ static int ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        }
        if ((opline->extended_value & ZEND_ARG_SEND_FUNCTION) &&
            !EX_T(opline->op1.u.var).var.fcall_returned_reference) {
-               zend_error(E_ERROR, "Only variables can be passed by reference");
+               zend_error_noreturn(E_ERROR, "Only variables can be passed by reference");
        } else {
                zval *varptr;
                zend_free_op free_op1;
@@ -18987,8 +18990,9 @@ static int ZEND_RETURN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                }
 
                if (IS_CV == IS_VAR && !(*retval_ptr_ptr)->is_ref) {
-                       if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr
-                               || (opline->extended_value == ZEND_RETURNS_FUNCTION && !EX_T(opline->op1.u.var).var.fcall_returned_reference)) {
+                       if (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+                           EX_T(opline->op1.u.var).var.fcall_returned_reference) {
+                       } else if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr) {
                                if (IS_CV == IS_VAR && !0) {
                                        PZVAL_LOCK(*retval_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */
                                }
@@ -19137,7 +19141,7 @@ static int ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        }
        if ((opline->extended_value & ZEND_ARG_SEND_FUNCTION) &&
            !EX_T(opline->op1.u.var).var.fcall_returned_reference) {
-               zend_error(E_ERROR, "Only variables can be passed by reference");
+               zend_error_noreturn(E_ERROR, "Only variables can be passed by reference");
        } else {
                zval *varptr;