-
Notifications
You must be signed in to change notification settings - Fork 8k
Expand file tree
/
Copy pathcpp_reassign_child_redefine.phpt
More file actions
84 lines (72 loc) · 2.04 KB
/
cpp_reassign_child_redefine.phpt
File metadata and controls
84 lines (72 loc) · 2.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
--TEST--
Promoted readonly property reassignment in constructor - child redefines parent property
--FILE--
<?php
// Case 1: Parent uses CPP, child redefines as non-promoted, child tries to reassign.
// P1 owns the CPP reassignment window; it is cleared when P1's constructor exits,
// before C1's body runs. So C1's write attempt fails.
class P1 {
public function __construct(
public readonly string $x = 'P',
) {}
}
class C1 extends P1 {
public readonly string $x;
public function __construct() {
parent::__construct();
try {
$this->x = 'C';
} catch (Throwable $e) {
echo get_class($e), ": ", $e->getMessage(), "\n";
}
}
}
$c1 = new C1();
var_dump($c1->x);
// Case 2: Parent uses CPP and reassigns; child redefines as non-promoted.
// The child does not use CPP, so it does not claim CPP ownership of the property.
// P2's CPP "owns" the reassignment window: P2's body write succeeds.
class P2 {
public function __construct(
public readonly string $x = 'P1',
) {
$this->x = 'P2';
}
}
class C2 extends P2 {
public readonly string $x;
public function __construct() {
parent::__construct();
}
}
$c2 = new C2();
var_dump($c2->x);
// Case 3: Parent uses CPP, child uses CPP redefinition.
// Child's CPP opens the reassignment window for C3::$x. When parent::__construct()
// runs, P3's CPP tries to initialize C3::$x again, which must fail since C3
// owns the property and has already initialized it.
class P3 {
public function __construct(
public readonly string $x = 'P',
) {}
}
class C3 extends P3 {
public function __construct(
public readonly string $x = 'C1',
) {
try {
parent::__construct();
} catch (Throwable $e) {
echo get_class($e), ": ", $e->getMessage(), "\n";
}
}
}
$c3 = new C3();
var_dump($c3->x);
?>
--EXPECT--
Error: Cannot modify readonly property C1::$x
string(1) "P"
string(2) "P2"
Error: Cannot modify readonly property C3::$x
string(2) "C1"