From c1b5f3e86eb1699f68cfe6bb977f1326d3c2a475 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Sat, 25 Mar 2023 18:34:06 +0100 Subject: [PATCH] Add separate static property through trait if parent already declares it Closes GH-10935 --- Zend/tests/gh10935.phpt | 83 ++++++++++++++++++++++++++++++++++++++ Zend/zend_inheritance.c | 4 +- ext/opcache/zend_persist.c | 10 ++++- 3 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 Zend/tests/gh10935.phpt diff --git a/Zend/tests/gh10935.phpt b/Zend/tests/gh10935.phpt new file mode 100644 index 000000000000..e84a9e5fdd26 --- /dev/null +++ b/Zend/tests/gh10935.phpt @@ -0,0 +1,83 @@ +--TEST-- +GH-1093: Add separate static property through trait if parent already declares it +--FILE-- + +--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 diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index 028bdebbfb8f..5a689408263a 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -2377,7 +2377,9 @@ static void zend_do_traits_property_binding(zend_class_entry *ce, zend_class_ent ZSTR_VAL(prop_name), ZSTR_VAL(ce->name)); } - continue; + if (!(flags & ZEND_ACC_STATIC)) { + continue; + } } } diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c index cca90bb41e99..d7c2d6333910 100644 --- a/ext/opcache/zend_persist.c +++ b/ext/opcache/zend_persist.c @@ -1082,7 +1082,15 @@ void zend_update_parent_ce(zend_class_entry *ce) end = parent->parent ? parent->parent->default_static_members_count : 0; for (; i >= end; 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;