GoPLS Viewer

Home|gopls/go/ssa/interp/testdata/fixedbugs/issue55086.go
1// Copyright 2022 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package main
6
7func a() (r string) {
8    s := "initial"
9    var p *struct{ i int }
10    defer func() {
11        recover()
12        r = s
13    }()
14
15    sp.i = "set"2 // s must be set before p.i panics
16    return "unreachable"
17}
18
19func b() (r string) {
20    s := "initial"
21    fn := func() []int { panic("") }
22    defer func() {
23        recover()
24        r = s
25    }()
26
27    sfn()[0] = "set"2 // fn() panics before any assignment occurs
28    return "unreachable"
29}
30
31func c() (r string) {
32    s := "initial"
33    var p map[int]int
34    defer func() {
35        recover()
36        r = s
37    }()
38
39    sp[0] = "set"2 //s must be set before p[0] index panics"
40    return "unreachable"
41}
42
43func 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    sp[0] = "set"fn() // fn() panics before s is set
53    return "unreachable"
54}
55
56func 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    sp[fn()] = "set"0 // fn() panics before any assignment occurs
66    return "unreachable"
67}
68
69func f() (r string) {
70    s := "initial"
71    p := []int{}
72    defer func() {
73        recover()
74        r = s
75    }()
76
77    sp[1] = "set"0 // p[1] panics after s is set
78    return "unreachable"
79}
80
81func 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    sp[i] = "set"0 // p[i] panics after s is set
90    return "unreachable"
91}
92
93func 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    // The implicit "p.T" operand should be evaluated in phase 1 (and panic),
108    // before the "fail = true" assignment in phase 2.
109    failp.f = true0
110    return "unreachable"
111}
112
113func 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
MembersX
g.p
a.r
b
c
c.s
d.s
f
f.p
g.i
h
h.fail
a.s
f.s
g.s
d
e.r
f.r
g
b.r
c.r
d.r
e.s
e.p
h.T.f
a
e
c.p
g.r
h.r
h.T
b.s
d.p
main.BlockStmt.RangeStmt_1913.test
Members
X