Source file test/escape2.go

     1  // errorcheck -0 -m -l
     2  
     3  // Copyright 2010 The Go Authors. All rights reserved.
     4  // Use of this source code is governed by a BSD-style
     5  // license that can be found in the LICENSE file.
     6  
     7  // Test, using compiler diagnostic flags, that the escape analysis is working.
     8  // Compiles but does not run.  Inlining is disabled.
     9  
    10  // escape2n.go contains all the same tests but compiles with -N.
    11  
    12  package foo
    13  
    14  import (
    15  	"fmt"
    16  	"unsafe"
    17  )
    18  
    19  var gxx *int
    20  
    21  func foo1(x int) { // ERROR "moved to heap: x$"
    22  	gxx = &x
    23  }
    24  
    25  func foo2(yy *int) { // ERROR "leaking param: yy$"
    26  	gxx = yy
    27  }
    28  
    29  func foo3(x int) *int { // ERROR "moved to heap: x$"
    30  	return &x
    31  }
    32  
    33  type T *T
    34  
    35  func foo3b(t T) { // ERROR "leaking param: t$"
    36  	*t = t
    37  }
    38  
    39  // xx isn't going anywhere, so use of yy is ok
    40  func foo4(xx, yy *int) { // ERROR "xx does not escape$" "yy does not escape$"
    41  	xx = yy
    42  }
    43  
    44  // xx isn't going anywhere, so taking address of yy is ok
    45  func foo5(xx **int, yy *int) { // ERROR "xx does not escape$" "yy does not escape$"
    46  	xx = &yy
    47  }
    48  
    49  func foo6(xx **int, yy *int) { // ERROR "xx does not escape$" "leaking param: yy$"
    50  	*xx = yy
    51  }
    52  
    53  func foo7(xx **int, yy *int) { // ERROR "xx does not escape$" "yy does not escape$"
    54  	**xx = *yy
    55  }
    56  
    57  func foo8(xx, yy *int) int { // ERROR "xx does not escape$" "yy does not escape$"
    58  	xx = yy
    59  	return *xx
    60  }
    61  
    62  func foo9(xx, yy *int) *int { // ERROR "leaking param: xx to result ~r0 level=0$" "leaking param: yy to result ~r0 level=0$"
    63  	xx = yy
    64  	return xx
    65  }
    66  
    67  func foo10(xx, yy *int) { // ERROR "xx does not escape$" "yy does not escape$"
    68  	*xx = *yy
    69  }
    70  
    71  func foo11() int {
    72  	x, y := 0, 42
    73  	xx := &x
    74  	yy := &y
    75  	*xx = *yy
    76  	return x
    77  }
    78  
    79  var xxx **int
    80  
    81  func foo12(yyy **int) { // ERROR "leaking param: yyy$"
    82  	xxx = yyy
    83  }
    84  
    85  // Must treat yyy as leaking because *yyy leaks, and the escape analysis
    86  // summaries in exported metadata do not distinguish these two cases.
    87  func foo13(yyy **int) { // ERROR "leaking param content: yyy$"
    88  	*xxx = *yyy
    89  }
    90  
    91  func foo14(yyy **int) { // ERROR "yyy does not escape$"
    92  	**xxx = **yyy
    93  }
    94  
    95  func foo15(yy *int) { // ERROR "moved to heap: yy$"
    96  	xxx = &yy
    97  }
    98  
    99  func foo16(yy *int) { // ERROR "leaking param: yy$"
   100  	*xxx = yy
   101  }
   102  
   103  func foo17(yy *int) { // ERROR "yy does not escape$"
   104  	**xxx = *yy
   105  }
   106  
   107  func foo18(y int) { // ERROR "moved to heap: y$"
   108  	*xxx = &y
   109  }
   110  
   111  func foo19(y int) {
   112  	**xxx = y
   113  }
   114  
   115  type Bar struct {
   116  	i  int
   117  	ii *int
   118  }
   119  
   120  func NewBar() *Bar {
   121  	return &Bar{42, nil} // ERROR "&Bar{...} escapes to heap$"
   122  }
   123  
   124  func NewBarp(x *int) *Bar { // ERROR "leaking param: x$"
   125  	return &Bar{42, x} // ERROR "&Bar{...} escapes to heap$"
   126  }
   127  
   128  func NewBarp2(x *int) *Bar { // ERROR "x does not escape$"
   129  	return &Bar{*x, nil} // ERROR "&Bar{...} escapes to heap$"
   130  }
   131  
   132  func (b *Bar) NoLeak() int { // ERROR "b does not escape$"
   133  	return *(b.ii)
   134  }
   135  
   136  func (b *Bar) Leak() *int { // ERROR "leaking param: b to result ~r0 level=0$"
   137  	return &b.i
   138  }
   139  
   140  func (b *Bar) AlsoNoLeak() *int { // ERROR "leaking param: b to result ~r0 level=1$"
   141  	return b.ii
   142  }
   143  
   144  func (b Bar) AlsoLeak() *int { // ERROR "leaking param: b to result ~r0 level=0$"
   145  	return b.ii
   146  }
   147  
   148  func (b Bar) LeaksToo() *int { // ERROR "leaking param: b to result ~r0 level=0$"
   149  	v := 0 // ERROR "moved to heap: v$"
   150  	b.ii = &v
   151  	return b.ii
   152  }
   153  
   154  func (b *Bar) LeaksABit() *int { // ERROR "leaking param: b to result ~r0 level=1$"
   155  	v := 0 // ERROR "moved to heap: v$"
   156  	b.ii = &v
   157  	return b.ii
   158  }
   159  
   160  func (b Bar) StillNoLeak() int { // ERROR "b does not escape$"
   161  	v := 0
   162  	b.ii = &v
   163  	return b.i
   164  }
   165  
   166  func goLeak(b *Bar) { // ERROR "leaking param: b$"
   167  	go b.NoLeak()
   168  }
   169  
   170  type Bar2 struct {
   171  	i  [12]int
   172  	ii []int
   173  }
   174  
   175  func NewBar2() *Bar2 {
   176  	return &Bar2{[12]int{42}, nil} // ERROR "&Bar2{...} escapes to heap$"
   177  }
   178  
   179  func (b *Bar2) NoLeak() int { // ERROR "b does not escape$"
   180  	return b.i[0]
   181  }
   182  
   183  func (b *Bar2) Leak() []int { // ERROR "leaking param: b to result ~r0 level=0$"
   184  	return b.i[:]
   185  }
   186  
   187  func (b *Bar2) AlsoNoLeak() []int { // ERROR "leaking param: b to result ~r0 level=1$"
   188  	return b.ii[0:1]
   189  }
   190  
   191  func (b Bar2) AgainNoLeak() [12]int { // ERROR "b does not escape$"
   192  	return b.i
   193  }
   194  
   195  func (b *Bar2) LeakSelf() { // ERROR "leaking param: b$"
   196  	b.ii = b.i[0:4]
   197  }
   198  
   199  func (b *Bar2) LeakSelf2() { // ERROR "leaking param: b$"
   200  	var buf []int
   201  	buf = b.i[0:]
   202  	b.ii = buf
   203  }
   204  
   205  func foo21() func() int {
   206  	x := 42
   207  	return func() int { // ERROR "func literal escapes to heap$"
   208  		return x
   209  	}
   210  }
   211  
   212  func foo21a() func() int {
   213  	x := 42             // ERROR "moved to heap: x$"
   214  	return func() int { // ERROR "func literal escapes to heap$"
   215  		x++
   216  		return x
   217  	}
   218  }
   219  
   220  func foo22() int {
   221  	x := 42
   222  	return func() int { // ERROR "func literal does not escape$"
   223  		return x
   224  	}()
   225  }
   226  
   227  func foo23(x int) func() int {
   228  	return func() int { // ERROR "func literal escapes to heap$"
   229  		return x
   230  	}
   231  }
   232  
   233  func foo23a(x int) func() int {
   234  	f := func() int { // ERROR "func literal escapes to heap$"
   235  		return x
   236  	}
   237  	return f
   238  }
   239  
   240  func foo23b(x int) *(func() int) {
   241  	f := func() int { return x } // ERROR "func literal escapes to heap$" "moved to heap: f$"
   242  	return &f
   243  }
   244  
   245  func foo23c(x int) func() int { // ERROR "moved to heap: x$"
   246  	return func() int { // ERROR "func literal escapes to heap$"
   247  		x++
   248  		return x
   249  	}
   250  }
   251  
   252  func foo24(x int) int {
   253  	return func() int { // ERROR "func literal does not escape$"
   254  		return x
   255  	}()
   256  }
   257  
   258  var x *int
   259  
   260  func fooleak(xx *int) int { // ERROR "leaking param: xx$"
   261  	x = xx
   262  	return *x
   263  }
   264  
   265  func foonoleak(xx *int) int { // ERROR "xx does not escape$"
   266  	return *x + *xx
   267  }
   268  
   269  func foo31(x int) int { // ERROR "moved to heap: x$"
   270  	return fooleak(&x)
   271  }
   272  
   273  func foo32(x int) int {
   274  	return foonoleak(&x)
   275  }
   276  
   277  type Foo struct {
   278  	xx *int
   279  	x  int
   280  }
   281  
   282  var F Foo
   283  var pf *Foo
   284  
   285  func (f *Foo) fooleak() { // ERROR "leaking param: f$"
   286  	pf = f
   287  }
   288  
   289  func (f *Foo) foonoleak() { // ERROR "f does not escape$"
   290  	F.x = f.x
   291  }
   292  
   293  func (f *Foo) Leak() { // ERROR "leaking param: f$"
   294  	f.fooleak()
   295  }
   296  
   297  func (f *Foo) NoLeak() { // ERROR "f does not escape$"
   298  	f.foonoleak()
   299  }
   300  
   301  func foo41(x int) { // ERROR "moved to heap: x$"
   302  	F.xx = &x
   303  }
   304  
   305  func (f *Foo) foo42(x int) { // ERROR "f does not escape$" "moved to heap: x$"
   306  	f.xx = &x
   307  }
   308  
   309  func foo43(f *Foo, x int) { // ERROR "f does not escape$" "moved to heap: x$"
   310  	f.xx = &x
   311  }
   312  
   313  func foo44(yy *int) { // ERROR "leaking param: yy$"
   314  	F.xx = yy
   315  }
   316  
   317  func (f *Foo) foo45() { // ERROR "f does not escape$"
   318  	F.x = f.x
   319  }
   320  
   321  // See foo13 above for explanation of why f leaks.
   322  func (f *Foo) foo46() { // ERROR "leaking param content: f$"
   323  	F.xx = f.xx
   324  }
   325  
   326  func (f *Foo) foo47() { // ERROR "leaking param: f$"
   327  	f.xx = &f.x
   328  }
   329  
   330  var ptrSlice []*int
   331  
   332  func foo50(i *int) { // ERROR "leaking param: i$"
   333  	ptrSlice[0] = i
   334  }
   335  
   336  var ptrMap map[*int]*int
   337  
   338  func foo51(i *int) { // ERROR "leaking param: i$"
   339  	ptrMap[i] = i
   340  }
   341  
   342  func indaddr1(x int) *int { // ERROR "moved to heap: x$"
   343  	return &x
   344  }
   345  
   346  func indaddr2(x *int) *int { // ERROR "leaking param: x to result ~r0 level=0$"
   347  	return *&x
   348  }
   349  
   350  func indaddr3(x *int32) *int { // ERROR "leaking param: x to result ~r0 level=0$"
   351  	return *(**int)(unsafe.Pointer(&x))
   352  }
   353  
   354  // From package math:
   355  
   356  func Float32bits(f float32) uint32 {
   357  	return *(*uint32)(unsafe.Pointer(&f))
   358  }
   359  
   360  func Float32frombits(b uint32) float32 {
   361  	return *(*float32)(unsafe.Pointer(&b))
   362  }
   363  
   364  func Float64bits(f float64) uint64 {
   365  	return *(*uint64)(unsafe.Pointer(&f))
   366  }
   367  
   368  func Float64frombits(b uint64) float64 {
   369  	return *(*float64)(unsafe.Pointer(&b))
   370  }
   371  
   372  // contrast with
   373  func float64bitsptr(f float64) *uint64 { // ERROR "moved to heap: f$"
   374  	return (*uint64)(unsafe.Pointer(&f))
   375  }
   376  
   377  func float64ptrbitsptr(f *float64) *uint64 { // ERROR "leaking param: f to result ~r0 level=0$"
   378  	return (*uint64)(unsafe.Pointer(f))
   379  }
   380  
   381  func typesw(i interface{}) *int { // ERROR "leaking param: i to result ~r0 level=0$"
   382  	switch val := i.(type) {
   383  	case *int:
   384  		return val
   385  	case *int8:
   386  		v := int(*val) // ERROR "moved to heap: v$"
   387  		return &v
   388  	}
   389  	return nil
   390  }
   391  
   392  func exprsw(i *int) *int { // ERROR "leaking param: i to result ~r0 level=0$"
   393  	switch j := i; *j + 110 {
   394  	case 12:
   395  		return j
   396  	case 42:
   397  		return nil
   398  	}
   399  	return nil
   400  }
   401  
   402  // assigning to an array element is like assigning to the array
   403  func foo60(i *int) *int { // ERROR "leaking param: i to result ~r0 level=0$"
   404  	var a [12]*int
   405  	a[0] = i
   406  	return a[1]
   407  }
   408  
   409  func foo60a(i *int) *int { // ERROR "i does not escape$"
   410  	var a [12]*int
   411  	a[0] = i
   412  	return nil
   413  }
   414  
   415  // assigning to a struct field  is like assigning to the struct
   416  func foo61(i *int) *int { // ERROR "leaking param: i to result ~r0 level=0$"
   417  	type S struct {
   418  		a, b *int
   419  	}
   420  	var s S
   421  	s.a = i
   422  	return s.b
   423  }
   424  
   425  func foo61a(i *int) *int { // ERROR "i does not escape$"
   426  	type S struct {
   427  		a, b *int
   428  	}
   429  	var s S
   430  	s.a = i
   431  	return nil
   432  }
   433  
   434  // assigning to a struct field is like assigning to the struct but
   435  // here this subtlety is lost, since s.a counts as an assignment to a
   436  // track-losing dereference.
   437  func foo62(i *int) *int { // ERROR "leaking param: i$"
   438  	type S struct {
   439  		a, b *int
   440  	}
   441  	s := new(S) // ERROR "new\(S\) does not escape$"
   442  	s.a = i
   443  	return nil // s.b
   444  }
   445  
   446  type M interface {
   447  	M()
   448  }
   449  
   450  func foo63(m M) { // ERROR "m does not escape$"
   451  }
   452  
   453  func foo64(m M) { // ERROR "leaking param: m$"
   454  	m.M()
   455  }
   456  
   457  func foo64b(m M) { // ERROR "leaking param: m$"
   458  	defer m.M()
   459  }
   460  
   461  type MV int
   462  
   463  func (MV) M() {}
   464  
   465  func foo65() {
   466  	var mv MV
   467  	foo63(&mv)
   468  }
   469  
   470  func foo66() {
   471  	var mv MV // ERROR "moved to heap: mv$"
   472  	foo64(&mv)
   473  }
   474  
   475  func foo67() {
   476  	var mv MV
   477  	foo63(mv) // ERROR "mv does not escape$"
   478  }
   479  
   480  func foo68() {
   481  	var mv MV
   482  	// escapes but it's an int so irrelevant
   483  	foo64(mv) // ERROR "mv escapes to heap$"
   484  }
   485  
   486  func foo69(m M) { // ERROR "leaking param: m$"
   487  	foo64(m)
   488  }
   489  
   490  func foo70(mv1 *MV, m M) { // ERROR "leaking param: m$" "leaking param: mv1$"
   491  	m = mv1
   492  	foo64(m)
   493  }
   494  
   495  func foo71(x *int) []*int { // ERROR "leaking param: x$"
   496  	var y []*int
   497  	y = append(y, x)
   498  	return y
   499  }
   500  
   501  func foo71a(x int) []*int { // ERROR "moved to heap: x$"
   502  	var y []*int
   503  	y = append(y, &x)
   504  	return y
   505  }
   506  
   507  func foo72() {
   508  	var x int
   509  	var y [1]*int
   510  	y[0] = &x
   511  }
   512  
   513  func foo72aa() [10]*int {
   514  	var x int // ERROR "moved to heap: x$"
   515  	var y [10]*int
   516  	y[0] = &x
   517  	return y
   518  }
   519  
   520  func foo72a() {
   521  	var y [10]*int
   522  	for i := 0; i < 10; i++ {
   523  		// escapes its scope
   524  		x := i // ERROR "moved to heap: x$"
   525  		y[i] = &x
   526  	}
   527  	return
   528  }
   529  
   530  func foo72b() [10]*int {
   531  	var y [10]*int
   532  	for i := 0; i < 10; i++ {
   533  		x := i // ERROR "moved to heap: x$"
   534  		y[i] = &x
   535  	}
   536  	return y
   537  }
   538  
   539  // issue 2145
   540  func foo73() {
   541  	s := []int{3, 2, 1} // ERROR "\[\]int{...} does not escape$"
   542  	for _, v := range s {
   543  		vv := v
   544  		// actually just escapes its scope
   545  		defer func() { // ERROR "func literal escapes to heap$"
   546  			println(vv)
   547  		}()
   548  	}
   549  }
   550  
   551  func foo731() {
   552  	s := []int{3, 2, 1} // ERROR "\[\]int{...} does not escape$"
   553  	for _, v := range s {
   554  		vv := v // ERROR "moved to heap: vv$"
   555  		// actually just escapes its scope
   556  		defer func() { // ERROR "func literal escapes to heap$"
   557  			vv = 42
   558  			println(vv)
   559  		}()
   560  	}
   561  }
   562  
   563  func foo74() {
   564  	s := []int{3, 2, 1} // ERROR "\[\]int{...} does not escape$"
   565  	for _, v := range s {
   566  		vv := v
   567  		// actually just escapes its scope
   568  		fn := func() { // ERROR "func literal escapes to heap$"
   569  			println(vv)
   570  		}
   571  		defer fn()
   572  	}
   573  }
   574  
   575  func foo74a() {
   576  	s := []int{3, 2, 1} // ERROR "\[\]int{...} does not escape$"
   577  	for _, v := range s {
   578  		vv := v // ERROR "moved to heap: vv$"
   579  		// actually just escapes its scope
   580  		fn := func() { // ERROR "func literal escapes to heap$"
   581  			vv += 1
   582  			println(vv)
   583  		}
   584  		defer fn()
   585  	}
   586  }
   587  
   588  // issue 3975
   589  func foo74b() {
   590  	var array [3]func()
   591  	s := []int{3, 2, 1} // ERROR "\[\]int{...} does not escape$"
   592  	for i, v := range s {
   593  		vv := v
   594  		// actually just escapes its scope
   595  		array[i] = func() { // ERROR "func literal escapes to heap$"
   596  			println(vv)
   597  		}
   598  	}
   599  }
   600  
   601  func foo74c() {
   602  	var array [3]func()
   603  	s := []int{3, 2, 1} // ERROR "\[\]int{...} does not escape$"
   604  	for i, v := range s {
   605  		vv := v // ERROR "moved to heap: vv$"
   606  		// actually just escapes its scope
   607  		array[i] = func() { // ERROR "func literal escapes to heap$"
   608  			println(&vv)
   609  		}
   610  	}
   611  }
   612  
   613  func myprint(y *int, x ...interface{}) *int { // ERROR "leaking param: y to result ~r0 level=0$" "x does not escape$"
   614  	return y
   615  }
   616  
   617  func myprint1(y *int, x ...interface{}) *interface{} { // ERROR "leaking param: x to result ~r0 level=0$" "y does not escape$"
   618  	return &x[0]
   619  }
   620  
   621  func foo75(z *int) { // ERROR "z does not escape$"
   622  	myprint(z, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "... argument does not escape$"
   623  }
   624  
   625  func foo75a(z *int) { // ERROR "z does not escape$"
   626  	myprint1(z, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "... argument does not escape$"
   627  }
   628  
   629  func foo75esc(z *int) { // ERROR "leaking param: z$"
   630  	gxx = myprint(z, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "... argument does not escape$"
   631  }
   632  
   633  func foo75aesc(z *int) { // ERROR "z does not escape$"
   634  	var ppi **interface{}       // assignments to pointer dereferences lose track
   635  	*ppi = myprint1(z, 1, 2, 3) // ERROR "... argument escapes to heap$" "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$"
   636  }
   637  
   638  func foo75aesc1(z *int) { // ERROR "z does not escape$"
   639  	sink = myprint1(z, 1, 2, 3) // ERROR "... argument escapes to heap$" "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$"
   640  }
   641  
   642  func foo76(z *int) { // ERROR "z does not escape"
   643  	myprint(nil, z) // ERROR "... argument does not escape$"
   644  }
   645  
   646  func foo76a(z *int) { // ERROR "z does not escape"
   647  	myprint1(nil, z) // ERROR "... argument does not escape$"
   648  }
   649  
   650  func foo76b() {
   651  	myprint(nil, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "... argument does not escape$"
   652  }
   653  
   654  func foo76c() {
   655  	myprint1(nil, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "... argument does not escape$"
   656  }
   657  
   658  func foo76d() {
   659  	defer myprint(nil, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "... argument does not escape$"
   660  }
   661  
   662  func foo76e() {
   663  	defer myprint1(nil, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "... argument does not escape$"
   664  }
   665  
   666  func foo76f() {
   667  	for {
   668  		// TODO: This one really only escapes its scope, but we don't distinguish yet.
   669  		defer myprint(nil, 1, 2, 3) // ERROR "... argument does not escape$" "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$"
   670  	}
   671  }
   672  
   673  func foo76g() {
   674  	for {
   675  		defer myprint1(nil, 1, 2, 3) // ERROR "... argument does not escape$" "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$"
   676  	}
   677  }
   678  
   679  func foo77(z []interface{}) { // ERROR "z does not escape$"
   680  	myprint(nil, z...) // z does not escape
   681  }
   682  
   683  func foo77a(z []interface{}) { // ERROR "z does not escape$"
   684  	myprint1(nil, z...)
   685  }
   686  
   687  func foo77b(z []interface{}) { // ERROR "leaking param: z$"
   688  	var ppi **interface{}
   689  	*ppi = myprint1(nil, z...)
   690  }
   691  
   692  func foo77c(z []interface{}) { // ERROR "leaking param: z$"
   693  	sink = myprint1(nil, z...)
   694  }
   695  
   696  func dotdotdot() {
   697  	i := 0
   698  	myprint(nil, &i) // ERROR "... argument does not escape$"
   699  
   700  	j := 0
   701  	myprint1(nil, &j) // ERROR "... argument does not escape$"
   702  }
   703  
   704  func foo78(z int) *int { // ERROR "moved to heap: z$"
   705  	return &z
   706  }
   707  
   708  func foo78a(z int) *int { // ERROR "moved to heap: z$"
   709  	y := &z
   710  	x := &y
   711  	return *x // really return y
   712  }
   713  
   714  func foo79() *int {
   715  	return new(int) // ERROR "new\(int\) escapes to heap$"
   716  }
   717  
   718  func foo80() *int {
   719  	var z *int
   720  	for {
   721  		// Really just escapes its scope but we don't distinguish
   722  		z = new(int) // ERROR "new\(int\) escapes to heap$"
   723  	}
   724  	_ = z
   725  	return nil
   726  }
   727  
   728  func foo81() *int {
   729  	for {
   730  		z := new(int) // ERROR "new\(int\) does not escape$"
   731  		_ = z
   732  	}
   733  	return nil
   734  }
   735  
   736  func tee(p *int) (x, y *int) { return p, p } // ERROR "leaking param: p to result x level=0$" "leaking param: p to result y level=0$"
   737  
   738  func noop(x, y *int) {} // ERROR "x does not escape$" "y does not escape$"
   739  
   740  func foo82() {
   741  	var x, y, z int // ERROR "moved to heap: x$" "moved to heap: y$" "moved to heap: z$"
   742  	go noop(tee(&z))
   743  	go noop(&x, &y)
   744  	for {
   745  		var u, v, w int // ERROR "moved to heap: u$" "moved to heap: v$" "moved to heap: w$"
   746  		defer noop(tee(&u))
   747  		defer noop(&v, &w)
   748  	}
   749  }
   750  
   751  type Fooer interface {
   752  	Foo()
   753  }
   754  
   755  type LimitedFooer struct {
   756  	Fooer
   757  	N int64
   758  }
   759  
   760  func LimitFooer(r Fooer, n int64) Fooer { // ERROR "leaking param: r$"
   761  	return &LimitedFooer{r, n} // ERROR "&LimitedFooer{...} escapes to heap$"
   762  }
   763  
   764  func foo90(x *int) map[*int]*int { // ERROR "leaking param: x$"
   765  	return map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int{...} escapes to heap$"
   766  }
   767  
   768  func foo91(x *int) map[*int]*int { // ERROR "leaking param: x$"
   769  	return map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int{...} escapes to heap$"
   770  }
   771  
   772  func foo92(x *int) [2]*int { // ERROR "leaking param: x to result ~r0 level=0$"
   773  	return [2]*int{x, nil}
   774  }
   775  
   776  // does not leak c
   777  func foo93(c chan *int) *int { // ERROR "c does not escape$"
   778  	for v := range c {
   779  		return v
   780  	}
   781  	return nil
   782  }
   783  
   784  // does not leak m
   785  func foo94(m map[*int]*int, b bool) *int { // ERROR "leaking param: m to result ~r0 level=1"
   786  	for k, v := range m {
   787  		if b {
   788  			return k
   789  		}
   790  		return v
   791  	}
   792  	return nil
   793  }
   794  
   795  // does leak x
   796  func foo95(m map[*int]*int, x *int) { // ERROR "m does not escape$" "leaking param: x$"
   797  	m[x] = x
   798  }
   799  
   800  // does not leak m but does leak content
   801  func foo96(m []*int) *int { // ERROR "leaking param: m to result ~r0 level=1"
   802  	return m[0]
   803  }
   804  
   805  // does leak m
   806  func foo97(m [1]*int) *int { // ERROR "leaking param: m to result ~r0 level=0$"
   807  	return m[0]
   808  }
   809  
   810  // does not leak m
   811  func foo98(m map[int]*int) *int { // ERROR "m does not escape$"
   812  	return m[0]
   813  }
   814  
   815  // does leak m
   816  func foo99(m *[1]*int) []*int { // ERROR "leaking param: m to result ~r0 level=0$"
   817  	return m[:]
   818  }
   819  
   820  // does not leak m
   821  func foo100(m []*int) *int { // ERROR "leaking param: m to result ~r0 level=1"
   822  	for _, v := range m {
   823  		return v
   824  	}
   825  	return nil
   826  }
   827  
   828  // does leak m
   829  func foo101(m [1]*int) *int { // ERROR "leaking param: m to result ~r0 level=0$"
   830  	for _, v := range m {
   831  		return v
   832  	}
   833  	return nil
   834  }
   835  
   836  // does not leak m
   837  func foo101a(m [1]*int) *int { // ERROR "m does not escape$"
   838  	for i := range m { // ERROR "moved to heap: i$"
   839  		return &i
   840  	}
   841  	return nil
   842  }
   843  
   844  // does leak x
   845  func foo102(m []*int, x *int) { // ERROR "m does not escape$" "leaking param: x$"
   846  	m[0] = x
   847  }
   848  
   849  // does not leak x
   850  func foo103(m [1]*int, x *int) { // ERROR "m does not escape$" "x does not escape$"
   851  	m[0] = x
   852  }
   853  
   854  var y []*int
   855  
   856  // does not leak x but does leak content
   857  func foo104(x []*int) { // ERROR "leaking param content: x"
   858  	copy(y, x)
   859  }
   860  
   861  // does not leak x but does leak content
   862  func foo105(x []*int) { // ERROR "leaking param content: x"
   863  	_ = append(y, x...)
   864  }
   865  
   866  // does leak x
   867  func foo106(x *int) { // ERROR "leaking param: x$"
   868  	_ = append(y, x)
   869  }
   870  
   871  func foo107(x *int) map[*int]*int { // ERROR "leaking param: x$"
   872  	return map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int{...} escapes to heap$"
   873  }
   874  
   875  func foo108(x *int) map[*int]*int { // ERROR "leaking param: x$"
   876  	return map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int{...} escapes to heap$"
   877  }
   878  
   879  func foo109(x *int) *int { // ERROR "leaking param: x$"
   880  	m := map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int{...} does not escape$"
   881  	for k, _ := range m {
   882  		return k
   883  	}
   884  	return nil
   885  }
   886  
   887  func foo110(x *int) *int { // ERROR "leaking param: x$"
   888  	m := map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int{...} does not escape$"
   889  	return m[nil]
   890  }
   891  
   892  func foo111(x *int) *int { // ERROR "leaking param: x to result ~r0 level=0"
   893  	m := []*int{x} // ERROR "\[\]\*int{...} does not escape$"
   894  	return m[0]
   895  }
   896  
   897  func foo112(x *int) *int { // ERROR "leaking param: x to result ~r0 level=0$"
   898  	m := [1]*int{x}
   899  	return m[0]
   900  }
   901  
   902  func foo113(x *int) *int { // ERROR "leaking param: x to result ~r0 level=0$"
   903  	m := Bar{ii: x}
   904  	return m.ii
   905  }
   906  
   907  func foo114(x *int) *int { // ERROR "leaking param: x to result ~r0 level=0$"
   908  	m := &Bar{ii: x} // ERROR "&Bar{...} does not escape$"
   909  	return m.ii
   910  }
   911  
   912  func foo115(x *int) *int { // ERROR "leaking param: x to result ~r0 level=0$"
   913  	return (*int)(unsafe.Pointer(uintptr(unsafe.Pointer(x)) + 1))
   914  }
   915  
   916  func foo116(b bool) *int {
   917  	if b {
   918  		x := 1 // ERROR "moved to heap: x$"
   919  		return &x
   920  	} else {
   921  		y := 1 // ERROR "moved to heap: y$"
   922  		return &y
   923  	}
   924  	return nil
   925  }
   926  
   927  func foo117(unknown func(interface{})) { // ERROR "unknown does not escape$"
   928  	x := 1 // ERROR "moved to heap: x$"
   929  	unknown(&x)
   930  }
   931  
   932  func foo118(unknown func(*int)) { // ERROR "unknown does not escape$"
   933  	x := 1 // ERROR "moved to heap: x$"
   934  	unknown(&x)
   935  }
   936  
   937  func external(*int)
   938  
   939  func foo119(x *int) { // ERROR "leaking param: x$"
   940  	external(x)
   941  }
   942  
   943  func foo120() {
   944  	// formerly exponential time analysis
   945  L1:
   946  L2:
   947  L3:
   948  L4:
   949  L5:
   950  L6:
   951  L7:
   952  L8:
   953  L9:
   954  L10:
   955  L11:
   956  L12:
   957  L13:
   958  L14:
   959  L15:
   960  L16:
   961  L17:
   962  L18:
   963  L19:
   964  L20:
   965  L21:
   966  L22:
   967  L23:
   968  L24:
   969  L25:
   970  L26:
   971  L27:
   972  L28:
   973  L29:
   974  L30:
   975  L31:
   976  L32:
   977  L33:
   978  L34:
   979  L35:
   980  L36:
   981  L37:
   982  L38:
   983  L39:
   984  L40:
   985  L41:
   986  L42:
   987  L43:
   988  L44:
   989  L45:
   990  L46:
   991  L47:
   992  L48:
   993  L49:
   994  L50:
   995  L51:
   996  L52:
   997  L53:
   998  L54:
   999  L55:
  1000  L56:
  1001  L57:
  1002  L58:
  1003  L59:
  1004  L60:
  1005  L61:
  1006  L62:
  1007  L63:
  1008  L64:
  1009  L65:
  1010  L66:
  1011  L67:
  1012  L68:
  1013  L69:
  1014  L70:
  1015  L71:
  1016  L72:
  1017  L73:
  1018  L74:
  1019  L75:
  1020  L76:
  1021  L77:
  1022  L78:
  1023  L79:
  1024  L80:
  1025  L81:
  1026  L82:
  1027  L83:
  1028  L84:
  1029  L85:
  1030  L86:
  1031  L87:
  1032  L88:
  1033  L89:
  1034  L90:
  1035  L91:
  1036  L92:
  1037  L93:
  1038  L94:
  1039  L95:
  1040  L96:
  1041  L97:
  1042  L98:
  1043  L99:
  1044  L100:
  1045  	// use the labels to silence compiler errors
  1046  	goto L1
  1047  	goto L2
  1048  	goto L3
  1049  	goto L4
  1050  	goto L5
  1051  	goto L6
  1052  	goto L7
  1053  	goto L8
  1054  	goto L9
  1055  	goto L10
  1056  	goto L11
  1057  	goto L12
  1058  	goto L13
  1059  	goto L14
  1060  	goto L15
  1061  	goto L16
  1062  	goto L17
  1063  	goto L18
  1064  	goto L19
  1065  	goto L20
  1066  	goto L21
  1067  	goto L22
  1068  	goto L23
  1069  	goto L24
  1070  	goto L25
  1071  	goto L26
  1072  	goto L27
  1073  	goto L28
  1074  	goto L29
  1075  	goto L30
  1076  	goto L31
  1077  	goto L32
  1078  	goto L33
  1079  	goto L34
  1080  	goto L35
  1081  	goto L36
  1082  	goto L37
  1083  	goto L38
  1084  	goto L39
  1085  	goto L40
  1086  	goto L41
  1087  	goto L42
  1088  	goto L43
  1089  	goto L44
  1090  	goto L45
  1091  	goto L46
  1092  	goto L47
  1093  	goto L48
  1094  	goto L49
  1095  	goto L50
  1096  	goto L51
  1097  	goto L52
  1098  	goto L53
  1099  	goto L54
  1100  	goto L55
  1101  	goto L56
  1102  	goto L57
  1103  	goto L58
  1104  	goto L59
  1105  	goto L60
  1106  	goto L61
  1107  	goto L62
  1108  	goto L63
  1109  	goto L64
  1110  	goto L65
  1111  	goto L66
  1112  	goto L67
  1113  	goto L68
  1114  	goto L69
  1115  	goto L70
  1116  	goto L71
  1117  	goto L72
  1118  	goto L73
  1119  	goto L74
  1120  	goto L75
  1121  	goto L76
  1122  	goto L77
  1123  	goto L78
  1124  	goto L79
  1125  	goto L80
  1126  	goto L81
  1127  	goto L82
  1128  	goto L83
  1129  	goto L84
  1130  	goto L85
  1131  	goto L86
  1132  	goto L87
  1133  	goto L88
  1134  	goto L89
  1135  	goto L90
  1136  	goto L91
  1137  	goto L92
  1138  	goto L93
  1139  	goto L94
  1140  	goto L95
  1141  	goto L96
  1142  	goto L97
  1143  	goto L98
  1144  	goto L99
  1145  	goto L100
  1146  }
  1147  
  1148  func foo121() {
  1149  	for i := 0; i < 10; i++ {
  1150  		defer myprint(nil, i) // ERROR "... argument does not escape$" "i escapes to heap$"
  1151  		go myprint(nil, i)    // ERROR "... argument does not escape$" "i escapes to heap$"
  1152  	}
  1153  }
  1154  
  1155  // same as foo121 but check across import
  1156  func foo121b() {
  1157  	for i := 0; i < 10; i++ {
  1158  		defer fmt.Printf("%d", i) // ERROR "... argument does not escape$" "i escapes to heap$"
  1159  		go fmt.Printf("%d", i)    // ERROR "... argument does not escape$" "i escapes to heap$"
  1160  	}
  1161  }
  1162  
  1163  // a harmless forward jump
  1164  func foo122() {
  1165  	var i *int
  1166  
  1167  	goto L1
  1168  L1:
  1169  	i = new(int) // ERROR "new\(int\) does not escape$"
  1170  	_ = i
  1171  }
  1172  
  1173  // a backward jump, increases loopdepth
  1174  func foo123() {
  1175  	var i *int
  1176  
  1177  L1:
  1178  	i = new(int) // ERROR "new\(int\) escapes to heap$"
  1179  
  1180  	goto L1
  1181  	_ = i
  1182  }
  1183  
  1184  func foo124(x **int) { // ERROR "x does not escape$"
  1185  	var i int // ERROR "moved to heap: i$"
  1186  	p := &i
  1187  	func() { // ERROR "func literal does not escape$"
  1188  		*x = p
  1189  	}()
  1190  }
  1191  
  1192  func foo125(ch chan *int) { // ERROR "ch does not escape$"
  1193  	var i int // ERROR "moved to heap: i$"
  1194  	p := &i
  1195  	func() { // ERROR "func literal does not escape$"
  1196  		ch <- p
  1197  	}()
  1198  }
  1199  
  1200  func foo126() {
  1201  	var px *int // loopdepth 0
  1202  	for {
  1203  		// loopdepth 1
  1204  		var i int // ERROR "moved to heap: i$"
  1205  		func() {  // ERROR "func literal does not escape$"
  1206  			px = &i
  1207  		}()
  1208  	}
  1209  	_ = px
  1210  }
  1211  
  1212  var px *int
  1213  
  1214  func foo127() {
  1215  	var i int // ERROR "moved to heap: i$"
  1216  	p := &i
  1217  	q := p
  1218  	px = q
  1219  }
  1220  
  1221  func foo128() {
  1222  	var i int
  1223  	p := &i
  1224  	q := p
  1225  	_ = q
  1226  }
  1227  
  1228  func foo129() {
  1229  	var i int // ERROR "moved to heap: i$"
  1230  	p := &i
  1231  	func() { // ERROR "func literal does not escape$"
  1232  		q := p
  1233  		func() { // ERROR "func literal does not escape$"
  1234  			r := q
  1235  			px = r
  1236  		}()
  1237  	}()
  1238  }
  1239  
  1240  func foo130() {
  1241  	for {
  1242  		var i int // ERROR "moved to heap: i$"
  1243  		func() {  // ERROR "func literal does not escape$"
  1244  			px = &i
  1245  		}()
  1246  	}
  1247  }
  1248  
  1249  func foo131() {
  1250  	var i int // ERROR "moved to heap: i$"
  1251  	func() {  // ERROR "func literal does not escape$"
  1252  		px = &i
  1253  	}()
  1254  }
  1255  
  1256  func foo132() {
  1257  	var i int   // ERROR "moved to heap: i$"
  1258  	go func() { // ERROR "func literal escapes to heap$"
  1259  		px = &i
  1260  	}()
  1261  }
  1262  
  1263  func foo133() {
  1264  	var i int      // ERROR "moved to heap: i$"
  1265  	defer func() { // ERROR "func literal does not escape$"
  1266  		px = &i
  1267  	}()
  1268  }
  1269  
  1270  func foo134() {
  1271  	var i int
  1272  	p := &i
  1273  	func() { // ERROR "func literal does not escape$"
  1274  		q := p
  1275  		func() { // ERROR "func literal does not escape$"
  1276  			r := q
  1277  			_ = r
  1278  		}()
  1279  	}()
  1280  }
  1281  
  1282  func foo135() {
  1283  	var i int // ERROR "moved to heap: i$"
  1284  	p := &i
  1285  	go func() { // ERROR "func literal escapes to heap$"
  1286  		q := p
  1287  		func() { // ERROR "func literal does not escape$"
  1288  			r := q
  1289  			_ = r
  1290  		}()
  1291  	}()
  1292  }
  1293  
  1294  func foo136() {
  1295  	var i int // ERROR "moved to heap: i$"
  1296  	p := &i
  1297  	go func() { // ERROR "func literal escapes to heap$"
  1298  		q := p
  1299  		func() { // ERROR "func literal does not escape$"
  1300  			r := q
  1301  			px = r
  1302  		}()
  1303  	}()
  1304  }
  1305  
  1306  func foo137() {
  1307  	var i int // ERROR "moved to heap: i$"
  1308  	p := &i
  1309  	func() { // ERROR "func literal does not escape$"
  1310  		q := p
  1311  		go func() { // ERROR "func literal escapes to heap$"
  1312  			r := q
  1313  			_ = r
  1314  		}()
  1315  	}()
  1316  }
  1317  
  1318  func foo138() *byte {
  1319  	type T struct {
  1320  		x [1]byte
  1321  	}
  1322  	t := new(T) // ERROR "new\(T\) escapes to heap$"
  1323  	return &t.x[0]
  1324  }
  1325  
  1326  func foo139() *byte {
  1327  	type T struct {
  1328  		x struct {
  1329  			y byte
  1330  		}
  1331  	}
  1332  	t := new(T) // ERROR "new\(T\) escapes to heap$"
  1333  	return &t.x.y
  1334  }
  1335  
  1336  // issue 4751
  1337  func foo140() interface{} {
  1338  	type T struct {
  1339  		X string
  1340  	}
  1341  	type U struct {
  1342  		X string
  1343  		T *T
  1344  	}
  1345  	t := &T{} // ERROR "&T{} escapes to heap$"
  1346  	return U{ // ERROR "U{...} escapes to heap$"
  1347  		X: t.X,
  1348  		T: t,
  1349  	}
  1350  }
  1351  
  1352  //go:noescape
  1353  
  1354  func F1([]byte)
  1355  
  1356  func F2([]byte)
  1357  
  1358  //go:noescape
  1359  
  1360  func F3(x []byte) // ERROR "x does not escape$"
  1361  
  1362  func F4(x []byte) // ERROR "leaking param: x$"
  1363  
  1364  func G() {
  1365  	var buf1 [10]byte
  1366  	F1(buf1[:])
  1367  
  1368  	var buf2 [10]byte // ERROR "moved to heap: buf2$"
  1369  	F2(buf2[:])
  1370  
  1371  	var buf3 [10]byte
  1372  	F3(buf3[:])
  1373  
  1374  	var buf4 [10]byte // ERROR "moved to heap: buf4$"
  1375  	F4(buf4[:])
  1376  }
  1377  
  1378  type Tm struct {
  1379  	x int
  1380  }
  1381  
  1382  func (t *Tm) M() { // ERROR "t does not escape$"
  1383  }
  1384  
  1385  func foo141() {
  1386  	var f func()
  1387  
  1388  	t := new(Tm) // ERROR "new\(Tm\) does not escape$"
  1389  	f = t.M      // ERROR "t.M does not escape$"
  1390  	_ = f
  1391  }
  1392  
  1393  var gf func()
  1394  
  1395  func foo142() {
  1396  	t := new(Tm) // ERROR "new\(Tm\) escapes to heap$"
  1397  	gf = t.M     // ERROR "t.M escapes to heap$"
  1398  }
  1399  
  1400  // issue 3888.
  1401  func foo143() {
  1402  	for i := 0; i < 1000; i++ {
  1403  		func() { // ERROR "func literal does not escape$"
  1404  			for i := 0; i < 1; i++ {
  1405  				var t Tm
  1406  				t.M()
  1407  			}
  1408  		}()
  1409  	}
  1410  }
  1411  
  1412  // issue 5773
  1413  // Check that annotations take effect regardless of whether they
  1414  // are before or after the use in the source code.
  1415  
  1416  //go:noescape
  1417  
  1418  func foo144a(*int)
  1419  
  1420  func foo144() {
  1421  	var x int
  1422  	foo144a(&x)
  1423  	var y int
  1424  	foo144b(&y)
  1425  }
  1426  
  1427  //go:noescape
  1428  
  1429  func foo144b(*int)
  1430  
  1431  // issue 7313: for loop init should not be treated as "in loop"
  1432  
  1433  type List struct {
  1434  	Next *List
  1435  }
  1436  
  1437  func foo145(l List) { // ERROR "l does not escape$"
  1438  	var p *List
  1439  	for p = &l; p.Next != nil; p = p.Next {
  1440  	}
  1441  }
  1442  
  1443  func foo146(l List) { // ERROR "l does not escape$"
  1444  	var p *List
  1445  	p = &l
  1446  	for ; p.Next != nil; p = p.Next {
  1447  	}
  1448  }
  1449  
  1450  func foo147(l List) { // ERROR "l does not escape$"
  1451  	var p *List
  1452  	p = &l
  1453  	for p.Next != nil {
  1454  		p = p.Next
  1455  	}
  1456  }
  1457  
  1458  func foo148(l List) { // ERROR "l does not escape$"
  1459  	for p := &l; p.Next != nil; p = p.Next {
  1460  	}
  1461  }
  1462  
  1463  // related: address of variable should have depth of variable, not of loop
  1464  
  1465  func foo149(l List) { // ERROR "l does not escape$"
  1466  	var p *List
  1467  	for {
  1468  		for p = &l; p.Next != nil; p = p.Next {
  1469  		}
  1470  	}
  1471  }
  1472  
  1473  // issue 7934: missed ... if element type had no pointers
  1474  
  1475  var save150 []byte
  1476  
  1477  func foo150(x ...byte) { // ERROR "leaking param: x$"
  1478  	save150 = x
  1479  }
  1480  
  1481  func bar150() {
  1482  	foo150(1, 2, 3) // ERROR "... argument escapes to heap$"
  1483  }
  1484  
  1485  // issue 7931: bad handling of slice of array
  1486  
  1487  var save151 *int
  1488  
  1489  func foo151(x *int) { // ERROR "leaking param: x$"
  1490  	save151 = x
  1491  }
  1492  
  1493  func bar151() {
  1494  	var a [64]int // ERROR "moved to heap: a$"
  1495  	a[4] = 101
  1496  	foo151(&(&a)[4:8][0])
  1497  }
  1498  
  1499  func bar151b() {
  1500  	var a [10]int // ERROR "moved to heap: a$"
  1501  	b := a[:]
  1502  	foo151(&b[4:8][0])
  1503  }
  1504  
  1505  func bar151c() {
  1506  	var a [64]int // ERROR "moved to heap: a$"
  1507  	a[4] = 101
  1508  	foo151(&(&a)[4:8:8][0])
  1509  }
  1510  
  1511  func bar151d() {
  1512  	var a [10]int // ERROR "moved to heap: a$"
  1513  	b := a[:]
  1514  	foo151(&b[4:8:8][0])
  1515  }
  1516  
  1517  // issue 8120
  1518  
  1519  type U struct {
  1520  	s *string
  1521  }
  1522  
  1523  func (u *U) String() *string { // ERROR "leaking param: u to result ~r0 level=1$"
  1524  	return u.s
  1525  }
  1526  
  1527  type V struct {
  1528  	s *string
  1529  }
  1530  
  1531  func NewV(u U) *V { // ERROR "leaking param: u$"
  1532  	return &V{u.String()} // ERROR "&V{...} escapes to heap$"
  1533  }
  1534  
  1535  func foo152() {
  1536  	a := "a" // ERROR "moved to heap: a$"
  1537  	u := U{&a}
  1538  	v := NewV(u)
  1539  	println(v)
  1540  }
  1541  
  1542  // issue 8176 - &x in type switch body not marked as escaping
  1543  
  1544  func foo153(v interface{}) *int { // ERROR "v does not escape"
  1545  	switch x := v.(type) {
  1546  	case int: // ERROR "moved to heap: x$"
  1547  		return &x
  1548  	}
  1549  	panic(0) // ERROR "0 escapes to heap"
  1550  }
  1551  
  1552  // issue 8185 - &result escaping into result
  1553  
  1554  func f() (x int, y *int) { // ERROR "moved to heap: x$"
  1555  	y = &x
  1556  	return
  1557  }
  1558  
  1559  func g() (x interface{}) { // ERROR "moved to heap: x$"
  1560  	x = &x
  1561  	return
  1562  }
  1563  
  1564  var sink interface{}
  1565  
  1566  type Lit struct {
  1567  	p *int
  1568  }
  1569  
  1570  func ptrlitNoescape() {
  1571  	// Both literal and element do not escape.
  1572  	i := 0
  1573  	x := &Lit{&i} // ERROR "&Lit{...} does not escape$"
  1574  	_ = x
  1575  }
  1576  
  1577  func ptrlitNoEscape2() {
  1578  	// Literal does not escape, but element does.
  1579  	i := 0        // ERROR "moved to heap: i$"
  1580  	x := &Lit{&i} // ERROR "&Lit{...} does not escape$"
  1581  	sink = *x
  1582  }
  1583  
  1584  func ptrlitEscape() {
  1585  	// Both literal and element escape.
  1586  	i := 0        // ERROR "moved to heap: i$"
  1587  	x := &Lit{&i} // ERROR "&Lit{...} escapes to heap$"
  1588  	sink = x
  1589  }
  1590  
  1591  // self-assignments
  1592  
  1593  type Buffer struct {
  1594  	arr    [64]byte
  1595  	arrPtr *[64]byte
  1596  	buf1   []byte
  1597  	buf2   []byte
  1598  	str1   string
  1599  	str2   string
  1600  }
  1601  
  1602  func (b *Buffer) foo() { // ERROR "b does not escape$"
  1603  	b.buf1 = b.buf1[1:2]   // ERROR "\(\*Buffer\).foo ignoring self-assignment in b.buf1 = b.buf1\[1:2\]$"
  1604  	b.buf1 = b.buf1[1:2:3] // ERROR "\(\*Buffer\).foo ignoring self-assignment in b.buf1 = b.buf1\[1:2:3\]$"
  1605  	b.buf1 = b.buf2[1:2]   // ERROR "\(\*Buffer\).foo ignoring self-assignment in b.buf1 = b.buf2\[1:2\]$"
  1606  	b.buf1 = b.buf2[1:2:3] // ERROR "\(\*Buffer\).foo ignoring self-assignment in b.buf1 = b.buf2\[1:2:3\]$"
  1607  }
  1608  
  1609  func (b *Buffer) bar() { // ERROR "leaking param: b$"
  1610  	b.buf1 = b.arr[1:2]
  1611  }
  1612  
  1613  func (b *Buffer) arrayPtr() { // ERROR "b does not escape"
  1614  	b.buf1 = b.arrPtr[1:2]   // ERROR "\(\*Buffer\).arrayPtr ignoring self-assignment in b.buf1 = b.arrPtr\[1:2\]$"
  1615  	b.buf1 = b.arrPtr[1:2:3] // ERROR "\(\*Buffer\).arrayPtr ignoring self-assignment in b.buf1 = b.arrPtr\[1:2:3\]$"
  1616  }
  1617  
  1618  func (b *Buffer) baz() { // ERROR "b does not escape$"
  1619  	b.str1 = b.str1[1:2] // ERROR "\(\*Buffer\).baz ignoring self-assignment in b.str1 = b.str1\[1:2\]$"
  1620  	b.str1 = b.str2[1:2] // ERROR "\(\*Buffer\).baz ignoring self-assignment in b.str1 = b.str2\[1:2\]$"
  1621  }
  1622  
  1623  func (b *Buffer) bat() { // ERROR "leaking param content: b$"
  1624  	o := new(Buffer) // ERROR "new\(Buffer\) escapes to heap$"
  1625  	o.buf1 = b.buf1[1:2]
  1626  	sink = o
  1627  }
  1628  
  1629  func quux(sp *string, bp *[]byte) { // ERROR "bp does not escape$" "sp does not escape$"
  1630  	*sp = (*sp)[1:2] // ERROR "quux ignoring self-assignment in \*sp = \(\*sp\)\[1:2\]$"
  1631  	*bp = (*bp)[1:2] // ERROR "quux ignoring self-assignment in \*bp = \(\*bp\)\[1:2\]$"
  1632  }
  1633  
  1634  type StructWithString struct {
  1635  	p *int
  1636  	s string
  1637  }
  1638  
  1639  // This is escape analysis false negative.
  1640  // We assign the pointer to x.p but leak x.s. Escape analysis coarsens flows
  1641  // to just x, and thus &i looks escaping.
  1642  func fieldFlowTracking() {
  1643  	var x StructWithString
  1644  	i := 0 // ERROR "moved to heap: i$"
  1645  	x.p = &i
  1646  	sink = x.s // ERROR "x.s escapes to heap$"
  1647  }
  1648  
  1649  // String operations.
  1650  
  1651  func slicebytetostring0() {
  1652  	b := make([]byte, 20) // ERROR "make\(\[\]byte, 20\) does not escape$"
  1653  	s := string(b)        // ERROR "string\(b\) does not escape$"
  1654  	_ = s
  1655  }
  1656  
  1657  func slicebytetostring1() {
  1658  	b := make([]byte, 20) // ERROR "make\(\[\]byte, 20\) does not escape$"
  1659  	s := string(b)        // ERROR "string\(b\) does not escape$"
  1660  	s1 := s[0:1]
  1661  	_ = s1
  1662  }
  1663  
  1664  func slicebytetostring2() {
  1665  	b := make([]byte, 20) // ERROR "make\(\[\]byte, 20\) does not escape$"
  1666  	s := string(b)        // ERROR "string\(b\) escapes to heap$"
  1667  	s1 := s[0:1]          // ERROR "moved to heap: s1$"
  1668  	sink = &s1
  1669  }
  1670  
  1671  func slicebytetostring3() {
  1672  	b := make([]byte, 20) // ERROR "make\(\[\]byte, 20\) does not escape$"
  1673  	s := string(b)        // ERROR "string\(b\) escapes to heap$"
  1674  	s1 := s[0:1]
  1675  	sink = s1 // ERROR "s1 escapes to heap$"
  1676  }
  1677  
  1678  func addstr0() {
  1679  	s0 := "a"
  1680  	s1 := "b"
  1681  	s := s0 + s1 // ERROR "s0 \+ s1 does not escape$"
  1682  	_ = s
  1683  }
  1684  
  1685  func addstr1() {
  1686  	s0 := "a"
  1687  	s1 := "b"
  1688  	s := "c"
  1689  	s += s0 + s1 // ERROR "s0 \+ s1 does not escape$"
  1690  	_ = s
  1691  }
  1692  
  1693  func addstr2() {
  1694  	b := make([]byte, 20) // ERROR "make\(\[\]byte, 20\) does not escape$"
  1695  	s0 := "a"
  1696  	s := string(b) + s0 // ERROR "string\(b\) \+ s0 does not escape$" "string\(b\) does not escape$"
  1697  	_ = s
  1698  }
  1699  
  1700  func addstr3() {
  1701  	s0 := "a"
  1702  	s1 := "b"
  1703  	s := s0 + s1 // ERROR "s0 \+ s1 escapes to heap$"
  1704  	s2 := s[0:1]
  1705  	sink = s2 // ERROR "s2 escapes to heap$"
  1706  }
  1707  
  1708  func intstring0() bool {
  1709  	// string does not escape
  1710  	x := '0'
  1711  	s := string(x) // ERROR "string\(x\) does not escape$"
  1712  	return s == "0"
  1713  }
  1714  
  1715  func intstring1() string {
  1716  	// string does not escape, but the buffer does
  1717  	x := '0'
  1718  	s := string(x) // ERROR "string\(x\) escapes to heap$"
  1719  	return s
  1720  }
  1721  
  1722  func intstring2() {
  1723  	// string escapes to heap
  1724  	x := '0'
  1725  	s := string(x) // ERROR "moved to heap: s$" "string\(x\) escapes to heap$"
  1726  	sink = &s
  1727  }
  1728  
  1729  func stringtoslicebyte0() {
  1730  	s := "foo"
  1731  	x := []byte(s) // ERROR "\(\[\]byte\)\(s\) does not escape$" "zero-copy string->\[\]byte conversion"
  1732  	_ = x
  1733  }
  1734  
  1735  func stringtoslicebyte1() []byte {
  1736  	s := "foo"
  1737  	return []byte(s) // ERROR "\(\[\]byte\)\(s\) escapes to heap$"
  1738  }
  1739  
  1740  func stringtoslicebyte2() {
  1741  	s := "foo"
  1742  	sink = []byte(s) // ERROR "\(\[\]byte\)\(s\) escapes to heap$"
  1743  }
  1744  
  1745  func stringtoslicerune0() {
  1746  	s := "foo"
  1747  	x := []rune(s) // ERROR "\(\[\]rune\)\(s\) does not escape$"
  1748  	_ = x
  1749  }
  1750  
  1751  func stringtoslicerune1() []rune {
  1752  	s := "foo"
  1753  	return []rune(s) // ERROR "\(\[\]rune\)\(s\) escapes to heap$"
  1754  }
  1755  
  1756  func stringtoslicerune2() {
  1757  	s := "foo"
  1758  	sink = []rune(s) // ERROR "\(\[\]rune\)\(s\) escapes to heap$"
  1759  }
  1760  
  1761  func slicerunetostring0() {
  1762  	r := []rune{1, 2, 3} // ERROR "\[\]rune{...} does not escape$"
  1763  	s := string(r)       // ERROR "string\(r\) does not escape$"
  1764  	_ = s
  1765  }
  1766  
  1767  func slicerunetostring1() string {
  1768  	r := []rune{1, 2, 3} // ERROR "\[\]rune{...} does not escape$"
  1769  	return string(r)     // ERROR "string\(r\) escapes to heap$"
  1770  }
  1771  
  1772  func slicerunetostring2() {
  1773  	r := []rune{1, 2, 3} // ERROR "\[\]rune{...} does not escape$"
  1774  	sink = string(r)     // ERROR "string\(r\) escapes to heap$"
  1775  }
  1776  
  1777  func makemap0() {
  1778  	m := make(map[int]int) // ERROR "make\(map\[int\]int\) does not escape$"
  1779  	m[0] = 0
  1780  	m[1]++
  1781  	delete(m, 1)
  1782  	sink = m[0] // ERROR "m\[0\] escapes to heap$"
  1783  }
  1784  
  1785  func makemap1() map[int]int {
  1786  	return make(map[int]int) // ERROR "make\(map\[int\]int\) escapes to heap$"
  1787  }
  1788  
  1789  func makemap2() {
  1790  	m := make(map[int]int) // ERROR "make\(map\[int\]int\) escapes to heap$"
  1791  	sink = m
  1792  }
  1793  
  1794  func nonescapingEface(m map[interface{}]bool) bool { // ERROR "m does not escape$"
  1795  	return m["foo"] // ERROR ".foo. does not escape$"
  1796  }
  1797  
  1798  func nonescapingIface(m map[M]bool) bool { // ERROR "m does not escape$"
  1799  	return m[MV(0)] // ERROR "MV\(0\) does not escape$"
  1800  }
  1801  
  1802  func issue10353() {
  1803  	x := new(int) // ERROR "new\(int\) escapes to heap$"
  1804  	issue10353a(x)()
  1805  }
  1806  
  1807  func issue10353a(x *int) func() { // ERROR "leaking param: x$"
  1808  	return func() { // ERROR "func literal escapes to heap$"
  1809  		println(*x)
  1810  	}
  1811  }
  1812  
  1813  func issue10353b() {
  1814  	var f func()
  1815  	for {
  1816  		x := new(int) // ERROR "new\(int\) escapes to heap$"
  1817  		f = func() {  // ERROR "func literal escapes to heap$"
  1818  			println(*x)
  1819  		}
  1820  	}
  1821  	_ = f
  1822  }
  1823  
  1824  func issue11387(x int) func() int {
  1825  	f := func() int { return x }    // ERROR "func literal escapes to heap"
  1826  	slice1 := []func() int{f}       // ERROR "\[\].* does not escape"
  1827  	slice2 := make([]func() int, 1) // ERROR "make\(.*\) does not escape"
  1828  	copy(slice2, slice1)
  1829  	return slice2[0]
  1830  }
  1831  
  1832  func issue12397(x, y int) { // ERROR "moved to heap: y$"
  1833  	// x does not escape below, because all relevant code is dead.
  1834  	if false {
  1835  		gxx = &x
  1836  	} else {
  1837  		gxx = &y
  1838  	}
  1839  
  1840  	if true {
  1841  		gxx = &y
  1842  	} else {
  1843  		gxx = &x
  1844  	}
  1845  }
  1846  

View as plain text