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