Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? ????, PHP 8.6.0beta1

- Core:
. Fixed bug GH-14156 (Inherited private methods incorrectly satisfied abstract
trait requirements). (Matthias Görgens)

- GMP:
. Added optional $definitely_prime output parameter to gmp_prevprime().
(Weilin Du)
Expand Down
18 changes: 18 additions & 0 deletions Zend/tests/traits/gh14156.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
--TEST--
GH-14156 (Inherited private method does not satisfy abstract trait requirement)
--FILE--
<?php
trait T {
public abstract function test(): void;
}

class P {
private function test(): void {}
}

class C extends P {
use T;
}
?>
--EXPECTF--
Fatal error: Class C contains 1 abstract method and must therefore be declared abstract or implement the remaining method (C::test) in %s on line %d
36 changes: 36 additions & 0 deletions Zend/tests/traits/gh14156_2.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
--TEST--
GH-14156 (Abstract trait requirement replaces inherited private method)
--FILE--
<?php
trait T {
public abstract function test(): void;

public function run(): void {
$this->test();
}
}

class P {
private function test(): void {}
}

abstract class C extends P {
use T;
}

$method = new ReflectionMethod(C::class, 'test');
var_dump($method->isAbstract());
var_dump($method->getDeclaringClass()->getName());

class D extends C {
public function test(): void {
echo "implemented\n";
}
}

(new D())->run();
?>
--EXPECT--
bool(true)
string(1) "C"
implemented
8 changes: 6 additions & 2 deletions Zend/zend_inheritance.c
Original file line number Diff line number Diff line change
Expand Up @@ -2377,8 +2377,12 @@ static void zend_add_trait_method(zend_class_entry *ce, zend_string *name, zend_
return;
}

/* Abstract method signatures from the trait must be satisfied. */
if (fn->common.fn_flags & ZEND_ACC_ABSTRACT) {
/* Abstract method signatures from the trait must be satisfied. An inherited
* private method is not accessible from the using class, so it does not
* satisfy the requirement; only a private method from the class itself does. */
if ((fn->common.fn_flags & ZEND_ACC_ABSTRACT)
&& (!(existing_fn->common.fn_flags & ZEND_ACC_PRIVATE)
|| fixup_trait_scope(existing_fn, ce) == ce)) {
/* "abstract private" methods in traits were not available prior to PHP 8.
* As such, "abstract protected" was sometimes used to indicate trait requirements,
* even though the "implementing" method was private. Do not check visibility
Expand Down
Loading