Black Lives Matter. Support the Equal Justice Initiative.

Source file test/escape2n.go

Documentation: test

     1  // errorcheck -0 -N -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  // Registerization is disabled too (-N), which should
    10  // have no effect on escape analysis.
    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 ~r2 level=0$" "leaking param: yy to result ~r2 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 ~r1 level=0$"
   347  	return *&x
   348  }
   349  
   350  func indaddr3(x *int32) *int { // ERROR "leaking param: x to result ~r1 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 ~r1 level=0$"
   378  	return (*uint64)(unsafe.Pointer(f))
   379  }
   380  
   381  func typesw(i interface{}) *int { // ERROR "leaking param: i to result ~r1 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 ~r1 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  
   403  // assigning to an array element is like assigning to the array
   404  func foo60(i *int) *int { // ERROR "leaking param: i to result ~r1 level=0$"
   405  	var a [12]*int
   406  	a[0] = i
   407  	return a[1]
   408  }
   409  
   410  func foo60a(i *int) *int { // ERROR "i does not escape$"
   411  	var a [12]*int
   412  	a[0] = i
   413  	return nil
   414  }
   415  
   416  // assigning to a struct field  is like assigning to the struct
   417  func foo61(i *int) *int { // ERROR "leaking param: i to result ~r1 level=0$"
   418  	type S struct {
   419  		a, b *int
   420  	}
   421  	var s S
   422  	s.a = i
   423  	return s.b
   424  }
   425  
   426  func foo61a(i *int) *int { // ERROR "i does not escape$"
   427  	type S struct {
   428  		a, b *int
   429  	}
   430  	var s S
   431  	s.a = i
   432  	return nil
   433  }
   434  
   435  // assigning to a struct field is like assigning to the struct but
   436  // here this subtlety is lost, since s.a counts as an assignment to a
   437  // track-losing dereference.
   438  func foo62(i *int) *int { // ERROR "leaking param: i$"
   439  	type S struct {
   440  		a, b *int
   441  	}
   442  	s := new(S) // ERROR "new\(S\) does not escape$"
   443  	s.a = i
   444  	return nil // s.b
   445  }
   446  
   447  type M interface {
   448  	M()
   449  }
   450  
   451  func foo63(m M) { // ERROR "m does not escape$"
   452  }
   453  
   454  func foo64(m M) { // ERROR "leaking param: m$"
   455  	m.M()
   456  }
   457  
   458  func foo64b(m M) { // ERROR "leaking param: m$"
   459  	defer m.M()
   460  }
   461  
   462  type MV int
   463  
   464  func (MV) M() {}
   465  
   466  func foo65() {
   467  	var mv MV
   468  	foo63(&mv)
   469  }
   470  
   471  func foo66() {
   472  	var mv MV // ERROR "moved to heap: mv$"
   473  	foo64(&mv)
   474  }
   475  
   476  func foo67() {
   477  	var mv MV
   478  	foo63(mv) // ERROR "mv does not escape$"
   479  }
   480  
   481  func foo68() {
   482  	var mv MV
   483  	// escapes but it's an int so irrelevant
   484  	foo64(mv) // ERROR "mv escapes to heap$"
   485  }
   486  
   487  func foo69(m M) { // ERROR "leaking param: m$"
   488  	foo64(m)
   489  }
   490  
   491  func foo70(mv1 *MV, m M) { // ERROR "leaking param: m$" "leaking param: mv1$"
   492  	m = mv1
   493  	foo64(m)
   494  }
   495  
   496  func foo71(x *int) []*int { // ERROR "leaking param: x$"
   497  	var y []*int
   498  	y = append(y, x)
   499  	return y
   500  }
   501  
   502  func foo71a(x int) []*int { // ERROR "moved to heap: x$"
   503  	var y []*int
   504  	y = append(y, &x)
   505  	return y
   506  }
   507  
   508  func foo72() {
   509  	var x int
   510  	var y [1]*int
   511  	y[0] = &x
   512  }
   513  
   514  func foo72aa() [10]*int {
   515  	var x int // ERROR "moved to heap: x$"
   516  	var y [10]*int
   517  	y[0] = &x
   518  	return y
   519  }
   520  
   521  func foo72a() {
   522  	var y [10]*int
   523  	for i := 0; i < 10; i++ {
   524  		// escapes its scope
   525  		x := i // ERROR "moved to heap: x$"
   526  		y[i] = &x
   527  	}
   528  	return
   529  }
   530  
   531  func foo72b() [10]*int {
   532  	var y [10]*int
   533  	for i := 0; i < 10; i++ {
   534  		x := i // ERROR "moved to heap: x$"
   535  		y[i] = &x
   536  	}
   537  	return y
   538  }
   539  
   540  // issue 2145
   541  func foo73() {
   542  	s := []int{3, 2, 1} // ERROR "\[\]int{...} does not escape$"
   543  	for _, v := range s {
   544  		vv := v
   545  		// actually just escapes its scope
   546  		defer func() { // ERROR "func literal escapes to heap$"
   547  			println(vv)
   548  		}()
   549  	}
   550  }
   551  
   552  func foo731() {
   553  	s := []int{3, 2, 1} // ERROR "\[\]int{...} does not escape$"
   554  	for _, v := range s {
   555  		vv := v // ERROR "moved to heap: vv$"
   556  		// actually just escapes its scope
   557  		defer func() { // ERROR "func literal escapes to heap$"
   558  			vv = 42
   559  			println(vv)
   560  		}()
   561  	}
   562  }
   563  
   564  func foo74() {
   565  	s := []int{3, 2, 1} // ERROR "\[\]int{...} does not escape$"
   566  	for _, v := range s {
   567  		vv := v
   568  		// actually just escapes its scope
   569  		fn := func() { // ERROR "func literal escapes to heap$"
   570  			println(vv)
   571  		}
   572  		defer fn()
   573  	}
   574  }
   575  
   576  func foo74a() {
   577  	s := []int{3, 2, 1} // ERROR "\[\]int{...} does not escape$"
   578  	for _, v := range s {
   579  		vv := v // ERROR "moved to heap: vv$"
   580  		// actually just escapes its scope
   581  		fn := func() { // ERROR "func literal escapes to heap$"
   582  			vv += 1
   583  			println(vv)
   584  		}
   585  		defer fn()
   586  	}
   587  }
   588  
   589  // issue 3975
   590  func foo74b() {
   591  	var array [3]func()
   592  	s := []int{3, 2, 1} // ERROR "\[\]int{...} does not escape$"
   593  	for i, v := range s {
   594  		vv := v
   595  		// actually just escapes its scope
   596  		array[i] = func() { // ERROR "func literal escapes to heap$"
   597  			println(vv)
   598  		}
   599  	}
   600  }
   601  
   602  func foo74c() {
   603  	var array [3]func()
   604  	s := []int{3, 2, 1} // ERROR "\[\]int{...} does not escape$"
   605  	for i, v := range s {
   606  		vv := v // ERROR "moved to heap: vv$"
   607  		// actually just escapes its scope
   608  		array[i] = func() { // ERROR "func literal escapes to heap$"
   609  			println(&vv)
   610  		}
   611  	}
   612  }
   613  
   614  func myprint(y *int, x ...interface{}) *int { // ERROR "leaking param: y to result ~r2 level=0$" "x does not escape$"
   615  	return y
   616  }
   617  
   618  func myprint1(y *int, x ...interface{}) *interface{} { // ERROR "leaking param: x to result ~r2 level=0$" "y does not escape$"
   619  	return &x[0]
   620  }
   621  
   622  func foo75(z *int) { // ERROR "z does not escape$"
   623  	myprint(z, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "... argument does not escape$"
   624  }
   625  
   626  func foo75a(z *int) { // ERROR "z does not escape$"
   627  	myprint1(z, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "... argument does not escape$"
   628  }
   629  
   630  func foo75esc(z *int) { // ERROR "leaking param: z$"
   631  	gxx = myprint(z, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "... argument does not escape$"
   632  }
   633  
   634  func foo75aesc(z *int) { // ERROR "z does not escape$"
   635  	var ppi **interface{}       // assignments to pointer dereferences lose track
   636  	*ppi = myprint1(z, 1, 2, 3) // ERROR "... argument escapes to heap$" "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$"
   637  }
   638  
   639  func foo75aesc1(z *int) { // ERROR "z does not escape$"
   640  	sink = myprint1(z, 1, 2, 3) // ERROR "... argument escapes to heap$" "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$"
   641  }
   642  
   643  func foo76(z *int) { // ERROR "z does not escape"
   644  	myprint(nil, z) // ERROR "... argument does not escape$"
   645  }
   646  
   647  func foo76a(z *int) { // ERROR "z does not escape"
   648  	myprint1(nil, z) // ERROR "... argument does not escape$"
   649  }
   650  
   651  func foo76b() {
   652  	myprint(nil, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "... argument does not escape$"
   653  }
   654  
   655  func foo76c() {
   656  	myprint1(nil, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "... argument does not escape$"
   657  }
   658  
   659  func foo76d() {
   660  	defer myprint(nil, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "... argument does not escape$"
   661  }
   662  
   663  func foo76e() {
   664  	defer myprint1(nil, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "... argument does not escape$"
   665  }
   666  
   667  func foo76f() {
   668  	for {
   669  		// TODO: This one really only escapes its scope, but we don't distinguish yet.
   670  		defer myprint(nil, 1, 2, 3) // ERROR "... argument escapes to heap$" "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$"
   671  	}
   672  }
   673  
   674  func foo76g() {
   675  	for {
   676  		defer myprint1(nil, 1, 2, 3) // ERROR "... argument escapes to heap$" "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$"
   677  	}
   678  }
   679  
   680  func foo77(z []interface{}) { // ERROR "z does not escape$"
   681  	myprint(nil, z...) // z does not escape
   682  }
   683  
   684  func foo77a(z []interface{}) { // ERROR "z does not escape$"
   685  	myprint1(nil, z...)
   686  }
   687  
   688  func foo77b(z []interface{}) { // ERROR "leaking param: z$"
   689  	var ppi **interface{}
   690  	*ppi = myprint1(nil, z...)
   691  }
   692  
   693  func foo77c(z []interface{}) { // ERROR "leaking param: z$"
   694  	sink = myprint1(nil, z...)
   695  }
   696  
   697  func dotdotdot() {
   698  	i := 0
   699  	myprint(nil, &i) // ERROR "... argument does not escape$"
   700  
   701  	j := 0
   702  	myprint1(nil, &j) // ERROR "... argument does not escape$"
   703  }
   704  
   705  func foo78(z int) *int { // ERROR "moved to heap: z$"
   706  	return &z
   707  }
   708  
   709  func foo78a(z int) *int { // ERROR "moved to heap: z$"
   710  	y := &z
   711  	x := &y
   712  	return *x // really return y
   713  }
   714  
   715  func foo79() *int {
   716  	return new(int) // ERROR "new\(int\) escapes to heap$"
   717  }
   718  
   719  func foo80() *int {
   720  	var z *int
   721  	for {
   722  		// Really just escapes its scope but we don't distinguish
   723  		z = new(int) // ERROR "new\(int\) escapes to heap$"
   724  	}
   725  	_ = z
   726  	return nil
   727  }
   728  
   729  func foo81() *int {
   730  	for {
   731  		z := new(int) // ERROR "new\(int\) does not escape$"
   732  		_ = z
   733  	}
   734  	return nil
   735  }
   736  
   737  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$"
   738  
   739  func noop(x, y *int) {} // ERROR "x does not escape$" "y does not escape$"
   740  
   741  func foo82() {
   742  	var x, y, z int // ERROR "moved to heap: x$" "moved to heap: y$" "moved to heap: z$"
   743  	go noop(tee(&z))
   744  	go noop(&x, &y)
   745  	for {
   746  		var u, v, w int // ERROR "moved to heap: u$" "moved to heap: v$" "moved to heap: w$"
   747  		defer noop(tee(&u))
   748  		defer noop(&v, &w)
   749  	}
   750  }
   751  
   752  type Fooer interface {
   753  	Foo()
   754  }
   755  
   756  type LimitedFooer struct {
   757  	Fooer
   758  	N int64
   759  }
   760  
   761  func LimitFooer(r Fooer, n int64) Fooer { // ERROR "leaking param: r$"
   762  	return &LimitedFooer{r, n} // ERROR "&LimitedFooer{...} escapes to heap$"
   763  }
   764  
   765  func foo90(x *int) map[*int]*int { // ERROR "leaking param: x$"
   766  	return map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int{...} escapes to heap$"
   767  }
   768  
   769  func foo91(x *int) map[*int]*int { // ERROR "leaking param: x$"
   770  	return map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int{...} escapes to heap$"
   771  }
   772  
   773  func foo92(x *int) [2]*int { // ERROR "leaking param: x to result ~r1 level=0$"
   774  	return [2]*int{x, nil}
   775  }
   776  
   777  // does not leak c
   778  func foo93(c chan *int) *int { // ERROR "c does not escape$"
   779  	for v := range c {
   780  		return v
   781  	}
   782  	return nil
   783  }
   784  
   785  // does not leak m
   786  func foo94(m map[*int]*int, b bool) *int { // ERROR "leaking param: m to result ~r2 level=1"
   787  	for k, v := range m {
   788  		if b {
   789  			return k
   790  		}
   791  		return v
   792  	}
   793  	return nil
   794  }
   795  
   796  // does leak x
   797  func foo95(m map[*int]*int, x *int) { // ERROR "m does not escape$" "leaking param: x$"
   798  	m[x] = x
   799  }
   800  
   801  // does not leak m but does leak content
   802  func foo96(m []*int) *int { // ERROR "leaking param: m to result ~r1 level=1"
   803  	return m[0]
   804  }
   805  
   806  // does leak m
   807  func foo97(m [1]*int) *int { // ERROR "leaking param: m to result ~r1 level=0$"
   808  	return m[0]
   809  }
   810  
   811  // does not leak m
   812  func foo98(m map[int]*int) *int { // ERROR "m does not escape$"
   813  	return m[0]
   814  }
   815  
   816  // does leak m
   817  func foo99(m *[1]*int) []*int { // ERROR "leaking param: m to result ~r1 level=0$"
   818  	return m[:]
   819  }
   820  
   821  // does not leak m
   822  func foo100(m []*int) *int { // ERROR "leaking param: m to result ~r1 level=1"
   823  	for _, v := range m {
   824  		return v
   825  	}
   826  	return nil
   827  }
   828  
   829  // does leak m
   830  func foo101(m [1]*int) *int { // ERROR "leaking param: m to result ~r1 level=0$"
   831  	for _, v := range m {
   832  		return v
   833  	}
   834  	return nil
   835  }
   836  
   837  // does not leak m
   838  func foo101a(m [1]*int) *int { // ERROR "m does not escape$"
   839  	for i := range m { // ERROR "moved to heap: i$"
   840  		return &i
   841  	}
   842  	return nil
   843  }
   844  
   845  // does leak x
   846  func foo102(m []*int, x *int) { // ERROR "m does not escape$" "leaking param: x$"
   847  	m[0] = x
   848  }
   849  
   850  // does not leak x
   851  func foo103(m [1]*int, x *int) { // ERROR "m does not escape$" "x does not escape$"
   852  	m[0] = x
   853  }
   854  
   855  var y []*int
   856  
   857  // does not leak x but does leak content
   858  func foo104(x []*int) { // ERROR "leaking param content: x"
   859  	copy(y, x)
   860  }
   861  
   862  // does not leak x but does leak content
   863  func foo105(x []*int) { // ERROR "leaking param content: x"
   864  	_ = append(y, x...)
   865  }
   866  
   867  // does leak x
   868  func foo106(x *int) { // ERROR "leaking param: x$"
   869  	_ = append(y, x)
   870  }
   871  
   872  func foo107(x *int) map[*int]*int { // ERROR "leaking param: x$"
   873  	return map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int{...} escapes to heap$"
   874  }
   875  
   876  func foo108(x *int) map[*int]*int { // ERROR "leaking param: x$"
   877  	return map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int{...} escapes to heap$"
   878  }
   879  
   880  func foo109(x *int) *int { // ERROR "leaking param: x$"
   881  	m := map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int{...} does not escape$"
   882  	for k, _ := range m {
   883  		return k
   884  	}
   885  	return nil
   886  }
   887  
   888  func foo110(x *int) *int { // ERROR "leaking param: x$"
   889  	m := map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int{...} does not escape$"
   890  	return m[nil]
   891  }
   892  
   893  func foo111(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0"
   894  	m := []*int{x} // ERROR "\[\]\*int{...} does not escape$"
   895  	return m[0]
   896  }
   897  
   898  func foo112(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
   899  	m := [1]*int{x}
   900  	return m[0]
   901  }
   902  
   903  func foo113(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
   904  	m := Bar{ii: x}
   905  	return m.ii
   906  }
   907  
   908  func foo114(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
   909  	m := &Bar{ii: x} // ERROR "&Bar{...} does not escape$"
   910  	return m.ii
   911  }
   912  
   913  func foo115(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
   914  	return (*int)(unsafe.Pointer(uintptr(unsafe.Pointer(x)) + 1))
   915  }
   916  
   917  func foo116(b bool) *int {
   918  	if b {
   919  		x := 1 // ERROR "moved to heap: x$"
   920  		return &x
   921  	} else {
   922  		y := 1 // ERROR "moved to heap: y$"
   923  		return &y
   924  	}
   925  	return nil
   926  }
   927  
   928  func foo117(unknown func(interface{})) { // ERROR "unknown does not escape$"
   929  	x := 1 // ERROR "moved to heap: x$"
   930  	unknown(&x)
   931  }
   932  
   933  func foo118(unknown func(*int)) { // ERROR "unknown does not escape$"
   934  	x := 1 // ERROR "moved to heap: x$"
   935  	unknown(&x)
   936  }
   937  
   938  func external(*int)
   939  
   940  func foo119(x *int) { // ERROR "leaking param: x$"
   941  	external(x)
   942  }
   943  
   944  func foo120() {
   945  	// formerly exponential time analysis
   946  L1:
   947  L2:
   948  L3:
   949  L4:
   950  L5:
   951  L6:
   952  L7:
   953  L8:
   954  L9:
   955  L10:
   956  L11:
   957  L12:
   958  L13:
   959  L14:
   960  L15:
   961  L16:
   962  L17:
   963  L18:
   964  L19:
   965  L20:
   966  L21:
   967  L22:
   968  L23:
   969  L24:
   970  L25:
   971  L26:
   972  L27:
   973  L28:
   974  L29:
   975  L30:
   976  L31:
   977  L32:
   978  L33:
   979  L34:
   980  L35:
   981  L36:
   982  L37:
   983  L38:
   984  L39:
   985  L40:
   986  L41:
   987  L42:
   988  L43:
   989  L44:
   990  L45:
   991  L46:
   992  L47:
   993  L48:
   994  L49:
   995  L50:
   996  L51:
   997  L52:
   998  L53:
   999  L54:
  1000  L55:
  1001  L56:
  1002  L57:
  1003  L58:
  1004  L59:
  1005  L60:
  1006  L61:
  1007  L62:
  1008  L63:
  1009  L64:
  1010  L65:
  1011  L66:
  1012  L67:
  1013  L68:
  1014  L69:
  1015  L70:
  1016  L71:
  1017  L72:
  1018  L73:
  1019  L74:
  1020  L75:
  1021  L76:
  1022  L77:
  1023  L78:
  1024  L79:
  1025  L80:
  1026  L81:
  1027  L82:
  1028  L83:
  1029  L84:
  1030  L85:
  1031  L86:
  1032  L87:
  1033  L88:
  1034  L89:
  1035  L90:
  1036  L91:
  1037  L92:
  1038  L93:
  1039  L94:
  1040  L95:
  1041  L96:
  1042  L97:
  1043  L98:
  1044  L99:
  1045  L100:
  1046  	// use the labels to silence compiler errors
  1047  	goto L1
  1048  	goto L2
  1049  	goto L3
  1050  	goto L4
  1051  	goto L5
  1052  	goto L6
  1053  	goto L7
  1054  	goto L8
  1055  	goto L9
  1056  	goto L10
  1057  	goto L11
  1058  	goto L12
  1059  	goto L13
  1060  	goto L14
  1061  	goto L15
  1062  	goto L16
  1063  	goto L17
  1064  	goto L18
  1065  	goto L19
  1066  	goto L20
  1067  	goto L21
  1068  	goto L22
  1069  	goto L23
  1070  	goto L24
  1071  	goto L25
  1072  	goto L26
  1073  	goto L27
  1074  	goto L28
  1075  	goto L29
  1076  	goto L30
  1077  	goto L31
  1078  	goto L32
  1079  	goto L33
  1080  	goto L34
  1081  	goto L35
  1082  	goto L36
  1083  	goto L37
  1084  	goto L38
  1085  	goto L39
  1086  	goto L40
  1087  	goto L41
  1088  	goto L42
  1089  	goto L43
  1090  	goto L44
  1091  	goto L45
  1092  	goto L46
  1093  	goto L47
  1094  	goto L48
  1095  	goto L49
  1096  	goto L50
  1097  	goto L51
  1098  	goto L52
  1099  	goto L53
  1100  	goto L54
  1101  	goto L55
  1102  	goto L56
  1103  	goto L57
  1104  	goto L58
  1105  	goto L59
  1106  	goto L60
  1107  	goto L61
  1108  	goto L62
  1109  	goto L63
  1110  	goto L64
  1111  	goto L65
  1112  	goto L66
  1113  	goto L67
  1114  	goto L68
  1115  	goto L69
  1116  	goto L70
  1117  	goto L71
  1118  	goto L72
  1119  	goto L73
  1120  	goto L74
  1121  	goto L75
  1122  	goto L76
  1123  	goto L77
  1124  	goto L78
  1125  	goto L79
  1126  	goto L80
  1127  	goto L81
  1128  	goto L82
  1129  	goto L83
  1130  	goto L84
  1131  	goto L85
  1132  	goto L86
  1133  	goto L87
  1134  	goto L88
  1135  	goto L89
  1136  	goto L90
  1137  	goto L91
  1138  	goto L92
  1139  	goto L93
  1140  	goto L94
  1141  	goto L95
  1142  	goto L96
  1143  	goto L97
  1144  	goto L98
  1145  	goto L99
  1146  	goto L100
  1147  }
  1148  
  1149  func foo121() {
  1150  	for i := 0; i < 10; i++ {
  1151  		defer myprint(nil, i) // ERROR "... argument escapes to heap$" "i escapes to heap$"
  1152  		go myprint(nil, i)    // ERROR "... argument escapes to heap$" "i escapes to heap$"
  1153  	}
  1154  }
  1155  
  1156  // same as foo121 but check across import
  1157  func foo121b() {
  1158  	for i := 0; i < 10; i++ {
  1159  		defer fmt.Printf("%d", i) // ERROR "... argument escapes to heap$" "i escapes to heap$"
  1160  		go fmt.Printf("%d", i)    // ERROR "... argument escapes to heap$" "i escapes to heap$"
  1161  	}
  1162  }
  1163  
  1164  // a harmless forward jump
  1165  func foo122() {
  1166  	var i *int
  1167  
  1168  	goto L1
  1169  L1:
  1170  	i = new(int) // ERROR "new\(int\) does not escape$"
  1171  	_ = i
  1172  }
  1173  
  1174  // a backward jump, increases loopdepth
  1175  func foo123() {
  1176  	var i *int
  1177  
  1178  L1:
  1179  	i = new(int) // ERROR "new\(int\) escapes to heap$"
  1180  
  1181  	goto L1
  1182  	_ = i
  1183  }
  1184  
  1185  func foo124(x **int) { // ERROR "x does not escape$"
  1186  	var i int // ERROR "moved to heap: i$"
  1187  	p := &i
  1188  	func() { // ERROR "func literal does not escape$"
  1189  		*x = p
  1190  	}()
  1191  }
  1192  
  1193  func foo125(ch chan *int) { // ERROR "ch does not escape$"
  1194  	var i int // ERROR "moved to heap: i$"
  1195  	p := &i
  1196  	func() { // ERROR "func literal does not escape$"
  1197  		ch <- p
  1198  	}()
  1199  }
  1200  
  1201  func foo126() {
  1202  	var px *int // loopdepth 0
  1203  	for {
  1204  		// loopdepth 1
  1205  		var i int // ERROR "moved to heap: i$"
  1206  		func() {  // ERROR "func literal does not escape$"
  1207  			px = &i
  1208  		}()
  1209  	}
  1210  	_ = px
  1211  }
  1212  
  1213  var px *int
  1214  
  1215  func foo127() {
  1216  	var i int // ERROR "moved to heap: i$"
  1217  	p := &i
  1218  	q := p
  1219  	px = q
  1220  }
  1221  
  1222  func foo128() {
  1223  	var i int
  1224  	p := &i
  1225  	q := p
  1226  	_ = q
  1227  }
  1228  
  1229  func foo129() {
  1230  	var i int // ERROR "moved to heap: i$"
  1231  	p := &i
  1232  	func() { // ERROR "func literal does not escape$"
  1233  		q := p
  1234  		func() { // ERROR "func literal does not escape$"
  1235  			r := q
  1236  			px = r
  1237  		}()
  1238  	}()
  1239  }
  1240  
  1241  func foo130() {
  1242  	for {
  1243  		var i int // ERROR "moved to heap: i$"
  1244  		func() {  // ERROR "func literal does not escape$"
  1245  			px = &i
  1246  		}()
  1247  	}
  1248  }
  1249  
  1250  func foo131() {
  1251  	var i int // ERROR "moved to heap: i$"
  1252  	func() {  // ERROR "func literal does not escape$"
  1253  		px = &i
  1254  	}()
  1255  }
  1256  
  1257  func foo132() {
  1258  	var i int   // ERROR "moved to heap: i$"
  1259  	go func() { // ERROR "func literal escapes to heap$"
  1260  		px = &i
  1261  	}()
  1262  }
  1263  
  1264  func foo133() {
  1265  	var i int      // ERROR "moved to heap: i$"
  1266  	defer func() { // ERROR "func literal does not escape$"
  1267  		px = &i
  1268  	}()
  1269  }
  1270  
  1271  func foo134() {
  1272  	var i int
  1273  	p := &i
  1274  	func() { // ERROR "func literal does not escape$"
  1275  		q := p
  1276  		func() { // ERROR "func literal does not escape$"
  1277  			r := q
  1278  			_ = r
  1279  		}()
  1280  	}()
  1281  }
  1282  
  1283  func foo135() {
  1284  	var i int // ERROR "moved to heap: i$"
  1285  	p := &i
  1286  	go func() { // ERROR "func literal escapes to heap$"
  1287  		q := p
  1288  		func() { // ERROR "func literal does not escape$"
  1289  			r := q
  1290  			_ = r
  1291  		}()
  1292  	}()
  1293  }
  1294  
  1295  func foo136() {
  1296  	var i int // ERROR "moved to heap: i$"
  1297  	p := &i
  1298  	go func() { // ERROR "func literal escapes to heap$"
  1299  		q := p
  1300  		func() { // ERROR "func literal does not escape$"
  1301  			r := q
  1302  			px = r
  1303  		}()
  1304  	}()
  1305  }
  1306  
  1307  func foo137() {
  1308  	var i int // ERROR "moved to heap: i$"
  1309  	p := &i
  1310  	func() { // ERROR "func literal does not escape$"
  1311  		q := p
  1312  		go func() { // ERROR "func literal escapes to heap$"
  1313  			r := q
  1314  			_ = r
  1315  		}()
  1316  	}()
  1317  }
  1318  
  1319  func foo138() *byte {
  1320  	type T struct {
  1321  		x [1]byte
  1322  	}
  1323  	t := new(T) // ERROR "new\(T\) escapes to heap$"
  1324  	return &t.x[0]
  1325  }
  1326  
  1327  func foo139() *byte {
  1328  	type T struct {
  1329  		x struct {
  1330  			y byte
  1331  		}
  1332  	}
  1333  	t := new(T) // ERROR "new\(T\) escapes to heap$"
  1334  	return &t.x.y
  1335  }
  1336  
  1337  // issue 4751
  1338  func foo140() interface{} {
  1339  	type T struct {
  1340  		X string
  1341  	}
  1342  	type U struct {
  1343  		X string
  1344  		T *T
  1345  	}
  1346  	t := &T{} // ERROR "&T{} escapes to heap$"
  1347  	return U{ // ERROR "U{...} escapes to heap$"
  1348  		X: t.X,
  1349  		T: t,
  1350  	}
  1351  }
  1352  
  1353  //go:noescape
  1354  
  1355  func F1([]byte)
  1356  
  1357  func F2([]byte)
  1358  
  1359  //go:noescape
  1360  
  1361  func F3(x []byte) // ERROR "x does not escape$"
  1362  
  1363  func F4(x []byte) // ERROR "leaking param: x$"
  1364  
  1365  func G() {
  1366  	var buf1 [10]byte
  1367  	F1(buf1[:])
  1368  
  1369  	var buf2 [10]byte // ERROR "moved to heap: buf2$"
  1370  	F2(buf2[:])
  1371  
  1372  	var buf3 [10]byte
  1373  	F3(buf3[:])
  1374  
  1375  	var buf4 [10]byte // ERROR "moved to heap: buf4$"
  1376  	F4(buf4[:])
  1377  }
  1378  
  1379  type Tm struct {
  1380  	x int
  1381  }
  1382  
  1383  func (t *Tm) M() { // ERROR "t does not escape$"
  1384  }
  1385  
  1386  func foo141() {
  1387  	var f func()
  1388  
  1389  	t := new(Tm) // ERROR "new\(Tm\) does not escape$"
  1390  	f = t.M      // ERROR "t.M does not escape$"
  1391  	_ = f
  1392  }
  1393  
  1394  var gf func()
  1395  
  1396  func foo142() {
  1397  	t := new(Tm) // ERROR "new\(Tm\) escapes to heap$"
  1398  	gf = t.M     // ERROR "t.M escapes to heap$"
  1399  }
  1400  
  1401  // issue 3888.
  1402  func foo143() {
  1403  	for i := 0; i < 1000; i++ {
  1404  		func() { // ERROR "func literal does not escape$"
  1405  			for i := 0; i < 1; i++ {
  1406  				var t Tm
  1407  				t.M()
  1408  			}
  1409  		}()
  1410  	}
  1411  }
  1412  
  1413  // issue 5773
  1414  // Check that annotations take effect regardless of whether they
  1415  // are before or after the use in the source code.
  1416  
  1417  //go:noescape
  1418  
  1419  func foo144a(*int)
  1420  
  1421  func foo144() {
  1422  	var x int
  1423  	foo144a(&x)
  1424  	var y int
  1425  	foo144b(&y)
  1426  }
  1427  
  1428  //go:noescape
  1429  
  1430  func foo144b(*int)
  1431  
  1432  // issue 7313: for loop init should not be treated as "in loop"
  1433  
  1434  type List struct {
  1435  	Next *List
  1436  }
  1437  
  1438  func foo145(l List) { // ERROR "l does not escape$"
  1439  	var p *List
  1440  	for p = &l; p.Next != nil; p = p.Next {
  1441  	}
  1442  }
  1443  
  1444  func foo146(l List) { // ERROR "l does not escape$"
  1445  	var p *List
  1446  	p = &l
  1447  	for ; p.Next != nil; p = p.Next {
  1448  	}
  1449  }
  1450  
  1451  func foo147(l List) { // ERROR "l does not escape$"
  1452  	var p *List
  1453  	p = &l
  1454  	for p.Next != nil {
  1455  		p = p.Next
  1456  	}
  1457  }
  1458  
  1459  func foo148(l List) { // ERROR "l does not escape$"
  1460  	for p := &l; p.Next != nil; p = p.Next {
  1461  	}
  1462  }
  1463  
  1464  // related: address of variable should have depth of variable, not of loop
  1465  
  1466  func foo149(l List) { // ERROR "l does not escape$"
  1467  	var p *List
  1468  	for {
  1469  		for p = &l; p.Next != nil; p = p.Next {
  1470  		}
  1471  	}
  1472  }
  1473  
  1474  // issue 7934: missed ... if element type had no pointers
  1475  
  1476  var save150 []byte
  1477  
  1478  func foo150(x ...byte) { // ERROR "leaking param: x$"
  1479  	save150 = x
  1480  }
  1481  
  1482  func bar150() {
  1483  	foo150(1, 2, 3) // ERROR "... argument escapes to heap$"
  1484  }
  1485  
  1486  // issue 7931: bad handling of slice of array
  1487  
  1488  var save151 *int
  1489  
  1490  func foo151(x *int) { // ERROR "leaking param: x$"
  1491  	save151 = x
  1492  }
  1493  
  1494  func bar151() {
  1495  	var a [64]int // ERROR "moved to heap: a$"
  1496  	a[4] = 101
  1497  	foo151(&(&a)[4:8][0])
  1498  }
  1499  
  1500  func bar151b() {
  1501  	var a [10]int // ERROR "moved to heap: a$"
  1502  	b := a[:]
  1503  	foo151(&b[4:8][0])
  1504  }
  1505  
  1506  func bar151c() {
  1507  	var a [64]int // ERROR "moved to heap: a$"
  1508  	a[4] = 101
  1509  	foo151(&(&a)[4:8:8][0])
  1510  }
  1511  
  1512  func bar151d() {
  1513  	var a [10]int // ERROR "moved to heap: a$"
  1514  	b := a[:]
  1515  	foo151(&b[4:8:8][0])
  1516  }
  1517  
  1518  // issue 8120
  1519  
  1520  type U struct {
  1521  	s *string
  1522  }
  1523  
  1524  func (u *U) String() *string { // ERROR "leaking param: u to result ~r0 level=1$"
  1525  	return u.s
  1526  }
  1527  
  1528  type V struct {
  1529  	s *string
  1530  }
  1531  
  1532  func NewV(u U) *V { // ERROR "leaking param: u$"
  1533  	return &V{u.String()} // ERROR "&V{...} escapes to heap$"
  1534  }
  1535  
  1536  func foo152() {
  1537  	a := "a" // ERROR "moved to heap: a$"
  1538  	u := U{&a}
  1539  	v := NewV(u)
  1540  	println(v)
  1541  }
  1542  
  1543  // issue 8176 - &x in type switch body not marked as escaping
  1544  
  1545  func foo153(v interface{}) *int { // ERROR "v does not escape"
  1546  	switch x := v.(type) {
  1547  	case int: // ERROR "moved to heap: x$"
  1548  		return &x
  1549  	}
  1550  	panic(0) // ERROR "0 escapes to heap"
  1551  }
  1552  
  1553  // issue 8185 - &result escaping into result
  1554  
  1555  func f() (x int, y *int) { // ERROR "moved to heap: x$"
  1556  	y = &x
  1557  	return
  1558  }
  1559  
  1560  func g() (x interface{}) { // ERROR "moved to heap: x$"
  1561  	x = &x
  1562  	return
  1563  }
  1564  
  1565  var sink interface{}
  1566  
  1567  type Lit struct {
  1568  	p *int
  1569  }
  1570  
  1571  func ptrlitNoescape() {
  1572  	// Both literal and element do not escape.
  1573  	i := 0
  1574  	x := &Lit{&i} // ERROR "&Lit{...} does not escape$"
  1575  	_ = x
  1576  }
  1577  
  1578  func ptrlitNoEscape2() {
  1579  	// Literal does not escape, but element does.
  1580  	i := 0        // ERROR "moved to heap: i$"
  1581  	x := &Lit{&i} // ERROR "&Lit{...} does not escape$"
  1582  	sink = *x
  1583  }
  1584  
  1585  func ptrlitEscape() {
  1586  	// Both literal and element escape.
  1587  	i := 0        // ERROR "moved to heap: i$"
  1588  	x := &Lit{&i} // ERROR "&Lit{...} escapes to heap$"
  1589  	sink = x
  1590  }
  1591  
  1592  // self-assignments
  1593  
  1594  type Buffer struct {
  1595  	arr    [64]byte
  1596  	arrPtr *[64]byte
  1597  	buf1   []byte
  1598  	buf2   []byte
  1599  	str1   string
  1600  	str2   string
  1601  }
  1602  
  1603  func (b *Buffer) foo() { // ERROR "b does not escape$"
  1604  	b.buf1 = b.buf1[1:2]   // ERROR "\(\*Buffer\).foo ignoring self-assignment in b.buf1 = b.buf1\[1:2\]$"
  1605  	b.buf1 = b.buf1[1:2:3] // ERROR "\(\*Buffer\).foo ignoring self-assignment in b.buf1 = b.buf1\[1:2:3\]$"
  1606  	b.buf1 = b.buf2[1:2]   // ERROR "\(\*Buffer\).foo ignoring self-assignment in b.buf1 = b.buf2\[1:2\]$"
  1607  	b.buf1 = b.buf2[1:2:3] // ERROR "\(\*Buffer\).foo ignoring self-assignment in b.buf1 = b.buf2\[1:2:3\]$"
  1608  }
  1609  
  1610  func (b *Buffer) bar() { // ERROR "leaking param: b$"
  1611  	b.buf1 = b.arr[1:2]
  1612  }
  1613  
  1614  func (b *Buffer) arrayPtr() { // ERROR "b does not escape"
  1615  	b.buf1 = b.arrPtr[1:2]   // ERROR "\(\*Buffer\).arrayPtr ignoring self-assignment in b.buf1 = b.arrPtr\[1:2\]$"
  1616  	b.buf1 = b.arrPtr[1:2:3] // ERROR "\(\*Buffer\).arrayPtr ignoring self-assignment in b.buf1 = b.arrPtr\[1:2:3\]$"
  1617  }
  1618  
  1619  func (b *Buffer) baz() { // ERROR "b does not escape$"
  1620  	b.str1 = b.str1[1:2] // ERROR "\(\*Buffer\).baz ignoring self-assignment in b.str1 = b.str1\[1:2\]$"
  1621  	b.str1 = b.str2[1:2] // ERROR "\(\*Buffer\).baz ignoring self-assignment in b.str1 = b.str2\[1:2\]$"
  1622  }
  1623  
  1624  func (b *Buffer) bat() { // ERROR "leaking param content: b$"
  1625  	o := new(Buffer) // ERROR "new\(Buffer\) escapes to heap$"
  1626  	o.buf1 = b.buf1[1:2]
  1627  	sink = o
  1628  }
  1629  
  1630  func quux(sp *string, bp *[]byte) { // ERROR "bp does not escape$" "sp does not escape$"
  1631  	*sp = (*sp)[1:2] // ERROR "quux ignoring self-assignment in \*sp = \(\*sp\)\[1:2\]$"
  1632  	*bp = (*bp)[1:2] // ERROR "quux ignoring self-assignment in \*bp = \(\*bp\)\[1:2\]$"
  1633  }
  1634  
  1635  type StructWithString struct {
  1636  	p *int
  1637  	s string
  1638  }
  1639  
  1640  // This is escape analysis false negative.
  1641  // We assign the pointer to x.p but leak x.s. Escape analysis coarsens flows
  1642  // to just x, and thus &i looks escaping.
  1643  func fieldFlowTracking() {
  1644  	var x StructWithString
  1645  	i := 0 // ERROR "moved to heap: i$"
  1646  	x.p = &i
  1647  	sink = x.s // ERROR "x.s escapes to heap$"
  1648  }
  1649  
  1650  // String operations.
  1651  
  1652  func slicebytetostring0() {
  1653  	b := make([]byte, 20) // ERROR "make\(\[\]byte, 20\) does not escape$"
  1654  	s := string(b)        // ERROR "string\(b\) does not escape$"
  1655  	_ = s
  1656  }
  1657  
  1658  func slicebytetostring1() {
  1659  	b := make([]byte, 20) // ERROR "make\(\[\]byte, 20\) does not escape$"
  1660  	s := string(b)        // ERROR "string\(b\) does not escape$"
  1661  	s1 := s[0:1]
  1662  	_ = s1
  1663  }
  1664  
  1665  func slicebytetostring2() {
  1666  	b := make([]byte, 20) // ERROR "make\(\[\]byte, 20\) does not escape$"
  1667  	s := string(b)        // ERROR "string\(b\) escapes to heap$"
  1668  	s1 := s[0:1]          // ERROR "moved to heap: s1$"
  1669  	sink = &s1
  1670  }
  1671  
  1672  func slicebytetostring3() {
  1673  	b := make([]byte, 20) // ERROR "make\(\[\]byte, 20\) does not escape$"
  1674  	s := string(b)        // ERROR "string\(b\) escapes to heap$"
  1675  	s1 := s[0:1]
  1676  	sink = s1 // ERROR "s1 escapes to heap$"
  1677  }
  1678  
  1679  func addstr0() {
  1680  	s0 := "a"
  1681  	s1 := "b"
  1682  	s := s0 + s1 // ERROR "s0 \+ s1 does not escape$"
  1683  	_ = s
  1684  }
  1685  
  1686  func addstr1() {
  1687  	s0 := "a"
  1688  	s1 := "b"
  1689  	s := "c"
  1690  	s += s0 + s1 // ERROR "s0 \+ s1 does not escape$"
  1691  	_ = s
  1692  }
  1693  
  1694  func addstr2() {
  1695  	b := make([]byte, 20) // ERROR "make\(\[\]byte, 20\) does not escape$"
  1696  	s0 := "a"
  1697  	s := string(b) + s0 // ERROR "string\(b\) \+ s0 does not escape$" "string\(b\) does not escape$"
  1698  	_ = s
  1699  }
  1700  
  1701  func addstr3() {
  1702  	s0 := "a"
  1703  	s1 := "b"
  1704  	s := s0 + s1 // ERROR "s0 \+ s1 escapes to heap$"
  1705  	s2 := s[0:1]
  1706  	sink = s2 // ERROR "s2 escapes to heap$"
  1707  }
  1708  
  1709  func intstring0() bool {
  1710  	// string does not escape
  1711  	x := '0'
  1712  	s := string(x) // ERROR "string\(x\) does not escape$"
  1713  	return s == "0"
  1714  }
  1715  
  1716  func intstring1() string {
  1717  	// string does not escape, but the buffer does
  1718  	x := '0'
  1719  	s := string(x) // ERROR "string\(x\) escapes to heap$"
  1720  	return s
  1721  }
  1722  
  1723  func intstring2() {
  1724  	// string escapes to heap
  1725  	x := '0'
  1726  	s := string(x) // ERROR "moved to heap: s$" "string\(x\) escapes to heap$"
  1727  	sink = &s
  1728  }
  1729  
  1730  func stringtoslicebyte0() {
  1731  	s := "foo"
  1732  	x := []byte(s) // ERROR "\(\[\]byte\)\(s\) does not escape$"
  1733  	_ = x
  1734  }
  1735  
  1736  func stringtoslicebyte1() []byte {
  1737  	s := "foo"
  1738  	return []byte(s) // ERROR "\(\[\]byte\)\(s\) escapes to heap$"
  1739  }
  1740  
  1741  func stringtoslicebyte2() {
  1742  	s := "foo"
  1743  	sink = []byte(s) // ERROR "\(\[\]byte\)\(s\) escapes to heap$"
  1744  }
  1745  
  1746  func stringtoslicerune0() {
  1747  	s := "foo"
  1748  	x := []rune(s) // ERROR "\(\[\]rune\)\(s\) does not escape$"
  1749  	_ = x
  1750  }
  1751  
  1752  func stringtoslicerune1() []rune {
  1753  	s := "foo"
  1754  	return []rune(s) // ERROR "\(\[\]rune\)\(s\) escapes to heap$"
  1755  }
  1756  
  1757  func stringtoslicerune2() {
  1758  	s := "foo"
  1759  	sink = []rune(s) // ERROR "\(\[\]rune\)\(s\) escapes to heap$"
  1760  }
  1761  
  1762  func slicerunetostring0() {
  1763  	r := []rune{1, 2, 3} // ERROR "\[\]rune{...} does not escape$"
  1764  	s := string(r)       // ERROR "string\(r\) does not escape$"
  1765  	_ = s
  1766  }
  1767  
  1768  func slicerunetostring1() string {
  1769  	r := []rune{1, 2, 3} // ERROR "\[\]rune{...} does not escape$"
  1770  	return string(r)     // ERROR "string\(r\) escapes to heap$"
  1771  }
  1772  
  1773  func slicerunetostring2() {
  1774  	r := []rune{1, 2, 3} // ERROR "\[\]rune{...} does not escape$"
  1775  	sink = string(r)     // ERROR "string\(r\) escapes to heap$"
  1776  }
  1777  
  1778  func makemap0() {
  1779  	m := make(map[int]int) // ERROR "make\(map\[int\]int\) does not escape$"
  1780  	m[0] = 0
  1781  	m[1]++
  1782  	delete(m, 1)
  1783  	sink = m[0] // ERROR "m\[0\] escapes to heap$"
  1784  }
  1785  
  1786  func makemap1() map[int]int {
  1787  	return make(map[int]int) // ERROR "make\(map\[int\]int\) escapes to heap$"
  1788  }
  1789  
  1790  func makemap2() {
  1791  	m := make(map[int]int) // ERROR "make\(map\[int\]int\) escapes to heap$"
  1792  	sink = m
  1793  }
  1794  
  1795  func nonescapingEface(m map[interface{}]bool) bool { // ERROR "m does not escape$"
  1796  	return m["foo"] // ERROR ".foo. does not escape$"
  1797  }
  1798  
  1799  func nonescapingIface(m map[M]bool) bool { // ERROR "m does not escape$"
  1800  	return m[MV(0)] // ERROR "MV\(0\) does not escape$"
  1801  }
  1802  
  1803  func issue10353() {
  1804  	x := new(int) // ERROR "new\(int\) escapes to heap$"
  1805  	issue10353a(x)()
  1806  }
  1807  
  1808  func issue10353a(x *int) func() { // ERROR "leaking param: x$"
  1809  	return func() { // ERROR "func literal escapes to heap$"
  1810  		println(*x)
  1811  	}
  1812  }
  1813  
  1814  func issue10353b() {
  1815  	var f func()
  1816  	for {
  1817  		x := new(int) // ERROR "new\(int\) escapes to heap$"
  1818  		f = func() {  // ERROR "func literal escapes to heap$"
  1819  			println(*x)
  1820  		}
  1821  	}
  1822  	_ = f
  1823  }
  1824  
  1825  func issue11387(x int) func() int {
  1826  	f := func() int { return x }    // ERROR "func literal escapes to heap"
  1827  	slice1 := []func() int{f}       // ERROR "\[\].* does not escape"
  1828  	slice2 := make([]func() int, 1) // ERROR "make\(.*\) does not escape"
  1829  	copy(slice2, slice1)
  1830  	return slice2[0]
  1831  }
  1832  
  1833  func issue12397(x, y int) { // ERROR "moved to heap: y$"
  1834  	// x does not escape below, because all relevant code is dead.
  1835  	if false {
  1836  		gxx = &x
  1837  	} else {
  1838  		gxx = &y
  1839  	}
  1840  
  1841  	if true {
  1842  		gxx = &y
  1843  	} else {
  1844  		gxx = &x
  1845  	}
  1846  }
  1847  

View as plain text