Fixed bug #70117 (Unexpected return type error)
authorXinchen Hui <laruence@php.net>
Thu, 23 Jul 2015 03:16:10 +0000 (11:16 +0800)
committerXinchen Hui <laruence@php.net>
Thu, 23 Jul 2015 03:16:10 +0000 (11:16 +0800)
NEWS
Zend/tests/bug70117.phpt [new file with mode: 0644]
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

diff --git a/NEWS b/NEWS
index 6fed09f52c1ecf0b79148520fd16d71a6ac489f5..8f5781375ee1ee230cd5149da407bfd0cf164360 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,7 @@ PHP                                                                        NEWS
 06 Aug 2015, PHP 7.0.0 Beta 3
 
 - Core:
+  . Fixed bug #70117 (Unexpected return type error). (Laruence)
   . Fixed bug #70106 (Inheritance by anonymous class). (Bob)
 
 - Opcache:
diff --git a/Zend/tests/bug70117.phpt b/Zend/tests/bug70117.phpt
new file mode 100644 (file)
index 0000000..4bdd12c
--- /dev/null
@@ -0,0 +1,21 @@
+--TEST--
+Bug #70117 (Unexpected return type error)
+--FILE--
+<?php
+
+function &foo() :string {
+       $a = array(1);
+       $b = &$a[0];
+       return $b;
+}
+
+function &foo1() :string {
+       $a = array("ref");
+       return $a[0];
+}
+
+var_dump(foo());
+var_dump(foo1());
+--EXPECT--
+string(1) "1"
+string(3) "ref"
index ac592197ee9cad7bcd2d16048feb81168e34ee35..db9f4eb4d4c01dbbb6d445fb391db72571f343e1 100644 (file)
@@ -3861,7 +3861,12 @@ ZEND_VM_HANDLER(124, ZEND_VERIFY_RETURN_TYPE, CONST|TMP|VAR|UNUSED|CV, UNUSED)
                if (OP1_TYPE == IS_CONST) {
                        ZVAL_COPY(EX_VAR(opline->result.var), retval_ptr);
                        retval_ref = retval_ptr = EX_VAR(opline->result.var);
-               } else if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) {
+               } else if (OP1_TYPE == IS_VAR) {
+                       if (UNEXPECTED(Z_TYPE_P(retval_ptr) == IS_INDIRECT)) {
+                               retval_ptr = Z_INDIRECT_P(retval_ptr);
+                       }
+                       ZVAL_DEREF(retval_ptr);
+               } else if (OP1_TYPE == IS_CV) {
                        ZVAL_DEREF(retval_ptr);
                }
 
index 9b4d2107fa5b1c22b2081dead3ab3bf68ed805d5..3257fd5fdf8ff791df6ceefe069d5f6808fdb21e 100644 (file)
@@ -7711,7 +7711,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_CONST_
                if (IS_CONST == IS_CONST) {
                        ZVAL_COPY(EX_VAR(opline->result.var), retval_ptr);
                        retval_ref = retval_ptr = EX_VAR(opline->result.var);
-               } else if (IS_CONST == IS_VAR || IS_CONST == IS_CV) {
+               } else if (IS_CONST == IS_VAR) {
+                       if (UNEXPECTED(Z_TYPE_P(retval_ptr) == IS_INDIRECT)) {
+                               retval_ptr = Z_INDIRECT_P(retval_ptr);
+                       }
+                       ZVAL_DEREF(retval_ptr);
+               } else if (IS_CONST == IS_CV) {
                        ZVAL_DEREF(retval_ptr);
                }
 
@@ -13507,7 +13512,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_TMP_UN
                if (IS_TMP_VAR == IS_CONST) {
                        ZVAL_COPY(EX_VAR(opline->result.var), retval_ptr);
                        retval_ref = retval_ptr = EX_VAR(opline->result.var);
-               } else if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) {
+               } else if (IS_TMP_VAR == IS_VAR) {
+                       if (UNEXPECTED(Z_TYPE_P(retval_ptr) == IS_INDIRECT)) {
+                               retval_ptr = Z_INDIRECT_P(retval_ptr);
+                       }
+                       ZVAL_DEREF(retval_ptr);
+               } else if (IS_TMP_VAR == IS_CV) {
                        ZVAL_DEREF(retval_ptr);
                }
 
@@ -19195,7 +19205,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UN
                if (IS_VAR == IS_CONST) {
                        ZVAL_COPY(EX_VAR(opline->result.var), retval_ptr);
                        retval_ref = retval_ptr = EX_VAR(opline->result.var);
-               } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) {
+               } else if (IS_VAR == IS_VAR) {
+                       if (UNEXPECTED(Z_TYPE_P(retval_ptr) == IS_INDIRECT)) {
+                               retval_ptr = Z_INDIRECT_P(retval_ptr);
+                       }
+                       ZVAL_DEREF(retval_ptr);
+               } else if (IS_VAR == IS_CV) {
                        ZVAL_DEREF(retval_ptr);
                }
 
@@ -24879,7 +24894,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED
                if (IS_UNUSED == IS_CONST) {
                        ZVAL_COPY(EX_VAR(opline->result.var), retval_ptr);
                        retval_ref = retval_ptr = EX_VAR(opline->result.var);
-               } else if (IS_UNUSED == IS_VAR || IS_UNUSED == IS_CV) {
+               } else if (IS_UNUSED == IS_VAR) {
+                       if (UNEXPECTED(Z_TYPE_P(retval_ptr) == IS_INDIRECT)) {
+                               retval_ptr = Z_INDIRECT_P(retval_ptr);
+                       }
+                       ZVAL_DEREF(retval_ptr);
+               } else if (IS_UNUSED == IS_CV) {
                        ZVAL_DEREF(retval_ptr);
                }
 
@@ -34314,7 +34334,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNU
                if (IS_CV == IS_CONST) {
                        ZVAL_COPY(EX_VAR(opline->result.var), retval_ptr);
                        retval_ref = retval_ptr = EX_VAR(opline->result.var);
-               } else if (IS_CV == IS_VAR || IS_CV == IS_CV) {
+               } else if (IS_CV == IS_VAR) {
+                       if (UNEXPECTED(Z_TYPE_P(retval_ptr) == IS_INDIRECT)) {
+                               retval_ptr = Z_INDIRECT_P(retval_ptr);
+                       }
+                       ZVAL_DEREF(retval_ptr);
+               } else if (IS_CV == IS_CV) {
                        ZVAL_DEREF(retval_ptr);
                }