Prep for subsequent CLs to remove old escape analysis pass.
This CL removes -newescape=true from tests that use it, and deletes
tests that use -newescape=false. (For history, see CL 170447.)
Notably, this removes escape_because.go without any replacement, but
this is being tracked by #31489.
Change-Id: I6f6058d58fff2c5d210cb1d2713200cc9f501ca7
Reviewed-on: https://go-review.googlesource.com/c/go/+/187617
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
-// errorcheck -0 -m -l -newescape=true
+// errorcheck -0 -m -l
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
-// errorcheck -0 -N -m -l -newescape=true
+// errorcheck -0 -N -m -l
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
-// errorcheck -0 -m -l -newescape=true
+// errorcheck -0 -m -l
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
+++ /dev/null
-// errorcheck -0 -m -m -l -newescape=false
-
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Note the doubled -m; this tests the "because" explanations for escapes,
-// and is likely to be annoyingly fragile under compiler change.
-// As long as the explanations look reasonably sane, meaning eyeball verify output of
-// go build -gcflags '-l -m -m' escape_because.go
-// and investigate changes, feel free to update with
-// go run run.go -update_errors -- escape_because.go
-
-package main
-
-func main() {
-}
-
-var sink interface{}
-
-type pair struct {
- x, y *int
-}
-
-type Pairy interface {
- EqualParts() bool
-}
-
-func (p *pair) EqualParts() bool { // ERROR "\(\*pair\).EqualParts p does not escape$"
- return p != nil && (p.x == p.y || *p.x == *p.y)
-}
-
-func f1(p *int) { // ERROR "from \[3\]\*int literal \(array literal element\) at escape_because.go:34$" "from a \(assigned\) at escape_because.go:34$" "from a \(interface-converted\) at escape_because.go:35$" "from sink \(assigned to top level variable\) at escape_because.go:35$" "leaking param: p$"
- a := [3]*int{p, nil, nil}
- sink = a // ERROR "a escapes to heap$" "from sink \(assigned to top level variable\) at escape_because.go:35$"
-
-}
-
-func f2(q *int) { // ERROR "from &u \(address-of\) at escape_because.go:43$" "from &u \(interface-converted\) at escape_because.go:43$" "from pair literal \(struct literal element\) at escape_because.go:41$" "from s \(assigned\) at escape_because.go:40$" "from sink \(assigned to top level variable\) at escape_because.go:43$" "from t \(assigned\) at escape_because.go:41$" "from u \(assigned\) at escape_because.go:42$" "leaking param: q$"
- s := q
- t := pair{s, nil}
- u := t // ERROR "moved to heap: u$"
- sink = &u // ERROR "&u escapes to heap$" "from sink \(assigned to top level variable\) at escape_because.go:43$"
-}
-
-func f3(r *int) interface{} { // ERROR "from \[\]\*int literal \(slice-literal-element\) at escape_because.go:47$" "from c \(assigned\) at escape_because.go:47$" "from c \(interface-converted\) at escape_because.go:48$" "from ~r1 \(return\) at escape_because.go:48$" "leaking param: r"
- c := []*int{r} // ERROR "\[\]\*int literal escapes to heap$" "from c \(assigned\) at escape_because.go:47$" "from c \(interface-converted\) at escape_because.go:48$" "from ~r1 \(return\) at escape_because.go:48$"
- return c // "return" // ERROR "c escapes to heap$" "from ~r1 \(return\) at escape_because.go:48$"
-}
-
-func f4(a *int, s []*int) int { // ERROR "from \*s \(indirection\) at escape_because.go:51$" "from append\(s, a\) \(appended to slice\) at escape_because.go:52$" "from append\(s, a\) \(appendee slice\) at escape_because.go:52$" "leaking param content: s$" "leaking param: a$"
- s = append(s, a)
- return *(s[0])
-}
-
-func f5(s1, s2 []*int) int { // ERROR "from \*s1 \(indirection\) at escape_because.go:56$" "from \*s2 \(indirection\) at escape_because.go:56$" "from append\(s1, s2...\) \(appended slice...\) at escape_because.go:57$" "from append\(s1, s2...\) \(appendee slice\) at escape_because.go:57$" "leaking param content: s1$" "leaking param content: s2$"
- s1 = append(s1, s2...)
- return *(s1[0])
-}
-
-func f6(x, y *int) bool { // ERROR "f6 x does not escape$" "f6 y does not escape$"
- p := pair{x, y}
- var P Pairy = &p // ERROR "f6 &p does not escape$"
- pp := P.(*pair)
- return pp.EqualParts()
-}
-
-func f7(x map[int]*int, y int) *int { // ERROR "f7 x does not escape$"
- z, ok := x[y]
- if !ok {
- return nil
- }
- return z
-}
-
-func f8(x int, y *int) *int { // ERROR "from ~r2 \(return\) at escape_because.go:78$" "from ~r2 \(returned from recursive function\) at escape_because.go:76$" "leaking param: y$" "moved to heap: x$"
- if x <= 0 {
- return y
- }
- x--
- return f8(*y, &x)
-}
-
-func f9(x int, y ...*int) *int { // ERROR "from y\[0\] \(dot of pointer\) at escape_because.go:86$" "from ~r2 \(return\) at escape_because.go:86$" "from ~r2 \(returned from recursive function\) at escape_because.go:84$" "leaking param content: y$" "leaking param: y to result ~r2 level=1$" "moved to heap: x$"
- if x <= 0 {
- return y[0]
- }
- x--
- return f9(*y[0], &x) // ERROR "f9 ... argument does not escape$"
-}
-
-func f10(x map[*int]*int, y, z *int) *int { // ERROR "f10 x does not escape$" "from x\[y\] \(key of map put\) at escape_because.go:93$" "from x\[y\] \(value of map put\) at escape_because.go:93$" "leaking param: y$" "leaking param: z$"
- x[y] = z
- return z
-}
-
-func f11(x map[*int]*int, y, z *int) map[*int]*int { // ERROR "f11 x does not escape$" "from map\[\*int\]\*int literal \(map literal key\) at escape_because.go:98$" "from map\[\*int\]\*int literal \(map literal value\) at escape_because.go:98$" "leaking param: y$" "leaking param: z$"
- return map[*int]*int{y: z} // ERROR "from ~r3 \(return\) at escape_because.go:98$" "map\[\*int\]\*int literal escapes to heap$"
-}
-
-func f12() {
- b := []byte("test") // ERROR "\(\[\]byte\)\(.test.\) escapes to heap$" "from b \(assigned\) at escape_because.go:102$" "from b \(passed to call\[argument escapes\]\) at escape_because.go:103$"
- escape(b)
-}
-
-func escape(b []byte) { // ERROR "from panic\(b\) \(panic\) at escape_because.go:107$" "leaking param: b$"
- panic(b)
-}
-
-func f13() {
- b := []byte("test") // ERROR "\(\[\]byte\)\(.test.\) escapes to heap$" "from .out0 \(passed-to-and-returned-from-call\) at escape_because.go:112$" "from b \(assigned\) at escape_because.go:111$" "from c \(assigned\) at escape_because.go:112$" "from c \(passed to call\[argument escapes\]\) at escape_because.go:113$"
- c := transmit(b)
- escape(c)
-}
-
-func transmit(b []byte) []byte { // ERROR "from ~r1 \(return\) at escape_because.go:117$" "leaking param: b to result ~r1 level=0$"
- return b
-}
-
-func f14() {
- n := 32
- s1 := make([]int, n) // ERROR "make\(\[\]int, n\) escapes to heap" "from make\(\[\]int, n\) \(non-constant size\)"
- s2 := make([]int, 0, n) // ERROR "make\(\[\]int, 0, n\) escapes to heap" "from make\(\[\]int, 0, n\) \(non-constant size\)"
- _, _ = s1, s2
-}
-
-func leakParams(p1, p2 *int) (*int, *int) { // ERROR "leaking param: p1 to result ~r2 level=0$" "from ~r2 \(return\) at escape_because.go:128$" "leaking param: p2 to result ~r3 level=0$" "from ~r3 \(return\) at escape_because.go:128$"
- return p1, p2
-}
-
-func leakThroughOAS2() {
- // See #26987.
- i := 0 // ERROR "moved to heap: i$"
- j := 0 // ERROR "moved to heap: j$"
- sink, sink = &i, &j // ERROR "&i escapes to heap$" "from sink \(assign-pair\) at escape_because.go:135$" "&j escapes to heap$"
-}
-
-func leakThroughOAS2FUNC() {
- // See #26987.
- i := 0 // ERROR "moved to heap: i$"
- j := 0
- sink, _ = leakParams(&i, &j)
-}
-
-// The list below is all of the why-escapes messages seen building the escape analysis tests.
-/*
- for i in escape*go ; do echo compile $i; go build -gcflags '-l -m -m' $i >& `basename $i .go`.log ; done
- grep 'from .* at ' escape*.log | sed -e 's/^.*(\([^()]*\))[^()]*$/\1/' | sort -u
-*/
-// sed RE above assumes that (reason) is the last parenthesized phrase in the line,
-// and that none of the reasons contains any parentheses
-
-/*
-... arg to recursive call
-address-of
-appended slice...
-appended to slice
-appendee slice
-arg to ...
-arg to recursive call
-array-element-equals
-array literal element
-assigned
-assigned to top level variable
-assign-pair-dot-type
-assign-pair-func-call
-captured by a closure
-captured by called closure
-dot
-dot-equals
-dot of pointer
-fixed-array-index-of
-go func arg
-indirection
-interface-converted
-key of map put
-map literal key
-map literal value
-non-constant size
-panic
-parameter to indirect call
-passed-to-and-returned-from-call
-passed to call[argument content escapes]
-passed to call[argument escapes]
-pointer literal
-range-deref
-receiver in indirect call
-return
-returned from recursive function
-slice-element-equals
-slice-literal-element
-star-dot-equals
-star-equals
-struct literal element
-too large for stack
-value of map put
-*/
-
-// Expected, but not yet seen (they may be unreachable):
-
-/*
-append-first-arg
-assign-pair-mapr
-assign-pair-receive
-call receiver
-map index
-pointer literal [assign]
-slice literal element
-*/
-// errorcheck -0 -m -l -newescape=true
+// errorcheck -0 -m -l
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
-// errorcheck -0 -m -l -newescape=true
+// errorcheck -0 -m -l
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
-// errorcheck -0 -m -l -newescape=true
+// errorcheck -0 -m -l
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
-// errorcheck -0 -m -l -newescape=true
+// errorcheck -0 -m -l
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
-// errorcheck -0 -m -l -newescape=true
+// errorcheck -0 -m -l
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
-// errorcheck -0 -m -l -newescape=true
+// errorcheck -0 -m -l
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
-// errorcheck -0 -m -l -newescape=true
+// errorcheck -0 -m -l
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
-// errorcheck -0 -N -m -l -newescape=true
+// errorcheck -0 -N -m -l
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
-// errorcheck -0 -m -l -smallframes -newescape=true
+// errorcheck -0 -m -l -smallframes
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
+++ /dev/null
-// errorcheck -0 -m -l -newescape=false
-
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Test escape analysis through ... parameters.
-
-package foo
-
-func FooN(vals ...*int) (s int) { // ERROR "FooN vals does not escape"
- for _, v := range vals {
- s += *v
- }
- return s
-}
-
-// Append forces heap allocation and copies entries in vals to heap, therefore they escape to heap.
-func FooNx(x *int, vals ...*int) (s int) { // ERROR "leaking param: x" "leaking param content: vals"
- vals = append(vals, x)
- return FooN(vals...)
-}
-
-var sink []*int
-
-func FooNy(x *int, vals ...*int) (s int) { // ERROR "leaking param: x" "leaking param: vals" "leaking param content: vals"
- vals = append(vals, x)
- sink = vals
- return FooN(vals...)
-}
-
-func FooNz(vals ...*int) (s int) { // ERROR "leaking param: vals"
- sink = vals
- return FooN(vals...)
-}
-
-func TFooN() {
- for i := 0; i < 1000; i++ {
- var i, j int
- FooN(&i, &j) // ERROR "TFooN ... argument does not escape"
- }
-}
-
-func TFooNx() {
- for i := 0; i < 1000; i++ {
- var i, j, k int // ERROR "moved to heap: i" "moved to heap: j" "moved to heap: k"
- FooNx(&k, &i, &j) // ERROR "TFooNx ... argument does not escape"
- }
-}
-
-func TFooNy() {
- for i := 0; i < 1000; i++ {
- var i, j, k int // ERROR "moved to heap: i" "moved to heap: j" "moved to heap: k"
- FooNy(&k, &i, &j) // ERROR "... argument escapes to heap"
- }
-}
-
-func TFooNz() {
- for i := 0; i < 1000; i++ {
- var i, j int // ERROR "moved to heap: i" "moved to heap: j"
- FooNz(&i, &j) // ERROR "... argument escapes to heap"
- }
-}
-
-var isink *int32
-
-func FooI(args ...interface{}) { // ERROR "leaking param content: args"
- for i := 0; i < len(args); i++ {
- switch x := args[i].(type) {
- case nil:
- println("is nil")
- case int32:
- println("is int32")
- case *int32:
- println("is *int32")
- isink = x
- case string:
- println("is string")
- }
- }
-}
-
-func TFooI() {
- a := int32(1) // ERROR "moved to heap: a"
- b := "cat"
- c := &a
- FooI(a, b, c) // ERROR "a escapes to heap" "b escapes to heap" "c escapes to heap" "TFooI ... argument does not escape"
-}
-
-func FooJ(args ...interface{}) *int32 { // ERROR "leaking param: args to result ~r1 level=1"
- for i := 0; i < len(args); i++ {
- switch x := args[i].(type) {
- case nil:
- println("is nil")
- case int32:
- println("is int32")
- case *int32:
- println("is *int32")
- return x
- case string:
- println("is string")
- }
- }
- return nil
-}
-
-func TFooJ1() {
- a := int32(1)
- b := "cat"
- c := &a
- FooJ(a, b, c) // ERROR "TFooJ1 a does not escape" "TFooJ1 b does not escape" "TFooJ1 c does not escape" "TFooJ1 ... argument does not escape"
-}
-
-func TFooJ2() {
- a := int32(1) // ERROR "moved to heap: a"
- b := "cat"
- c := &a
- isink = FooJ(a, b, c) // ERROR "a escapes to heap" "b escapes to heap" "c escapes to heap" "TFooJ2 ... argument does not escape"
-}
-
-type fakeSlice struct {
- l int
- a *[4]interface{}
-}
-
-func FooK(args fakeSlice) *int32 { // ERROR "leaking param: args to result ~r1 level=1"
- for i := 0; i < args.l; i++ {
- switch x := (*args.a)[i].(type) {
- case nil:
- println("is nil")
- case int32:
- println("is int32")
- case *int32:
- println("is *int32")
- return x
- case string:
- println("is string")
- }
- }
- return nil
-}
-
-func TFooK2() {
- a := int32(1) // ERROR "moved to heap: a"
- b := "cat"
- c := &a
- fs := fakeSlice{3, &[4]interface{}{a, b, c, nil}} // ERROR "a escapes to heap" "b escapes to heap" "c escapes to heap" "TFooK2 &\[4\]interface {} literal does not escape"
- isink = FooK(fs)
-}
-
-func FooL(args []interface{}) *int32 { // ERROR "leaking param: args to result ~r1 level=1"
- for i := 0; i < len(args); i++ {
- switch x := args[i].(type) {
- case nil:
- println("is nil")
- case int32:
- println("is int32")
- case *int32:
- println("is *int32")
- return x
- case string:
- println("is string")
- }
- }
- return nil
-}
-
-func TFooL2() {
- a := int32(1) // ERROR "moved to heap: a"
- b := "cat"
- c := &a
- s := []interface{}{a, b, c} // ERROR "a escapes to heap" "b escapes to heap" "c escapes to heap" "TFooL2 \[\]interface {} literal does not escape"
- isink = FooL(s)
-}
+++ /dev/null
-// errorcheck -0 -N -m -l -newescape=false
-
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// The escape analyzer needs to run till its root set settles
-// (this is not that often, it turns out).
-// This test is likely to become stale because the leak depends
-// on a spurious-escape bug -- return an interface as a named
-// output parameter appears to cause the called closure to escape,
-// where returning it as a regular type does not.
-
-package main
-
-import (
- "fmt"
-)
-
-type closure func(i, j int) ent
-
-type ent int
-
-func (e ent) String() string {
- return fmt.Sprintf("%d", int(e)) // ERROR "ent.String ... argument does not escape$" "int\(e\) escapes to heap$"
-}
-
-//go:noinline
-func foo(ops closure, j int) (err fmt.Stringer) { // ERROR "leaking param: ops$" "leaking param: ops to result err level=0$"
- enqueue := func(i int) fmt.Stringer { // ERROR "func literal escapes to heap$"
- return ops(i, j) // ERROR "ops\(i, j\) escapes to heap$"
- }
- err = enqueue(4)
- if err != nil {
- return err
- }
- return // return result of enqueue, a fmt.Stringer
-}
-
-func main() {
- // 3 identical functions, to get different escape behavior.
- f := func(i, j int) ent { // ERROR "func literal escapes to heap$"
- return ent(i + j)
- }
- i := foo(f, 3).(ent)
- fmt.Printf("foo(f,3)=%d\n", int(i)) // ERROR "int\(i\) escapes to heap$" "main ... argument does not escape$"
-}
-// errorcheckandrundir -0 -m -l=4 -newescape=true
+// errorcheckandrundir -0 -m -l=4
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
+++ /dev/null
-// errorcheck -0 -m -l -newescape=false
-
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Test, using compiler diagnostic flags, that the escape analysis is working.
-// Compiles but does not run. Inlining is disabled.
-
-// escape2n.go contains all the same tests but compiles with -N.
-
-package foo
-
-import (
- "fmt"
- "unsafe"
-)
-
-var gxx *int
-
-func foo1(x int) { // ERROR "moved to heap: x$"
- gxx = &x
-}
-
-func foo2(yy *int) { // ERROR "leaking param: yy$"
- gxx = yy
-}
-
-func foo3(x int) *int { // ERROR "moved to heap: x$"
- return &x
-}
-
-type T *T
-
-func foo3b(t T) { // ERROR "leaking param: t$"
- *t = t
-}
-
-// xx isn't going anywhere, so use of yy is ok
-func foo4(xx, yy *int) { // ERROR "foo4 xx does not escape$" "foo4 yy does not escape$"
- xx = yy
-}
-
-// xx isn't going anywhere, so taking address of yy is ok
-func foo5(xx **int, yy *int) { // ERROR "foo5 xx does not escape$" "foo5 yy does not escape$"
- xx = &yy
-}
-
-func foo6(xx **int, yy *int) { // ERROR "foo6 xx does not escape$" "leaking param: yy$"
- *xx = yy
-}
-
-func foo7(xx **int, yy *int) { // ERROR "foo7 xx does not escape$" "foo7 yy does not escape$"
- **xx = *yy
-}
-
-func foo8(xx, yy *int) int { // ERROR "foo8 xx does not escape$" "foo8 yy does not escape$"
- xx = yy
- return *xx
-}
-
-func foo9(xx, yy *int) *int { // ERROR "leaking param: xx to result ~r2 level=0$" "leaking param: yy to result ~r2 level=0$"
- xx = yy
- return xx
-}
-
-func foo10(xx, yy *int) { // ERROR "foo10 xx does not escape$" "foo10 yy does not escape$"
- *xx = *yy
-}
-
-func foo11() int {
- x, y := 0, 42
- xx := &x
- yy := &y
- *xx = *yy
- return x
-}
-
-var xxx **int
-
-func foo12(yyy **int) { // ERROR "leaking param: yyy$"
- xxx = yyy
-}
-
-// Must treat yyy as leaking because *yyy leaks, and the escape analysis
-// summaries in exported metadata do not distinguish these two cases.
-func foo13(yyy **int) { // ERROR "leaking param content: yyy$"
- *xxx = *yyy
-}
-
-func foo14(yyy **int) { // ERROR "foo14 yyy does not escape$"
- **xxx = **yyy
-}
-
-func foo15(yy *int) { // ERROR "moved to heap: yy$"
- xxx = &yy
-}
-
-func foo16(yy *int) { // ERROR "leaking param: yy$"
- *xxx = yy
-}
-
-func foo17(yy *int) { // ERROR "foo17 yy does not escape$"
- **xxx = *yy
-}
-
-func foo18(y int) { // ERROR "moved to heap: y$"
- *xxx = &y
-}
-
-func foo19(y int) {
- **xxx = y
-}
-
-type Bar struct {
- i int
- ii *int
-}
-
-func NewBar() *Bar {
- return &Bar{42, nil} // ERROR "&Bar literal escapes to heap$"
-}
-
-func NewBarp(x *int) *Bar { // ERROR "leaking param: x to result ~r1 level=-1$"
- return &Bar{42, x} // ERROR "&Bar literal escapes to heap$"
-}
-
-func NewBarp2(x *int) *Bar { // ERROR "NewBarp2 x does not escape$"
- return &Bar{*x, nil} // ERROR "&Bar literal escapes to heap$"
-}
-
-func (b *Bar) NoLeak() int { // ERROR "\(\*Bar\).NoLeak b does not escape$"
- return *(b.ii)
-}
-
-func (b *Bar) Leak() *int { // ERROR "leaking param: b to result ~r0 level=0$"
- return &b.i
-}
-
-func (b *Bar) AlsoNoLeak() *int { // ERROR "leaking param: b to result ~r0 level=1$"
- return b.ii
-}
-
-func (b Bar) AlsoLeak() *int { // ERROR "leaking param: b to result ~r0 level=0$"
- return b.ii
-}
-
-func (b Bar) LeaksToo() *int { // ERROR "leaking param: b to result ~r0 level=0$"
- v := 0 // ERROR "moved to heap: v$"
- b.ii = &v
- return b.ii
-}
-
-func (b *Bar) LeaksABit() *int { // ERROR "leaking param: b to result ~r0 level=1$"
- v := 0 // ERROR "moved to heap: v$"
- b.ii = &v
- return b.ii
-}
-
-func (b Bar) StillNoLeak() int { // ERROR "Bar.StillNoLeak b does not escape$"
- v := 0
- b.ii = &v
- return b.i
-}
-
-func goLeak(b *Bar) { // ERROR "leaking param: b$"
- go b.NoLeak()
-}
-
-type Bar2 struct {
- i [12]int
- ii []int
-}
-
-func NewBar2() *Bar2 {
- return &Bar2{[12]int{42}, nil} // ERROR "&Bar2 literal escapes to heap$"
-}
-
-func (b *Bar2) NoLeak() int { // ERROR "\(\*Bar2\).NoLeak b does not escape$"
- return b.i[0]
-}
-
-func (b *Bar2) Leak() []int { // ERROR "leaking param: b to result ~r0 level=0$"
- return b.i[:]
-}
-
-func (b *Bar2) AlsoNoLeak() []int { // ERROR "leaking param: b to result ~r0 level=1$"
- return b.ii[0:1]
-}
-
-func (b Bar2) AgainNoLeak() [12]int { // ERROR "Bar2.AgainNoLeak b does not escape$"
- return b.i
-}
-
-func (b *Bar2) LeakSelf() { // ERROR "leaking param: b$"
- b.ii = b.i[0:4]
-}
-
-func (b *Bar2) LeakSelf2() { // ERROR "leaking param: b$"
- var buf []int
- buf = b.i[0:]
- b.ii = buf
-}
-
-func foo21() func() int {
- x := 42
- return func() int { // ERROR "func literal escapes to heap$"
- return x
- }
-}
-
-func foo21a() func() int {
- x := 42 // ERROR "moved to heap: x$"
- return func() int { // ERROR "func literal escapes to heap$"
- x++
- return x
- }
-}
-
-func foo22() int {
- x := 42
- return func() int { // ERROR "foo22 func literal does not escape$"
- return x
- }()
-}
-
-func foo23(x int) func() int {
- return func() int { // ERROR "func literal escapes to heap$"
- return x
- }
-}
-
-func foo23a(x int) func() int {
- f := func() int { // ERROR "func literal escapes to heap$"
- return x
- }
- return f
-}
-
-func foo23b(x int) *(func() int) {
- f := func() int { return x } // ERROR "func literal escapes to heap$" "moved to heap: f$"
- return &f
-}
-
-func foo23c(x int) func() int { // ERROR "moved to heap: x$"
- return func() int { // ERROR "func literal escapes to heap$"
- x++
- return x
- }
-}
-
-func foo24(x int) int {
- return func() int { // ERROR "foo24 func literal does not escape$"
- return x
- }()
-}
-
-var x *int
-
-func fooleak(xx *int) int { // ERROR "leaking param: xx$"
- x = xx
- return *x
-}
-
-func foonoleak(xx *int) int { // ERROR "foonoleak xx does not escape$"
- return *x + *xx
-}
-
-func foo31(x int) int { // ERROR "moved to heap: x$"
- return fooleak(&x)
-}
-
-func foo32(x int) int {
- return foonoleak(&x)
-}
-
-type Foo struct {
- xx *int
- x int
-}
-
-var F Foo
-var pf *Foo
-
-func (f *Foo) fooleak() { // ERROR "leaking param: f$"
- pf = f
-}
-
-func (f *Foo) foonoleak() { // ERROR "\(\*Foo\).foonoleak f does not escape$"
- F.x = f.x
-}
-
-func (f *Foo) Leak() { // ERROR "leaking param: f$"
- f.fooleak()
-}
-
-func (f *Foo) NoLeak() { // ERROR "\(\*Foo\).NoLeak f does not escape$"
- f.foonoleak()
-}
-
-func foo41(x int) { // ERROR "moved to heap: x$"
- F.xx = &x
-}
-
-func (f *Foo) foo42(x int) { // ERROR "\(\*Foo\).foo42 f does not escape$" "moved to heap: x$"
- f.xx = &x
-}
-
-func foo43(f *Foo, x int) { // ERROR "foo43 f does not escape$" "moved to heap: x$"
- f.xx = &x
-}
-
-func foo44(yy *int) { // ERROR "leaking param: yy$"
- F.xx = yy
-}
-
-func (f *Foo) foo45() { // ERROR "\(\*Foo\).foo45 f does not escape$"
- F.x = f.x
-}
-
-// See foo13 above for explanation of why f leaks.
-func (f *Foo) foo46() { // ERROR "leaking param content: f$"
- F.xx = f.xx
-}
-
-func (f *Foo) foo47() { // ERROR "leaking param: f$"
- f.xx = &f.x
-}
-
-var ptrSlice []*int
-
-func foo50(i *int) { // ERROR "leaking param: i$"
- ptrSlice[0] = i
-}
-
-var ptrMap map[*int]*int
-
-func foo51(i *int) { // ERROR "leaking param: i$"
- ptrMap[i] = i
-}
-
-func indaddr1(x int) *int { // ERROR "moved to heap: x$"
- return &x
-}
-
-func indaddr2(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
- return *&x
-}
-
-func indaddr3(x *int32) *int { // ERROR "leaking param: x to result ~r1 level=0$"
- return *(**int)(unsafe.Pointer(&x))
-}
-
-// From package math:
-
-func Float32bits(f float32) uint32 {
- return *(*uint32)(unsafe.Pointer(&f))
-}
-
-func Float32frombits(b uint32) float32 {
- return *(*float32)(unsafe.Pointer(&b))
-}
-
-func Float64bits(f float64) uint64 {
- return *(*uint64)(unsafe.Pointer(&f))
-}
-
-func Float64frombits(b uint64) float64 {
- return *(*float64)(unsafe.Pointer(&b))
-}
-
-// contrast with
-func float64bitsptr(f float64) *uint64 { // ERROR "moved to heap: f$"
- return (*uint64)(unsafe.Pointer(&f))
-}
-
-func float64ptrbitsptr(f *float64) *uint64 { // ERROR "leaking param: f to result ~r1 level=0$"
- return (*uint64)(unsafe.Pointer(f))
-}
-
-func typesw(i interface{}) *int { // ERROR "leaking param: i to result ~r1 level=0$"
- switch val := i.(type) {
- case *int:
- return val
- case *int8:
- v := int(*val) // ERROR "moved to heap: v$"
- return &v
- }
- return nil
-}
-
-func exprsw(i *int) *int { // ERROR "leaking param: i to result ~r1 level=0$"
- switch j := i; *j + 110 {
- case 12:
- return j
- case 42:
- return nil
- }
- return nil
-
-}
-
-// assigning to an array element is like assigning to the array
-func foo60(i *int) *int { // ERROR "leaking param: i to result ~r1 level=0$"
- var a [12]*int
- a[0] = i
- return a[1]
-}
-
-func foo60a(i *int) *int { // ERROR "foo60a i does not escape$"
- var a [12]*int
- a[0] = i
- return nil
-}
-
-// assigning to a struct field is like assigning to the struct
-func foo61(i *int) *int { // ERROR "leaking param: i to result ~r1 level=0$"
- type S struct {
- a, b *int
- }
- var s S
- s.a = i
- return s.b
-}
-
-func foo61a(i *int) *int { // ERROR "foo61a i does not escape$"
- type S struct {
- a, b *int
- }
- var s S
- s.a = i
- return nil
-}
-
-// assigning to a struct field is like assigning to the struct but
-// here this subtlety is lost, since s.a counts as an assignment to a
-// track-losing dereference.
-func foo62(i *int) *int { // ERROR "leaking param: i$"
- type S struct {
- a, b *int
- }
- s := new(S) // ERROR "foo62 new\(S\) does not escape$"
- s.a = i
- return nil // s.b
-}
-
-type M interface {
- M()
-}
-
-func foo63(m M) { // ERROR "foo63 m does not escape$"
-}
-
-func foo64(m M) { // ERROR "leaking param: m$"
- m.M()
-}
-
-func foo64b(m M) { // ERROR "leaking param: m$"
- defer m.M()
-}
-
-type MV int
-
-func (MV) M() {}
-
-func foo65() {
- var mv MV
- foo63(&mv) // ERROR "foo65 &mv does not escape$"
-}
-
-func foo66() {
- var mv MV // ERROR "moved to heap: mv$"
- foo64(&mv) // ERROR "&mv escapes to heap$"
-}
-
-func foo67() {
- var mv MV
- foo63(mv) // ERROR "foo67 mv does not escape$"
-}
-
-func foo68() {
- var mv MV
- // escapes but it's an int so irrelevant
- foo64(mv) // ERROR "mv escapes to heap$"
-}
-
-func foo69(m M) { // ERROR "leaking param: m$"
- foo64(m)
-}
-
-func foo70(mv1 *MV, m M) { // ERROR "leaking param: m$" "leaking param: mv1$"
- m = mv1 // ERROR "mv1 escapes to heap$"
- foo64(m)
-}
-
-func foo71(x *int) []*int { // ERROR "leaking param: x$"
- var y []*int
- y = append(y, x)
- return y
-}
-
-func foo71a(x int) []*int { // ERROR "moved to heap: x$"
- var y []*int
- y = append(y, &x)
- return y
-}
-
-func foo72() {
- var x int
- var y [1]*int
- y[0] = &x
-}
-
-func foo72aa() [10]*int {
- var x int // ERROR "moved to heap: x$"
- var y [10]*int
- y[0] = &x
- return y
-}
-
-func foo72a() {
- var y [10]*int
- for i := 0; i < 10; i++ {
- // escapes its scope
- x := i // ERROR "moved to heap: x$"
- y[i] = &x
- }
- return
-}
-
-func foo72b() [10]*int {
- var y [10]*int
- for i := 0; i < 10; i++ {
- x := i // ERROR "moved to heap: x$"
- y[i] = &x
- }
- return y
-}
-
-// issue 2145
-func foo73() {
- s := []int{3, 2, 1} // ERROR "foo73 \[\]int literal does not escape$"
- for _, v := range s {
- vv := v
- // actually just escapes its scope
- defer func() { // ERROR "func literal escapes to heap$"
- println(vv)
- }()
- }
-}
-
-func foo731() {
- s := []int{3, 2, 1} // ERROR "foo731 \[\]int literal does not escape$"
- for _, v := range s {
- vv := v // ERROR "moved to heap: vv$"
- // actually just escapes its scope
- defer func() { // ERROR "func literal escapes to heap$"
- vv = 42
- println(vv)
- }()
- }
-}
-
-func foo74() {
- s := []int{3, 2, 1} // ERROR "foo74 \[\]int literal does not escape$"
- for _, v := range s {
- vv := v
- // actually just escapes its scope
- fn := func() { // ERROR "func literal escapes to heap$"
- println(vv)
- }
- defer fn()
- }
-}
-
-func foo74a() {
- s := []int{3, 2, 1} // ERROR "foo74a \[\]int literal does not escape$"
- for _, v := range s {
- vv := v // ERROR "moved to heap: vv$"
- // actually just escapes its scope
- fn := func() { // ERROR "func literal escapes to heap$"
- vv += 1
- println(vv)
- }
- defer fn()
- }
-}
-
-// issue 3975
-func foo74b() {
- var array [3]func()
- s := []int{3, 2, 1} // ERROR "foo74b \[\]int literal does not escape$"
- for i, v := range s {
- vv := v
- // actually just escapes its scope
- array[i] = func() { // ERROR "func literal escapes to heap$"
- println(vv)
- }
- }
-}
-
-func foo74c() {
- var array [3]func()
- s := []int{3, 2, 1} // ERROR "foo74c \[\]int literal does not escape$"
- for i, v := range s {
- vv := v // ERROR "moved to heap: vv$"
- // actually just escapes its scope
- array[i] = func() { // ERROR "func literal escapes to heap$"
- println(&vv)
- }
- }
-}
-
-func myprint(y *int, x ...interface{}) *int { // ERROR "leaking param: y to result ~r2 level=0$" "myprint x does not escape$"
- return y
-}
-
-func myprint1(y *int, x ...interface{}) *interface{} { // ERROR "leaking param: x to result ~r2 level=0$" "myprint1 y does not escape$"
- return &x[0]
-}
-
-func foo75(z *int) { // ERROR "foo75 z does not escape$"
- myprint(z, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "foo75 ... argument does not escape$"
-}
-
-func foo75a(z *int) { // ERROR "foo75a z does not escape$"
- myprint1(z, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "foo75a ... argument does not escape$"
-}
-
-func foo75esc(z *int) { // ERROR "leaking param: z$"
- gxx = myprint(z, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "foo75esc ... argument does not escape$"
-}
-
-func foo75aesc(z *int) { // ERROR "foo75aesc z does not escape$"
- var ppi **interface{} // assignments to pointer dereferences lose track
- *ppi = myprint1(z, 1, 2, 3) // ERROR "... argument escapes to heap$" "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$"
-}
-
-func foo75aesc1(z *int) { // ERROR "foo75aesc1 z does not escape$"
- sink = myprint1(z, 1, 2, 3) // ERROR "... argument escapes to heap$" "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$" "myprint1\(z, 1, 2, 3\) escapes to heap$"
-}
-
-func foo76(z *int) { // ERROR "z does not escape"
- myprint(nil, z) // ERROR "foo76 ... argument does not escape$" "z does not escape"
-}
-
-func foo76a(z *int) { // ERROR "z does not escape"
- myprint1(nil, z) // ERROR "foo76a ... argument does not escape$" "z does not escape"
-}
-
-func foo76b() {
- myprint(nil, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "foo76b ... argument does not escape$"
-}
-
-func foo76c() {
- myprint1(nil, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "foo76c ... argument does not escape$"
-}
-
-func foo76d() {
- defer myprint(nil, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "foo76d ... argument does not escape$"
-}
-
-func foo76e() {
- defer myprint1(nil, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "foo76e ... argument does not escape$"
-}
-
-func foo76f() {
- for {
- // TODO: This one really only escapes its scope, but we don't distinguish yet.
- defer myprint(nil, 1, 2, 3) // ERROR "... argument escapes to heap$" "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$"
- }
-}
-
-func foo76g() {
- for {
- defer myprint1(nil, 1, 2, 3) // ERROR "... argument escapes to heap$" "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$"
- }
-}
-
-func foo77(z []interface{}) { // ERROR "foo77 z does not escape$"
- myprint(nil, z...) // z does not escape
-}
-
-func foo77a(z []interface{}) { // ERROR "foo77a z does not escape$"
- myprint1(nil, z...)
-}
-
-func foo77b(z []interface{}) { // ERROR "leaking param: z$"
- var ppi **interface{}
- *ppi = myprint1(nil, z...)
-}
-
-func foo77c(z []interface{}) { // ERROR "leaking param: z$"
- sink = myprint1(nil, z...) // ERROR "myprint1\(nil, z...\) escapes to heap$"
-}
-
-func dotdotdot() {
- i := 0
- myprint(nil, &i) // ERROR "&i does not escape" "dotdotdot ... argument does not escape$"
-
- j := 0
- myprint1(nil, &j) // ERROR "&j does not escape" "dotdotdot ... argument does not escape$"
-}
-
-func foo78(z int) *int { // ERROR "moved to heap: z$"
- return &z
-}
-
-func foo78a(z int) *int { // ERROR "moved to heap: z$"
- y := &z
- x := &y
- return *x // really return y
-}
-
-func foo79() *int {
- return new(int) // ERROR "new\(int\) escapes to heap$"
-}
-
-func foo80() *int {
- var z *int
- for {
- // Really just escapes its scope but we don't distinguish
- z = new(int) // ERROR "new\(int\) escapes to heap$"
- }
- _ = z
- return nil
-}
-
-func foo81() *int {
- for {
- z := new(int) // ERROR "foo81 new\(int\) does not escape$"
- _ = z
- }
- return nil
-}
-
-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$"
-
-func noop(x, y *int) {} // ERROR "noop x does not escape$" "noop y does not escape$"
-
-func foo82() {
- var x, y, z int // ERROR "moved to heap: x$" "moved to heap: y$" "moved to heap: z$"
- go noop(tee(&z))
- go noop(&x, &y)
- for {
- var u, v, w int // ERROR "moved to heap: u$" "moved to heap: v$" "moved to heap: w$"
- defer noop(tee(&u))
- defer noop(&v, &w)
- }
-}
-
-type Fooer interface {
- Foo()
-}
-
-type LimitedFooer struct {
- Fooer
- N int64
-}
-
-func LimitFooer(r Fooer, n int64) Fooer { // ERROR "leaking param: r to result ~r2 level=-1$"
- return &LimitedFooer{r, n} // ERROR "&LimitedFooer literal escapes to heap$"
-}
-
-func foo90(x *int) map[*int]*int { // ERROR "leaking param: x$"
- return map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int literal escapes to heap$"
-}
-
-func foo91(x *int) map[*int]*int { // ERROR "leaking param: x$"
- return map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int literal escapes to heap$"
-}
-
-func foo92(x *int) [2]*int { // ERROR "leaking param: x to result ~r1 level=0$"
- return [2]*int{x, nil}
-}
-
-// does not leak c
-func foo93(c chan *int) *int { // ERROR "foo93 c does not escape$"
- for v := range c {
- return v
- }
- return nil
-}
-
-// does not leak m
-func foo94(m map[*int]*int, b bool) *int { // ERROR "leaking param: m to result ~r2 level=1"
- for k, v := range m {
- if b {
- return k
- }
- return v
- }
- return nil
-}
-
-// does leak x
-func foo95(m map[*int]*int, x *int) { // ERROR "foo95 m does not escape$" "leaking param: x$"
- m[x] = x
-}
-
-// does not leak m but does leak content
-func foo96(m []*int) *int { // ERROR "leaking param: m to result ~r1 level=1"
- return m[0]
-}
-
-// does leak m
-func foo97(m [1]*int) *int { // ERROR "leaking param: m to result ~r1 level=0$"
- return m[0]
-}
-
-// does not leak m
-func foo98(m map[int]*int) *int { // ERROR "foo98 m does not escape$"
- return m[0]
-}
-
-// does leak m
-func foo99(m *[1]*int) []*int { // ERROR "leaking param: m to result ~r1 level=0$"
- return m[:]
-}
-
-// does not leak m
-func foo100(m []*int) *int { // ERROR "leaking param: m to result ~r1 level=1"
- for _, v := range m {
- return v
- }
- return nil
-}
-
-// does leak m
-func foo101(m [1]*int) *int { // ERROR "leaking param: m to result ~r1 level=0$"
- for _, v := range m {
- return v
- }
- return nil
-}
-
-// does not leak m
-func foo101a(m [1]*int) *int { // ERROR "foo101a m does not escape$"
- for i := range m { // ERROR "moved to heap: i$"
- return &i
- }
- return nil
-}
-
-// does leak x
-func foo102(m []*int, x *int) { // ERROR "foo102 m does not escape$" "leaking param: x$"
- m[0] = x
-}
-
-// does not leak x
-func foo103(m [1]*int, x *int) { // ERROR "foo103 m does not escape$" "foo103 x does not escape$"
- m[0] = x
-}
-
-var y []*int
-
-// does not leak x but does leak content
-func foo104(x []*int) { // ERROR "leaking param content: x"
- copy(y, x)
-}
-
-// does not leak x but does leak content
-func foo105(x []*int) { // ERROR "leaking param content: x"
- _ = append(y, x...)
-}
-
-// does leak x
-func foo106(x *int) { // ERROR "leaking param: x$"
- _ = append(y, x)
-}
-
-func foo107(x *int) map[*int]*int { // ERROR "leaking param: x$"
- return map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int literal escapes to heap$"
-}
-
-func foo108(x *int) map[*int]*int { // ERROR "leaking param: x$"
- return map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int literal escapes to heap$"
-}
-
-func foo109(x *int) *int { // ERROR "leaking param: x$"
- m := map[*int]*int{x: nil} // ERROR "foo109 map\[\*int\]\*int literal does not escape$"
- for k, _ := range m {
- return k
- }
- return nil
-}
-
-func foo110(x *int) *int { // ERROR "leaking param: x$"
- m := map[*int]*int{nil: x} // ERROR "foo110 map\[\*int\]\*int literal does not escape$"
- return m[nil]
-}
-
-func foo111(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0"
- m := []*int{x} // ERROR "foo111 \[\]\*int literal does not escape$"
- return m[0]
-}
-
-func foo112(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
- m := [1]*int{x}
- return m[0]
-}
-
-func foo113(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
- m := Bar{ii: x}
- return m.ii
-}
-
-func foo114(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
- m := &Bar{ii: x} // ERROR "foo114 &Bar literal does not escape$"
- return m.ii
-}
-
-func foo115(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
- return (*int)(unsafe.Pointer(uintptr(unsafe.Pointer(x)) + 1))
-}
-
-func foo116(b bool) *int {
- if b {
- x := 1 // ERROR "moved to heap: x$"
- return &x
- } else {
- y := 1 // ERROR "moved to heap: y$"
- return &y
- }
- return nil
-}
-
-func foo117(unknown func(interface{})) { // ERROR "foo117 unknown does not escape$"
- x := 1 // ERROR "moved to heap: x$"
- unknown(&x) // ERROR "&x escapes to heap$"
-}
-
-func foo118(unknown func(*int)) { // ERROR "foo118 unknown does not escape$"
- x := 1 // ERROR "moved to heap: x$"
- unknown(&x)
-}
-
-func external(*int)
-
-func foo119(x *int) { // ERROR "leaking param: x$"
- external(x)
-}
-
-func foo120() {
- // formerly exponential time analysis
-L1:
-L2:
-L3:
-L4:
-L5:
-L6:
-L7:
-L8:
-L9:
-L10:
-L11:
-L12:
-L13:
-L14:
-L15:
-L16:
-L17:
-L18:
-L19:
-L20:
-L21:
-L22:
-L23:
-L24:
-L25:
-L26:
-L27:
-L28:
-L29:
-L30:
-L31:
-L32:
-L33:
-L34:
-L35:
-L36:
-L37:
-L38:
-L39:
-L40:
-L41:
-L42:
-L43:
-L44:
-L45:
-L46:
-L47:
-L48:
-L49:
-L50:
-L51:
-L52:
-L53:
-L54:
-L55:
-L56:
-L57:
-L58:
-L59:
-L60:
-L61:
-L62:
-L63:
-L64:
-L65:
-L66:
-L67:
-L68:
-L69:
-L70:
-L71:
-L72:
-L73:
-L74:
-L75:
-L76:
-L77:
-L78:
-L79:
-L80:
-L81:
-L82:
-L83:
-L84:
-L85:
-L86:
-L87:
-L88:
-L89:
-L90:
-L91:
-L92:
-L93:
-L94:
-L95:
-L96:
-L97:
-L98:
-L99:
-L100:
- // use the labels to silence compiler errors
- goto L1
- goto L2
- goto L3
- goto L4
- goto L5
- goto L6
- goto L7
- goto L8
- goto L9
- goto L10
- goto L11
- goto L12
- goto L13
- goto L14
- goto L15
- goto L16
- goto L17
- goto L18
- goto L19
- goto L20
- goto L21
- goto L22
- goto L23
- goto L24
- goto L25
- goto L26
- goto L27
- goto L28
- goto L29
- goto L30
- goto L31
- goto L32
- goto L33
- goto L34
- goto L35
- goto L36
- goto L37
- goto L38
- goto L39
- goto L40
- goto L41
- goto L42
- goto L43
- goto L44
- goto L45
- goto L46
- goto L47
- goto L48
- goto L49
- goto L50
- goto L51
- goto L52
- goto L53
- goto L54
- goto L55
- goto L56
- goto L57
- goto L58
- goto L59
- goto L60
- goto L61
- goto L62
- goto L63
- goto L64
- goto L65
- goto L66
- goto L67
- goto L68
- goto L69
- goto L70
- goto L71
- goto L72
- goto L73
- goto L74
- goto L75
- goto L76
- goto L77
- goto L78
- goto L79
- goto L80
- goto L81
- goto L82
- goto L83
- goto L84
- goto L85
- goto L86
- goto L87
- goto L88
- goto L89
- goto L90
- goto L91
- goto L92
- goto L93
- goto L94
- goto L95
- goto L96
- goto L97
- goto L98
- goto L99
- goto L100
-}
-
-func foo121() {
- for i := 0; i < 10; i++ {
- defer myprint(nil, i) // ERROR "... argument escapes to heap$" "i escapes to heap$"
- go myprint(nil, i) // ERROR "... argument escapes to heap$" "i escapes to heap$"
- }
-}
-
-// same as foo121 but check across import
-func foo121b() {
- for i := 0; i < 10; i++ {
- defer fmt.Printf("%d", i) // ERROR "... argument escapes to heap$" "i escapes to heap$"
- go fmt.Printf("%d", i) // ERROR "... argument escapes to heap$" "i escapes to heap$"
- }
-}
-
-// a harmless forward jump
-func foo122() {
- var i *int
-
- goto L1
-L1:
- i = new(int) // ERROR "foo122 new\(int\) does not escape$"
- _ = i
-}
-
-// a backward jump, increases loopdepth
-func foo123() {
- var i *int
-
-L1:
- i = new(int) // ERROR "new\(int\) escapes to heap$"
-
- goto L1
- _ = i
-}
-
-func foo124(x **int) { // ERROR "foo124 x does not escape$"
- var i int // ERROR "moved to heap: i$"
- p := &i
- func() { // ERROR "foo124 func literal does not escape$"
- *x = p
- }()
-}
-
-func foo125(ch chan *int) { // ERROR "foo125 ch does not escape$"
- var i int // ERROR "moved to heap: i$"
- p := &i
- func() { // ERROR "foo125 func literal does not escape$"
- ch <- p
- }()
-}
-
-func foo126() {
- var px *int // loopdepth 0
- for {
- // loopdepth 1
- var i int // ERROR "moved to heap: i$"
- func() { // ERROR "foo126 func literal does not escape$"
- px = &i
- }()
- }
- _ = px
-}
-
-var px *int
-
-func foo127() {
- var i int // ERROR "moved to heap: i$"
- p := &i
- q := p
- px = q
-}
-
-func foo128() {
- var i int
- p := &i
- q := p
- _ = q
-}
-
-func foo129() {
- var i int // ERROR "moved to heap: i$"
- p := &i
- func() { // ERROR "foo129 func literal does not escape$"
- q := p
- func() { // ERROR "foo129.func1 func literal does not escape$"
- r := q
- px = r
- }()
- }()
-}
-
-func foo130() {
- for {
- var i int // ERROR "moved to heap: i$"
- func() { // ERROR "foo130 func literal does not escape$"
- px = &i
- }()
- }
-}
-
-func foo131() {
- var i int // ERROR "moved to heap: i$"
- func() { // ERROR "foo131 func literal does not escape$"
- px = &i
- }()
-}
-
-func foo132() {
- var i int // ERROR "moved to heap: i$"
- go func() { // ERROR "func literal escapes to heap$"
- px = &i
- }()
-}
-
-func foo133() {
- var i int // ERROR "moved to heap: i$"
- defer func() { // ERROR "foo133 func literal does not escape$"
- px = &i
- }()
-}
-
-func foo134() {
- var i int
- p := &i
- func() { // ERROR "foo134 func literal does not escape$"
- q := p
- func() { // ERROR "foo134.func1 func literal does not escape$"
- r := q
- _ = r
- }()
- }()
-}
-
-func foo135() {
- var i int // ERROR "moved to heap: i$"
- p := &i
- go func() { // ERROR "func literal escapes to heap$"
- q := p
- func() { // ERROR "foo135.func1 func literal does not escape$"
- r := q
- _ = r
- }()
- }()
-}
-
-func foo136() {
- var i int // ERROR "moved to heap: i$"
- p := &i
- go func() { // ERROR "func literal escapes to heap$"
- q := p
- func() { // ERROR "foo136.func1 func literal does not escape$"
- r := q
- px = r
- }()
- }()
-}
-
-func foo137() {
- var i int // ERROR "moved to heap: i$"
- p := &i
- func() { // ERROR "foo137 func literal does not escape$"
- q := p
- go func() { // ERROR "func literal escapes to heap$"
- r := q
- _ = r
- }()
- }()
-}
-
-func foo138() *byte {
- type T struct {
- x [1]byte
- }
- t := new(T) // ERROR "new\(T\) escapes to heap$"
- return &t.x[0]
-}
-
-func foo139() *byte {
- type T struct {
- x struct {
- y byte
- }
- }
- t := new(T) // ERROR "new\(T\) escapes to heap$"
- return &t.x.y
-}
-
-// issue 4751
-func foo140() interface{} {
- type T struct {
- X string
- }
- type U struct {
- X string
- T *T
- }
- t := &T{} // ERROR "&T literal escapes to heap$"
- return U{ // ERROR "U literal escapes to heap$"
- X: t.X,
- T: t,
- }
-}
-
-//go:noescape
-
-func F1([]byte)
-
-func F2([]byte)
-
-//go:noescape
-
-func F3(x []byte) // ERROR "F3 x does not escape$"
-
-func F4(x []byte)
-
-func G() {
- var buf1 [10]byte
- F1(buf1[:])
-
- var buf2 [10]byte // ERROR "moved to heap: buf2$"
- F2(buf2[:])
-
- var buf3 [10]byte
- F3(buf3[:])
-
- var buf4 [10]byte // ERROR "moved to heap: buf4$"
- F4(buf4[:])
-}
-
-type Tm struct {
- x int
-}
-
-func (t *Tm) M() { // ERROR "\(\*Tm\).M t does not escape$"
-}
-
-func foo141() {
- var f func()
-
- t := new(Tm) // ERROR "new\(Tm\) escapes to heap$"
- f = t.M // ERROR "foo141 t.M does not escape$"
- _ = f
-}
-
-var gf func()
-
-func foo142() {
- t := new(Tm) // ERROR "new\(Tm\) escapes to heap$"
- gf = t.M // ERROR "t.M escapes to heap$"
-}
-
-// issue 3888.
-func foo143() {
- for i := 0; i < 1000; i++ {
- func() { // ERROR "foo143 func literal does not escape$"
- for i := 0; i < 1; i++ {
- var t Tm
- t.M()
- }
- }()
- }
-}
-
-// issue 5773
-// Check that annotations take effect regardless of whether they
-// are before or after the use in the source code.
-
-//go:noescape
-
-func foo144a(*int)
-
-func foo144() {
- var x int
- foo144a(&x)
- var y int
- foo144b(&y)
-}
-
-//go:noescape
-
-func foo144b(*int)
-
-// issue 7313: for loop init should not be treated as "in loop"
-
-type List struct {
- Next *List
-}
-
-func foo145(l List) { // ERROR "foo145 l does not escape$"
- var p *List
- for p = &l; p.Next != nil; p = p.Next {
- }
-}
-
-func foo146(l List) { // ERROR "foo146 l does not escape$"
- var p *List
- p = &l
- for ; p.Next != nil; p = p.Next {
- }
-}
-
-func foo147(l List) { // ERROR "foo147 l does not escape$"
- var p *List
- p = &l
- for p.Next != nil {
- p = p.Next
- }
-}
-
-func foo148(l List) { // ERROR "foo148 l does not escape$"
- for p := &l; p.Next != nil; p = p.Next {
- }
-}
-
-// related: address of variable should have depth of variable, not of loop
-
-func foo149(l List) { // ERROR "foo149 l does not escape$"
- var p *List
- for {
- for p = &l; p.Next != nil; p = p.Next {
- }
- }
-}
-
-// issue 7934: missed ... if element type had no pointers
-
-var save150 []byte
-
-func foo150(x ...byte) { // ERROR "leaking param: x$"
- save150 = x
-}
-
-func bar150() {
- foo150(1, 2, 3) // ERROR "... argument escapes to heap$"
-}
-
-// issue 7931: bad handling of slice of array
-
-var save151 *int
-
-func foo151(x *int) { // ERROR "leaking param: x$"
- save151 = x
-}
-
-func bar151() {
- var a [64]int // ERROR "moved to heap: a$"
- a[4] = 101
- foo151(&(&a)[4:8][0])
-}
-
-func bar151b() {
- var a [10]int // ERROR "moved to heap: a$"
- b := a[:]
- foo151(&b[4:8][0])
-}
-
-func bar151c() {
- var a [64]int // ERROR "moved to heap: a$"
- a[4] = 101
- foo151(&(&a)[4:8:8][0])
-}
-
-func bar151d() {
- var a [10]int // ERROR "moved to heap: a$"
- b := a[:]
- foo151(&b[4:8:8][0])
-}
-
-// issue 8120
-
-type U struct {
- s *string
-}
-
-func (u *U) String() *string { // ERROR "leaking param: u to result ~r0 level=1$"
- return u.s
-}
-
-type V struct {
- s *string
-}
-
-// BAD -- level of leak ought to be 0
-func NewV(u U) *V { // ERROR "leaking param: u to result ~r1 level=-1"
- return &V{u.String()} // ERROR "&V literal escapes to heap$"
-}
-
-func foo152() {
- a := "a" // ERROR "moved to heap: a$"
- u := U{&a}
- v := NewV(u)
- println(v)
-}
-
-// issue 8176 - &x in type switch body not marked as escaping
-
-func foo153(v interface{}) *int { // ERROR "leaking param: v to result ~r1 level=-1$"
- switch x := v.(type) {
- case int: // ERROR "moved to heap: x$"
- return &x
- }
- panic(0)
-}
-
-// issue 8185 - &result escaping into result
-
-func f() (x int, y *int) { // ERROR "moved to heap: x$"
- y = &x
- return
-}
-
-func g() (x interface{}) { // ERROR "moved to heap: x$"
- x = &x // ERROR "&x escapes to heap$"
- return
-}
-
-var sink interface{}
-
-type Lit struct {
- p *int
-}
-
-func ptrlitNoescape() {
- // Both literal and element do not escape.
- i := 0
- x := &Lit{&i} // ERROR "ptrlitNoescape &Lit literal does not escape$"
- _ = x
-}
-
-func ptrlitNoEscape2() {
- // Literal does not escape, but element does.
- i := 0 // ERROR "moved to heap: i$"
- x := &Lit{&i} // ERROR "ptrlitNoEscape2 &Lit literal does not escape$"
- sink = *x // ERROR "\*x escapes to heap$"
-}
-
-func ptrlitEscape() {
- // Both literal and element escape.
- i := 0 // ERROR "moved to heap: i$"
- x := &Lit{&i} // ERROR "&Lit literal escapes to heap$"
- sink = x // ERROR "x escapes to heap$"
-}
-
-// self-assignments
-
-type Buffer struct {
- arr [64]byte
- arrPtr *[64]byte
- buf1 []byte
- buf2 []byte
- str1 string
- str2 string
-}
-
-func (b *Buffer) foo() { // ERROR "\(\*Buffer\).foo b does not escape$"
- b.buf1 = b.buf1[1:2] // ERROR "\(\*Buffer\).foo ignoring self-assignment in b.buf1 = b.buf1\[1:2\]$"
- b.buf1 = b.buf1[1:2:3] // ERROR "\(\*Buffer\).foo ignoring self-assignment in b.buf1 = b.buf1\[1:2:3\]$"
- b.buf1 = b.buf2[1:2] // ERROR "\(\*Buffer\).foo ignoring self-assignment in b.buf1 = b.buf2\[1:2\]$"
- b.buf1 = b.buf2[1:2:3] // ERROR "\(\*Buffer\).foo ignoring self-assignment in b.buf1 = b.buf2\[1:2:3\]$"
-}
-
-func (b *Buffer) bar() { // ERROR "leaking param: b$"
- b.buf1 = b.arr[1:2]
-}
-
-func (b *Buffer) arrayPtr() { // ERROR "\(\*Buffer\).arrayPtr b does not escape"
- b.buf1 = b.arrPtr[1:2] // ERROR "\(\*Buffer\).arrayPtr ignoring self-assignment in b.buf1 = b.arrPtr\[1:2\]$"
- b.buf1 = b.arrPtr[1:2:3] // ERROR "\(\*Buffer\).arrayPtr ignoring self-assignment in b.buf1 = b.arrPtr\[1:2:3\]$"
-}
-
-func (b *Buffer) baz() { // ERROR "\(\*Buffer\).baz b does not escape$"
- b.str1 = b.str1[1:2] // ERROR "\(\*Buffer\).baz ignoring self-assignment in b.str1 = b.str1\[1:2\]$"
- b.str1 = b.str2[1:2] // ERROR "\(\*Buffer\).baz ignoring self-assignment in b.str1 = b.str2\[1:2\]$"
-}
-
-func (b *Buffer) bat() { // ERROR "leaking param content: b$"
- o := new(Buffer) // ERROR "new\(Buffer\) escapes to heap$"
- o.buf1 = b.buf1[1:2]
- sink = o // ERROR "o escapes to heap$"
-}
-
-func quux(sp *string, bp *[]byte) { // ERROR "quux bp does not escape$" "quux sp does not escape$"
- *sp = (*sp)[1:2] // ERROR "quux ignoring self-assignment in \*sp = \(\*sp\)\[1:2\]$"
- *bp = (*bp)[1:2] // ERROR "quux ignoring self-assignment in \*bp = \(\*bp\)\[1:2\]$"
-}
-
-type StructWithString struct {
- p *int
- s string
-}
-
-// This is escape analysis false negative.
-// We assign the pointer to x.p but leak x.s. Escape analysis coarsens flows
-// to just x, and thus &i looks escaping.
-func fieldFlowTracking() {
- var x StructWithString
- i := 0 // ERROR "moved to heap: i$"
- x.p = &i
- sink = x.s // ERROR "x.s escapes to heap$"
-}
-
-// String operations.
-
-func slicebytetostring0() {
- b := make([]byte, 20) // ERROR "slicebytetostring0 make\(\[\]byte, 20\) does not escape$"
- s := string(b) // ERROR "slicebytetostring0 string\(b\) does not escape$"
- _ = s
-}
-
-func slicebytetostring1() {
- b := make([]byte, 20) // ERROR "slicebytetostring1 make\(\[\]byte, 20\) does not escape$"
- s := string(b) // ERROR "slicebytetostring1 string\(b\) does not escape$"
- s1 := s[0:1]
- _ = s1
-}
-
-func slicebytetostring2() {
- b := make([]byte, 20) // ERROR "slicebytetostring2 make\(\[\]byte, 20\) does not escape$"
- s := string(b) // ERROR "string\(b\) escapes to heap$"
- s1 := s[0:1] // ERROR "moved to heap: s1$"
- sink = &s1 // ERROR "&s1 escapes to heap$"
-}
-
-func slicebytetostring3() {
- b := make([]byte, 20) // ERROR "slicebytetostring3 make\(\[\]byte, 20\) does not escape$"
- s := string(b) // ERROR "string\(b\) escapes to heap$"
- s1 := s[0:1]
- sink = s1 // ERROR "s1 escapes to heap$"
-}
-
-func addstr0() {
- s0 := "a"
- s1 := "b"
- s := s0 + s1 // ERROR "addstr0 s0 \+ s1 does not escape$"
- _ = s
-}
-
-func addstr1() {
- s0 := "a"
- s1 := "b"
- s := "c"
- s += s0 + s1 // ERROR "addstr1 s0 \+ s1 does not escape$"
- _ = s
-}
-
-func addstr2() {
- b := make([]byte, 20) // ERROR "addstr2 make\(\[\]byte, 20\) does not escape$"
- s0 := "a"
- s := string(b) + s0 // ERROR "addstr2 string\(b\) \+ s0 does not escape$" "addstr2 string\(b\) does not escape$"
- _ = s
-}
-
-func addstr3() {
- s0 := "a"
- s1 := "b"
- s := s0 + s1 // ERROR "s0 \+ s1 escapes to heap$"
- s2 := s[0:1]
- sink = s2 // ERROR "s2 escapes to heap$"
-}
-
-func intstring0() bool {
- // string does not escape
- x := '0'
- s := string(x) // ERROR "intstring0 string\(x\) does not escape$"
- return s == "0"
-}
-
-func intstring1() string {
- // string does not escape, but the buffer does
- x := '0'
- s := string(x) // ERROR "string\(x\) escapes to heap$"
- return s
-}
-
-func intstring2() {
- // string escapes to heap
- x := '0'
- s := string(x) // ERROR "moved to heap: s$" "string\(x\) escapes to heap$"
- sink = &s // ERROR "&s escapes to heap$"
-}
-
-func stringtoslicebyte0() {
- s := "foo"
- x := []byte(s) // ERROR "stringtoslicebyte0 \(\[\]byte\)\(s\) does not escape$"
- _ = x
-}
-
-func stringtoslicebyte1() []byte {
- s := "foo"
- return []byte(s) // ERROR "\(\[\]byte\)\(s\) escapes to heap$"
-}
-
-func stringtoslicebyte2() {
- s := "foo"
- sink = []byte(s) // ERROR "\(\[\]byte\)\(s\) escapes to heap$"
-}
-
-func stringtoslicerune0() {
- s := "foo"
- x := []rune(s) // ERROR "stringtoslicerune0 \(\[\]rune\)\(s\) does not escape$"
- _ = x
-}
-
-func stringtoslicerune1() []rune {
- s := "foo"
- return []rune(s) // ERROR "\(\[\]rune\)\(s\) escapes to heap$"
-}
-
-func stringtoslicerune2() {
- s := "foo"
- sink = []rune(s) // ERROR "\(\[\]rune\)\(s\) escapes to heap$"
-}
-
-func slicerunetostring0() {
- r := []rune{1, 2, 3} // ERROR "slicerunetostring0 \[\]rune literal does not escape$"
- s := string(r) // ERROR "slicerunetostring0 string\(r\) does not escape$"
- _ = s
-}
-
-func slicerunetostring1() string {
- r := []rune{1, 2, 3} // ERROR "slicerunetostring1 \[\]rune literal does not escape$"
- return string(r) // ERROR "string\(r\) escapes to heap$"
-}
-
-func slicerunetostring2() {
- r := []rune{1, 2, 3} // ERROR "slicerunetostring2 \[\]rune literal does not escape$"
- sink = string(r) // ERROR "string\(r\) escapes to heap$"
-}
-
-func makemap0() {
- m := make(map[int]int) // ERROR "makemap0 make\(map\[int\]int\) does not escape$"
- m[0] = 0
- m[1]++
- delete(m, 1)
- sink = m[0] // ERROR "m\[0\] escapes to heap$"
-}
-
-func makemap1() map[int]int {
- return make(map[int]int) // ERROR "make\(map\[int\]int\) escapes to heap$"
-}
-
-func makemap2() {
- m := make(map[int]int) // ERROR "make\(map\[int\]int\) escapes to heap$"
- sink = m // ERROR "m escapes to heap$"
-}
-
-func nonescapingEface(m map[interface{}]bool) bool { // ERROR "nonescapingEface m does not escape$"
- return m["foo"] // ERROR "nonescapingEface .foo. does not escape$"
-}
-
-func nonescapingIface(m map[M]bool) bool { // ERROR "nonescapingIface m does not escape$"
- return m[MV(0)] // ERROR "nonescapingIface MV\(0\) does not escape$"
-}
-
-func issue10353() {
- x := new(int) // ERROR "new\(int\) escapes to heap$"
- issue10353a(x)()
-}
-
-func issue10353a(x *int) func() { // ERROR "leaking param: x to result ~r1 level=-1$"
- return func() { // ERROR "func literal escapes to heap$"
- println(*x)
- }
-}
-
-func issue10353b() {
- var f func()
- for {
- x := new(int) // ERROR "new\(int\) escapes to heap$"
- f = func() { // ERROR "func literal escapes to heap$"
- println(*x)
- }
- }
- _ = f
-}
-
-func issue11387(x int) func() int {
- f := func() int { return x } // ERROR "func literal escapes to heap"
- slice1 := []func() int{f} // ERROR "\[\].* does not escape"
- slice2 := make([]func() int, 1) // ERROR "make\(.*\) does not escape"
- copy(slice2, slice1)
- return slice2[0]
-}
-
-func issue12397(x, y int) { // ERROR "moved to heap: y$"
- // x does not escape below, because all relevant code is dead.
- if false {
- gxx = &x
- } else {
- gxx = &y
- }
-
- if true {
- gxx = &y
- } else {
- gxx = &x
- }
-}
+++ /dev/null
-// errorcheck -0 -N -m -l -newescape=false
-
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Test, using compiler diagnostic flags, that the escape analysis is working.
-// Compiles but does not run. Inlining is disabled.
-// Registerization is disabled too (-N), which should
-// have no effect on escape analysis.
-
-package foo
-
-import (
- "fmt"
- "unsafe"
-)
-
-var gxx *int
-
-func foo1(x int) { // ERROR "moved to heap: x$"
- gxx = &x
-}
-
-func foo2(yy *int) { // ERROR "leaking param: yy$"
- gxx = yy
-}
-
-func foo3(x int) *int { // ERROR "moved to heap: x$"
- return &x
-}
-
-type T *T
-
-func foo3b(t T) { // ERROR "leaking param: t$"
- *t = t
-}
-
-// xx isn't going anywhere, so use of yy is ok
-func foo4(xx, yy *int) { // ERROR "foo4 xx does not escape$" "foo4 yy does not escape$"
- xx = yy
-}
-
-// xx isn't going anywhere, so taking address of yy is ok
-func foo5(xx **int, yy *int) { // ERROR "foo5 xx does not escape$" "foo5 yy does not escape$"
- xx = &yy
-}
-
-func foo6(xx **int, yy *int) { // ERROR "foo6 xx does not escape$" "leaking param: yy$"
- *xx = yy
-}
-
-func foo7(xx **int, yy *int) { // ERROR "foo7 xx does not escape$" "foo7 yy does not escape$"
- **xx = *yy
-}
-
-func foo8(xx, yy *int) int { // ERROR "foo8 xx does not escape$" "foo8 yy does not escape$"
- xx = yy
- return *xx
-}
-
-func foo9(xx, yy *int) *int { // ERROR "leaking param: xx to result ~r2 level=0$" "leaking param: yy to result ~r2 level=0$"
- xx = yy
- return xx
-}
-
-func foo10(xx, yy *int) { // ERROR "foo10 xx does not escape$" "foo10 yy does not escape$"
- *xx = *yy
-}
-
-func foo11() int {
- x, y := 0, 42
- xx := &x
- yy := &y
- *xx = *yy
- return x
-}
-
-var xxx **int
-
-func foo12(yyy **int) { // ERROR "leaking param: yyy$"
- xxx = yyy
-}
-
-// Must treat yyy as leaking because *yyy leaks, and the escape analysis
-// summaries in exported metadata do not distinguish these two cases.
-func foo13(yyy **int) { // ERROR "leaking param content: yyy$"
- *xxx = *yyy
-}
-
-func foo14(yyy **int) { // ERROR "foo14 yyy does not escape$"
- **xxx = **yyy
-}
-
-func foo15(yy *int) { // ERROR "moved to heap: yy$"
- xxx = &yy
-}
-
-func foo16(yy *int) { // ERROR "leaking param: yy$"
- *xxx = yy
-}
-
-func foo17(yy *int) { // ERROR "foo17 yy does not escape$"
- **xxx = *yy
-}
-
-func foo18(y int) { // ERROR "moved to heap: y$"
- *xxx = &y
-}
-
-func foo19(y int) {
- **xxx = y
-}
-
-type Bar struct {
- i int
- ii *int
-}
-
-func NewBar() *Bar {
- return &Bar{42, nil} // ERROR "&Bar literal escapes to heap$"
-}
-
-func NewBarp(x *int) *Bar { // ERROR "leaking param: x to result ~r1 level=-1$"
- return &Bar{42, x} // ERROR "&Bar literal escapes to heap$"
-}
-
-func NewBarp2(x *int) *Bar { // ERROR "NewBarp2 x does not escape$"
- return &Bar{*x, nil} // ERROR "&Bar literal escapes to heap$"
-}
-
-func (b *Bar) NoLeak() int { // ERROR "\(\*Bar\).NoLeak b does not escape$"
- return *(b.ii)
-}
-
-func (b *Bar) Leak() *int { // ERROR "leaking param: b to result ~r0 level=0$"
- return &b.i
-}
-
-func (b *Bar) AlsoNoLeak() *int { // ERROR "leaking param: b to result ~r0 level=1$"
- return b.ii
-}
-
-func (b Bar) AlsoLeak() *int { // ERROR "leaking param: b to result ~r0 level=0$"
- return b.ii
-}
-
-func (b Bar) LeaksToo() *int { // ERROR "leaking param: b to result ~r0 level=0$"
- v := 0 // ERROR "moved to heap: v$"
- b.ii = &v
- return b.ii
-}
-
-func (b *Bar) LeaksABit() *int { // ERROR "leaking param: b to result ~r0 level=1$"
- v := 0 // ERROR "moved to heap: v$"
- b.ii = &v
- return b.ii
-}
-
-func (b Bar) StillNoLeak() int { // ERROR "Bar.StillNoLeak b does not escape$"
- v := 0
- b.ii = &v
- return b.i
-}
-
-func goLeak(b *Bar) { // ERROR "leaking param: b$"
- go b.NoLeak()
-}
-
-type Bar2 struct {
- i [12]int
- ii []int
-}
-
-func NewBar2() *Bar2 {
- return &Bar2{[12]int{42}, nil} // ERROR "&Bar2 literal escapes to heap$"
-}
-
-func (b *Bar2) NoLeak() int { // ERROR "\(\*Bar2\).NoLeak b does not escape$"
- return b.i[0]
-}
-
-func (b *Bar2) Leak() []int { // ERROR "leaking param: b to result ~r0 level=0$"
- return b.i[:]
-}
-
-func (b *Bar2) AlsoNoLeak() []int { // ERROR "leaking param: b to result ~r0 level=1$"
- return b.ii[0:1]
-}
-
-func (b Bar2) AgainNoLeak() [12]int { // ERROR "Bar2.AgainNoLeak b does not escape$"
- return b.i
-}
-
-func (b *Bar2) LeakSelf() { // ERROR "leaking param: b$"
- b.ii = b.i[0:4]
-}
-
-func (b *Bar2) LeakSelf2() { // ERROR "leaking param: b$"
- var buf []int
- buf = b.i[0:]
- b.ii = buf
-}
-
-func foo21() func() int {
- x := 42
- return func() int { // ERROR "func literal escapes to heap$"
- return x
- }
-}
-
-func foo21a() func() int {
- x := 42 // ERROR "moved to heap: x$"
- return func() int { // ERROR "func literal escapes to heap$"
- x++
- return x
- }
-}
-
-func foo22() int {
- x := 42
- return func() int { // ERROR "foo22 func literal does not escape$"
- return x
- }()
-}
-
-func foo23(x int) func() int {
- return func() int { // ERROR "func literal escapes to heap$"
- return x
- }
-}
-
-func foo23a(x int) func() int {
- f := func() int { // ERROR "func literal escapes to heap$"
- return x
- }
- return f
-}
-
-func foo23b(x int) *(func() int) {
- f := func() int { return x } // ERROR "func literal escapes to heap$" "moved to heap: f$"
- return &f
-}
-
-func foo23c(x int) func() int { // ERROR "moved to heap: x$"
- return func() int { // ERROR "func literal escapes to heap$"
- x++
- return x
- }
-}
-
-func foo24(x int) int {
- return func() int { // ERROR "foo24 func literal does not escape$"
- return x
- }()
-}
-
-var x *int
-
-func fooleak(xx *int) int { // ERROR "leaking param: xx$"
- x = xx
- return *x
-}
-
-func foonoleak(xx *int) int { // ERROR "foonoleak xx does not escape$"
- return *x + *xx
-}
-
-func foo31(x int) int { // ERROR "moved to heap: x$"
- return fooleak(&x)
-}
-
-func foo32(x int) int {
- return foonoleak(&x)
-}
-
-type Foo struct {
- xx *int
- x int
-}
-
-var F Foo
-var pf *Foo
-
-func (f *Foo) fooleak() { // ERROR "leaking param: f$"
- pf = f
-}
-
-func (f *Foo) foonoleak() { // ERROR "\(\*Foo\).foonoleak f does not escape$"
- F.x = f.x
-}
-
-func (f *Foo) Leak() { // ERROR "leaking param: f$"
- f.fooleak()
-}
-
-func (f *Foo) NoLeak() { // ERROR "\(\*Foo\).NoLeak f does not escape$"
- f.foonoleak()
-}
-
-func foo41(x int) { // ERROR "moved to heap: x$"
- F.xx = &x
-}
-
-func (f *Foo) foo42(x int) { // ERROR "\(\*Foo\).foo42 f does not escape$" "moved to heap: x$"
- f.xx = &x
-}
-
-func foo43(f *Foo, x int) { // ERROR "foo43 f does not escape$" "moved to heap: x$"
- f.xx = &x
-}
-
-func foo44(yy *int) { // ERROR "leaking param: yy$"
- F.xx = yy
-}
-
-func (f *Foo) foo45() { // ERROR "\(\*Foo\).foo45 f does not escape$"
- F.x = f.x
-}
-
-// See foo13 above for explanation of why f leaks.
-func (f *Foo) foo46() { // ERROR "leaking param content: f$"
- F.xx = f.xx
-}
-
-func (f *Foo) foo47() { // ERROR "leaking param: f$"
- f.xx = &f.x
-}
-
-var ptrSlice []*int
-
-func foo50(i *int) { // ERROR "leaking param: i$"
- ptrSlice[0] = i
-}
-
-var ptrMap map[*int]*int
-
-func foo51(i *int) { // ERROR "leaking param: i$"
- ptrMap[i] = i
-}
-
-func indaddr1(x int) *int { // ERROR "moved to heap: x$"
- return &x
-}
-
-func indaddr2(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
- return *&x
-}
-
-func indaddr3(x *int32) *int { // ERROR "leaking param: x to result ~r1 level=0$"
- return *(**int)(unsafe.Pointer(&x))
-}
-
-// From package math:
-
-func Float32bits(f float32) uint32 {
- return *(*uint32)(unsafe.Pointer(&f))
-}
-
-func Float32frombits(b uint32) float32 {
- return *(*float32)(unsafe.Pointer(&b))
-}
-
-func Float64bits(f float64) uint64 {
- return *(*uint64)(unsafe.Pointer(&f))
-}
-
-func Float64frombits(b uint64) float64 {
- return *(*float64)(unsafe.Pointer(&b))
-}
-
-// contrast with
-func float64bitsptr(f float64) *uint64 { // ERROR "moved to heap: f$"
- return (*uint64)(unsafe.Pointer(&f))
-}
-
-func float64ptrbitsptr(f *float64) *uint64 { // ERROR "leaking param: f to result ~r1 level=0$"
- return (*uint64)(unsafe.Pointer(f))
-}
-
-func typesw(i interface{}) *int { // ERROR "leaking param: i to result ~r1 level=0$"
- switch val := i.(type) {
- case *int:
- return val
- case *int8:
- v := int(*val) // ERROR "moved to heap: v$"
- return &v
- }
- return nil
-}
-
-func exprsw(i *int) *int { // ERROR "leaking param: i to result ~r1 level=0$"
- switch j := i; *j + 110 {
- case 12:
- return j
- case 42:
- return nil
- }
- return nil
-
-}
-
-// assigning to an array element is like assigning to the array
-func foo60(i *int) *int { // ERROR "leaking param: i to result ~r1 level=0$"
- var a [12]*int
- a[0] = i
- return a[1]
-}
-
-func foo60a(i *int) *int { // ERROR "foo60a i does not escape$"
- var a [12]*int
- a[0] = i
- return nil
-}
-
-// assigning to a struct field is like assigning to the struct
-func foo61(i *int) *int { // ERROR "leaking param: i to result ~r1 level=0$"
- type S struct {
- a, b *int
- }
- var s S
- s.a = i
- return s.b
-}
-
-func foo61a(i *int) *int { // ERROR "foo61a i does not escape$"
- type S struct {
- a, b *int
- }
- var s S
- s.a = i
- return nil
-}
-
-// assigning to a struct field is like assigning to the struct but
-// here this subtlety is lost, since s.a counts as an assignment to a
-// track-losing dereference.
-func foo62(i *int) *int { // ERROR "leaking param: i$"
- type S struct {
- a, b *int
- }
- s := new(S) // ERROR "foo62 new\(S\) does not escape$"
- s.a = i
- return nil // s.b
-}
-
-type M interface {
- M()
-}
-
-func foo63(m M) { // ERROR "foo63 m does not escape$"
-}
-
-func foo64(m M) { // ERROR "leaking param: m$"
- m.M()
-}
-
-func foo64b(m M) { // ERROR "leaking param: m$"
- defer m.M()
-}
-
-type MV int
-
-func (MV) M() {}
-
-func foo65() {
- var mv MV
- foo63(&mv) // ERROR "foo65 &mv does not escape$"
-}
-
-func foo66() {
- var mv MV // ERROR "moved to heap: mv$"
- foo64(&mv) // ERROR "&mv escapes to heap$"
-}
-
-func foo67() {
- var mv MV
- foo63(mv) // ERROR "foo67 mv does not escape$"
-}
-
-func foo68() {
- var mv MV
- // escapes but it's an int so irrelevant
- foo64(mv) // ERROR "mv escapes to heap$"
-}
-
-func foo69(m M) { // ERROR "leaking param: m$"
- foo64(m)
-}
-
-func foo70(mv1 *MV, m M) { // ERROR "leaking param: m$" "leaking param: mv1$"
- m = mv1 // ERROR "mv1 escapes to heap$"
- foo64(m)
-}
-
-func foo71(x *int) []*int { // ERROR "leaking param: x$"
- var y []*int
- y = append(y, x)
- return y
-}
-
-func foo71a(x int) []*int { // ERROR "moved to heap: x$"
- var y []*int
- y = append(y, &x)
- return y
-}
-
-func foo72() {
- var x int
- var y [1]*int
- y[0] = &x
-}
-
-func foo72aa() [10]*int {
- var x int // ERROR "moved to heap: x$"
- var y [10]*int
- y[0] = &x
- return y
-}
-
-func foo72a() {
- var y [10]*int
- for i := 0; i < 10; i++ {
- // escapes its scope
- x := i // ERROR "moved to heap: x$"
- y[i] = &x
- }
- return
-}
-
-func foo72b() [10]*int {
- var y [10]*int
- for i := 0; i < 10; i++ {
- x := i // ERROR "moved to heap: x$"
- y[i] = &x
- }
- return y
-}
-
-// issue 2145
-func foo73() {
- s := []int{3, 2, 1} // ERROR "foo73 \[\]int literal does not escape$"
- for _, v := range s {
- vv := v
- // actually just escapes its scope
- defer func() { // ERROR "func literal escapes to heap$"
- println(vv)
- }()
- }
-}
-
-func foo731() {
- s := []int{3, 2, 1} // ERROR "foo731 \[\]int literal does not escape$"
- for _, v := range s {
- vv := v // ERROR "moved to heap: vv$"
- // actually just escapes its scope
- defer func() { // ERROR "func literal escapes to heap$"
- vv = 42
- println(vv)
- }()
- }
-}
-
-func foo74() {
- s := []int{3, 2, 1} // ERROR "foo74 \[\]int literal does not escape$"
- for _, v := range s {
- vv := v
- // actually just escapes its scope
- fn := func() { // ERROR "func literal escapes to heap$"
- println(vv)
- }
- defer fn()
- }
-}
-
-func foo74a() {
- s := []int{3, 2, 1} // ERROR "foo74a \[\]int literal does not escape$"
- for _, v := range s {
- vv := v // ERROR "moved to heap: vv$"
- // actually just escapes its scope
- fn := func() { // ERROR "func literal escapes to heap$"
- vv += 1
- println(vv)
- }
- defer fn()
- }
-}
-
-// issue 3975
-func foo74b() {
- var array [3]func()
- s := []int{3, 2, 1} // ERROR "foo74b \[\]int literal does not escape$"
- for i, v := range s {
- vv := v
- // actually just escapes its scope
- array[i] = func() { // ERROR "func literal escapes to heap$"
- println(vv)
- }
- }
-}
-
-func foo74c() {
- var array [3]func()
- s := []int{3, 2, 1} // ERROR "foo74c \[\]int literal does not escape$"
- for i, v := range s {
- vv := v // ERROR "moved to heap: vv$"
- // actually just escapes its scope
- array[i] = func() { // ERROR "func literal escapes to heap$"
- println(&vv)
- }
- }
-}
-
-func myprint(y *int, x ...interface{}) *int { // ERROR "leaking param: y to result ~r2 level=0$" "myprint x does not escape$"
- return y
-}
-
-func myprint1(y *int, x ...interface{}) *interface{} { // ERROR "leaking param: x to result ~r2 level=0$" "myprint1 y does not escape$"
- return &x[0]
-}
-
-func foo75(z *int) { // ERROR "foo75 z does not escape$"
- myprint(z, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "foo75 ... argument does not escape$"
-}
-
-func foo75a(z *int) { // ERROR "foo75a z does not escape$"
- myprint1(z, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "foo75a ... argument does not escape$"
-}
-
-func foo75esc(z *int) { // ERROR "leaking param: z$"
- gxx = myprint(z, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "foo75esc ... argument does not escape$"
-}
-
-func foo75aesc(z *int) { // ERROR "foo75aesc z does not escape$"
- var ppi **interface{} // assignments to pointer dereferences lose track
- *ppi = myprint1(z, 1, 2, 3) // ERROR "... argument escapes to heap$" "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$"
-}
-
-func foo75aesc1(z *int) { // ERROR "foo75aesc1 z does not escape$"
- sink = myprint1(z, 1, 2, 3) // ERROR "... argument escapes to heap$" "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$" "myprint1\(z, 1, 2, 3\) escapes to heap$"
-}
-
-func foo76(z *int) { // ERROR "z does not escape"
- myprint(nil, z) // ERROR "foo76 ... argument does not escape$" "z does not escape"
-}
-
-func foo76a(z *int) { // ERROR "z does not escape"
- myprint1(nil, z) // ERROR "foo76a ... argument does not escape$" "z does not escape"
-}
-
-func foo76b() {
- myprint(nil, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "foo76b ... argument does not escape$"
-}
-
-func foo76c() {
- myprint1(nil, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "foo76c ... argument does not escape$"
-}
-
-func foo76d() {
- defer myprint(nil, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "foo76d ... argument does not escape$"
-}
-
-func foo76e() {
- defer myprint1(nil, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "foo76e ... argument does not escape$"
-}
-
-func foo76f() {
- for {
- // TODO: This one really only escapes its scope, but we don't distinguish yet.
- defer myprint(nil, 1, 2, 3) // ERROR "... argument escapes to heap$" "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$"
- }
-}
-
-func foo76g() {
- for {
- defer myprint1(nil, 1, 2, 3) // ERROR "... argument escapes to heap$" "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$"
- }
-}
-
-func foo77(z []interface{}) { // ERROR "foo77 z does not escape$"
- myprint(nil, z...) // z does not escape
-}
-
-func foo77a(z []interface{}) { // ERROR "foo77a z does not escape$"
- myprint1(nil, z...)
-}
-
-func foo77b(z []interface{}) { // ERROR "leaking param: z$"
- var ppi **interface{}
- *ppi = myprint1(nil, z...)
-}
-
-func foo77c(z []interface{}) { // ERROR "leaking param: z$"
- sink = myprint1(nil, z...) // ERROR "myprint1\(nil, z...\) escapes to heap$"
-}
-
-func dotdotdot() {
- i := 0
- myprint(nil, &i) // ERROR "&i does not escape" "dotdotdot ... argument does not escape$"
-
- j := 0
- myprint1(nil, &j) // ERROR "&j does not escape" "dotdotdot ... argument does not escape$"
-}
-
-func foo78(z int) *int { // ERROR "moved to heap: z$"
- return &z
-}
-
-func foo78a(z int) *int { // ERROR "moved to heap: z$"
- y := &z
- x := &y
- return *x // really return y
-}
-
-func foo79() *int {
- return new(int) // ERROR "new\(int\) escapes to heap$"
-}
-
-func foo80() *int {
- var z *int
- for {
- // Really just escapes its scope but we don't distinguish
- z = new(int) // ERROR "new\(int\) escapes to heap$"
- }
- _ = z
- return nil
-}
-
-func foo81() *int {
- for {
- z := new(int) // ERROR "foo81 new\(int\) does not escape$"
- _ = z
- }
- return nil
-}
-
-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$"
-
-func noop(x, y *int) {} // ERROR "noop x does not escape$" "noop y does not escape$"
-
-func foo82() {
- var x, y, z int // ERROR "moved to heap: x$" "moved to heap: y$" "moved to heap: z$"
- go noop(tee(&z))
- go noop(&x, &y)
- for {
- var u, v, w int // ERROR "moved to heap: u$" "moved to heap: v$" "moved to heap: w$"
- defer noop(tee(&u))
- defer noop(&v, &w)
- }
-}
-
-type Fooer interface {
- Foo()
-}
-
-type LimitedFooer struct {
- Fooer
- N int64
-}
-
-func LimitFooer(r Fooer, n int64) Fooer { // ERROR "leaking param: r to result ~r2 level=-1$"
- return &LimitedFooer{r, n} // ERROR "&LimitedFooer literal escapes to heap$"
-}
-
-func foo90(x *int) map[*int]*int { // ERROR "leaking param: x$"
- return map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int literal escapes to heap$"
-}
-
-func foo91(x *int) map[*int]*int { // ERROR "leaking param: x$"
- return map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int literal escapes to heap$"
-}
-
-func foo92(x *int) [2]*int { // ERROR "leaking param: x to result ~r1 level=0$"
- return [2]*int{x, nil}
-}
-
-// does not leak c
-func foo93(c chan *int) *int { // ERROR "foo93 c does not escape$"
- for v := range c {
- return v
- }
- return nil
-}
-
-// does not leak m
-func foo94(m map[*int]*int, b bool) *int { // ERROR "leaking param: m to result ~r2 level=1"
- for k, v := range m {
- if b {
- return k
- }
- return v
- }
- return nil
-}
-
-// does leak x
-func foo95(m map[*int]*int, x *int) { // ERROR "foo95 m does not escape$" "leaking param: x$"
- m[x] = x
-}
-
-// does not leak m but does leak content
-func foo96(m []*int) *int { // ERROR "leaking param: m to result ~r1 level=1"
- return m[0]
-}
-
-// does leak m
-func foo97(m [1]*int) *int { // ERROR "leaking param: m to result ~r1 level=0$"
- return m[0]
-}
-
-// does not leak m
-func foo98(m map[int]*int) *int { // ERROR "foo98 m does not escape$"
- return m[0]
-}
-
-// does leak m
-func foo99(m *[1]*int) []*int { // ERROR "leaking param: m to result ~r1 level=0$"
- return m[:]
-}
-
-// does not leak m
-func foo100(m []*int) *int { // ERROR "leaking param: m to result ~r1 level=1"
- for _, v := range m {
- return v
- }
- return nil
-}
-
-// does leak m
-func foo101(m [1]*int) *int { // ERROR "leaking param: m to result ~r1 level=0$"
- for _, v := range m {
- return v
- }
- return nil
-}
-
-// does not leak m
-func foo101a(m [1]*int) *int { // ERROR "foo101a m does not escape$"
- for i := range m { // ERROR "moved to heap: i$"
- return &i
- }
- return nil
-}
-
-// does leak x
-func foo102(m []*int, x *int) { // ERROR "foo102 m does not escape$" "leaking param: x$"
- m[0] = x
-}
-
-// does not leak x
-func foo103(m [1]*int, x *int) { // ERROR "foo103 m does not escape$" "foo103 x does not escape$"
- m[0] = x
-}
-
-var y []*int
-
-// does not leak x but does leak content
-func foo104(x []*int) { // ERROR "leaking param content: x"
- copy(y, x)
-}
-
-// does not leak x but does leak content
-func foo105(x []*int) { // ERROR "leaking param content: x"
- _ = append(y, x...)
-}
-
-// does leak x
-func foo106(x *int) { // ERROR "leaking param: x$"
- _ = append(y, x)
-}
-
-func foo107(x *int) map[*int]*int { // ERROR "leaking param: x$"
- return map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int literal escapes to heap$"
-}
-
-func foo108(x *int) map[*int]*int { // ERROR "leaking param: x$"
- return map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int literal escapes to heap$"
-}
-
-func foo109(x *int) *int { // ERROR "leaking param: x$"
- m := map[*int]*int{x: nil} // ERROR "foo109 map\[\*int\]\*int literal does not escape$"
- for k, _ := range m {
- return k
- }
- return nil
-}
-
-func foo110(x *int) *int { // ERROR "leaking param: x$"
- m := map[*int]*int{nil: x} // ERROR "foo110 map\[\*int\]\*int literal does not escape$"
- return m[nil]
-}
-
-func foo111(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0"
- m := []*int{x} // ERROR "foo111 \[\]\*int literal does not escape$"
- return m[0]
-}
-
-func foo112(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
- m := [1]*int{x}
- return m[0]
-}
-
-func foo113(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
- m := Bar{ii: x}
- return m.ii
-}
-
-func foo114(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
- m := &Bar{ii: x} // ERROR "foo114 &Bar literal does not escape$"
- return m.ii
-}
-
-func foo115(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
- return (*int)(unsafe.Pointer(uintptr(unsafe.Pointer(x)) + 1))
-}
-
-func foo116(b bool) *int {
- if b {
- x := 1 // ERROR "moved to heap: x$"
- return &x
- } else {
- y := 1 // ERROR "moved to heap: y$"
- return &y
- }
- return nil
-}
-
-func foo117(unknown func(interface{})) { // ERROR "foo117 unknown does not escape$"
- x := 1 // ERROR "moved to heap: x$"
- unknown(&x) // ERROR "&x escapes to heap$"
-}
-
-func foo118(unknown func(*int)) { // ERROR "foo118 unknown does not escape$"
- x := 1 // ERROR "moved to heap: x$"
- unknown(&x)
-}
-
-func external(*int)
-
-func foo119(x *int) { // ERROR "leaking param: x$"
- external(x)
-}
-
-func foo120() {
- // formerly exponential time analysis
-L1:
-L2:
-L3:
-L4:
-L5:
-L6:
-L7:
-L8:
-L9:
-L10:
-L11:
-L12:
-L13:
-L14:
-L15:
-L16:
-L17:
-L18:
-L19:
-L20:
-L21:
-L22:
-L23:
-L24:
-L25:
-L26:
-L27:
-L28:
-L29:
-L30:
-L31:
-L32:
-L33:
-L34:
-L35:
-L36:
-L37:
-L38:
-L39:
-L40:
-L41:
-L42:
-L43:
-L44:
-L45:
-L46:
-L47:
-L48:
-L49:
-L50:
-L51:
-L52:
-L53:
-L54:
-L55:
-L56:
-L57:
-L58:
-L59:
-L60:
-L61:
-L62:
-L63:
-L64:
-L65:
-L66:
-L67:
-L68:
-L69:
-L70:
-L71:
-L72:
-L73:
-L74:
-L75:
-L76:
-L77:
-L78:
-L79:
-L80:
-L81:
-L82:
-L83:
-L84:
-L85:
-L86:
-L87:
-L88:
-L89:
-L90:
-L91:
-L92:
-L93:
-L94:
-L95:
-L96:
-L97:
-L98:
-L99:
-L100:
- // use the labels to silence compiler errors
- goto L1
- goto L2
- goto L3
- goto L4
- goto L5
- goto L6
- goto L7
- goto L8
- goto L9
- goto L10
- goto L11
- goto L12
- goto L13
- goto L14
- goto L15
- goto L16
- goto L17
- goto L18
- goto L19
- goto L20
- goto L21
- goto L22
- goto L23
- goto L24
- goto L25
- goto L26
- goto L27
- goto L28
- goto L29
- goto L30
- goto L31
- goto L32
- goto L33
- goto L34
- goto L35
- goto L36
- goto L37
- goto L38
- goto L39
- goto L40
- goto L41
- goto L42
- goto L43
- goto L44
- goto L45
- goto L46
- goto L47
- goto L48
- goto L49
- goto L50
- goto L51
- goto L52
- goto L53
- goto L54
- goto L55
- goto L56
- goto L57
- goto L58
- goto L59
- goto L60
- goto L61
- goto L62
- goto L63
- goto L64
- goto L65
- goto L66
- goto L67
- goto L68
- goto L69
- goto L70
- goto L71
- goto L72
- goto L73
- goto L74
- goto L75
- goto L76
- goto L77
- goto L78
- goto L79
- goto L80
- goto L81
- goto L82
- goto L83
- goto L84
- goto L85
- goto L86
- goto L87
- goto L88
- goto L89
- goto L90
- goto L91
- goto L92
- goto L93
- goto L94
- goto L95
- goto L96
- goto L97
- goto L98
- goto L99
- goto L100
-}
-
-func foo121() {
- for i := 0; i < 10; i++ {
- defer myprint(nil, i) // ERROR "... argument escapes to heap$" "i escapes to heap$"
- go myprint(nil, i) // ERROR "... argument escapes to heap$" "i escapes to heap$"
- }
-}
-
-// same as foo121 but check across import
-func foo121b() {
- for i := 0; i < 10; i++ {
- defer fmt.Printf("%d", i) // ERROR "... argument escapes to heap$" "i escapes to heap$"
- go fmt.Printf("%d", i) // ERROR "... argument escapes to heap$" "i escapes to heap$"
- }
-}
-
-// a harmless forward jump
-func foo122() {
- var i *int
-
- goto L1
-L1:
- i = new(int) // ERROR "foo122 new\(int\) does not escape$"
- _ = i
-}
-
-// a backward jump, increases loopdepth
-func foo123() {
- var i *int
-
-L1:
- i = new(int) // ERROR "new\(int\) escapes to heap$"
-
- goto L1
- _ = i
-}
-
-func foo124(x **int) { // ERROR "foo124 x does not escape$"
- var i int // ERROR "moved to heap: i$"
- p := &i
- func() { // ERROR "foo124 func literal does not escape$"
- *x = p
- }()
-}
-
-func foo125(ch chan *int) { // ERROR "foo125 ch does not escape$"
- var i int // ERROR "moved to heap: i$"
- p := &i
- func() { // ERROR "foo125 func literal does not escape$"
- ch <- p
- }()
-}
-
-func foo126() {
- var px *int // loopdepth 0
- for {
- // loopdepth 1
- var i int // ERROR "moved to heap: i$"
- func() { // ERROR "foo126 func literal does not escape$"
- px = &i
- }()
- }
- _ = px
-}
-
-var px *int
-
-func foo127() {
- var i int // ERROR "moved to heap: i$"
- p := &i
- q := p
- px = q
-}
-
-func foo128() {
- var i int
- p := &i
- q := p
- _ = q
-}
-
-func foo129() {
- var i int // ERROR "moved to heap: i$"
- p := &i
- func() { // ERROR "foo129 func literal does not escape$"
- q := p
- func() { // ERROR "foo129.func1 func literal does not escape$"
- r := q
- px = r
- }()
- }()
-}
-
-func foo130() {
- for {
- var i int // ERROR "moved to heap: i$"
- func() { // ERROR "foo130 func literal does not escape$"
- px = &i
- }()
- }
-}
-
-func foo131() {
- var i int // ERROR "moved to heap: i$"
- func() { // ERROR "foo131 func literal does not escape$"
- px = &i
- }()
-}
-
-func foo132() {
- var i int // ERROR "moved to heap: i$"
- go func() { // ERROR "func literal escapes to heap$"
- px = &i
- }()
-}
-
-func foo133() {
- var i int // ERROR "moved to heap: i$"
- defer func() { // ERROR "foo133 func literal does not escape$"
- px = &i
- }()
-}
-
-func foo134() {
- var i int
- p := &i
- func() { // ERROR "foo134 func literal does not escape$"
- q := p
- func() { // ERROR "foo134.func1 func literal does not escape$"
- r := q
- _ = r
- }()
- }()
-}
-
-func foo135() {
- var i int // ERROR "moved to heap: i$"
- p := &i
- go func() { // ERROR "func literal escapes to heap$"
- q := p
- func() { // ERROR "foo135.func1 func literal does not escape$"
- r := q
- _ = r
- }()
- }()
-}
-
-func foo136() {
- var i int // ERROR "moved to heap: i$"
- p := &i
- go func() { // ERROR "func literal escapes to heap$"
- q := p
- func() { // ERROR "foo136.func1 func literal does not escape$"
- r := q
- px = r
- }()
- }()
-}
-
-func foo137() {
- var i int // ERROR "moved to heap: i$"
- p := &i
- func() { // ERROR "foo137 func literal does not escape$"
- q := p
- go func() { // ERROR "func literal escapes to heap$"
- r := q
- _ = r
- }()
- }()
-}
-
-func foo138() *byte {
- type T struct {
- x [1]byte
- }
- t := new(T) // ERROR "new\(T\) escapes to heap$"
- return &t.x[0]
-}
-
-func foo139() *byte {
- type T struct {
- x struct {
- y byte
- }
- }
- t := new(T) // ERROR "new\(T\) escapes to heap$"
- return &t.x.y
-}
-
-// issue 4751
-func foo140() interface{} {
- type T struct {
- X string
- }
- type U struct {
- X string
- T *T
- }
- t := &T{} // ERROR "&T literal escapes to heap$"
- return U{ // ERROR "U literal escapes to heap$"
- X: t.X,
- T: t,
- }
-}
-
-//go:noescape
-
-func F1([]byte)
-
-func F2([]byte)
-
-//go:noescape
-
-func F3(x []byte) // ERROR "F3 x does not escape$"
-
-func F4(x []byte)
-
-func G() {
- var buf1 [10]byte
- F1(buf1[:])
-
- var buf2 [10]byte // ERROR "moved to heap: buf2$"
- F2(buf2[:])
-
- var buf3 [10]byte
- F3(buf3[:])
-
- var buf4 [10]byte // ERROR "moved to heap: buf4$"
- F4(buf4[:])
-}
-
-type Tm struct {
- x int
-}
-
-func (t *Tm) M() { // ERROR "\(\*Tm\).M t does not escape$"
-}
-
-func foo141() {
- var f func()
-
- t := new(Tm) // ERROR "new\(Tm\) escapes to heap$"
- f = t.M // ERROR "foo141 t.M does not escape$"
- _ = f
-}
-
-var gf func()
-
-func foo142() {
- t := new(Tm) // ERROR "new\(Tm\) escapes to heap$"
- gf = t.M // ERROR "t.M escapes to heap$"
-}
-
-// issue 3888.
-func foo143() {
- for i := 0; i < 1000; i++ {
- func() { // ERROR "foo143 func literal does not escape$"
- for i := 0; i < 1; i++ {
- var t Tm
- t.M()
- }
- }()
- }
-}
-
-// issue 5773
-// Check that annotations take effect regardless of whether they
-// are before or after the use in the source code.
-
-//go:noescape
-
-func foo144a(*int)
-
-func foo144() {
- var x int
- foo144a(&x)
- var y int
- foo144b(&y)
-}
-
-//go:noescape
-
-func foo144b(*int)
-
-// issue 7313: for loop init should not be treated as "in loop"
-
-type List struct {
- Next *List
-}
-
-func foo145(l List) { // ERROR "foo145 l does not escape$"
- var p *List
- for p = &l; p.Next != nil; p = p.Next {
- }
-}
-
-func foo146(l List) { // ERROR "foo146 l does not escape$"
- var p *List
- p = &l
- for ; p.Next != nil; p = p.Next {
- }
-}
-
-func foo147(l List) { // ERROR "foo147 l does not escape$"
- var p *List
- p = &l
- for p.Next != nil {
- p = p.Next
- }
-}
-
-func foo148(l List) { // ERROR "foo148 l does not escape$"
- for p := &l; p.Next != nil; p = p.Next {
- }
-}
-
-// related: address of variable should have depth of variable, not of loop
-
-func foo149(l List) { // ERROR "foo149 l does not escape$"
- var p *List
- for {
- for p = &l; p.Next != nil; p = p.Next {
- }
- }
-}
-
-// issue 7934: missed ... if element type had no pointers
-
-var save150 []byte
-
-func foo150(x ...byte) { // ERROR "leaking param: x$"
- save150 = x
-}
-
-func bar150() {
- foo150(1, 2, 3) // ERROR "... argument escapes to heap$"
-}
-
-// issue 7931: bad handling of slice of array
-
-var save151 *int
-
-func foo151(x *int) { // ERROR "leaking param: x$"
- save151 = x
-}
-
-func bar151() {
- var a [64]int // ERROR "moved to heap: a$"
- a[4] = 101
- foo151(&(&a)[4:8][0])
-}
-
-func bar151b() {
- var a [10]int // ERROR "moved to heap: a$"
- b := a[:]
- foo151(&b[4:8][0])
-}
-
-func bar151c() {
- var a [64]int // ERROR "moved to heap: a$"
- a[4] = 101
- foo151(&(&a)[4:8:8][0])
-}
-
-func bar151d() {
- var a [10]int // ERROR "moved to heap: a$"
- b := a[:]
- foo151(&b[4:8:8][0])
-}
-
-// issue 8120
-
-type U struct {
- s *string
-}
-
-func (u *U) String() *string { // ERROR "leaking param: u to result ~r0 level=1$"
- return u.s
-}
-
-type V struct {
- s *string
-}
-
-// BAD -- level of leak ought to be 0
-func NewV(u U) *V { // ERROR "leaking param: u to result ~r1 level=-1"
- return &V{u.String()} // ERROR "&V literal escapes to heap$"
-}
-
-func foo152() {
- a := "a" // ERROR "moved to heap: a$"
- u := U{&a}
- v := NewV(u)
- println(v)
-}
-
-// issue 8176 - &x in type switch body not marked as escaping
-
-func foo153(v interface{}) *int { // ERROR "leaking param: v to result ~r1 level=-1$"
- switch x := v.(type) {
- case int: // ERROR "moved to heap: x$"
- return &x
- }
- panic(0)
-}
-
-// issue 8185 - &result escaping into result
-
-func f() (x int, y *int) { // ERROR "moved to heap: x$"
- y = &x
- return
-}
-
-func g() (x interface{}) { // ERROR "moved to heap: x$"
- x = &x // ERROR "&x escapes to heap$"
- return
-}
-
-var sink interface{}
-
-type Lit struct {
- p *int
-}
-
-func ptrlitNoescape() {
- // Both literal and element do not escape.
- i := 0
- x := &Lit{&i} // ERROR "ptrlitNoescape &Lit literal does not escape$"
- _ = x
-}
-
-func ptrlitNoEscape2() {
- // Literal does not escape, but element does.
- i := 0 // ERROR "moved to heap: i$"
- x := &Lit{&i} // ERROR "ptrlitNoEscape2 &Lit literal does not escape$"
- sink = *x // ERROR "\*x escapes to heap$"
-}
-
-func ptrlitEscape() {
- // Both literal and element escape.
- i := 0 // ERROR "moved to heap: i$"
- x := &Lit{&i} // ERROR "&Lit literal escapes to heap$"
- sink = x // ERROR "x escapes to heap$"
-}
-
-// self-assignments
-
-type Buffer struct {
- arr [64]byte
- arrPtr *[64]byte
- buf1 []byte
- buf2 []byte
- str1 string
- str2 string
-}
-
-func (b *Buffer) foo() { // ERROR "\(\*Buffer\).foo b does not escape$"
- b.buf1 = b.buf1[1:2] // ERROR "\(\*Buffer\).foo ignoring self-assignment in b.buf1 = b.buf1\[1:2\]$"
- b.buf1 = b.buf1[1:2:3] // ERROR "\(\*Buffer\).foo ignoring self-assignment in b.buf1 = b.buf1\[1:2:3\]$"
- b.buf1 = b.buf2[1:2] // ERROR "\(\*Buffer\).foo ignoring self-assignment in b.buf1 = b.buf2\[1:2\]$"
- b.buf1 = b.buf2[1:2:3] // ERROR "\(\*Buffer\).foo ignoring self-assignment in b.buf1 = b.buf2\[1:2:3\]$"
-}
-
-func (b *Buffer) bar() { // ERROR "leaking param: b$"
- b.buf1 = b.arr[1:2]
-}
-
-func (b *Buffer) arrayPtr() { // ERROR "\(\*Buffer\).arrayPtr b does not escape"
- b.buf1 = b.arrPtr[1:2] // ERROR "\(\*Buffer\).arrayPtr ignoring self-assignment in b.buf1 = b.arrPtr\[1:2\]$"
- b.buf1 = b.arrPtr[1:2:3] // ERROR "\(\*Buffer\).arrayPtr ignoring self-assignment in b.buf1 = b.arrPtr\[1:2:3\]$"
-}
-
-func (b *Buffer) baz() { // ERROR "\(\*Buffer\).baz b does not escape$"
- b.str1 = b.str1[1:2] // ERROR "\(\*Buffer\).baz ignoring self-assignment in b.str1 = b.str1\[1:2\]$"
- b.str1 = b.str2[1:2] // ERROR "\(\*Buffer\).baz ignoring self-assignment in b.str1 = b.str2\[1:2\]$"
-}
-
-func (b *Buffer) bat() { // ERROR "leaking param content: b$"
- o := new(Buffer) // ERROR "new\(Buffer\) escapes to heap$"
- o.buf1 = b.buf1[1:2]
- sink = o // ERROR "o escapes to heap$"
-}
-
-func quux(sp *string, bp *[]byte) { // ERROR "quux bp does not escape$" "quux sp does not escape$"
- *sp = (*sp)[1:2] // ERROR "quux ignoring self-assignment in \*sp = \(\*sp\)\[1:2\]$"
- *bp = (*bp)[1:2] // ERROR "quux ignoring self-assignment in \*bp = \(\*bp\)\[1:2\]$"
-}
-
-type StructWithString struct {
- p *int
- s string
-}
-
-// This is escape analysis false negative.
-// We assign the pointer to x.p but leak x.s. Escape analysis coarsens flows
-// to just x, and thus &i looks escaping.
-func fieldFlowTracking() {
- var x StructWithString
- i := 0 // ERROR "moved to heap: i$"
- x.p = &i
- sink = x.s // ERROR "x.s escapes to heap$"
-}
-
-// String operations.
-
-func slicebytetostring0() {
- b := make([]byte, 20) // ERROR "slicebytetostring0 make\(\[\]byte, 20\) does not escape$"
- s := string(b) // ERROR "slicebytetostring0 string\(b\) does not escape$"
- _ = s
-}
-
-func slicebytetostring1() {
- b := make([]byte, 20) // ERROR "slicebytetostring1 make\(\[\]byte, 20\) does not escape$"
- s := string(b) // ERROR "slicebytetostring1 string\(b\) does not escape$"
- s1 := s[0:1]
- _ = s1
-}
-
-func slicebytetostring2() {
- b := make([]byte, 20) // ERROR "slicebytetostring2 make\(\[\]byte, 20\) does not escape$"
- s := string(b) // ERROR "string\(b\) escapes to heap$"
- s1 := s[0:1] // ERROR "moved to heap: s1$"
- sink = &s1 // ERROR "&s1 escapes to heap$"
-}
-
-func slicebytetostring3() {
- b := make([]byte, 20) // ERROR "slicebytetostring3 make\(\[\]byte, 20\) does not escape$"
- s := string(b) // ERROR "string\(b\) escapes to heap$"
- s1 := s[0:1]
- sink = s1 // ERROR "s1 escapes to heap$"
-}
-
-func addstr0() {
- s0 := "a"
- s1 := "b"
- s := s0 + s1 // ERROR "addstr0 s0 \+ s1 does not escape$"
- _ = s
-}
-
-func addstr1() {
- s0 := "a"
- s1 := "b"
- s := "c"
- s += s0 + s1 // ERROR "addstr1 s0 \+ s1 does not escape$"
- _ = s
-}
-
-func addstr2() {
- b := make([]byte, 20) // ERROR "addstr2 make\(\[\]byte, 20\) does not escape$"
- s0 := "a"
- s := string(b) + s0 // ERROR "addstr2 string\(b\) \+ s0 does not escape$" "addstr2 string\(b\) does not escape$"
- _ = s
-}
-
-func addstr3() {
- s0 := "a"
- s1 := "b"
- s := s0 + s1 // ERROR "s0 \+ s1 escapes to heap$"
- s2 := s[0:1]
- sink = s2 // ERROR "s2 escapes to heap$"
-}
-
-func intstring0() bool {
- // string does not escape
- x := '0'
- s := string(x) // ERROR "intstring0 string\(x\) does not escape$"
- return s == "0"
-}
-
-func intstring1() string {
- // string does not escape, but the buffer does
- x := '0'
- s := string(x) // ERROR "string\(x\) escapes to heap$"
- return s
-}
-
-func intstring2() {
- // string escapes to heap
- x := '0'
- s := string(x) // ERROR "moved to heap: s$" "string\(x\) escapes to heap$"
- sink = &s // ERROR "&s escapes to heap$"
-}
-
-func stringtoslicebyte0() {
- s := "foo"
- x := []byte(s) // ERROR "stringtoslicebyte0 \(\[\]byte\)\(s\) does not escape$"
- _ = x
-}
-
-func stringtoslicebyte1() []byte {
- s := "foo"
- return []byte(s) // ERROR "\(\[\]byte\)\(s\) escapes to heap$"
-}
-
-func stringtoslicebyte2() {
- s := "foo"
- sink = []byte(s) // ERROR "\(\[\]byte\)\(s\) escapes to heap$"
-}
-
-func stringtoslicerune0() {
- s := "foo"
- x := []rune(s) // ERROR "stringtoslicerune0 \(\[\]rune\)\(s\) does not escape$"
- _ = x
-}
-
-func stringtoslicerune1() []rune {
- s := "foo"
- return []rune(s) // ERROR "\(\[\]rune\)\(s\) escapes to heap$"
-}
-
-func stringtoslicerune2() {
- s := "foo"
- sink = []rune(s) // ERROR "\(\[\]rune\)\(s\) escapes to heap$"
-}
-
-func slicerunetostring0() {
- r := []rune{1, 2, 3} // ERROR "slicerunetostring0 \[\]rune literal does not escape$"
- s := string(r) // ERROR "slicerunetostring0 string\(r\) does not escape$"
- _ = s
-}
-
-func slicerunetostring1() string {
- r := []rune{1, 2, 3} // ERROR "slicerunetostring1 \[\]rune literal does not escape$"
- return string(r) // ERROR "string\(r\) escapes to heap$"
-}
-
-func slicerunetostring2() {
- r := []rune{1, 2, 3} // ERROR "slicerunetostring2 \[\]rune literal does not escape$"
- sink = string(r) // ERROR "string\(r\) escapes to heap$"
-}
-
-func makemap0() {
- m := make(map[int]int) // ERROR "makemap0 make\(map\[int\]int\) does not escape$"
- m[0] = 0
- m[1]++
- delete(m, 1)
- sink = m[0] // ERROR "m\[0\] escapes to heap$"
-}
-
-func makemap1() map[int]int {
- return make(map[int]int) // ERROR "make\(map\[int\]int\) escapes to heap$"
-}
-
-func makemap2() {
- m := make(map[int]int) // ERROR "make\(map\[int\]int\) escapes to heap$"
- sink = m // ERROR "m escapes to heap$"
-}
-
-func nonescapingEface(m map[interface{}]bool) bool { // ERROR "nonescapingEface m does not escape$"
- return m["foo"] // ERROR "nonescapingEface .foo. does not escape$"
-}
-
-func nonescapingIface(m map[M]bool) bool { // ERROR "nonescapingIface m does not escape$"
- return m[MV(0)] // ERROR "nonescapingIface MV\(0\) does not escape$"
-}
-
-func issue10353() {
- x := new(int) // ERROR "new\(int\) escapes to heap$"
- issue10353a(x)()
-}
-
-func issue10353a(x *int) func() { // ERROR "leaking param: x to result ~r1 level=-1$"
- return func() { // ERROR "func literal escapes to heap$"
- println(*x)
- }
-}
-
-func issue10353b() {
- var f func()
- for {
- x := new(int) // ERROR "new\(int\) escapes to heap$"
- f = func() { // ERROR "func literal escapes to heap$"
- println(*x)
- }
- }
- _ = f
-}
-
-func issue11387(x int) func() int {
- f := func() int { return x } // ERROR "func literal escapes to heap"
- slice1 := []func() int{f} // ERROR "\[\].* does not escape"
- slice2 := make([]func() int, 1) // ERROR "make\(.*\) does not escape"
- copy(slice2, slice1)
- return slice2[0]
-}
-
-func issue12397(x, y int) { // ERROR "moved to heap: y$"
- // x does not escape below, because all relevant code is dead.
- if false {
- gxx = &x
- } else {
- gxx = &y
- }
-
- if true {
- gxx = &y
- } else {
- gxx = &x
- }
-}
+++ /dev/null
-// errorcheck -0 -m -l -newescape=false
-
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Test, using compiler diagnostic flags, that the escape analysis is working.
-// Compiles but does not run. Inlining is disabled.
-
-package foo
-
-import "runtime"
-
-func noleak(p *int) int { // ERROR "p does not escape"
- return *p
-}
-
-func leaktoret(p *int) *int { // ERROR "leaking param: p to result"
- return p
-}
-
-func leaktoret2(p *int) (*int, *int) { // ERROR "leaking param: p to result ~r1" "leaking param: p to result ~r2"
- return p, p
-}
-
-func leaktoret22(p, q *int) (*int, *int) { // ERROR "leaking param: p to result ~r2" "leaking param: q to result ~r3"
- return p, q
-}
-
-func leaktoret22b(p, q *int) (*int, *int) { // ERROR "leaking param: p to result ~r3" "leaking param: q to result ~r2"
- return leaktoret22(q, p)
-}
-
-func leaktoret22c(p, q *int) (*int, *int) { // ERROR "leaking param: p to result ~r3" "leaking param: q to result ~r2"
- r, s := leaktoret22(q, p)
- return r, s
-}
-
-func leaktoret22d(p, q *int) (r, s *int) { // ERROR "leaking param: p to result s" "leaking param: q to result r"
- r, s = leaktoret22(q, p)
- return
-}
-
-func leaktoret22e(p, q *int) (r, s *int) { // ERROR "leaking param: p to result s" "leaking param: q to result r"
- r, s = leaktoret22(q, p)
- return r, s
-}
-
-func leaktoret22f(p, q *int) (r, s *int) { // ERROR "leaking param: p to result s" "leaking param: q to result r"
- rr, ss := leaktoret22(q, p)
- return rr, ss
-}
-
-var gp *int
-
-func leaktosink(p *int) *int { // ERROR "leaking param: p"
- gp = p
- return p
-}
-
-func f1() {
- var x int
- p := noleak(&x)
- _ = p
-}
-
-func f2() {
- var x int
- p := leaktoret(&x)
- _ = p
-}
-
-func f3() {
- var x int // ERROR "moved to heap: x"
- p := leaktoret(&x)
- gp = p
-}
-
-func f4() {
- var x int // ERROR "moved to heap: x"
- p, q := leaktoret2(&x)
- gp = p
- gp = q
-}
-
-func f5() {
- var x int
- leaktoret22(leaktoret2(&x))
-}
-
-func f6() {
- var x int // ERROR "moved to heap: x"
- px1, px2 := leaktoret22(leaktoret2(&x))
- gp = px1
- _ = px2
-}
-
-type T struct{ x int }
-
-func (t *T) Foo(u int) (*T, bool) { // ERROR "leaking param: t to result"
- t.x += u
- return t, true
-}
-
-func f7() *T {
- r, _ := new(T).Foo(42) // ERROR "new.T. escapes to heap"
- return r
-}
-
-func leakrecursive1(p, q *int) (*int, *int) { // ERROR "leaking param: p" "leaking param: q"
- return leakrecursive2(q, p)
-}
-
-func leakrecursive2(p, q *int) (*int, *int) { // ERROR "leaking param: p" "leaking param: q"
- if *p > *q {
- return leakrecursive1(q, p)
- }
- // without this, leakrecursive? are safe for p and q, b/c in fact their graph does not have leaking edges.
- return p, q
-}
-
-var global interface{}
-
-type T1 struct {
- X *int
-}
-
-type T2 struct {
- Y *T1
-}
-
-func f8(p *T1) (k T2) { // ERROR "leaking param: p to result k" "leaking param: p"
- if p == nil {
- k = T2{}
- return
- }
-
- // should make p leak always
- global = p // ERROR "p escapes to heap"
- return T2{p}
-}
-
-func f9() {
- var j T1 // ERROR "moved to heap: j"
- f8(&j)
-}
-
-func f10() {
- // These don't escape but are too big for the stack
- var x [1 << 30]byte // ERROR "moved to heap: x"
- var y = make([]byte, 1<<30) // ERROR "make\(\[\]byte, 1 << 30\) escapes to heap"
- _ = x[0] + y[0]
-}
-
-// Test for issue 19687 (passing to unnamed parameters does not escape).
-func f11(**int) {
-}
-func f12(_ **int) {
-}
-func f13() {
- var x *int
- f11(&x)
- f12(&x)
- runtime.KeepAlive(&x) // ERROR "&x does not escape"
-}
-
-// Test for issue 24305 (passing to unnamed receivers does not escape).
-type U int
-
-func (*U) M() {}
-func (_ *U) N() {}
-
-func _() {
- var u U
- u.M()
- u.N()
-}
-
-// Issue 24730: taking address in a loop causes unnecessary escape
-type T24730 struct {
- x [64]byte
-}
-
-func (t *T24730) g() { // ERROR "t does not escape"
- y := t.x[:]
- for i := range t.x[:] {
- y = t.x[:]
- y[i] = 1
- }
-
- var z *byte
- for i := range t.x[:] {
- z = &t.x[i]
- *z = 2
- }
-}
-
-// Issue 15730: copy causes unnecessary escape
-
-var sink []byte
-var sink2 []int
-var sink3 []*int
-
-func f15730a(args ...interface{}) { // ERROR "args does not escape"
- for _, arg := range args {
- switch a := arg.(type) {
- case string:
- copy(sink, a)
- }
- }
-}
-
-func f15730b(args ...interface{}) { // ERROR "args does not escape"
- for _, arg := range args {
- switch a := arg.(type) {
- case []int:
- copy(sink2, a)
- }
- }
-}
-
-func f15730c(args ...interface{}) { // ERROR "leaking param content: args"
- for _, arg := range args {
- switch a := arg.(type) {
- case []*int:
- // copy pointerful data should cause escape
- copy(sink3, a)
- }
- }
-}
-
-// Issue 29000: unnamed parameter is not handled correctly
-
-var sink4 interface{}
-var alwaysFalse = false
-
-func f29000(_ int, x interface{}) { // ERROR "leaking param: x"
- sink4 = x
- if alwaysFalse {
- g29000()
- }
-}
-
-func g29000() {
- x := 1
- f29000(2, x) // ERROR "x escapes to heap"
-}
+++ /dev/null
-// errorcheck -0 -m -l -newescape=false
-
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Test escape analysis for function parameters.
-
-// In this test almost everything is BAD except the simplest cases
-// where input directly flows to output.
-
-package foo
-
-func f(buf []byte) []byte { // ERROR "leaking param: buf to result ~r1 level=0$"
- return buf
-}
-
-func g(*byte) string
-
-func h(e int) {
- var x [32]byte // ERROR "moved to heap: x$"
- g(&f(x[:])[0])
-}
-
-type Node struct {
- s string
- left, right *Node
-}
-
-func walk(np **Node) int { // ERROR "leaking param content: np"
- n := *np
- w := len(n.s)
- if n == nil {
- return 0
- }
- wl := walk(&n.left)
- wr := walk(&n.right)
- if wl < wr {
- n.left, n.right = n.right, n.left
- wl, wr = wr, wl
- }
- *np = n
- return w + wl + wr
-}
-
-// Test for bug where func var f used prototype's escape analysis results.
-func prototype(xyz []string) {} // ERROR "prototype xyz does not escape"
-func bar() {
- var got [][]string
- f := prototype
- f = func(ss []string) { got = append(got, ss) } // ERROR "leaking param: ss" "func literal does not escape"
- s := "string"
- f([]string{s}) // ERROR "\[\]string literal escapes to heap"
-}
+++ /dev/null
-// errorcheck -0 -m -l -newescape=false
-
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Test escape analysis for closure arguments.
-
-package escape
-
-var sink interface{}
-
-func ClosureCallArgs0() {
- x := 0 // ERROR "moved to heap: x"
- func(p *int) { // ERROR "p does not escape" "func literal does not escape"
- *p = 1
- // BAD: x should not escape to heap here
- }(&x)
-}
-
-func ClosureCallArgs1() {
- x := 0 // ERROR "moved to heap: x"
- for {
- func(p *int) { // ERROR "p does not escape" "func literal does not escape"
- *p = 1
- // BAD: x should not escape to heap here
- }(&x)
- }
-}
-
-func ClosureCallArgs2() {
- for {
- // BAD: x should not escape here
- x := 0 // ERROR "moved to heap: x"
- func(p *int) { // ERROR "p does not escape" "func literal does not escape"
- *p = 1
- }(&x)
- }
-}
-
-func ClosureCallArgs3() {
- x := 0 // ERROR "moved to heap: x"
- func(p *int) { // ERROR "leaking param: p" "func literal does not escape"
- sink = p // ERROR "p escapes to heap"
- }(&x)
-}
-
-func ClosureCallArgs4() {
- // BAD: x should not leak here
- x := 0 // ERROR "moved to heap: x"
- _ = func(p *int) *int { // ERROR "leaking param: p to result ~r1" "func literal does not escape"
- return p
- }(&x)
-}
-
-func ClosureCallArgs5() {
- x := 0 // ERROR "moved to heap: x"
- sink = func(p *int) *int { // ERROR "leaking param: p to result ~r1" "func literal does not escape" "\(func literal\)\(&x\) escapes to heap"
- return p
- }(&x)
-}
-
-func ClosureCallArgs6() {
- x := 0 // ERROR "moved to heap: x"
- func(p *int) { // ERROR "moved to heap: p" "func literal does not escape"
- sink = &p // ERROR "&p escapes to heap"
- }(&x)
-}
-
-func ClosureCallArgs7() {
- var pp *int
- for {
- x := 0 // ERROR "moved to heap: x"
- func(p *int) { // ERROR "leaking param: p" "func literal does not escape"
- pp = p
- }(&x)
- }
- _ = pp
-}
-
-func ClosureCallArgs8() {
- x := 0 // ERROR "moved to heap: x"
- defer func(p *int) { // ERROR "p does not escape" "func literal does not escape"
- *p = 1
- // BAD: x should not escape to heap here
- }(&x)
-}
-
-func ClosureCallArgs9() {
- // BAD: x should not leak
- x := 0 // ERROR "moved to heap: x"
- for {
- defer func(p *int) { // ERROR "func literal escapes to heap" "p does not escape"
- *p = 1
- }(&x)
- }
-}
-
-func ClosureCallArgs10() {
- for {
- x := 0 // ERROR "moved to heap: x"
- defer func(p *int) { // ERROR "func literal escapes to heap" "p does not escape"
- *p = 1
- }(&x)
- }
-}
-
-func ClosureCallArgs11() {
- x := 0 // ERROR "moved to heap: x"
- defer func(p *int) { // ERROR "leaking param: p" "func literal does not escape"
- sink = p // ERROR "p escapes to heap"
- }(&x)
-}
-
-func ClosureCallArgs12() {
- // BAD: x should not leak
- x := 0 // ERROR "moved to heap: x"
- defer func(p *int) *int { // ERROR "leaking param: p to result ~r1" "func literal does not escape"
- return p
- }(&x)
-}
-
-func ClosureCallArgs13() {
- x := 0 // ERROR "moved to heap: x"
- defer func(p *int) { // ERROR "moved to heap: p" "func literal does not escape"
- sink = &p // ERROR "&p escapes to heap"
- }(&x)
-}
-
-func ClosureCallArgs14() {
- x := 0 // ERROR "moved to heap: x"
- // BAD: &x should not escape here
- p := &x // ERROR "moved to heap: p"
- _ = func(p **int) *int { // ERROR "leaking param: p to result ~r1 level=1" "func literal does not escape"
- return *p
- // BAD: p should not escape here
- }(&p)
-}
-
-func ClosureCallArgs15() {
- x := 0 // ERROR "moved to heap: x"
- p := &x // ERROR "moved to heap: p"
- sink = func(p **int) *int { // ERROR "leaking param: p to result ~r1 level=1" "func literal does not escape" "\(func literal\)\(&p\) escapes to heap"
- return *p
- // BAD: p should not escape here
- }(&p)
-}
-
-func ClosureLeak1(s string) string { // ERROR "ClosureLeak1 s does not escape"
- t := s + "YYYY" // ERROR "escapes to heap"
- return ClosureLeak1a(t) // ERROR "ClosureLeak1 ... argument does not escape"
-}
-
-// See #14409 -- returning part of captured var leaks it.
-func ClosureLeak1a(a ...string) string { // ERROR "leaking param: a to result ~r1 level=1"
- return func() string { // ERROR "ClosureLeak1a func literal does not escape"
- return a[0]
- }()
-}
-
-func ClosureLeak2(s string) string { // ERROR "ClosureLeak2 s does not escape"
- t := s + "YYYY" // ERROR "escapes to heap"
- c := ClosureLeak2a(t) // ERROR "ClosureLeak2 ... argument does not escape"
- return c
-}
-func ClosureLeak2a(a ...string) string { // ERROR "leaking param: a to result ~r1 level=1"
- return ClosureLeak2b(func() string { // ERROR "ClosureLeak2a func literal does not escape"
- return a[0]
- })
-}
-func ClosureLeak2b(f func() string) string { // ERROR "leaking param: f to result ~r1 level=1"
- return f()
-}
+++ /dev/null
-// errorcheck -0 -m -l -newescape=false
-
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Test escape analysis with respect to field assignments.
-
-package escape
-
-var sink interface{}
-
-type X struct {
- p1 *int
- p2 *int
- a [2]*int
-}
-
-type Y struct {
- x X
-}
-
-func field0() {
- i := 0 // ERROR "moved to heap: i$"
- var x X
- x.p1 = &i
- sink = x.p1 // ERROR "x\.p1 escapes to heap"
-}
-
-func field1() {
- i := 0 // ERROR "moved to heap: i$"
- var x X
- // BAD: &i should not escape
- x.p1 = &i
- sink = x.p2 // ERROR "x\.p2 escapes to heap"
-}
-
-func field3() {
- i := 0 // ERROR "moved to heap: i$"
- var x X
- x.p1 = &i
- sink = x // ERROR "x escapes to heap"
-}
-
-func field4() {
- i := 0 // ERROR "moved to heap: i$"
- var y Y
- y.x.p1 = &i
- x := y.x
- sink = x // ERROR "x escapes to heap"
-}
-
-func field5() {
- i := 0 // ERROR "moved to heap: i$"
- var x X
- // BAD: &i should not escape here
- x.a[0] = &i
- sink = x.a[1] // ERROR "x\.a\[1\] escapes to heap"
-}
-
-// BAD: we are not leaking param x, only x.p2
-func field6(x *X) { // ERROR "leaking param content: x$"
- sink = x.p2 // ERROR "x\.p2 escapes to heap"
-}
-
-func field6a() {
- i := 0 // ERROR "moved to heap: i$"
- var x X
- // BAD: &i should not escape
- x.p1 = &i
- field6(&x)
-}
-
-func field7() {
- i := 0
- var y Y
- y.x.p1 = &i
- x := y.x
- var y1 Y
- y1.x = x
- _ = y1.x.p1
-}
-
-func field8() {
- i := 0 // ERROR "moved to heap: i$"
- var y Y
- y.x.p1 = &i
- x := y.x
- var y1 Y
- y1.x = x
- sink = y1.x.p1 // ERROR "y1\.x\.p1 escapes to heap"
-}
-
-func field9() {
- i := 0 // ERROR "moved to heap: i$"
- var y Y
- y.x.p1 = &i
- x := y.x
- var y1 Y
- y1.x = x
- sink = y1.x // ERROR "y1\.x escapes to heap"
-}
-
-func field10() {
- i := 0 // ERROR "moved to heap: i$"
- var y Y
- // BAD: &i should not escape
- y.x.p1 = &i
- x := y.x
- var y1 Y
- y1.x = x
- sink = y1.x.p2 // ERROR "y1\.x\.p2 escapes to heap"
-}
-
-func field11() {
- i := 0 // ERROR "moved to heap: i$"
- x := X{p1: &i}
- sink = x.p1 // ERROR "x\.p1 escapes to heap"
-}
-
-func field12() {
- i := 0 // ERROR "moved to heap: i$"
- // BAD: &i should not escape
- x := X{p1: &i}
- sink = x.p2 // ERROR "x\.p2 escapes to heap"
-}
-
-func field13() {
- i := 0 // ERROR "moved to heap: i$"
- x := &X{p1: &i} // ERROR "field13 &X literal does not escape$"
- sink = x.p1 // ERROR "x\.p1 escapes to heap"
-}
-
-func field14() {
- i := 0 // ERROR "moved to heap: i$"
- // BAD: &i should not escape
- x := &X{p1: &i} // ERROR "field14 &X literal does not escape$"
- sink = x.p2 // ERROR "x\.p2 escapes to heap"
-}
-
-func field15() {
- i := 0 // ERROR "moved to heap: i$"
- x := &X{p1: &i} // ERROR "&X literal escapes to heap$"
- sink = x // ERROR "x escapes to heap"
-}
-
-func field16() {
- i := 0 // ERROR "moved to heap: i$"
- var x X
- // BAD: &i should not escape
- x.p1 = &i
- var iface interface{} = x // ERROR "x escapes to heap"
- x1 := iface.(X)
- sink = x1.p2 // ERROR "x1\.p2 escapes to heap"
-}
-
-func field17() {
- i := 0 // ERROR "moved to heap: i$"
- var x X
- x.p1 = &i
- var iface interface{} = x // ERROR "x escapes to heap"
- x1 := iface.(X)
- sink = x1.p1 // ERROR "x1\.p1 escapes to heap"
-}
-
-func field18() {
- i := 0 // ERROR "moved to heap: i$"
- var x X
- // BAD: &i should not escape
- x.p1 = &i
- var iface interface{} = x // ERROR "x escapes to heap"
- y, _ := iface.(Y) // Put X, but extracted Y. The cast will fail, so y is zero initialized.
- sink = y // ERROR "y escapes to heap"
-}
+++ /dev/null
-// errorcheck -0 -m -l -newescape=false
-
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Test escape analysis for interface conversions.
-
-package escape
-
-var sink interface{}
-
-type M interface {
- M()
-}
-
-func mescapes(m M) { // ERROR "leaking param: m"
- sink = m // ERROR "m escapes to heap"
-}
-
-func mdoesnotescape(m M) { // ERROR "m does not escape"
-}
-
-// Tests for type stored directly in iface and with value receiver method.
-type M0 struct {
- p *int
-}
-
-func (M0) M() {
-}
-
-func efaceEscape0() {
- {
- i := 0
- v := M0{&i}
- var x M = v // ERROR "v does not escape"
- _ = x
- }
- {
- i := 0 // ERROR "moved to heap: i"
- v := M0{&i}
- var x M = v // ERROR "v escapes to heap"
- sink = x // ERROR "x escapes to heap"
- }
- {
- i := 0
- v := M0{&i}
- var x M = v // ERROR "v does not escape"
- v1 := x.(M0)
- _ = v1
- }
- {
- i := 0 // ERROR "moved to heap: i"
- v := M0{&i}
- // BAD: v does not escape to heap here
- var x M = v // ERROR "v escapes to heap"
- v1 := x.(M0)
- sink = v1 // ERROR "v1 escapes to heap"
- }
- {
- i := 0 // ERROR "moved to heap: i"
- v := M0{&i}
- // BAD: v does not escape to heap here
- var x M = v // ERROR "v escapes to heap"
- x.M()
- }
- {
- i := 0 // ERROR "moved to heap: i"
- v := M0{&i}
- var x M = v // ERROR "v escapes to heap"
- mescapes(x)
- }
- {
- i := 0
- v := M0{&i}
- var x M = v // ERROR "v does not escape"
- mdoesnotescape(x)
- }
-}
-
-// Tests for type stored indirectly in iface and with value receiver method.
-type M1 struct {
- p *int
- x int
-}
-
-func (M1) M() {
-}
-
-func efaceEscape1() {
- {
- i := 0
- v := M1{&i, 0}
- var x M = v // ERROR "v does not escape"
- _ = x
- }
- {
- i := 0 // ERROR "moved to heap: i"
- v := M1{&i, 0}
- var x M = v // ERROR "v escapes to heap"
- sink = x // ERROR "x escapes to heap"
- }
- {
- i := 0
- v := M1{&i, 0}
- var x M = v // ERROR "v does not escape"
- v1 := x.(M1)
- _ = v1
- }
- {
- i := 0 // ERROR "moved to heap: i"
- v := M1{&i, 0}
- // BAD: v does not escape to heap here
- var x M = v // ERROR "v escapes to heap"
- v1 := x.(M1)
- sink = v1 // ERROR "v1 escapes to heap"
- }
- {
- i := 0 // ERROR "moved to heap: i"
- v := M1{&i, 0}
- // BAD: v does not escape to heap here
- var x M = v // ERROR "v escapes to heap"
- x.M()
- }
- {
- i := 0 // ERROR "moved to heap: i"
- v := M1{&i, 0}
- var x M = v // ERROR "v escapes to heap"
- mescapes(x)
- }
- {
- i := 0
- v := M1{&i, 0}
- var x M = v // ERROR "v does not escape"
- mdoesnotescape(x)
- }
-}
-
-// Tests for type stored directly in iface and with pointer receiver method.
-type M2 struct {
- p *int
-}
-
-func (*M2) M() {
-}
-
-func efaceEscape2() {
- {
- i := 0
- v := &M2{&i} // ERROR "&M2 literal does not escape"
- var x M = v // ERROR "v does not escape"
- _ = x
- }
- {
- i := 0 // ERROR "moved to heap: i"
- v := &M2{&i} // ERROR "&M2 literal escapes to heap"
- var x M = v // ERROR "v escapes to heap"
- sink = x // ERROR "x escapes to heap"
- }
- {
- i := 0
- v := &M2{&i} // ERROR "&M2 literal does not escape"
- var x M = v // ERROR "v does not escape"
- v1 := x.(*M2)
- _ = v1
- }
- {
- i := 0 // ERROR "moved to heap: i"
- v := &M2{&i} // ERROR "&M2 literal escapes to heap"
- // BAD: v does not escape to heap here
- var x M = v // ERROR "v escapes to heap"
- v1 := x.(*M2)
- sink = v1 // ERROR "v1 escapes to heap"
- }
- {
- i := 0 // ERROR "moved to heap: i"
- v := &M2{&i} // ERROR "&M2 literal does not escape"
- // BAD: v does not escape to heap here
- var x M = v // ERROR "v does not escape"
- v1 := x.(*M2)
- sink = *v1 // ERROR "v1 escapes to heap"
- }
- {
- i := 0 // ERROR "moved to heap: i"
- v := &M2{&i} // ERROR "&M2 literal does not escape"
- // BAD: v does not escape to heap here
- var x M = v // ERROR "v does not escape"
- v1, ok := x.(*M2)
- sink = *v1 // ERROR "v1 escapes to heap"
- _ = ok
- }
- {
- i := 0 // ERROR "moved to heap: i"
- v := &M2{&i} // ERROR "&M2 literal escapes to heap"
- // BAD: v does not escape to heap here
- var x M = v // ERROR "v escapes to heap"
- x.M()
- }
- {
- i := 0 // ERROR "moved to heap: i"
- v := &M2{&i} // ERROR "&M2 literal escapes to heap"
- var x M = v // ERROR "v escapes to heap"
- mescapes(x)
- }
- {
- i := 0
- v := &M2{&i} // ERROR "&M2 literal does not escape"
- var x M = v // ERROR "v does not escape"
- mdoesnotescape(x)
- }
-}
-
-type T1 struct {
- p *int
-}
-
-type T2 struct {
- T1 T1
-}
-
-func dotTypeEscape() *T2 { // #11931
- var x interface{}
- x = &T1{p: new(int)} // ERROR "new\(int\) escapes to heap" "&T1 literal does not escape"
- return &T2{
- T1: *(x.(*T1)), // ERROR "&T2 literal escapes to heap"
- }
-}
-
-func dotTypeEscape2() { // #13805, #15796
- {
- i := 0
- j := 0
- var v int
- var ok bool
- var x interface{} = i // ERROR "i does not escape"
- var y interface{} = j // ERROR "j does not escape"
-
- *(&v) = x.(int)
- *(&v), *(&ok) = y.(int)
- }
- {
- i := 0
- j := 0
- var ok bool
- var x interface{} = i // ERROR "i does not escape"
- var y interface{} = j // ERROR "j does not escape"
-
- sink = x.(int) // ERROR "x.\(int\) escapes to heap"
- sink, *(&ok) = y.(int)
- }
- {
- i := 0 // ERROR "moved to heap: i"
- j := 0 // ERROR "moved to heap: j"
- var ok bool
- var x interface{} = &i // ERROR "&i escapes to heap"
- var y interface{} = &j // ERROR "&j escapes to heap"
-
- sink = x.(*int) // ERROR "x.\(\*int\) escapes to heap"
- sink, *(&ok) = y.(*int)
- }
-}
+++ /dev/null
-// errorcheckandrundir -0 -m -l=4 -newescape=false
-
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Tests that linknames are included in export data (issue 18167).
-package ignored
-
-/*
-Without CL 33911, this test would fail with the following error:
-
-main.main: relocation target linkname2.byteIndex not defined
-main.main: undefined: "linkname2.byteIndex"
-*/
+++ /dev/null
-// errorcheck -0 -m -l -newescape=false
-
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Test escape analysis for function parameters.
-
-// In this test almost everything is BAD except the simplest cases
-// where input directly flows to output.
-
-package escape
-
-func zero() int { return 0 }
-
-var sink interface{}
-
-// in -> out
-func param0(p *int) *int { // ERROR "leaking param: p to result ~r1"
- return p
-}
-
-func caller0a() {
- i := 0
- _ = param0(&i)
-}
-
-func caller0b() {
- i := 0 // ERROR "moved to heap: i$"
- sink = param0(&i) // ERROR "param0\(&i\) escapes to heap"
-}
-
-// in, in -> out, out
-func param1(p1, p2 *int) (*int, *int) { // ERROR "leaking param: p1 to result ~r2" "leaking param: p2 to result ~r3"
- return p1, p2
-}
-
-func caller1() {
- i := 0 // ERROR "moved to heap: i$"
- j := 0
- sink, _ = param1(&i, &j)
-}
-
-// in -> other in
-func param2(p1 *int, p2 **int) { // ERROR "leaking param: p1$" "param2 p2 does not escape$"
- *p2 = p1
-}
-
-func caller2a() {
- i := 0 // ERROR "moved to heap: i$"
- var p *int
- param2(&i, &p)
- _ = p
-}
-
-func caller2b() {
- i := 0 // ERROR "moved to heap: i$"
- var p *int
- param2(&i, &p)
- sink = p // ERROR "p escapes to heap$"
-}
-
-func paramArraySelfAssign(p *PairOfPairs) { // ERROR "p does not escape"
- p.pairs[0] = p.pairs[1] // ERROR "ignoring self-assignment in p.pairs\[0\] = p.pairs\[1\]"
-}
-
-func paramArraySelfAssignUnsafeIndex(p *PairOfPairs) { // ERROR "leaking param content: p"
- // Function call inside index disables self-assignment case to trigger.
- p.pairs[zero()] = p.pairs[1]
- p.pairs[zero()+1] = p.pairs[1]
-}
-
-type PairOfPairs struct {
- pairs [2]*Pair
-}
-
-type BoxedPair struct {
- pair *Pair
-}
-
-type WrappedPair struct {
- pair Pair
-}
-
-func leakParam(x interface{}) { // ERROR "leaking param: x"
- sink = x
-}
-
-func sinkAfterSelfAssignment1(box *BoxedPair) { // ERROR "leaking param content: box"
- box.pair.p1 = box.pair.p2 // ERROR "ignoring self-assignment in box.pair.p1 = box.pair.p2"
- sink = box.pair.p2 // ERROR "box.pair.p2 escapes to heap"
-}
-
-func sinkAfterSelfAssignment2(box *BoxedPair) { // ERROR "leaking param content: box"
- box.pair.p1 = box.pair.p2 // ERROR "ignoring self-assignment in box.pair.p1 = box.pair.p2"
- sink = box.pair // ERROR "box.pair escapes to heap"
-}
-
-func sinkAfterSelfAssignment3(box *BoxedPair) { // ERROR "leaking param content: box"
- box.pair.p1 = box.pair.p2 // ERROR "ignoring self-assignment in box.pair.p1 = box.pair.p2"
- leakParam(box.pair.p2) // ERROR "box.pair.p2 escapes to heap"
-}
-
-func sinkAfterSelfAssignment4(box *BoxedPair) { // ERROR "leaking param content: box"
- box.pair.p1 = box.pair.p2 // ERROR "ignoring self-assignment in box.pair.p1 = box.pair.p2"
- leakParam(box.pair) // ERROR "box.pair escapes to heap"
-}
-
-func selfAssignmentAndUnrelated(box1, box2 *BoxedPair) { // ERROR "leaking param content: box2" "box1 does not escape"
- box1.pair.p1 = box1.pair.p2 // ERROR "ignoring self-assignment in box1.pair.p1 = box1.pair.p2"
- leakParam(box2.pair.p2) // ERROR "box2.pair.p2 escapes to heap"
-}
-
-func notSelfAssignment1(box1, box2 *BoxedPair) { // ERROR "leaking param content: box2" "box1 does not escape"
- box1.pair.p1 = box2.pair.p1
-}
-
-func notSelfAssignment2(p1, p2 *PairOfPairs) { // ERROR "leaking param content: p2" "p1 does not escape"
- p1.pairs[0] = p2.pairs[1]
-}
-
-func notSelfAssignment3(p1, p2 *PairOfPairs) { // ERROR "leaking param content: p2" "p1 does not escape"
- p1.pairs[0].p1 = p2.pairs[1].p1
-}
-
-func boxedPairSelfAssign(box *BoxedPair) { // ERROR "box does not escape"
- box.pair.p1 = box.pair.p2 // ERROR "ignoring self-assignment in box.pair.p1 = box.pair.p2"
-}
-
-func wrappedPairSelfAssign(w *WrappedPair) { // ERROR "w does not escape"
- w.pair.p1 = w.pair.p2 // ERROR "ignoring self-assignment in w.pair.p1 = w.pair.p2"
-}
-
-// in -> in
-type Pair struct {
- p1 *int
- p2 *int
-}
-
-func param3(p *Pair) { // ERROR "param3 p does not escape"
- p.p1 = p.p2 // ERROR "param3 ignoring self-assignment in p.p1 = p.p2"
-}
-
-func caller3a() {
- i := 0
- j := 0
- p := Pair{&i, &j}
- param3(&p)
- _ = p
-}
-
-func caller3b() {
- i := 0 // ERROR "moved to heap: i$"
- j := 0 // ERROR "moved to heap: j$"
- p := Pair{&i, &j}
- param3(&p)
- sink = p // ERROR "p escapes to heap$"
-}
-
-// in -> rcvr
-func (p *Pair) param4(i *int) { // ERROR "\(\*Pair\).param4 p does not escape$" "leaking param: i$"
- p.p1 = i
-}
-
-func caller4a() {
- i := 0 // ERROR "moved to heap: i$"
- p := Pair{}
- p.param4(&i)
- _ = p
-}
-
-func caller4b() {
- i := 0 // ERROR "moved to heap: i$"
- p := Pair{}
- p.param4(&i)
- sink = p // ERROR "p escapes to heap$"
-}
-
-// in -> heap
-func param5(i *int) { // ERROR "leaking param: i$"
- sink = i // ERROR "i escapes to heap$"
-}
-
-func caller5() {
- i := 0 // ERROR "moved to heap: i$"
- param5(&i)
-}
-
-// *in -> heap
-func param6(i ***int) { // ERROR "leaking param content: i$"
- sink = *i // ERROR "\*i escapes to heap$"
-}
-
-func caller6a() {
- i := 0 // ERROR "moved to heap: i$"
- p := &i // ERROR "moved to heap: p$"
- p2 := &p
- param6(&p2)
-}
-
-// **in -> heap
-func param7(i ***int) { // ERROR "leaking param content: i$"
- sink = **i // ERROR "\* \(\*i\) escapes to heap"
-}
-
-func caller7() {
- i := 0 // ERROR "moved to heap: i$"
- p := &i // ERROR "moved to heap: p$"
- p2 := &p
- param7(&p2)
-}
-
-// **in -> heap
-func param8(i **int) { // ERROR "param8 i does not escape$"
- sink = **i // ERROR "\* \(\*i\) escapes to heap"
-}
-
-func caller8() {
- i := 0
- p := &i
- param8(&p)
-}
-
-// *in -> out
-func param9(p ***int) **int { // ERROR "leaking param: p to result ~r1 level=1"
- return *p
-}
-
-func caller9a() {
- i := 0
- p := &i
- p2 := &p
- _ = param9(&p2)
-}
-
-func caller9b() {
- i := 0 // ERROR "moved to heap: i$"
- p := &i // ERROR "moved to heap: p$"
- p2 := &p
- sink = param9(&p2) // ERROR "param9\(&p2\) escapes to heap"
-}
-
-// **in -> out
-func param10(p ***int) *int { // ERROR "leaking param: p to result ~r1 level=2"
- return **p
-}
-
-func caller10a() {
- i := 0
- p := &i
- p2 := &p
- _ = param10(&p2)
-}
-
-func caller10b() {
- i := 0 // ERROR "moved to heap: i$"
- p := &i
- p2 := &p
- sink = param10(&p2) // ERROR "param10\(&p2\) escapes to heap"
-}
-
-// in escapes to heap (address of param taken and returned)
-func param11(i **int) ***int { // ERROR "moved to heap: i$"
- return &i
-}
-
-func caller11a() {
- i := 0 // ERROR "moved to heap: i"
- p := &i // ERROR "moved to heap: p"
- _ = param11(&p)
-}
-
-func caller11b() {
- i := 0 // ERROR "moved to heap: i$"
- p := &i // ERROR "moved to heap: p$"
- sink = param11(&p) // ERROR "param11\(&p\) escapes to heap"
-}
-
-func caller11c() { // GOOD
- i := 0 // ERROR "moved to heap: i$"
- p := &i // ERROR "moved to heap: p"
- sink = *param11(&p) // ERROR "\*param11\(&p\) escapes to heap"
-}
-
-func caller11d() {
- i := 0 // ERROR "moved to heap: i$"
- p := &i // ERROR "moved to heap: p"
- p2 := &p
- sink = param11(p2) // ERROR "param11\(p2\) escapes to heap"
-}
-
-// &in -> rcvr
-type Indir struct {
- p ***int
-}
-
-func (r *Indir) param12(i **int) { // ERROR "\(\*Indir\).param12 r does not escape$" "moved to heap: i$"
- r.p = &i
-}
-
-func caller12a() {
- i := 0 // ERROR "moved to heap: i$"
- p := &i // ERROR "moved to heap: p$"
- var r Indir
- r.param12(&p)
- _ = r
-}
-
-func caller12b() {
- i := 0 // ERROR "moved to heap: i$"
- p := &i // ERROR "moved to heap: p$"
- r := &Indir{} // ERROR "caller12b &Indir literal does not escape$"
- r.param12(&p)
- _ = r
-}
-
-func caller12c() {
- i := 0 // ERROR "moved to heap: i$"
- p := &i // ERROR "moved to heap: p$"
- r := Indir{}
- r.param12(&p)
- sink = r // ERROR "r escapes to heap$"
-}
-
-func caller12d() {
- i := 0 // ERROR "moved to heap: i$"
- p := &i // ERROR "moved to heap: p$"
- r := Indir{}
- r.param12(&p)
- sink = **r.p // ERROR "\* \(\*r\.p\) escapes to heap"
-}
-
-// in -> value rcvr
-type Val struct {
- p **int
-}
-
-func (v Val) param13(i *int) { // ERROR "Val.param13 v does not escape$" "leaking param: i$"
- *v.p = i
-}
-
-func caller13a() {
- i := 0 // ERROR "moved to heap: i$"
- var p *int
- var v Val
- v.p = &p
- v.param13(&i)
- _ = v
-}
-
-func caller13b() {
- i := 0 // ERROR "moved to heap: i$"
- var p *int
- v := Val{&p}
- v.param13(&i)
- _ = v
-}
-
-func caller13c() {
- i := 0 // ERROR "moved to heap: i$"
- var p *int
- v := &Val{&p} // ERROR "caller13c &Val literal does not escape$"
- v.param13(&i)
- _ = v
-}
-
-func caller13d() {
- i := 0 // ERROR "moved to heap: i$"
- var p *int // ERROR "moved to heap: p$"
- var v Val
- v.p = &p
- v.param13(&i)
- sink = v // ERROR "v escapes to heap$"
-}
-
-func caller13e() {
- i := 0 // ERROR "moved to heap: i$"
- var p *int // ERROR "moved to heap: p$"
- v := Val{&p}
- v.param13(&i)
- sink = v // ERROR "v escapes to heap$"
-}
-
-func caller13f() {
- i := 0 // ERROR "moved to heap: i$"
- var p *int // ERROR "moved to heap: p$"
- v := &Val{&p} // ERROR "&Val literal escapes to heap$"
- v.param13(&i)
- sink = v // ERROR "v escapes to heap$"
-}
-
-func caller13g() {
- i := 0 // ERROR "moved to heap: i$"
- var p *int
- v := Val{&p}
- v.param13(&i)
- sink = *v.p // ERROR "\*v\.p escapes to heap"
-}
-
-func caller13h() {
- i := 0 // ERROR "moved to heap: i$"
- var p *int
- v := &Val{&p} // ERROR "caller13h &Val literal does not escape$"
- v.param13(&i)
- sink = **v.p // ERROR "\* \(\*v\.p\) escapes to heap"
-}
-
-type Node struct {
- p *Node
-}
-
-var Sink *Node
-
-func f(x *Node) { // ERROR "leaking param content: x"
- Sink = &Node{x.p} // ERROR "&Node literal escapes to heap"
-}
-
-func g(x *Node) *Node { // ERROR "leaking param: x to result ~r1 level=0"
- return &Node{x.p} // ERROR "&Node literal escapes to heap"
-}
-
-func h(x *Node) { // ERROR "leaking param: x"
- y := &Node{x} // ERROR "h &Node literal does not escape"
- Sink = g(y)
- f(y)
-}
-
-// interface(in) -> out
-// See also issue 29353.
-
-// Convert to a non-direct interface, require an allocation and
-// copy x to heap (not to result).
-func param14a(x [4]*int) interface{} { // ERROR "leaking param: x$"
- return x // ERROR "x escapes to heap"
-}
-
-// Convert to a direct interface, does not need an allocation.
-// So x only leaks to result.
-func param14b(x *int) interface{} { // ERROR "leaking param: x to result ~r1 level=0"
- return x // ERROR "x escapes to heap"
-}
+++ /dev/null
-// errorcheck -0 -m -l -newescape=false
-
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Test escape analysis for function parameters.
-
-package foo
-
-var Ssink *string
-
-type U struct {
- _sp *string
- _spp **string
-}
-
-func A(sp *string, spp **string) U { // ERROR "leaking param: sp to result ~r2 level=0$" "leaking param: spp to result ~r2 level=0$"
- return U{sp, spp}
-}
-
-func B(spp **string) U { // ERROR "leaking param: spp to result ~r1 level=0$" "leaking param: spp to result ~r1 level=1$"
- return U{*spp, spp}
-}
-
-func tA1() {
- s := "cat"
- sp := &s
- spp := &sp
- u := A(sp, spp)
- _ = u
- println(s)
-}
-
-func tA2() {
- s := "cat"
- sp := &s
- spp := &sp
- u := A(sp, spp)
- println(*u._sp)
-}
-
-func tA3() {
- s := "cat"
- sp := &s
- spp := &sp
- u := A(sp, spp)
- println(**u._spp)
-}
-
-func tB1() {
- s := "cat"
- sp := &s
- spp := &sp
- u := B(spp)
- _ = u
- println(s)
-}
-
-func tB2() {
- s := "cat"
- sp := &s
- spp := &sp
- u := B(spp)
- println(*u._sp)
-}
-
-func tB3() {
- s := "cat"
- sp := &s
- spp := &sp
- u := B(spp)
- println(**u._spp)
-}
-// errorcheck -0 -+ -p=runtime -m -newescape=true
+// errorcheck -0 -+ -p=runtime -m
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style