summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXinchen Hui <laruence@php.net>2015-07-23 11:16:10 +0800
committerXinchen Hui <laruence@php.net>2015-07-23 11:16:10 +0800
commita123876b4e181731e3d95cabfb88bbc42d7d844b (patch)
treed85a72b73d990571d0acbaba914dee3788adf447
parent3e479ef424b2193f41a28fda18bde076a79ea71e (diff)
downloadphp-git-a123876b4e181731e3d95cabfb88bbc42d7d844b.tar.gz
Fixed bug #70117 (Unexpected return type error)
-rw-r--r--NEWS1
-rw-r--r--Zend/tests/bug70117.phpt21
-rw-r--r--Zend/zend_vm_def.h7
-rw-r--r--Zend/zend_vm_execute.h35
4 files changed, 58 insertions, 6 deletions
diff --git a/NEWS b/NEWS
index 6fed09f52c..8f5781375e 100644
--- 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
index 0000000000..4bdd12caef
--- /dev/null
+++ b/Zend/tests/bug70117.phpt
@@ -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"
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index ac592197ee..db9f4eb4d4 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -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);
}
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 9b4d2107fa..3257fd5fdf 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -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);
}