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