Skip to content

Commit 4a61d84

Browse files
committed
Fixed bug #78776
By using the normal inheritance check if the parent is abstract as well.
1 parent 76eb30d commit 4a61d84

File tree

3 files changed

+36
-9
lines changed

3 files changed

+36
-9
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ PHP NEWS
88
(Alexey Kachalin)
99
. Fixed bug #78973 (Destructor during CV freeing causes segfault if opline
1010
never saved). (Nikita)
11+
. Fixed bug #78776 (Abstract method implementation from trait does not check
12+
"static"). (Nikita)
1113

1214
- OPcache:
1315
. Fixed bug #78961 (erroneous optimization of re-assigned $GLOBALS). (Dmitry)

Zend/tests/bug78776.phpt

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
--TEST--
2+
Bug #78776: Abstract method implementation from trait does not check "static"
3+
--FILE--
4+
<?php
5+
6+
abstract class A
7+
{
8+
abstract public function createApp();
9+
}
10+
11+
class B extends A
12+
{
13+
use C;
14+
}
15+
16+
trait C
17+
{
18+
public static function createApp()
19+
{
20+
echo "You should not be here\n";
21+
}
22+
}
23+
24+
B::createApp();
25+
26+
?>
27+
--EXPECTF--
28+
Fatal error: Cannot make non static method A::createApp() static in class C in %s on line %d

Zend/zend_inheritance.c

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -812,15 +812,15 @@ static zend_always_inline inheritance_status do_inheritance_check_on_method_ex(z
812812
parent = proto;
813813
}
814814

815-
if (!check_only && child_zv && child->common.prototype != proto) {
815+
if (!check_only && child->common.prototype != proto) {
816816
do {
817817
if (child->common.scope != ce
818818
&& child->type == ZEND_USER_FUNCTION
819819
&& !child->op_array.static_variables) {
820820
if (ce->ce_flags & ZEND_ACC_INTERFACE) {
821821
/* Few parent interfaces contain the same method */
822822
break;
823-
} else {
823+
} else if (child_zv) {
824824
/* op_array wasn't duplicated yet */
825825
zend_function *new_function = zend_arena_alloc(&CG(arena), sizeof(zend_op_array));
826826
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
15851585
}
15861586
zend_hash_update_mem(*overridden, key, fn, sizeof(zend_function));
15871587
return;
1588-
} else if (existing_fn->common.fn_flags & ZEND_ACC_ABSTRACT &&
1589-
(existing_fn->common.scope->ce_flags & ZEND_ACC_INTERFACE) == 0) {
1590-
/* Make sure the trait method is compatible with previosly declared abstract method */
1591-
perform_delayable_implementation_check(
1592-
ce, fn, existing_fn, /*always_error*/ 1);
1593-
} else if (fn->common.fn_flags & ZEND_ACC_ABSTRACT) {
1588+
} else if ((fn->common.fn_flags & ZEND_ACC_ABSTRACT)
1589+
&& !(existing_fn->common.fn_flags & ZEND_ACC_ABSTRACT)) {
15941590
/* Make sure the abstract declaration is compatible with previous declaration */
15951591
perform_delayable_implementation_check(
15961592
ce, existing_fn, fn, /*always_error*/ 1);
15971593
return;
1598-
} else if (UNEXPECTED(existing_fn->common.scope->ce_flags & ZEND_ACC_TRAIT)) {
1594+
} else if (UNEXPECTED((existing_fn->common.scope->ce_flags & ZEND_ACC_TRAIT)
1595+
&& !(existing_fn->common.fn_flags & ZEND_ACC_ABSTRACT))) {
15991596
/* two traits can't define the same non-abstract method */
16001597
#if 1
16011598
zend_error_noreturn(E_COMPILE_ERROR, "Trait method %s has not been applied, because there are collisions with other trait methods on %s",

0 commit comments

Comments
 (0)