summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikic@php.net>2015-03-22 18:50:36 +0100
committerNikita Popov <nikic@php.net>2015-03-22 18:56:14 +0100
commita34f81deee53ddf3b59405fc37d9f92cf41c8636 (patch)
tree2cffb4a85a3644aacc1e2b4c01a6c853a550c17a
parenta50e9d87f265f911f9c76ca0e998588be0bd6eac (diff)
downloadphp-git-a34f81deee53ddf3b59405fc37d9f92cf41c8636.tar.gz
Allow adding return type during inheritance
This is allowed as per the return types RFC. The test for this behavior happened to use an internal class without arginfo, which is why this was not properly implemented.
-rw-r--r--Zend/tests/typehints/add_return_type.phpt23
-rw-r--r--Zend/zend_inheritance.c9
2 files changed, 29 insertions, 3 deletions
diff --git a/Zend/tests/typehints/add_return_type.phpt b/Zend/tests/typehints/add_return_type.phpt
new file mode 100644
index 0000000000..de8a17d8c0
--- /dev/null
+++ b/Zend/tests/typehints/add_return_type.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Adding a return type during inheritance is allowed
+--FILE--
+<?php
+
+interface One {
+ public function a();
+ public function b();
+ public function c();
+ public function d();
+}
+
+interface Two extends One {
+ public function a() : stdClass;
+ public function c() : callable;
+ public function b() : array;
+ public function d() : int;
+}
+
+?>
+Done
+--EXPECT--
+Done
diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c
index e3ef17cc90..3e9083c8a4 100644
--- a/Zend/zend_inheritance.c
+++ b/Zend/zend_inheritance.c
@@ -328,11 +328,14 @@ static zend_bool zend_do_perform_implementation_check(const zend_function *fe, c
}
}
- /* check return type compataibility */
- if ((proto->common.fn_flags | fe->common.fn_flags) & ZEND_ACC_HAS_RETURN_TYPE) {
- if ((proto->common.fn_flags ^ fe->common.fn_flags) & ZEND_ACC_HAS_RETURN_TYPE) {
+ /* Check return type compatibility, but only if the prototype already specifies
+ * a return type. Adding a new return type is always valid. */
+ if (proto->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+ /* Removing a return type is not valid. */
+ if (!(fe->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE)) {
return 0;
}
+
if (!zend_do_perform_type_hint_check(fe, fe->common.arg_info - 1, proto, proto->common.arg_info - 1)) {
return 0;
}