...
1
2
3
4
5 package main
6
7 func a() (r string) {
8 s := "initial"
9 var p *struct{ i int }
10 defer func() {
11 recover()
12 r = s
13 }()
14
15 s, p.i = "set", 2
16 return "unreachable"
17 }
18
19 func b() (r string) {
20 s := "initial"
21 fn := func() []int { panic("") }
22 defer func() {
23 recover()
24 r = s
25 }()
26
27 s, fn()[0] = "set", 2
28 return "unreachable"
29 }
30
31 func c() (r string) {
32 s := "initial"
33 var p map[int]int
34 defer func() {
35 recover()
36 r = s
37 }()
38
39 s, p[0] = "set", 2
40 return "unreachable"
41 }
42
43 func d() (r string) {
44 s := "initial"
45 var p map[int]int
46 defer func() {
47 recover()
48 r = s
49 }()
50 fn := func() int { panic("") }
51
52 s, p[0] = "set", fn()
53 return "unreachable"
54 }
55
56 func e() (r string) {
57 s := "initial"
58 p := map[int]int{}
59 defer func() {
60 recover()
61 r = s
62 }()
63 fn := func() int { panic("") }
64
65 s, p[fn()] = "set", 0
66 return "unreachable"
67 }
68
69 func f() (r string) {
70 s := "initial"
71 p := []int{}
72 defer func() {
73 recover()
74 r = s
75 }()
76
77 s, p[1] = "set", 0
78 return "unreachable"
79 }
80
81 func g() (r string) {
82 s := "initial"
83 p := map[any]any{}
84 defer func() {
85 recover()
86 r = s
87 }()
88 var i any = func() {}
89 s, p[i] = "set", 0
90 return "unreachable"
91 }
92
93 func h() (r string) {
94 fail := false
95 defer func() {
96 recover()
97 if fail {
98 r = "fail"
99 } else {
100 r = "success"
101 }
102 }()
103
104 type T struct{ f int }
105 var p *struct{ *T }
106
107
108
109 fail, p.f = true, 0
110 return "unreachable"
111 }
112
113 func main() {
114 for _, test := range []struct {
115 fn func() string
116 want string
117 desc string
118 }{
119 {a, "set", "s must be set before p.i panics"},
120 {b, "initial", "p() panics before s is set"},
121 {c, "set", "s must be set before p[0] index panics"},
122 {d, "initial", "fn() panics before s is set"},
123 {e, "initial", "fn() panics before s is set"},
124 {f, "set", "p[1] panics after s is set"},
125 {g, "set", "p[i] panics after s is set"},
126 {h, "success", "p.T panics before fail is set"},
127 } {
128 if test.fn() != test.want {
129 panic(test.desc)
130 }
131 }
132 }
133
View as plain text