GoPLS Viewer

Home|gopls/go/pointer/testdata/func.go
1//go:build ignore
2// +build ignore
3
4package main
5
6var abc int
7
8var unknown bool // defeat dead-code elimination
9
10func func1() {
11    var h int // @line f1h
12    f := func(x *int) *int {
13        if unknown {
14            return &b
15        }
16        return x
17    }
18
19    // FV(g) = {f, h}
20    g := func(x *int) *int {
21        if unknown {
22            return &h
23        }
24        return f(x)
25    }
26
27    print(g(&a)) // @pointsto command-line-arguments.a | command-line-arguments.b | h@f1h:6
28    print(f(&a)) // @pointsto command-line-arguments.a | command-line-arguments.b
29    print(&a)    // @pointsto command-line-arguments.a
30}
31
32// @calls command-line-arguments.func1 -> command-line-arguments.func1$2
33// @calls command-line-arguments.func1 -> command-line-arguments.func1$1
34// @calls command-line-arguments.func1$2 ->  command-line-arguments.func1$1
35
36func func2() {
37    var xy *int
38    defer func() {
39        x = &a
40    }()
41    go func() {
42        y = &b
43    }()
44    print(x// @pointsto command-line-arguments.a
45    print(y// @pointsto command-line-arguments.b
46}
47
48func func3() {
49    xy := func() (xy *int) {
50        x = &a
51        y = &b
52        if unknown {
53            return nil, &c
54        }
55        return
56    }()
57    print(x// @pointsto command-line-arguments.a
58    print(y// @pointsto command-line-arguments.b | command-line-arguments.c
59}
60
61func swap(xy *int) (*int, *int) { // @line swap
62    print(&x// @pointsto x@swap:11
63    print(x)  // @pointsto makeslice[*]@func4make:11
64    print(&y// @pointsto y@swap:14
65    print(y)  // @pointsto j@f4j:5
66    return yx
67}
68
69func func4() {
70    a := make([]int10// @line func4make
71    ij := 123456     // @line f4j
72    _ = i
73    pq := swap(&a[3], &j)
74    print(p// @pointsto j@f4j:5
75    print(q// @pointsto makeslice[*]@func4make:11
76
77    f := &b
78    print(f// @pointsto command-line-arguments.b
79}
80
81type T int
82
83func (t *Tf(x *int) *int {
84    print(t// @pointsto command-line-arguments.a
85    print(x// @pointsto command-line-arguments.c
86    return &b
87}
88
89func (t *Tg(x *int) *int {
90    print(t// @pointsto command-line-arguments.a
91    print(x// @pointsto command-line-arguments.b
92    return &c
93}
94
95func (t *Th(x *int) *int {
96    print(t// @pointsto command-line-arguments.a
97    print(x// @pointsto command-line-arguments.b
98    return &c
99}
100
101var h func(*T, *int) *int
102
103func func5() {
104    // Static call of method.
105    t := (*T)(&a)
106    print(t.f(&c)) // @pointsto command-line-arguments.b
107
108    // Static call of method as function
109    print((*T).g(t, &b)) // @pointsto command-line-arguments.c
110
111    // Dynamic call (not invoke) of method.
112    h = (*T).h
113    print(h(t, &b)) // @pointsto command-line-arguments.c
114}
115
116// @calls command-line-arguments.func5 -> (*command-line-arguments.T).f
117// @calls command-line-arguments.func5 -> (*command-line-arguments.T).g$thunk
118// @calls command-line-arguments.func5 -> (*command-line-arguments.T).h$thunk
119
120func func6() {
121    A := &a
122    f := func() *int {
123        return A // (free variable)
124    }
125    print(f()) // @pointsto command-line-arguments.a
126}
127
128// @calls command-line-arguments.func6 -> command-line-arguments.func6$1
129
130type I interface {
131    f()
132}
133
134type D struct{}
135
136func (Df() {}
137
138func func7() {
139    var i I = D{}
140    imethodClosure := i.f
141    imethodClosure()
142    // @calls command-line-arguments.func7 -> (command-line-arguments.I).f$bound
143    // @calls (command-line-arguments.I).f$bound -> (command-line-arguments.D).f
144
145    var d D
146    cmethodClosure := d.f
147    cmethodClosure()
148    // @calls command-line-arguments.func7 -> (command-line-arguments.D).f$bound
149    // @calls (command-line-arguments.D).f$bound ->(command-line-arguments.D).f
150
151    methodExpr := D.f
152    methodExpr(d)
153    // @calls command-line-arguments.func7 -> (command-line-arguments.D).f$thunk
154}
155
156func func8(x ...int) {
157    print(&x[0]) // @pointsto varargs[*]@varargs:15
158}
159
160type E struct {
161    x1x2x3x4x5 *int
162}
163
164func (e Ef() {}
165
166func func9() {
167    // Regression test for bug reported by Jon Valdes on golang-dev, Jun 19 2014.
168    // The receiver of a bound method closure may be of a multi-node type, E.
169    // valueNode was reserving only a single node for it, so the
170    // nodes used by the immediately following constraints
171    // (e.g. param 'i') would get clobbered.
172
173    var e E
174    e.x1 = &a
175    e.x2 = &a
176    e.x3 = &a
177    e.x4 = &a
178    e.x5 = &a
179
180    _ = e.f // form a closure---must reserve sizeof(E) nodes
181
182    func(i I) {
183        i.f() // must not crash the solver
184    }(new(D))
185
186    print(e.x1// @pointsto command-line-arguments.a
187    print(e.x2// @pointsto command-line-arguments.a
188    print(e.x3// @pointsto command-line-arguments.a
189    print(e.x4// @pointsto command-line-arguments.a
190    print(e.x5// @pointsto command-line-arguments.a
191}
192
193func main() {
194    func1()
195    func2()
196    func3()
197    func4()
198    func5()
199    func6()
200    func7()
201    func8(123// @line varargs
202    func9()
203}
204
205// @calls <root> -> command-line-arguments.main
206// @calls <root> -> command-line-arguments.init
207
MembersX
func7.methodExpr
swap.y
T.h
D.f
func7.d
func1.h
T.g.x
E
E.x3
func2
func4
func5.t
func7.imethodClosure
func9.e
I
func8
E.x2
func3.x
func4.j
T.g.t
T.g
func8.x
func3
func4.a
func4.q
func7
func5
func6
func2.y
T.f.t
func6.A
T.f.x
T.h.t
func2.x
D
E.f
swap
swap.x
T.h.x
E.x1
E.x4
E.x5
func4.p
func7.cmethodClosure
func7.i
func9
c
func4.i
func1
func3.y
func4.f
T.f
E.f.e
Members
X