mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Add separate static property through trait if parent already declares it
Fixes GH-10935 Closes GH-10937
This commit is contained in:
parent
ebf86d284e
commit
9a250cc9d6
5 changed files with 101 additions and 2 deletions
2
NEWS
2
NEWS
|
@ -29,6 +29,8 @@ PHP NEWS
|
||||||
(ilutov)
|
(ilutov)
|
||||||
. Fix bug GH-10168, GH-10582 (Various segfaults with destructors and VM return
|
. Fix bug GH-10168, GH-10582 (Various segfaults with destructors and VM return
|
||||||
values). (dstogov, nielsdos, ilutov)
|
values). (dstogov, nielsdos, ilutov)
|
||||||
|
. Fix bug GH-10935 (Use of trait doesn't redeclare static property if class
|
||||||
|
has inherited it from its parent). (ilutov)
|
||||||
|
|
||||||
- Date:
|
- Date:
|
||||||
. Implement More Appropriate Date/Time Exceptions RFC. (Derick)
|
. Implement More Appropriate Date/Time Exceptions RFC. (Derick)
|
||||||
|
|
|
@ -35,6 +35,10 @@ PHP 8.3 UPGRADE NOTES
|
||||||
proc_get_status() to check whether the result was cached.
|
proc_get_status() to check whether the result was cached.
|
||||||
. Zend Max Execution Timers is now enabled by default for ZTS builds on
|
. Zend Max Execution Timers is now enabled by default for ZTS builds on
|
||||||
Linux.
|
Linux.
|
||||||
|
. Uses of traits with static properties will now redeclare static properties
|
||||||
|
inherited from the parent class. This will create a separate static property
|
||||||
|
storage for the current class. This is analogous to adding the static
|
||||||
|
property to the class directly without traits.
|
||||||
|
|
||||||
- FFI:
|
- FFI:
|
||||||
. C functions that have a return type of void now return null instead of
|
. C functions that have a return type of void now return null instead of
|
||||||
|
|
83
Zend/tests/gh10935.phpt
Normal file
83
Zend/tests/gh10935.phpt
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
--TEST--
|
||||||
|
GH-1093: Add separate static property through trait if parent already declares it
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
trait Foo {
|
||||||
|
static $test;
|
||||||
|
|
||||||
|
public static function getFooSelf() {
|
||||||
|
return self::$test;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getFooStatic() {
|
||||||
|
return static::$test;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
trait Bar {
|
||||||
|
public static function getBarSelf() {
|
||||||
|
return self::$test;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getBarStatic() {
|
||||||
|
return static::$test;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class A {
|
||||||
|
use Foo;
|
||||||
|
use Bar;
|
||||||
|
|
||||||
|
public static function getASelf() {
|
||||||
|
return self::$test;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getAStatic() {
|
||||||
|
return static::$test;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class B extends A {
|
||||||
|
use Foo;
|
||||||
|
|
||||||
|
public static function getBSelf() {
|
||||||
|
return self::$test;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getBStatic() {
|
||||||
|
return static::$test;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
A::$test = 'A';
|
||||||
|
B::$test = 'B';
|
||||||
|
|
||||||
|
echo 'A::$test: ' . A::$test . "\n";
|
||||||
|
echo 'A::getASelf(): ' . A::getASelf() . "\n";
|
||||||
|
echo 'A::getAStatic(): ' . A::getAStatic() . "\n";
|
||||||
|
echo 'A::getFooSelf(): ' . A::getFooSelf() . "\n";
|
||||||
|
echo 'A::getFooStatic(): ' . A::getFooStatic() . "\n";
|
||||||
|
echo 'B::$test: ' . B::$test . "\n";
|
||||||
|
echo 'B::getASelf(): ' . B::getASelf() . "\n";
|
||||||
|
echo 'B::getAStatic(): ' . B::getAStatic() . "\n";
|
||||||
|
echo 'B::getBSelf(): ' . B::getBSelf() . "\n";
|
||||||
|
echo 'B::getBStatic(): ' . B::getBStatic() . "\n";
|
||||||
|
echo 'B::getFooSelf(): ' . B::getFooSelf() . "\n";
|
||||||
|
echo 'B::getFooStatic(): ' . B::getFooStatic() . "\n";
|
||||||
|
echo 'B::getBarSelf(): ' . B::getBarSelf() . "\n";
|
||||||
|
echo 'B::getBarStatic(): ' . B::getBarStatic() . "\n";
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
A::$test: A
|
||||||
|
A::getASelf(): A
|
||||||
|
A::getAStatic(): A
|
||||||
|
A::getFooSelf(): A
|
||||||
|
A::getFooStatic(): A
|
||||||
|
B::$test: B
|
||||||
|
B::getASelf(): A
|
||||||
|
B::getAStatic(): B
|
||||||
|
B::getBSelf(): B
|
||||||
|
B::getBStatic(): B
|
||||||
|
B::getFooSelf(): B
|
||||||
|
B::getFooStatic(): B
|
||||||
|
B::getBarSelf(): A
|
||||||
|
B::getBarStatic(): B
|
|
@ -2377,7 +2377,9 @@ static void zend_do_traits_property_binding(zend_class_entry *ce, zend_class_ent
|
||||||
ZSTR_VAL(prop_name),
|
ZSTR_VAL(prop_name),
|
||||||
ZSTR_VAL(ce->name));
|
ZSTR_VAL(ce->name));
|
||||||
}
|
}
|
||||||
continue;
|
if (!(flags & ZEND_ACC_STATIC)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1082,7 +1082,15 @@ void zend_update_parent_ce(zend_class_entry *ce)
|
||||||
end = parent->parent ? parent->parent->default_static_members_count : 0;
|
end = parent->parent ? parent->parent->default_static_members_count : 0;
|
||||||
for (; i >= end; i--) {
|
for (; i >= end; i--) {
|
||||||
zval *p = &ce->default_static_members_table[i];
|
zval *p = &ce->default_static_members_table[i];
|
||||||
ZVAL_INDIRECT(p, &parent->default_static_members_table[i]);
|
/* The static property may have been overridden by a trait
|
||||||
|
* during inheritance. In that case, the property default
|
||||||
|
* value is replaced by zend_declare_typed_property() at the
|
||||||
|
* property index of the parent property. Make sure we only
|
||||||
|
* point to the parent property value if the child value was
|
||||||
|
* already indirect. */
|
||||||
|
if (Z_TYPE_P(p) == IS_INDIRECT) {
|
||||||
|
ZVAL_INDIRECT(p, &parent->default_static_members_table[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parent = parent->parent;
|
parent = parent->parent;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue