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