1--TEST--
2Automatic promotion of falsy to object
3--FILE--
4<?php
5
6class Test {
7    public ?Test $prop;
8    public ?stdClass $stdProp;
9    public ?object $objectProp;
10
11    public static ?Test $staticProp = null;
12    public static ?stdClass $staticStdProp = null;
13    public static ?object $staticObjectProp = null;
14}
15
16// Object properties
17$test = new Test;
18try {
19    $test->prop->wat = 123;
20} catch (TypeError $e) {
21    echo $e->getMessage(), "\n";
22}
23$test->stdProp->wat = 123;
24$test->objectProp->wat = 123;
25var_dump($test);
26
27// Object properties via reference
28$test = new Test;
29$prop =& $test->prop;
30$stdProp =& $test->stdProp;
31$objectProp =& $test->objectProp;
32try {
33    $prop->wat = 123;
34} catch (TypeError $e) {
35    echo $e->getMessage(), "\n";
36}
37$stdProp->wat = 123;
38$objectProp->wat = 123;
39var_dump($test);
40
41// Object properties via reference rw
42$test = new Test;
43$prop =& $test->prop;
44$stdProp =& $test->stdProp;
45$objectProp =& $test->objectProp;
46try {
47    $prop->wat->wat = 123;
48} catch (TypeError $e) {
49    echo $e->getMessage(), "\n";
50}
51$stdProp->wat->wat = 123;
52$objectProp->wat->wat = 123;
53var_dump($test);
54
55// Static properties
56try {
57    Test::$staticProp->wat = 123;
58} catch (TypeError $e) {
59    echo $e->getMessage(), "\n";
60}
61Test::$staticStdProp->wat = 123;
62Test::$staticObjectProp->wat = 123;
63var_dump(Test::$staticProp, Test::$staticStdProp, Test::$staticObjectProp);
64
65// Non-string property name
66$test = new Test;
67$propName = new class {
68    public function __toString() {
69        return 'prop';
70    }
71};
72try {
73    $test->$propName->wat = 123;
74} catch (TypeError $e) {
75    echo $e->getMessage(), "\n";
76}
77var_dump($test);
78
79// Initially null
80$test = new Test;
81$test->prop = NULL;
82$test->stdProp = NULL;
83$test->objectProp = NULL;
84try {
85    $test->prop->wat = 123;
86} catch (TypeError $e) {
87    echo $e->getMessage(), "\n";
88}
89$test->stdProp->wat = 123;
90$test->objectProp->wat = 123;
91var_dump($test);
92
93?>
94--EXPECTF--
95Cannot auto-initialize an stdClass inside property Test::$prop of type ?Test
96
97Warning: Creating default object from empty value in %s on line %d
98
99Warning: Creating default object from empty value in %s on line %d
100object(Test)#1 (2) {
101  ["prop"]=>
102  uninitialized(?Test)
103  ["stdProp"]=>
104  object(stdClass)#3 (1) {
105    ["wat"]=>
106    int(123)
107  }
108  ["objectProp"]=>
109  object(stdClass)#4 (1) {
110    ["wat"]=>
111    int(123)
112  }
113}
114Cannot auto-initialize an stdClass inside a reference held by property Test::$prop of type ?Test
115
116Warning: Creating default object from empty value in %s on line %d
117
118Warning: Creating default object from empty value in %s on line %d
119object(Test)#5 (3) {
120  ["prop"]=>
121  &NULL
122  ["stdProp"]=>
123  &object(stdClass)#2 (1) {
124    ["wat"]=>
125    int(123)
126  }
127  ["objectProp"]=>
128  &object(stdClass)#4 (1) {
129    ["wat"]=>
130    int(123)
131  }
132}
133Cannot auto-initialize an stdClass inside a reference held by property Test::$prop of type ?Test
134
135Warning: Creating default object from empty value in %s on line %d
136
137Warning: Creating default object from empty value in %s on line %d
138
139Warning: Creating default object from empty value in %s on line %d
140
141Warning: Creating default object from empty value in %s on line %d
142object(Test)#3 (3) {
143  ["prop"]=>
144  &NULL
145  ["stdProp"]=>
146  &object(stdClass)#1 (1) {
147    ["wat"]=>
148    object(stdClass)#2 (1) {
149      ["wat"]=>
150      int(123)
151    }
152  }
153  ["objectProp"]=>
154  &object(stdClass)#5 (1) {
155    ["wat"]=>
156    object(stdClass)#6 (1) {
157      ["wat"]=>
158      int(123)
159    }
160  }
161}
162Cannot auto-initialize an stdClass inside property Test::$staticProp of type ?Test
163
164Warning: Creating default object from empty value in %s on line %d
165
166Warning: Creating default object from empty value in %s on line %d
167NULL
168object(stdClass)#4 (1) {
169  ["wat"]=>
170  int(123)
171}
172object(stdClass)#8 (1) {
173  ["wat"]=>
174  int(123)
175}
176Cannot auto-initialize an stdClass inside property Test::$prop of type ?Test
177object(Test)#9 (0) {
178  ["prop"]=>
179  uninitialized(?Test)
180  ["stdProp"]=>
181  uninitialized(?stdClass)
182  ["objectProp"]=>
183  uninitialized(?object)
184}
185Cannot auto-initialize an stdClass inside property Test::$prop of type ?Test
186
187Warning: Creating default object from empty value in %s on line %d
188
189Warning: Creating default object from empty value in %s on line %d
190object(Test)#7 (3) {
191  ["prop"]=>
192  NULL
193  ["stdProp"]=>
194  object(stdClass)#10 (1) {
195    ["wat"]=>
196    int(123)
197  }
198  ["objectProp"]=>
199  object(stdClass)#11 (1) {
200    ["wat"]=>
201    int(123)
202  }
203}
204