github.com/powerman/golang-tools@v0.1.11-0.20220410185822-5ad214d8d803/go/pointer/testdata/func.go (about) 1 //go:build ignore 2 // +build ignore 3 4 package main 5 6 var a, b, c int 7 8 var unknown bool // defeat dead-code elimination 9 10 func 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 36 func func2() { 37 var x, y *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 48 func func3() { 49 x, y := func() (x, y *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 61 func swap(x, y *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 y, x 67 } 68 69 func func4() { 70 a := make([]int, 10) // @line func4make 71 i, j := 123, 456 // @line f4j 72 _ = i 73 p, q := 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 81 type T int 82 83 func (t *T) f(x *int) *int { 84 print(t) // @pointsto command-line-arguments.a 85 print(x) // @pointsto command-line-arguments.c 86 return &b 87 } 88 89 func (t *T) g(x *int) *int { 90 print(t) // @pointsto command-line-arguments.a 91 print(x) // @pointsto command-line-arguments.b 92 return &c 93 } 94 95 func (t *T) h(x *int) *int { 96 print(t) // @pointsto command-line-arguments.a 97 print(x) // @pointsto command-line-arguments.b 98 return &c 99 } 100 101 var h func(*T, *int) *int 102 103 func 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 120 func 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 130 type I interface { 131 f() 132 } 133 134 type D struct{} 135 136 func (D) f() {} 137 138 func 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 156 func func8(x ...int) { 157 print(&x[0]) // @pointsto varargs[*]@varargs:15 158 } 159 160 type E struct { 161 x1, x2, x3, x4, x5 *int 162 } 163 164 func (e E) f() {} 165 166 func 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 193 func main() { 194 func1() 195 func2() 196 func3() 197 func4() 198 func5() 199 func6() 200 func7() 201 func8(1, 2, 3) // @line varargs 202 func9() 203 } 204 205 // @calls <root> -> command-line-arguments.main 206 // @calls <root> -> command-line-arguments.init