github.com/v2fly/tools@v0.100.0/go/pointer/testdata/func.go (about) 1 // +build ignore 2 3 package main 4 5 var a, b, c int 6 7 var unknown bool // defeat dead-code elimination 8 9 func 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 35 func 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 47 func 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 60 func 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 68 func 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 80 type T int 81 82 func (t *T) f(x *int) *int { 83 print(t) // @pointsto main.a 84 print(x) // @pointsto main.c 85 return &b 86 } 87 88 func (t *T) g(x *int) *int { 89 print(t) // @pointsto main.a 90 print(x) // @pointsto main.b 91 return &c 92 } 93 94 func (t *T) h(x *int) *int { 95 print(t) // @pointsto main.a 96 print(x) // @pointsto main.b 97 return &c 98 } 99 100 var h func(*T, *int) *int 101 102 func 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 119 func 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 129 type I interface { 130 f() 131 } 132 133 type D struct{} 134 135 func (D) f() {} 136 137 func 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 155 func func8(x ...int) { 156 print(&x[0]) // @pointsto varargs[*]@varargs:15 157 } 158 159 type E struct { 160 x1, x2, x3, x4, x5 *int 161 } 162 163 func (e E) f() {} 164 165 func 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 192 func 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