Skip to content

Commit 15c2477

Browse files
committed
Merge branch 'PHP-8.4'
* PHP-8.4: Fix accidentally inherited default value in overridden virtual properties
2 parents 84d00ec + e0c69dd commit 15c2477

File tree

5 files changed

+65
-4
lines changed

5 files changed

+65
-4
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
--TEST--
2+
Property default values are not inherited
3+
--FILE--
4+
<?php
5+
6+
class P {
7+
public $a = 1;
8+
public int $b = 1;
9+
public $c = 1;
10+
public int $d = 1;
11+
}
12+
13+
class C extends P {
14+
public $a { get => parent::$a::get(); }
15+
public int $b { get => parent::$b::get(); }
16+
public $c = 2 { get => parent::$c::get(); }
17+
public int $d = 2 { get => parent::$d::get(); }
18+
}
19+
20+
class GC extends C {
21+
public $a { get => parent::$a::get(); }
22+
public int $b { get => parent::$b::get(); }
23+
public $c { get => parent::$c::get(); }
24+
public int $d { get => parent::$d::get(); }
25+
}
26+
27+
function test(P $p) {
28+
var_dump($p->a);
29+
try {
30+
var_dump($p->b);
31+
} catch (Error $e) {
32+
echo $e->getMessage(), "\n";
33+
}
34+
var_dump($p->c);
35+
try {
36+
var_dump($p->d);
37+
} catch (Error $e) {
38+
echo $e->getMessage(), "\n";
39+
}
40+
}
41+
42+
test(new C);
43+
test(new GC);
44+
45+
?>
46+
--EXPECT--
47+
NULL
48+
Typed property C::$b must not be accessed before initialization
49+
int(2)
50+
int(2)
51+
NULL
52+
Typed property GC::$b must not be accessed before initialization
53+
NULL
54+
Typed property GC::$d must not be accessed before initialization

Zend/tests/property_hooks/dump.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class Test {
3434
}
3535

3636
class Child extends Test {
37-
public $addedHooks {
37+
public $addedHooks = 'addedHooks' {
3838
get { return strtoupper(parent::$addedHooks::get()); }
3939
}
4040
private $changed = 'changed Child' {

Zend/tests/property_hooks/generator_hook_002.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ class A {
88
}
99

1010
class B extends A {
11-
public $prop {
11+
public $prop = 42 {
1212
get {
1313
yield parent::$prop::get() + 1;
1414
yield parent::$prop::get() + 2;

Zend/tests/property_hooks/parent_get_plain.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ class P {
88
}
99

1010
class C extends P {
11-
public $prop {
11+
public $prop = 42 {
1212
get => parent::$prop::get();
1313
}
1414
}

Zend/zend_inheritance.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1490,14 +1490,21 @@ static void do_inherit_property(zend_property_info *parent_info, zend_string *ke
14901490
zend_error_noreturn(E_COMPILE_ERROR, "Access level to %s::$%s must be %s (as in class %s)%s", ZSTR_VAL(ce->name), ZSTR_VAL(key), zend_visibility_string(parent_info->flags), ZSTR_VAL(parent_info->ce->name), (parent_info->flags&ZEND_ACC_PUBLIC) ? "" : " or weaker");
14911491
}
14921492
if (!(child_info->flags & ZEND_ACC_STATIC) && !(parent_info->flags & ZEND_ACC_VIRTUAL)) {
1493+
int parent_num = OBJ_PROP_TO_NUM(parent_info->offset);
14931494
if (child_info->offset != ZEND_VIRTUAL_PROPERTY_OFFSET) {
1494-
int parent_num = OBJ_PROP_TO_NUM(parent_info->offset);
14951495
int child_num = OBJ_PROP_TO_NUM(child_info->offset);
14961496

14971497
/* Don't keep default properties in GC (they may be freed by opcache) */
14981498
zval_ptr_dtor_nogc(&(ce->default_properties_table[parent_num]));
14991499
ce->default_properties_table[parent_num] = ce->default_properties_table[child_num];
15001500
ZVAL_UNDEF(&ce->default_properties_table[child_num]);
1501+
} else {
1502+
/* Default value was removed in child, remove it from parent too. */
1503+
if (ZEND_TYPE_IS_SET(child_info->type)) {
1504+
ZVAL_UNDEF(&ce->default_properties_table[parent_num]);
1505+
} else {
1506+
ZVAL_NULL(&ce->default_properties_table[parent_num]);
1507+
}
15011508
}
15021509

15031510
child_info->offset = parent_info->offset;

0 commit comments

Comments
 (0)