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