// +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 -> func@19.7 // @calls main.func1 -> func@11.7 // @calls func@19.7 -> func@11.7 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 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 // @calls main.func5 -> (*main.T).h func func6() { A := &a f := func() *int { return A // (free variable) } print(f()) // @pointsto main.a } // @calls main.func6 -> func@120.7 type I interface { f() } type D struct{} func (D) f() {} func func7() { var i I = D{} imethodClosure := i.f imethodClosure() // @calls main.func7 -> bound$(main.I).f // @calls bound$(main.I).f -> (main.D).f var d D cmethodClosure := d.f cmethodClosure() // @calls main.func7 -> bound$(main.D).f // @calls bound$(main.D).f ->(main.D).f methodExpr := D.f methodExpr(d) // @calls main.func7 -> (main.D).f } func main() { func1() func2() func3() func4() func5() func6() func7() } // @calls -> main.main // @calls -> main.init