summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS2
-rw-r--r--Zend/tests/bug78776.phpt28
-rw-r--r--Zend/zend_inheritance.c15
3 files changed, 36 insertions, 9 deletions
diff --git a/NEWS b/NEWS
index 73688acdb8..237d20ce18 100644
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,8 @@ PHP NEWS
(Alexey Kachalin)
. Fixed bug #78973 (Destructor during CV freeing causes segfault if opline
never saved). (Nikita)
+ . Fixed bug #78776 (Abstract method implementation from trait does not check
+ "static"). (Nikita)
- OPcache:
. Fixed bug #78961 (erroneous optimization of re-assigned $GLOBALS). (Dmitry)
diff --git a/Zend/tests/bug78776.phpt b/Zend/tests/bug78776.phpt
new file mode 100644
index 0000000000..3696d955a3
--- /dev/null
+++ b/Zend/tests/bug78776.phpt
@@ -0,0 +1,28 @@
+--TEST--
+Bug #78776: Abstract method implementation from trait does not check "static"
+--FILE--
+<?php
+
+abstract class A
+{
+ abstract public function createApp();
+}
+
+class B extends A
+{
+ use C;
+}
+
+trait C
+{
+ public static function createApp()
+ {
+ echo "You should not be here\n";
+ }
+}
+
+B::createApp();
+
+?>
+--EXPECTF--
+Fatal error: Cannot make non static method A::createApp() static in class C in %s on line %d
diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c
index 0dbb5b77a6..9a11269801 100644
--- a/Zend/zend_inheritance.c
+++ b/Zend/zend_inheritance.c
@@ -812,7 +812,7 @@ static zend_always_inline inheritance_status do_inheritance_check_on_method_ex(z
parent = proto;
}
- if (!check_only && child_zv && child->common.prototype != proto) {
+ if (!check_only && child->common.prototype != proto) {
do {
if (child->common.scope != ce
&& child->type == ZEND_USER_FUNCTION
@@ -820,7 +820,7 @@ static zend_always_inline inheritance_status do_inheritance_check_on_method_ex(z
if (ce->ce_flags & ZEND_ACC_INTERFACE) {
/* Few parent interfaces contain the same method */
break;
- } else {
+ } else if (child_zv) {
/* op_array wasn't duplicated yet */
zend_function *new_function = zend_arena_alloc(&CG(arena), sizeof(zend_op_array));
memcpy(new_function, child, sizeof(zend_op_array));
@@ -1585,17 +1585,14 @@ static void zend_add_trait_method(zend_class_entry *ce, const char *name, zend_s
}
zend_hash_update_mem(*overridden, key, fn, sizeof(zend_function));
return;
- } else if (existing_fn->common.fn_flags & ZEND_ACC_ABSTRACT &&
- (existing_fn->common.scope->ce_flags & ZEND_ACC_INTERFACE) == 0) {
- /* Make sure the trait method is compatible with previosly declared abstract method */
- perform_delayable_implementation_check(
- ce, fn, existing_fn, /*always_error*/ 1);
- } else if (fn->common.fn_flags & ZEND_ACC_ABSTRACT) {
+ } else if ((fn->common.fn_flags & ZEND_ACC_ABSTRACT)
+ && !(existing_fn->common.fn_flags & ZEND_ACC_ABSTRACT)) {
/* Make sure the abstract declaration is compatible with previous declaration */
perform_delayable_implementation_check(
ce, existing_fn, fn, /*always_error*/ 1);
return;
- } else if (UNEXPECTED(existing_fn->common.scope->ce_flags & ZEND_ACC_TRAIT)) {
+ } else if (UNEXPECTED((existing_fn->common.scope->ce_flags & ZEND_ACC_TRAIT)
+ && !(existing_fn->common.fn_flags & ZEND_ACC_ABSTRACT))) {
/* two traits can't define the same non-abstract method */
#if 1
zend_error_noreturn(E_COMPILE_ERROR, "Trait method %s has not been applied, because there are collisions with other trait methods on %s",