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