summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPedro Magalhães <mail@pmmaga.net>2017-04-22 18:41:54 +0200
committerNikita Popov <nikita.ppv@gmail.com>2017-05-24 17:42:01 +0200
commita5eb57c96e8e851793d419cd4a4b4815a2cb44cb (patch)
tree0c6ac290e746e4b6bf7176e99130b8b76ac2f7d0
parent5dc43b4c9d7dbff583b5906a6d50890d615568c1 (diff)
downloadphp-git-a5eb57c96e8e851793d419cd4a4b4815a2cb44cb.tar.gz
Allow overriding abstract methods
RFC: https://wiki.php.net/rfc/allow-abstract-function-override
-rw-r--r--NEWS2
-rw-r--r--UPGRADING3
-rw-r--r--Zend/tests/abstract_inheritance_001.phpt12
-rw-r--r--Zend/tests/abstract_inheritance_002.phpt12
-rw-r--r--Zend/tests/abstract_inheritance_003.phpt12
-rw-r--r--Zend/zend_inheritance.c10
6 files changed, 41 insertions, 10 deletions
diff --git a/NEWS b/NEWS
index 8cce767459..c231f50eda 100644
--- a/NEWS
+++ b/NEWS
@@ -45,6 +45,8 @@ PHP NEWS
loosely-equal value). (pmmaga)
. Fixed bug #61970 (Restraining __construct() access level in subclass gives
a fatal error). (pmmaga)
+ . Fixed bug #63384 (Cannot override an abstract method with an abstract
+ method). (pmmaga, wes)
- BCMath:
. Fixed bug #46564 (bcmod truncates fractionals). (liborm85)
diff --git a/UPGRADING b/UPGRADING
index 0530958def..4a61694383 100644
--- a/UPGRADING
+++ b/UPGRADING
@@ -101,6 +101,9 @@ PHP 7.2 UPGRADE NOTES
inherited method. This complies with contravariance of method argument types
under the Liskov Substitution Principle.
(https://wiki.php.net/rfc/parameter-no-type-variance)
+ . It is now allowed to override an abstract method with another abstract
+ method in a child class.
+ (https://wiki.php.net/rfc/allow-abstract-function-override)
. A trailing comma in group use statements is now allowed.
(https://wiki.php.net/rfc/list-syntax-trailing-commas)
diff --git a/Zend/tests/abstract_inheritance_001.phpt b/Zend/tests/abstract_inheritance_001.phpt
new file mode 100644
index 0000000000..9e061e65d5
--- /dev/null
+++ b/Zend/tests/abstract_inheritance_001.phpt
@@ -0,0 +1,12 @@
+--TEST--
+Allow abstract function override
+--FILE--
+<?php
+
+abstract class A { abstract function bar($x); }
+abstract class B extends A { abstract function bar($x); }
+
+echo "DONE";
+?>
+--EXPECT--
+DONE
diff --git a/Zend/tests/abstract_inheritance_002.phpt b/Zend/tests/abstract_inheritance_002.phpt
new file mode 100644
index 0000000000..78f53c85c8
--- /dev/null
+++ b/Zend/tests/abstract_inheritance_002.phpt
@@ -0,0 +1,12 @@
+--TEST--
+Allow abstract function override
+--FILE--
+<?php
+
+abstract class A { abstract function bar($x); }
+abstract class B extends A { abstract function bar($x, $y = 0); }
+
+echo "DONE";
+?>
+--EXPECT--
+DONE
diff --git a/Zend/tests/abstract_inheritance_003.phpt b/Zend/tests/abstract_inheritance_003.phpt
new file mode 100644
index 0000000000..24d5920cc1
--- /dev/null
+++ b/Zend/tests/abstract_inheritance_003.phpt
@@ -0,0 +1,12 @@
+--TEST--
+Allow abstract function override
+--FILE--
+<?php
+
+abstract class A { abstract function bar($x, $y = 0); }
+abstract class B extends A { abstract function bar($x); }
+
+echo "DONE";
+?>
+--EXPECTF--
+Fatal error: Declaration of B::bar($x) must be compatible with A::bar($x, $y = 0) in %s
diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c
index 3a32215708..8f43d15600 100644
--- a/Zend/zend_inheritance.c
+++ b/Zend/zend_inheritance.c
@@ -551,16 +551,6 @@ static void do_inheritance_check_on_method(zend_function *child, zend_function *
uint32_t child_flags;
uint32_t parent_flags = parent->common.fn_flags;
- if ((parent->common.scope->ce_flags & ZEND_ACC_INTERFACE) == 0
- && parent->common.fn_flags & ZEND_ACC_ABSTRACT
- && parent->common.scope != (child->common.prototype ? child->common.prototype->common.scope : child->common.scope)
- && child->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_IMPLEMENTED_ABSTRACT)) {
- zend_error_noreturn(E_COMPILE_ERROR, "Can't inherit abstract function %s::%s() (previously declared abstract in %s)",
- ZSTR_VAL(parent->common.scope->name),
- ZSTR_VAL(child->common.function_name),
- child->common.prototype ? ZSTR_VAL(child->common.prototype->common.scope->name) : ZSTR_VAL(child->common.scope->name));
- }
-
if (UNEXPECTED(parent_flags & ZEND_ACC_FINAL)) {
zend_error_noreturn(E_COMPILE_ERROR, "Cannot override final method %s::%s()", ZEND_FN_SCOPE_NAME(parent), ZSTR_VAL(child->common.function_name));
}