1--TEST--
2Exceptions thrown in operand cleaning must cause leak of return value
3--FILE--
4<?php
5
6try {
7	var_dump(new class {
8		function __toString() { return "a"; }
9		function __destruct() { throw new Exception; }
10	} . "foo");
11} catch (Exception $e) { print "caught Exception 1\n"; }
12
13try {
14	var_dump([0] + [new class {
15		function __destruct() { throw new Exception; }
16	}]);
17} catch (Exception $e) { print "caught Exception 2\n"; }
18
19try {
20	$foo = [0];
21	var_dump($foo += [new class {
22		function __destruct() { throw new Exception; }
23	}]);
24} catch (Exception $e) { print "caught Exception 3\n"; }
25
26try {
27	$foo = (object)["foo" => [0]];
28	var_dump($foo->foo += [new class {
29		function __destruct() { throw new Exception; }
30	}]);
31} catch (Exception $e) { print "caught Exception 4\n"; }
32
33try {
34	$foo = new class {
35		function __get($x) { return [0]; }
36		function __set($x, $y) {}
37	};
38	var_dump($foo->foo += [new class {
39		function __destruct() { throw new Exception; }
40	}]);
41} catch (Exception $e) { print "caught Exception 5\n"; }
42
43try {
44	$foo = new class {
45		public $bar = [0];
46		function &__get($x) { return $this->bar; }
47	};
48	var_dump($foo->foo += [new class {
49		function __destruct() { throw new Exception; }
50	}]);
51} catch (Exception $e) { print "caught Exception 6\n"; }
52
53try {
54	$foo = new class implements ArrayAccess {
55		function offsetGet($x) { return [0]; }
56		function offsetSet($x, $y) {}
57		function offsetExists($x) { return true; }
58		function offsetUnset($x) {}
59	};
60	var_dump($foo[0] += [new class {
61		function __destruct() { throw new Exception; }
62	}]);
63} catch (Exception $e) { print "caught Exception 7\n"; }
64
65try {
66	$foo = new class implements ArrayAccess {
67		public $foo = [0];
68		function &offsetGet($x) { return $this->foo; }
69		function offsetSet($x, $y) {}
70		function offsetExists($x) { return true; }
71		function offsetUnset($x) {}
72	};
73	var_dump($foo[0] += [new class {
74		function __destruct() { throw new Exception; }
75	}]);
76} catch (Exception $e) { print "caught Exception 8\n"; }
77
78try {
79	var_dump((function() { return new class {
80		function __construct() { $this->foo = new stdClass; }
81		function __destruct() { throw new Exception; }
82	}; })()->foo++);
83} catch (Exception $e) { print "caught Exception 9\n"; }
84
85try {
86	var_dump((function() { return new class {
87		function __get($x) { return new stdClass; }
88		function __set($x, $y) {}
89		function __destruct() { throw new Exception; }
90	}; })()->foo++);
91} catch (Exception $e) { print "caught Exception 10\n"; }
92
93try {
94	var_dump((function() { return new class {
95		function __construct() { $this->bar = new stdClass; }
96		function &__get($x) { return $this->bar; }
97		function __destruct() { throw new Exception; }
98	}; })()->foo++);
99} catch (Exception $e) { print "caught Exception 11\n"; }
100
101try {
102	var_dump(++(function() { return new class {
103		function __construct() { $this->foo = new stdClass; }
104		function __destruct() { throw new Exception; }
105	}; })()->foo);
106} catch (Exception $e) { print "caught Exception 12\n"; }
107
108try {
109	var_dump(++(function() { return new class {
110		function __get($x) { return new stdClass; }
111		function __set($x, $y) {}
112		function __destruct() { throw new Exception; }
113	}; })()->foo);
114} catch (Exception $e) { print "caught Exception 13\n"; }
115
116try {
117	var_dump(++(function() { return new class {
118		function __construct() { $this->bar = new stdClass; }
119		function &__get($x) { return $this->bar; }
120		function __destruct() { throw new Exception; }
121	}; })()->foo);
122} catch (Exception $e) { print "caught Exception 14\n"; }
123
124try {
125	var_dump((function() { return new class implements ArrayAccess {
126		function offsetGet($x) { return [new stdClass]; }
127		function offsetSet($x, $y) {}
128		function offsetExists($x) { return true; }
129		function offsetUnset($x) {}
130		function __destruct() { throw new Exception; }
131	}; })()[0]++);
132} catch (Exception $e) { print "caught Exception 15\n"; }
133
134try {
135	var_dump(++(function() { return new class implements ArrayAccess {
136		function offsetGet($x) { return [new stdClass]; }
137		function offsetSet($x, $y) {}
138		function offsetExists($x) { return true; }
139		function offsetUnset($x) {}
140		function __destruct() { throw new Exception; }
141	}; })()[0]);
142} catch (Exception $e) { print "caught Exception 16\n"; }
143
144try {
145	var_dump((new class {
146		function __construct() { $this->foo = new stdClass; }
147		function __destruct() { throw new Exception; }
148	})->foo);
149} catch (Exception $e) { print "caught Exception 17\n"; }
150
151try {
152	var_dump((new class {
153		function __get($x) { return new stdClass; }
154		function __set($x, $y) {}
155		function __destruct() { throw new Exception; }
156	})->foo);
157} catch (Exception $e) { print "caught Exception 18\n"; }
158
159try {
160	var_dump((new class implements ArrayAccess {
161		function offsetGet($x) { return [new stdClass]; }
162		function offsetSet($x, $y) {}
163		function offsetExists($x) { return true; }
164		function offsetUnset($x) {}
165		function __destruct() { throw new Exception; }
166	})[0]);
167} catch (Exception $e) { print "caught Exception 19\n"; }
168
169try {
170	var_dump(isset((new class {
171		function __construct() { $this->foo = new stdClass; }
172		function __destruct() { throw new Exception; }
173	})->foo->bar));
174} catch (Exception $e) { print "caught Exception 20\n"; }
175
176try {
177	var_dump(isset((new class {
178		function __get($x) { return new stdClass; }
179		function __set($x, $y) {}
180		function __destruct() { throw new Exception; }
181	})->foo->bar));
182} catch (Exception $e) { print "caught Exception 21\n"; }
183
184try {
185	var_dump(isset((new class implements ArrayAccess {
186		function offsetGet($x) { return [new stdClass]; }
187		function offsetSet($x, $y) {}
188		function offsetExists($x) { return true; }
189		function offsetUnset($x) {}
190		function __destruct() { throw new Exception; }
191	})[0]->bar));
192} catch (Exception $e) { print "caught Exception 22\n"; }
193
194try {
195	$foo = new class {
196		function __destruct() { throw new Exception; }
197	};
198	var_dump($foo = new stdClass);
199} catch (Exception $e) { print "caught Exception 23\n"; }
200
201try {
202	$foo = [new class {
203		function __destruct() { throw new Exception; }
204	}];
205	var_dump($foo[0] = new stdClass);
206} catch (Exception $e) { print "caught Exception 24\n"; }
207
208try {
209	$foo = (object) ["foo" => new class {
210		function __destruct() { throw new Exception; }
211	}];
212	var_dump($foo->foo = new stdClass);
213} catch (Exception $e) { print "caught Exception 25\n"; }
214
215try {
216	$foo = new class {
217		function __get($x) {}
218		function __set($x, $y) { throw new Exception; }
219	};
220	var_dump($foo->foo = new stdClass);
221} catch (Exception $e) { print "caught Exception 26\n"; }
222
223try {
224	$foo = new class implements ArrayAccess {
225		function offsetGet($x) {}
226		function offsetSet($x, $y) { throw new Exception; }
227		function offsetExists($x) { return true; }
228		function offsetUnset($x) {}
229	};
230	var_dump($foo[0] = new stdClass);
231} catch (Exception $e) { print "caught Exception 27\n"; }
232
233try {
234	$foo = new class {
235		function __destruct() { throw new Exception; }
236	};
237	$bar = new stdClass;
238	var_dump($foo = &$bar);
239} catch (Exception $e) { print "caught Exception 28\n"; }
240
241try {
242	$f = function() {
243		return new class {
244			function __toString() { return "a"; }
245			function __destruct() { throw new Exception; }
246		};
247	};
248	var_dump("{$f()}foo");
249} catch (Exception $e) { print "caught Exception 29\n"; }
250
251try {
252	$f = function() {
253		return new class {
254			function __toString() { return "a"; }
255			function __destruct() { throw new Exception; }
256		};
257	};
258	var_dump("bar{$f()}foo");
259} catch (Exception $e) { print "caught Exception 30\n"; }
260
261try {
262	var_dump((string) new class {
263		function __toString() { $x = "Z"; return ++$x; }
264		function __destruct() { throw new Exception; }
265	});
266} catch (Exception $e) { print "caught Exception 31\n"; }
267
268try {
269	var_dump(clone (new class {
270		function __clone() { throw new Exception; }
271	}));
272} catch (Exception $e) { print "caught Exception 32\n"; }
273
274?>
275--EXPECTF--
276caught Exception 1
277caught Exception 2
278caught Exception 3
279caught Exception 4
280caught Exception 5
281caught Exception 6
282caught Exception 7
283caught Exception 8
284caught Exception 9
285caught Exception 10
286caught Exception 11
287caught Exception 12
288caught Exception 13
289caught Exception 14
290
291Notice: Indirect modification of overloaded element of class@anonymous has no effect in %s on line %d
292caught Exception 15
293
294Notice: Indirect modification of overloaded element of class@anonymous has no effect in %s on line %d
295caught Exception 16
296caught Exception 17
297caught Exception 18
298caught Exception 19
299caught Exception 20
300caught Exception 21
301caught Exception 22
302caught Exception 23
303caught Exception 24
304caught Exception 25
305caught Exception 26
306caught Exception 27
307caught Exception 28
308caught Exception 29
309caught Exception 30
310caught Exception 31
311caught Exception 32
312