1--TEST--
2Coalesce assign (??=): Exception handling
3--FILE--
4<?php
5
6$foo = "fo";
7$foo .= "o";
8$bar = "ba";
9$bar .= "r";
10
11function id($arg) {
12    echo "id($arg)\n";
13    return $arg;
14}
15
16function do_throw($msg) {
17    throw new Exception($msg);
18}
19
20$ary = [];
21try {
22    $ary[id($foo)] ??= do_throw("ex1");
23} catch (Exception $e) {
24    echo $e->getMessage(), "\n";
25}
26var_dump($ary);
27
28class AA implements ArrayAccess {
29    public function offsetExists($k) {
30        return true;
31    }
32    public function &offsetGet($k) {
33        $var = ["foo" => "bar"];
34        return $var;
35    }
36    public function offsetSet($k,$v) {}
37    public function offsetUnset($k) {}
38}
39
40class Dtor {
41    public function __destruct() {
42        throw new Exception("dtor");
43    }
44}
45
46$ary = new AA;
47try {
48    $ary[new Dtor][id($foo)] ??= $bar;
49} catch (Exception $e) {
50    echo $e->getMessage(), "\n";
51}
52var_dump($foo);
53
54class AA2 implements ArrayAccess {
55    public function offsetExists($k) {
56        return false;
57    }
58    public function offsetGet($k) {
59        return null;
60    }
61    public function offsetSet($k,$v) {}
62    public function offsetUnset($k) {}
63}
64
65$ary = ["foo" => new AA2];
66try {
67    $ary[id($foo)][new Dtor] ??= $bar;
68} catch (Exception $e) {
69    echo $e->getMessage(), "\n";
70}
71var_dump($foo);
72
73?>
74--EXPECT--
75id(foo)
76ex1
77array(0) {
78}
79id(foo)
80dtor
81string(3) "foo"
82id(foo)
83dtor
84string(3) "foo"
85