]> Cypherpunks.ru repositories - gostls13.git/blobdiff - test/escape2n.go
cmd/compile/internal/inline: score call sites exposed by inlines
[gostls13.git] / test / escape2n.go
index 002a78ea50d14f49024e1a7e0e869d13dae13e83..350be65202c00b14b24ce9ad258842554a1d9268 100644 (file)
@@ -1,6 +1,6 @@
 // errorcheck -0 -N -m -l
 
-// Copyright 2010 The Go Authors.  All rights reserved.
+// 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.
 
@@ -18,94 +18,94 @@ import (
 
 var gxx *int
 
-func foo1(x int) { // ERROR "moved to heap: x"
-       gxx = &x // ERROR "&x escapes to heap"
+func foo1(x int) { // ERROR "moved to heap: x$"
+       gxx = &x
 }
 
-func foo2(yy *int) { // ERROR "leaking param: yy"
+func foo2(yy *int) { // ERROR "leaking param: yy$"
        gxx = yy
 }
 
-func foo3(x int) *int { // ERROR "moved to heap: x"
-       return &x // ERROR "&x escapes to heap"
+func foo3(x int) *int { // ERROR "moved to heap: x$"
+       return &x
 }
 
 type T *T
 
-func foo3b(t T) { // ERROR "leaking param: 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 "xx does not escape" "yy does not escape"
+func foo4(xx, yy *int) { // ERROR "xx does not escape$" "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 "xx does not escape" "yy does not escape"
-       xx = &yy // ERROR "&yy does not escape"
+func foo5(xx **int, yy *int) { // ERROR "xx does not escape$" "yy does not escape$"
+       xx = &yy
 }
 
-func foo6(xx **int, yy *int) { // ERROR "xx does not escape" "leaking param: yy"
+func foo6(xx **int, yy *int) { // ERROR "xx does not escape$" "leaking param: yy$"
        *xx = yy
 }
 
-func foo7(xx **int, yy *int) { // ERROR "xx does not escape" "yy does not escape"
+func foo7(xx **int, yy *int) { // ERROR "xx does not escape$" "yy does not escape$"
        **xx = *yy
 }
 
-func foo8(xx, yy *int) int { // ERROR "xx does not escape" "yy does not escape"
+func foo8(xx, yy *int) int { // ERROR "xx does not escape$" "yy does not escape$"
        xx = yy
        return *xx
 }
 
-func foo9(xx, yy *int) *int { // ERROR "leaking param: xx" "leaking param: yy"
+func foo9(xx, yy *int) *int { // ERROR "leaking param: xx to result ~r0 level=0$" "leaking param: yy to result ~r0 level=0$"
        xx = yy
        return xx
 }
 
-func foo10(xx, yy *int) { // ERROR "xx does not escape" "yy does not escape"
+func foo10(xx, yy *int) { // ERROR "xx does not escape$" "yy does not escape$"
        *xx = *yy
 }
 
 func foo11() int {
        x, y := 0, 42
-       xx := &x // ERROR "&x does not escape"
-       yy := &y // ERROR "&y does not escape"
+       xx := &x
+       yy := &y
        *xx = *yy
        return x
 }
 
 var xxx **int
 
-func foo12(yyy **int) { // ERROR "leaking param: yyy"
+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: yyy"
+func foo13(yyy **int) { // ERROR "leaking param content: yyy$"
        *xxx = *yyy
 }
 
-func foo14(yyy **int) { // ERROR "yyy does not escape"
+func foo14(yyy **int) { // ERROR "yyy does not escape$"
        **xxx = **yyy
 }
 
-func foo15(yy *int) { // ERROR "moved to heap: yy"
-       xxx = &yy // ERROR "&yy escapes to heap"
+func foo15(yy *int) { // ERROR "moved to heap: yy$"
+       xxx = &yy
 }
 
-func foo16(yy *int) { // ERROR "leaking param: yy"
+func foo16(yy *int) { // ERROR "leaking param: yy$"
        *xxx = yy
 }
 
-func foo17(yy *int) { // ERROR "yy does not escape"
+func foo17(yy *int) { // ERROR "yy does not escape$"
        **xxx = *yy
 }
 
-func foo18(y int) { // ERROR "moved to heap: "y"
-       *xxx = &y // ERROR "&y escapes to heap"
+func foo18(y int) { // ERROR "moved to heap: y$"
+       *xxx = &y
 }
 
 func foo19(y int) {
@@ -118,52 +118,52 @@ type Bar struct {
 }
 
 func NewBar() *Bar {
-       return &Bar{42, nil} // ERROR "&Bar literal escapes to heap"
+       return &Bar{42, nil} // ERROR "&Bar{...} escapes to heap$"
 }
 
-func NewBarp(x *int) *Bar { // ERROR "leaking param: x"
-       return &Bar{42, x} // ERROR "&Bar literal escapes to heap"
+func NewBarp(x *int) *Bar { // ERROR "leaking param: x$"
+       return &Bar{42, x} // ERROR "&Bar{...} escapes to heap$"
 }
 
-func NewBarp2(x *int) *Bar { // ERROR "x does not escape"
-       return &Bar{*x, nil} // ERROR "&Bar literal escapes to heap"
+func NewBarp2(x *int) *Bar { // ERROR "x does not escape$"
+       return &Bar{*x, nil} // ERROR "&Bar{...} escapes to heap$"
 }
 
-func (b *Bar) NoLeak() int { // ERROR "b does not escape"
+func (b *Bar) NoLeak() int { // ERROR "b does not escape$"
        return *(b.ii)
 }
 
-func (b *Bar) Leak() *int { // ERROR "leaking param: b"
-       return &b.i // ERROR "&b.i escapes to heap"
+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 content to result ~r0"
+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"
+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"
-       v := 0    // ERROR "moved to heap: v"
-       b.ii = &v // ERROR "&v escapes"
+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 content to result ~r0"
-       v := 0    // ERROR "moved to heap: v"
-       b.ii = &v // ERROR "&v escapes"
+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 "b does not escape"
+func (b Bar) StillNoLeak() int { // ERROR "b does not escape$"
        v := 0
-       b.ii = &v // ERROR "&v does not escape"
+       b.ii = &v
        return b.i
 }
 
-func goLeak(b *Bar) { // ERROR "leaking param: b"
+func goLeak(b *Bar) { // ERROR "leaking param: b$"
        go b.NoLeak()
 }
 
@@ -173,90 +173,105 @@ type Bar2 struct {
 }
 
 func NewBar2() *Bar2 {
-       return &Bar2{[12]int{42}, nil} // ERROR "&Bar2 literal escapes to heap"
+       return &Bar2{[12]int{42}, nil} // ERROR "&Bar2{...} escapes to heap$"
 }
 
-func (b *Bar2) NoLeak() int { // ERROR "b does not escape"
+func (b *Bar2) NoLeak() int { // ERROR "b does not escape$"
        return b.i[0]
 }
 
-func (b *Bar2) Leak() []int { // ERROR "leaking param: b"
-       return b.i[:] // ERROR "b.i escapes to heap"
+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 content to result ~r0"
+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 "b does not escape"
+func (b Bar2) AgainNoLeak() [12]int { // ERROR "b does not escape$"
        return b.i
 }
 
-func (b *Bar2) LeakSelf() { // ERROR "leaking param: b"
-       b.ii = b.i[0:4] // ERROR "b.i escapes to heap"
+func (b *Bar2) LeakSelf() { // ERROR "leaking param: b$"
+       b.ii = b.i[0:4]
 }
 
-func (b *Bar2) LeakSelf2() { // ERROR "leaking param: b"
+func (b *Bar2) LeakSelf2() { // ERROR "leaking param: b$"
        var buf []int
-       buf = b.i[0:] // ERROR "b.i escapes to heap"
+       buf = b.i[0:]
        b.ii = buf
 }
 
 func foo21() func() int {
-       x := 42             // ERROR "moved to heap: x"
-       return func() int { // ERROR "func literal escapes to heap"
-               return x // ERROR "&x escapes to heap"
+       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 "func literal does not escape"
+       return func() int { // ERROR "func literal does not escape$"
                return x
        }()
 }
 
-func foo23(x int) func() int { // ERROR "moved to heap: x"
-       return func() int { // ERROR "func literal escapes to heap"
-               return x // ERROR "&x escapes to heap"
+func foo23(x int) func() int {
+       return func() int { // ERROR "func literal escapes to heap$"
+               return x
        }
 }
 
-func foo23a(x int) func() int { // ERROR "moved to heap: x"
-       f := func() int { // ERROR "func literal escapes to heap"
-               return x // ERROR "&x escapes to heap"
+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) { // ERROR "moved to heap: x"
-       f := func() int { return x } // ERROR "moved to heap: f" "func literal escapes to heap" "&x escapes to heap"
-       return &f                    // ERROR "&f escapes to heap"
+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 "func literal does not escape"
+       return func() int { // ERROR "func literal does not escape$"
                return x
        }()
 }
 
 var x *int
 
-func fooleak(xx *int) int { // ERROR "leaking param: xx"
+func fooleak(xx *int) int { // ERROR "leaking param: xx$"
        x = xx
        return *x
 }
 
-func foonoleak(xx *int) int { // ERROR "xx does not escape"
+func foonoleak(xx *int) int { // ERROR "xx does not escape$"
        return *x + *xx
 }
 
-func foo31(x int) int { // ERROR "moved to heap: x"
-       return fooleak(&x) // ERROR "&x escapes to heap"
+func foo31(x int) int { // ERROR "moved to heap: x$"
+       return fooleak(&x)
 }
 
 func foo32(x int) int {
-       return foonoleak(&x) // ERROR "&x does not escape"
+       return foonoleak(&x)
 }
 
 type Foo struct {
@@ -267,114 +282,114 @@ type Foo struct {
 var F Foo
 var pf *Foo
 
-func (f *Foo) fooleak() { // ERROR "leaking param: f"
+func (f *Foo) fooleak() { // ERROR "leaking param: f$"
        pf = f
 }
 
-func (f *Foo) foonoleak() { // ERROR "f does not escape"
+func (f *Foo) foonoleak() { // ERROR "f does not escape$"
        F.x = f.x
 }
 
-func (f *Foo) Leak() { // ERROR "leaking param: f"
+func (f *Foo) Leak() { // ERROR "leaking param: f$"
        f.fooleak()
 }
 
-func (f *Foo) NoLeak() { // ERROR "f does not escape"
+func (f *Foo) NoLeak() { // ERROR "f does not escape$"
        f.foonoleak()
 }
 
-func foo41(x int) { // ERROR "moved to heap: x"
-       F.xx = &x // ERROR "&x escapes to heap"
+func foo41(x int) { // ERROR "moved to heap: x$"
+       F.xx = &x
 }
 
-func (f *Foo) foo42(x int) { // ERROR "f does not escape" "moved to heap: x"
-       f.xx = &x // ERROR "&x escapes to heap"
+func (f *Foo) foo42(x int) { // ERROR "f does not escape$" "moved to heap: x$"
+       f.xx = &x
 }
 
-func foo43(f *Foo, x int) { // ERROR "f does not escape" "moved to heap: x"
-       f.xx = &x // ERROR "&x escapes to heap"
+func foo43(f *Foo, x int) { // ERROR "f does not escape$" "moved to heap: x$"
+       f.xx = &x
 }
 
-func foo44(yy *int) { // ERROR "leaking param: yy"
+func foo44(yy *int) { // ERROR "leaking param: yy$"
        F.xx = yy
 }
 
-func (f *Foo) foo45() { // ERROR "f does not escape"
+func (f *Foo) foo45() { // ERROR "f does not escape$"
        F.x = f.x
 }
 
 // See foo13 above for explanation of why f leaks.
-func (f *Foo) foo46() { // ERROR "leaking param: f"
+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 // ERROR "&f.x escapes to heap"
+func (f *Foo) foo47() { // ERROR "leaking param: f$"
+       f.xx = &f.x
 }
 
 var ptrSlice []*int
 
-func foo50(i *int) { // ERROR "leaking param: i"
+func foo50(i *int) { // ERROR "leaking param: i$"
        ptrSlice[0] = i
 }
 
 var ptrMap map[*int]*int
 
-func foo51(i *int) { // ERROR "leaking param: i"
+func foo51(i *int) { // ERROR "leaking param: i$"
        ptrMap[i] = i
 }
 
-func indaddr1(x int) *int { // ERROR "moved to heap: x"
-       return &x // ERROR "&x escapes to heap"
+func indaddr1(x int) *int { // ERROR "moved to heap: x$"
+       return &x
 }
 
-func indaddr2(x *int) *int { // ERROR "leaking param: x"
-       return *&x // ERROR "&x does not escape"
+func indaddr2(x *int) *int { // ERROR "leaking param: x to result ~r0 level=0$"
+       return *&x
 }
 
-func indaddr3(x *int32) *int { // ERROR "leaking param: x"
-       return *(**int)(unsafe.Pointer(&x)) // ERROR "&x does not escape"
+func indaddr3(x *int32) *int { // ERROR "leaking param: x to result ~r0 level=0$"
+       return *(**int)(unsafe.Pointer(&x))
 }
 
 // From package math:
 
 func Float32bits(f float32) uint32 {
-       return *(*uint32)(unsafe.Pointer(&f)) // ERROR "&f does not escape"
+       return *(*uint32)(unsafe.Pointer(&f))
 }
 
 func Float32frombits(b uint32) float32 {
-       return *(*float32)(unsafe.Pointer(&b)) // ERROR "&b does not escape"
+       return *(*float32)(unsafe.Pointer(&b))
 }
 
 func Float64bits(f float64) uint64 {
-       return *(*uint64)(unsafe.Pointer(&f)) // ERROR "&f does not escape"
+       return *(*uint64)(unsafe.Pointer(&f))
 }
 
 func Float64frombits(b uint64) float64 {
-       return *(*float64)(unsafe.Pointer(&b)) // ERROR "&b does not escape"
+       return *(*float64)(unsafe.Pointer(&b))
 }
 
 // contrast with
-func float64bitsptr(f float64) *uint64 { // ERROR "moved to heap: f"
-       return (*uint64)(unsafe.Pointer(&f)) // ERROR "&f escapes to heap"
+func float64bitsptr(f float64) *uint64 { // ERROR "moved to heap: f$"
+       return (*uint64)(unsafe.Pointer(&f))
 }
 
-func float64ptrbitsptr(f *float64) *uint64 { // ERROR "leaking param: f"
+func float64ptrbitsptr(f *float64) *uint64 { // ERROR "leaking param: f to result ~r0 level=0$"
        return (*uint64)(unsafe.Pointer(f))
 }
 
-func typesw(i interface{}) *int { // ERROR "leaking param: i"
+func typesw(i interface{}) *int { // ERROR "leaking param: i to result ~r0 level=0$"
        switch val := i.(type) {
        case *int:
                return val
        case *int8:
-               v := int(*val) // ERROR "moved to heap: v"
-               return &v      // ERROR "&v escapes to heap"
+               v := int(*val) // ERROR "moved to heap: v$"
+               return &v
        }
        return nil
 }
 
-func exprsw(i *int) *int { // ERROR "leaking param: i"
+func exprsw(i *int) *int { // ERROR "leaking param: i to result ~r0 level=0$"
        switch j := i; *j + 110 {
        case 12:
                return j
@@ -386,20 +401,20 @@ func exprsw(i *int) *int { // ERROR "leaking param: i"
 }
 
 // assigning to an array element is like assigning to the array
-func foo60(i *int) *int { // ERROR "leaking param: i"
+func foo60(i *int) *int { // ERROR "leaking param: i to result ~r0 level=0$"
        var a [12]*int
        a[0] = i
        return a[1]
 }
 
-func foo60a(i *int) *int { // ERROR "i does not escape"
+func foo60a(i *int) *int { // ERROR "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"
+func foo61(i *int) *int { // ERROR "leaking param: i to result ~r0 level=0$"
        type S struct {
                a, b *int
        }
@@ -408,7 +423,7 @@ func foo61(i *int) *int { // ERROR "leaking param: i"
        return s.b
 }
 
-func foo61a(i *int) *int { // ERROR "i does not escape"
+func foo61a(i *int) *int { // ERROR "i does not escape$"
        type S struct {
                a, b *int
        }
@@ -420,11 +435,11 @@ func foo61a(i *int) *int { // ERROR "i does not escape"
 // 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"
+func foo62(i *int) *int { // ERROR "leaking param: i$"
        type S struct {
                a, b *int
        }
-       s := new(S) // ERROR "new[(]S[)] does not escape"
+       s := new(S) // ERROR "new\(S\) does not escape$"
        s.a = i
        return nil // s.b
 }
@@ -433,14 +448,14 @@ type M interface {
        M()
 }
 
-func foo63(m M) { // ERROR "m does not escape"
+func foo63(m M) { // ERROR "m does not escape$"
 }
 
-func foo64(m M) { // ERROR "leaking param: m"
+func foo64(m M) { // ERROR "leaking param: m$"
        m.M()
 }
 
-func foo64b(m M) { // ERROR "leaking param: m"
+func foo64b(m M) { // ERROR "leaking param: m$"
        defer m.M()
 }
 
@@ -450,55 +465,56 @@ func (MV) M() {}
 
 func foo65() {
        var mv MV
-       foo63(&mv) // ERROR "&mv does not escape"
+       foo63(&mv)
 }
 
 func foo66() {
-       var mv MV  // ERROR "moved to heap: mv"
-       foo64(&mv) // ERROR "&mv escapes to heap"
+       var mv MV // ERROR "moved to heap: mv$"
+       foo64(&mv)
 }
 
 func foo67() {
        var mv MV
-       foo63(mv)
+       foo63(mv) // ERROR "mv does not escape$"
 }
 
 func foo68() {
        var mv MV
-       foo64(mv) // escapes but it's an int so irrelevant
+       // escapes but it's an int so irrelevant
+       foo64(mv) // ERROR "mv escapes to heap$"
 }
 
-func foo69(m M) { // ERROR "leaking param: m"
+func foo69(m M) { // ERROR "leaking param: m$"
        foo64(m)
 }
 
-func foo70(mv1 *MV, m M) { // ERROR "leaking param: mv1" "leaking param: m"
+func foo70(mv1 *MV, m M) { // ERROR "leaking param: m$" "leaking param: mv1$"
        m = mv1
        foo64(m)
 }
 
-func foo71(x *int) []*int { // ERROR "leaking param: x"
+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"
+func foo71a(x int) []*int { // ERROR "moved to heap: x$"
        var y []*int
-       y = append(y, &x) // ERROR "&x escapes to heap"
+       y = append(y, &x)
        return y
 }
 
 func foo72() {
        var x int
        var y [1]*int
-       y[0] = &x // ERROR "&x does not escape"
+       y[0] = &x
 }
 
 func foo72aa() [10]*int {
-       var x int // ERROR "moved to heap: x"
+       var x int // ERROR "moved to heap: x$"
        var y [10]*int
-       y[0] = &x // ERROR "&x escapes to heap"
+       y[0] = &x
        return y
 }
 
@@ -506,8 +522,8 @@ 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 // ERROR "&x escapes to heap"
+               x := i // ERROR "moved to heap: x$"
+               y[i] = &x
        }
        return
 }
@@ -515,31 +531,56 @@ func foo72a() {
 func foo72b() [10]*int {
        var y [10]*int
        for i := 0; i < 10; i++ {
-               x := i    // ERROR "moved to heap: x"
-               y[i] = &x // ERROR "&x escapes to heap"
+               x := i // ERROR "moved to heap: x$"
+               y[i] = &x
        }
        return y
 }
 
 // issue 2145
 func foo73() {
-       s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape"
+       s := []int{3, 2, 1} // ERROR "\[\]int{...} does not escape$"
        for _, v := range s {
-               vv := v // ERROR "moved to heap: vv"
+               vv := v
                // actually just escapes its scope
-               defer func() { // ERROR "func literal escapes to heap"
-                       println(vv) // ERROR "&vv escapes to heap"
+               defer func() { // ERROR "func literal escapes to heap$"
+                       println(vv)
+               }()
+       }
+}
+
+func foo731() {
+       s := []int{3, 2, 1} // ERROR "\[\]int{...} 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 "\[\]int literal does not escape"
+       s := []int{3, 2, 1} // ERROR "\[\]int{...} 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 "\[\]int{...} does not escape$"
        for _, v := range s {
-               vv := v // ERROR "moved to heap: vv"
+               vv := v // ERROR "moved to heap: vv$"
                // actually just escapes its scope
-               fn := func() { // ERROR "func literal escapes to heap"
-                       println(vv) // ERROR "&vv escapes to heap"
+               fn := func() { // ERROR "func literal escapes to heap$"
+                       vv += 1
+                       println(vv)
                }
                defer fn()
        }
@@ -548,110 +589,138 @@ func foo74() {
 // issue 3975
 func foo74b() {
        var array [3]func()
-       s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape"
+       s := []int{3, 2, 1} // ERROR "\[\]int{...} does not escape$"
        for i, v := range s {
-               vv := v // ERROR "moved to heap: vv"
+               vv := v
                // actually just escapes its scope
-               array[i] = func() { // ERROR "func literal escapes to heap"
-                       println(vv) // ERROR "&vv escapes to heap"
+               array[i] = func() { // ERROR "func literal escapes to heap$"
+                       println(vv)
                }
        }
 }
 
-func myprint(y *int, x ...interface{}) *int { // ERROR "x does not escape" "leaking param: y"
+func foo74c() {
+       var array [3]func()
+       s := []int{3, 2, 1} // ERROR "\[\]int{...} 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 ~r0 level=0$" "x does not escape$"
        return y
 }
 
-func myprint1(y *int, x ...interface{}) *interface{} { // ERROR "y does not escape" "leaking param: x"
-       return &x[0] // ERROR "&x.0. escapes to heap"
+func myprint1(y *int, x ...interface{}) *interface{} { // ERROR "leaking param: x to result ~r0 level=0$" "y does not escape$"
+       return &x[0]
 }
 
-func foo75(z *int) { // ERROR "z does not escape"
-       myprint(z, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
+func foo75(z *int) { // ERROR "z does not escape$"
+       myprint(z, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "... argument does not escape$"
 }
 
-func foo75a(z *int) { // ERROR "z does not escape"
-       myprint1(z, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
+func foo75a(z *int) { // ERROR "z does not escape$"
+       myprint1(z, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "... argument does not escape$"
 }
 
-func foo75esc(z *int) { // ERROR "leaking param: z"
-       gxx = myprint(z, 1, 2, 3) // ERROR "[.][.][.] 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" "... argument does not escape$"
 }
 
-func foo75aesc(z *int) { // ERROR "z does not escape"
+func foo75aesc(z *int) { // ERROR "z does not escape$"
        var ppi **interface{}       // assignments to pointer dereferences lose track
-       *ppi = myprint1(z, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap"
+       *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 "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$"
 }
 
-func foo76(z *int) { // ERROR "leaking param: z"
-       myprint(nil, z) // ERROR "[.][.][.] argument does not escape"
+func foo76(z *int) { // ERROR "z does not escape"
+       myprint(nil, z) // ERROR "... argument does not escape$"
 }
 
-func foo76a(z *int) { // ERROR "leaking param: z"
-       myprint1(nil, z) // ERROR "[.][.][.] argument does not escape"
+func foo76a(z *int) { // ERROR "z does not escape"
+       myprint1(nil, z) // ERROR "... argument does not escape$"
 }
 
 func foo76b() {
-       myprint(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
+       myprint(nil, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "... argument does not escape$"
 }
 
 func foo76c() {
-       myprint1(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
+       myprint1(nil, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "... argument does not escape$"
 }
 
 func foo76d() {
-       defer myprint(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
+       defer myprint(nil, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "... argument does not escape$"
 }
 
 func foo76e() {
-       defer myprint1(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
+       defer myprint1(nil, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "... 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"
+               defer myprint(nil, 1, 2, 3) // ERROR "... argument does not escape$" "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"
+               defer myprint1(nil, 1, 2, 3) // ERROR "... argument does not escape$" "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$"
        }
 }
 
-func foo77(z []interface{}) { // ERROR "z does not escape"
+func foo77(z []interface{}) { // ERROR "z does not escape$"
        myprint(nil, z...) // z does not escape
 }
 
-func foo77a(z []interface{}) { // ERROR "z does not escape"
+func foo77a(z []interface{}) { // ERROR "z does not escape$"
        myprint1(nil, z...)
 }
 
-func foo77b(z []interface{}) { // ERROR "leaking param: z"
+func foo77b(z []interface{}) { // ERROR "leaking param: z$"
        var ppi **interface{}
        *ppi = myprint1(nil, z...)
 }
 
-func foo78(z int) *int { // ERROR "moved to heap: z"
-       return &z // ERROR "&z escapes to heap"
+func foo77c(z []interface{}) { // ERROR "leaking param: z$"
+       sink = myprint1(nil, z...)
 }
 
-func foo78a(z int) *int { // ERROR "moved to heap: z"
-       y := &z   // ERROR "&z escapes to heap"
-       x := &y   // ERROR "&y does not escape"
+func dotdotdot() {
+       i := 0
+       myprint(nil, &i) // ERROR "... argument does not escape$"
+
+       j := 0
+       myprint1(nil, &j) // ERROR "... 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"
+       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 = new(int) // ERROR "new\(int\) escapes to heap$"
        }
        _ = z
        return nil
@@ -659,24 +728,24 @@ func foo80() *int {
 
 func foo81() *int {
        for {
-               z := new(int) // ERROR "new[(]int[)] does not escape"
+               z := new(int) // ERROR "new\(int\) does not escape$"
                _ = z
        }
        return nil
 }
 
-func tee(p *int) (x, y *int) { return p, p } // ERROR "leaking param"
+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 "does not escape"
+func noop(x, y *int) {} // ERROR "x does not escape$" "y does not escape$"
 
 func foo82() {
-       var x, y, z int  // ERROR "moved to heap"
-       go noop(tee(&z)) // ERROR "&z escapes to heap"
-       go noop(&x, &y)  // ERROR "escapes to heap"
+       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"
-               defer noop(tee(&u)) // ERROR "&u escapes to heap"
-               defer noop(&v, &w)  // ERROR "escapes to heap"
+               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)
        }
 }
 
@@ -689,24 +758,24 @@ type LimitedFooer struct {
        N int64
 }
 
-func LimitFooer(r Fooer, n int64) Fooer { // ERROR "leaking param: r"
-       return &LimitedFooer{r, n} // ERROR "&LimitedFooer literal escapes to heap"
+func LimitFooer(r Fooer, n int64) Fooer { // ERROR "leaking param: r$"
+       return &LimitedFooer{r, n} // ERROR "&LimitedFooer{...} 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 foo90(x *int) map[*int]*int { // ERROR "leaking param: x$"
+       return map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int{...} 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 foo91(x *int) map[*int]*int { // ERROR "leaking param: x$"
+       return map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int{...} escapes to heap$"
 }
 
-func foo92(x *int) [2]*int { // ERROR "leaking param: x"
+func foo92(x *int) [2]*int { // ERROR "leaking param: x to result ~r0 level=0$"
        return [2]*int{x, nil}
 }
 
 // does not leak c
-func foo93(c chan *int) *int { // ERROR "c does not escape"
+func foo93(c chan *int) *int { // ERROR "c does not escape$"
        for v := range c {
                return v
        }
@@ -714,7 +783,7 @@ func foo93(c chan *int) *int { // ERROR "c does not escape"
 }
 
 // does not leak m
-func foo94(m map[*int]*int, b bool) *int { // ERROR "m does not escape"
+func foo94(m map[*int]*int, b bool) *int { // ERROR "leaking param: m to result ~r0 level=1"
        for k, v := range m {
                if b {
                        return k
@@ -725,32 +794,32 @@ func foo94(m map[*int]*int, b bool) *int { // ERROR "m does not escape"
 }
 
 // does leak x
-func foo95(m map[*int]*int, x *int) { // ERROR "m does not escape" "leaking param: x"
+func foo95(m map[*int]*int, x *int) { // ERROR "m does not escape$" "leaking param: x$"
        m[x] = x
 }
 
-// does not leak m
-func foo96(m []*int) *int { // ERROR "m does not escape"
+// does not leak m but does leak content
+func foo96(m []*int) *int { // ERROR "leaking param: m to result ~r0 level=1"
        return m[0]
 }
 
 // does leak m
-func foo97(m [1]*int) *int { // ERROR "leaking param: m"
+func foo97(m [1]*int) *int { // ERROR "leaking param: m to result ~r0 level=0$"
        return m[0]
 }
 
 // does not leak m
-func foo98(m map[int]*int) *int { // ERROR "m does not escape"
+func foo98(m map[int]*int) *int { // ERROR "m does not escape$"
        return m[0]
 }
 
 // does leak m
-func foo99(m *[1]*int) []*int { // ERROR "leaking param: m"
+func foo99(m *[1]*int) []*int { // ERROR "leaking param: m to result ~r0 level=0$"
        return m[:]
 }
 
 // does not leak m
-func foo100(m []*int) *int { // ERROR "m does not escape"
+func foo100(m []*int) *int { // ERROR "leaking param: m to result ~r0 level=1"
        for _, v := range m {
                return v
        }
@@ -758,7 +827,7 @@ func foo100(m []*int) *int { // ERROR "m does not escape"
 }
 
 // does leak m
-func foo101(m [1]*int) *int { // ERROR "leaking param: m"
+func foo101(m [1]*int) *int { // ERROR "leaking param: m to result ~r0 level=0$"
        for _, v := range m {
                return v
        }
@@ -766,109 +835,109 @@ func foo101(m [1]*int) *int { // ERROR "leaking param: m"
 }
 
 // does not leak m
-func foo101a(m [1]*int) *int { // ERROR "m does not escape"
-       for i := range m { // ERROR "moved to heap: i"
-               return &i // ERROR "&i escapes to heap"
+func foo101a(m [1]*int) *int { // ERROR "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 "m does not escape" "leaking param: x"
+func foo102(m []*int, x *int) { // ERROR "m does not escape$" "leaking param: x$"
        m[0] = x
 }
 
 // does not leak x
-func foo103(m [1]*int, x *int) { // ERROR "m does not escape" "x does not escape"
+func foo103(m [1]*int, x *int) { // ERROR "m does not escape$" "x does not escape$"
        m[0] = x
 }
 
 var y []*int
 
-// does not leak x
-func foo104(x []*int) { // ERROR "x does not escape"
+// does not leak x but does leak content
+func foo104(x []*int) { // ERROR "leaking param content: x"
        copy(y, x)
 }
 
-// does not leak x
-func foo105(x []*int) { // ERROR "x does not escape"
+// 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"
+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.* literal escapes to heap"
+func foo107(x *int) map[*int]*int { // ERROR "leaking param: x$"
+       return map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int{...} escapes to heap$"
 }
 
-func foo108(x *int) map[*int]*int { // ERROR "leaking param: x"
-       return map[*int]*int{nil: x} // ERROR "map.* 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{...} escapes to heap$"
 }
 
-func foo109(x *int) *int { // ERROR "leaking param: x"
-       m := map[*int]*int{x: nil} // ERROR "map.* literal does not escape"
+func foo109(x *int) *int { // ERROR "leaking param: x$"
+       m := map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int{...} 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 "map.* literal does not escape"
+func foo110(x *int) *int { // ERROR "leaking param: x$"
+       m := map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int{...} does not escape$"
        return m[nil]
 }
 
-func foo111(x *int) *int { // ERROR "leaking param: x"
-       m := []*int{x} // ERROR "\[\]\*int literal does not escape"
+func foo111(x *int) *int { // ERROR "leaking param: x to result ~r0 level=0"
+       m := []*int{x} // ERROR "\[\]\*int{...} does not escape$"
        return m[0]
 }
 
-func foo112(x *int) *int { // ERROR "leaking param: x"
+func foo112(x *int) *int { // ERROR "leaking param: x to result ~r0 level=0$"
        m := [1]*int{x}
        return m[0]
 }
 
-func foo113(x *int) *int { // ERROR "leaking param: x"
+func foo113(x *int) *int { // ERROR "leaking param: x to result ~r0 level=0$"
        m := Bar{ii: x}
        return m.ii
 }
 
-func foo114(x *int) *int { // ERROR "leaking param: x"
-       m := &Bar{ii: x} // ERROR "&Bar literal does not escape"
+func foo114(x *int) *int { // ERROR "leaking param: x to result ~r0 level=0$"
+       m := &Bar{ii: x} // ERROR "&Bar{...} does not escape$"
        return m.ii
 }
 
-func foo115(x *int) *int { // ERROR "leaking param: x"
+func foo115(x *int) *int { // ERROR "leaking param: x to result ~r0 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 // ERROR "&x escapes to heap"
+               x := 1 // ERROR "moved to heap: x$"
+               return &x
        } else {
-               y := 1    // ERROR "moved to heap: y"
-               return &y // ERROR "&y escapes to heap"
+               y := 1 // ERROR "moved to heap: y$"
+               return &y
        }
        return nil
 }
 
-func foo117(unknown func(interface{})) { // ERROR "unknown does not escape"
-       x := 1      // ERROR "moved to heap: x"
-       unknown(&x) // ERROR "&x escapes to heap"
+func foo117(unknown func(interface{})) { // ERROR "unknown does not escape$"
+       x := 1 // ERROR "moved to heap: x$"
+       unknown(&x)
 }
 
-func foo118(unknown func(*int)) { // ERROR "unknown does not escape"
-       x := 1      // ERROR "moved to heap: x"
-       unknown(&x) // ERROR "&x escapes to heap"
+func foo118(unknown func(*int)) { // ERROR "unknown does not escape$"
+       x := 1 // ERROR "moved to heap: x$"
+       unknown(&x)
 }
 
 func external(*int)
 
-func foo119(x *int) { // ERROR "leaking param: x"
+func foo119(x *int) { // ERROR "leaking param: x$"
        external(x)
 }
 
@@ -1079,16 +1148,16 @@ L100:
 
 func foo121() {
        for i := 0; i < 10; i++ {
-               defer myprint(nil, i) // ERROR "[.][.][.] argument escapes to heap"
-               go myprint(nil, i)    // ERROR "[.][.][.] argument escapes to heap"
+               defer myprint(nil, i) // ERROR "... argument does not escape$" "i escapes to heap$"
+               go myprint(nil, i)    // ERROR "... argument does not escape$" "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"
-               go fmt.Printf("%d", i)    // ERROR "[.][.][.] argument escapes to heap"
+               defer fmt.Printf("%d", i) // ERROR "... argument does not escape$" "i escapes to heap$"
+               go fmt.Printf("%d", i)    // ERROR "... argument does not escape$" "i escapes to heap$"
        }
 }
 
@@ -1098,7 +1167,7 @@ func foo122() {
 
        goto L1
 L1:
-       i = new(int) // ERROR "new.int. does not escape"
+       i = new(int) // ERROR "new\(int\) does not escape$"
        _ = i
 }
 
@@ -1107,25 +1176,25 @@ func foo123() {
        var i *int
 
 L1:
-       i = new(int) // ERROR "new.int. escapes to heap"
+       i = new(int) // ERROR "new\(int\) escapes to heap$"
 
        goto L1
        _ = i
 }
 
-func foo124(x **int) { // ERROR "x does not escape"
-       var i int // ERROR "moved to heap: i"
-       p := &i   // ERROR "&i escapes"
-       func() {  // ERROR "func literal does not escape"
-               *x = p // ERROR "leaking closure reference p"
+func foo124(x **int) { // ERROR "x does not escape$"
+       var i int // ERROR "moved to heap: i$"
+       p := &i
+       func() { // ERROR "func literal does not escape$"
+               *x = p
        }()
 }
 
-func foo125(ch chan *int) { // ERROR "does not escape"
-       var i int // ERROR "moved to heap"
-       p := &i   // ERROR "&i escapes to heap"
-       func() {  // ERROR "func literal does not escape"
-               ch <- p // ERROR "leaking closure reference p"
+func foo125(ch chan *int) { // ERROR "ch does not escape$"
+       var i int // ERROR "moved to heap: i$"
+       p := &i
+       func() { // ERROR "func literal does not escape$"
+               ch <- p
        }()
 }
 
@@ -1133,9 +1202,9 @@ func foo126() {
        var px *int // loopdepth 0
        for {
                // loopdepth 1
-               var i int // ERROR "moved to heap"
-               func() {  // ERROR "func literal does not escape"
-                       px = &i // ERROR "&i escapes"
+               var i int // ERROR "moved to heap: i$"
+               func() {  // ERROR "func literal does not escape$"
+                       px = &i
                }()
        }
        _ = px
@@ -1144,26 +1213,26 @@ func foo126() {
 var px *int
 
 func foo127() {
-       var i int // ERROR "moved to heap: i"
-       p := &i   // ERROR "&i escapes to heap"
+       var i int // ERROR "moved to heap: i$"
+       p := &i
        q := p
        px = q
 }
 
 func foo128() {
        var i int
-       p := &i // ERROR "&i does not escape"
+       p := &i
        q := p
        _ = q
 }
 
 func foo129() {
-       var i int // ERROR "moved to heap: i"
-       p := &i   // ERROR "&i escapes to heap"
-       func() {  // ERROR "func literal does not escape"
-               q := p   // ERROR "leaking closure reference p"
-               func() { // ERROR "func literal does not escape"
-                       r := q // ERROR "leaking closure reference q"
+       var i int // ERROR "moved to heap: i$"
+       p := &i
+       func() { // ERROR "func literal does not escape$"
+               q := p
+               func() { // ERROR "func literal does not escape$"
+                       r := q
                        px = r
                }()
        }()
@@ -1171,40 +1240,40 @@ func foo129() {
 
 func foo130() {
        for {
-               var i int // ERROR "moved to heap"
-               func() {  // ERROR "func literal does not escape"
-                       px = &i // ERROR "&i escapes" "leaking closure reference i"
+               var i int // ERROR "moved to heap: i$"
+               func() {  // ERROR "func literal does not escape$"
+                       px = &i
                }()
        }
 }
 
 func foo131() {
-       var i int // ERROR "moved to heap"
-       func() {  // ERROR "func literal does not escape"
-               px = &i // ERROR "&i escapes" "leaking closure reference i"
+       var i int // ERROR "moved to heap: i$"
+       func() {  // ERROR "func literal does not escape$"
+               px = &i
        }()
 }
 
 func foo132() {
-       var i int   // ERROR "moved to heap"
-       go func() { // ERROR "func literal escapes to heap"
-               px = &i // ERROR "&i escapes" "leaking closure reference i"
+       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"
-       defer func() { // ERROR "func literal does not escape"
-               px = &i // ERROR "&i escapes" "leaking closure reference i"
+       var i int      // ERROR "moved to heap: i$"
+       defer func() { // ERROR "func literal does not escape$"
+               px = &i
        }()
 }
 
 func foo134() {
        var i int
-       p := &i  // ERROR "&i does not escape"
-       func() { // ERROR "func literal does not escape"
+       p := &i
+       func() { // ERROR "func literal does not escape$"
                q := p
-               func() { // ERROR "func literal does not escape"
+               func() { // ERROR "func literal does not escape$"
                        r := q
                        _ = r
                }()
@@ -1212,11 +1281,11 @@ func foo134() {
 }
 
 func foo135() {
-       var i int   // ERROR "moved to heap: i"
-       p := &i     // ERROR "&i escapes to heap" "moved to heap: p"
-       go func() { // ERROR "func literal escapes to heap"
-               q := p   // ERROR "&p escapes to heap"
-               func() { // ERROR "func literal does not escape"
+       var i int // ERROR "moved to heap: i$"
+       p := &i
+       go func() { // ERROR "func literal escapes to heap$"
+               q := p
+               func() { // ERROR "func literal does not escape$"
                        r := q
                        _ = r
                }()
@@ -1224,24 +1293,24 @@ func foo135() {
 }
 
 func foo136() {
-       var i int   // ERROR "moved to heap: i"
-       p := &i     // ERROR "&i escapes to heap" "moved to heap: p"
-       go func() { // ERROR "func literal escapes to heap"
-               q := p   // ERROR "&p escapes to heap" "leaking closure reference p"
-               func() { // ERROR "func literal does not escape"
-                       r := q // ERROR "leaking closure reference q"
+       var i int // ERROR "moved to heap: i$"
+       p := &i
+       go func() { // ERROR "func literal escapes to heap$"
+               q := p
+               func() { // ERROR "func literal does not escape$"
+                       r := q
                        px = r
                }()
        }()
 }
 
 func foo137() {
-       var i int // ERROR "moved to heap: i"
-       p := &i   // ERROR "&i escapes to heap"
-       func() {  // ERROR "func literal does not escape"
-               q := p      // ERROR "leaking closure reference p" "moved to heap: q"
-               go func() { // ERROR "func literal escapes to heap"
-                       r := q // ERROR "&q escapes to heap"
+       var i int // ERROR "moved to heap: i$"
+       p := &i
+       func() { // ERROR "func literal does not escape$"
+               q := p
+               go func() { // ERROR "func literal escapes to heap$"
+                       r := q
                        _ = r
                }()
        }()
@@ -1251,8 +1320,8 @@ func foo138() *byte {
        type T struct {
                x [1]byte
        }
-       t := new(T)    // ERROR "new.T. escapes to heap"
-       return &t.x[0] // ERROR "&t.x.0. escapes to heap"
+       t := new(T) // ERROR "new\(T\) escapes to heap$"
+       return &t.x[0]
 }
 
 func foo139() *byte {
@@ -1261,8 +1330,8 @@ func foo139() *byte {
                        y byte
                }
        }
-       t := new(T)   // ERROR "new.T. escapes to heap"
-       return &t.x.y // ERROR "&t.x.y escapes to heap"
+       t := new(T) // ERROR "new\(T\) escapes to heap$"
+       return &t.x.y
 }
 
 // issue 4751
@@ -1274,8 +1343,8 @@ func foo140() interface{} {
                X string
                T *T
        }
-       t := &T{} // ERROR "&T literal escapes to heap"
-       return U{
+       t := &T{} // ERROR "&T{} escapes to heap$"
+       return U{ // ERROR "U{...} escapes to heap$"
                X: t.X,
                T: t,
        }
@@ -1289,53 +1358,53 @@ func F2([]byte)
 
 //go:noescape
 
-func F3(x []byte) // ERROR "F3 x does not escape"
+func F3(x []byte) // ERROR "x does not escape$"
 
-func F4(x []byte)
+func F4(x []byte) // ERROR "leaking param: x$"
 
 func G() {
        var buf1 [10]byte
-       F1(buf1[:]) // ERROR "buf1 does not escape"
+       F1(buf1[:])
 
-       var buf2 [10]byte // ERROR "moved to heap: buf2"
-       F2(buf2[:])       // ERROR "buf2 escapes to heap"
+       var buf2 [10]byte // ERROR "moved to heap: buf2$"
+       F2(buf2[:])
 
        var buf3 [10]byte
-       F3(buf3[:]) // ERROR "buf3 does not escape"
+       F3(buf3[:])
 
-       var buf4 [10]byte // ERROR "moved to heap: buf4"
-       F4(buf4[:])       // ERROR "buf4 escapes to heap"
+       var buf4 [10]byte // ERROR "moved to heap: buf4$"
+       F4(buf4[:])
 }
 
 type Tm struct {
        x int
 }
 
-func (t *Tm) M() { // ERROR "t does not escape"
+func (t *Tm) M() { // ERROR "t does not escape$"
 }
 
 func foo141() {
        var f func()
 
-       t := new(Tm) // ERROR "escapes to heap"
-       f = t.M      // ERROR "t.M does not escape"
+       t := new(Tm) // ERROR "new\(Tm\) does not escape$"
+       f = t.M      // ERROR "t.M does not escape$"
        _ = f
 }
 
 var gf func()
 
 func foo142() {
-       t := new(Tm) // ERROR "escapes to heap"
-       gf = t.M     // ERROR "t.M escapes to heap"
+       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 "func literal does not escape"
+               func() { // ERROR "func literal does not escape$"
                        for i := 0; i < 1; i++ {
                                var t Tm
-                               t.M() // ERROR "t does not escape"
+                               t.M()
                        }
                }()
        }
@@ -1351,9 +1420,9 @@ func foo144a(*int)
 
 func foo144() {
        var x int
-       foo144a(&x) // ERROR "&x does not escape"
+       foo144a(&x)
        var y int
-       foo144b(&y) // ERROR "&y does not escape"
+       foo144b(&y)
 }
 
 //go:noescape
@@ -1366,38 +1435,38 @@ type List struct {
        Next *List
 }
 
-func foo145(l List) { // ERROR "l does not escape"
+func foo145(l List) { // ERROR "l does not escape$"
        var p *List
-       for p = &l; p.Next != nil; p = p.Next { // ERROR "&l does not escape"
+       for p = &l; p.Next != nil; p = p.Next {
        }
 }
 
-func foo146(l List) { // ERROR "l does not escape"
+func foo146(l List) { // ERROR "l does not escape$"
        var p *List
-       p = &l // ERROR "&l does not escape"
+       p = &l
        for ; p.Next != nil; p = p.Next {
        }
 }
 
-func foo147(l List) { // ERROR "l does not escape"
+func foo147(l List) { // ERROR "l does not escape$"
        var p *List
-       p = &l // ERROR "&l does not escape"
+       p = &l
        for p.Next != nil {
                p = p.Next
        }
 }
 
-func foo148(l List) { // ERROR " l does not escape"
-       for p := &l; p.Next != nil; p = p.Next { // ERROR "&l does not escape"
+func foo148(l List) { // ERROR "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 " l does not escape"
+func foo149(l List) { // ERROR "l does not escape$"
        var p *List
        for {
-               for p = &l; p.Next != nil; p = p.Next { // ERROR "&l does not escape"
+               for p = &l; p.Next != nil; p = p.Next {
                }
        }
 }
@@ -1406,44 +1475,44 @@ func foo149(l List) { // ERROR " l does not escape"
 
 var save150 []byte
 
-func foo150(x ...byte) { // ERROR "leaking param: x"
+func foo150(x ...byte) { // ERROR "leaking param: x$"
        save150 = x
 }
 
 func bar150() {
-       foo150(1, 2, 3) // ERROR "[.][.][.] argument escapes to heap"
+       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"
+func foo151(x *int) { // ERROR "leaking param: x$"
        save151 = x
 }
 
 func bar151() {
-       var a [64]int // ERROR "moved to heap: a"
+       var a [64]int // ERROR "moved to heap: a$"
        a[4] = 101
-       foo151(&(&a)[4:8][0]) // ERROR "&\(&a\)\[4:8\]\[0\] escapes to heap" "&a escapes to heap"
+       foo151(&(&a)[4:8][0])
 }
 
 func bar151b() {
-       var a [10]int      // ERROR "moved to heap: a"
-       b := a[:]          // ERROR "a escapes to heap"
-       foo151(&b[4:8][0]) // ERROR "&b\[4:8\]\[0\] escapes to heap"
+       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"
+       var a [64]int // ERROR "moved to heap: a$"
        a[4] = 101
-       foo151(&(&a)[4:8:8][0]) // ERROR "&\(&a\)\[4:8:8\]\[0\] escapes to heap" "&a escapes to heap"
+       foo151(&(&a)[4:8:8][0])
 }
 
 func bar151d() {
-       var a [10]int        // ERROR "moved to heap: a"
-       b := a[:]            // ERROR "a escapes to heap"
-       foo151(&b[4:8:8][0]) // ERROR "&b\[4:8:8\]\[0\] escapes to heap"
+       var a [10]int // ERROR "moved to heap: a$"
+       b := a[:]
+       foo151(&b[4:8:8][0])
 }
 
 // issue 8120
@@ -1452,7 +1521,7 @@ type U struct {
        s *string
 }
 
-func (u *U) String() *string { // ERROR "leaking param u content to result ~r0"
+func (u *U) String() *string { // ERROR "leaking param: u to result ~r0 level=1$"
        return u.s
 }
 
@@ -1460,35 +1529,318 @@ type V struct {
        s *string
 }
 
-func NewV(u U) *V { // ERROR "leaking param: u"
-       return &V{u.String()} // ERROR "&V literal escapes to heap" "u does not escape"
+func NewV(u U) *V { // ERROR "leaking param: u$"
+       return &V{u.String()} // ERROR "&V{...} escapes to heap$"
 }
 
 func foo152() {
-       a := "a"   // ERROR "moved to heap: a"
-       u := U{&a} // ERROR "&a escapes to heap"
+       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"
+func foo153(v interface{}) *int { // ERROR "v does not escape"
        switch x := v.(type) {
-       case int: // ERROR "moved to heap: x"
-               return &x // ERROR "&x escapes to heap"
+       case int: // ERROR "moved to heap: x$"
+               return &x
        }
-       panic(0)
+       panic(0) // ERROR "0 escapes to heap"
 }
 
 // issue 8185 - &result escaping into result
 
-func f() (x int, y *int) { // ERROR "moved to heap: x"
-       y = &x // ERROR "&x escapes to heap"
+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"
+func g() (x interface{}) { // ERROR "moved to heap: x$"
+       x = &x
        return
 }
+
+var sink interface{}
+
+type Lit struct {
+       p *int
+}
+
+func ptrlitNoescape() {
+       // Both literal and element do not escape.
+       i := 0
+       x := &Lit{&i} // ERROR "&Lit{...} does not escape$"
+       _ = x
+}
+
+func ptrlitNoEscape2() {
+       // Literal does not escape, but element does.
+       i := 0        // ERROR "moved to heap: i$"
+       x := &Lit{&i} // ERROR "&Lit{...} does not escape$"
+       sink = *x
+}
+
+func ptrlitEscape() {
+       // Both literal and element escape.
+       i := 0        // ERROR "moved to heap: i$"
+       x := &Lit{&i} // ERROR "&Lit{...} escapes to heap$"
+       sink = x
+}
+
+// self-assignments
+
+type Buffer struct {
+       arr    [64]byte
+       arrPtr *[64]byte
+       buf1   []byte
+       buf2   []byte
+       str1   string
+       str2   string
+}
+
+func (b *Buffer) foo() { // ERROR "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 "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 "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
+}
+
+func quux(sp *string, bp *[]byte) { // ERROR "bp does not escape$" "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 "make\(\[\]byte, 20\) does not escape$"
+       s := string(b)        // ERROR "string\(b\) does not escape$"
+       _ = s
+}
+
+func slicebytetostring1() {
+       b := make([]byte, 20) // ERROR "make\(\[\]byte, 20\) does not escape$"
+       s := string(b)        // ERROR "string\(b\) does not escape$"
+       s1 := s[0:1]
+       _ = s1
+}
+
+func slicebytetostring2() {
+       b := make([]byte, 20) // ERROR "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
+}
+
+func slicebytetostring3() {
+       b := make([]byte, 20) // ERROR "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 "s0 \+ s1 does not escape$"
+       _ = s
+}
+
+func addstr1() {
+       s0 := "a"
+       s1 := "b"
+       s := "c"
+       s += s0 + s1 // ERROR "s0 \+ s1 does not escape$"
+       _ = s
+}
+
+func addstr2() {
+       b := make([]byte, 20) // ERROR "make\(\[\]byte, 20\) does not escape$"
+       s0 := "a"
+       s := string(b) + s0 // ERROR "string\(b\) \+ s0 does not escape$" "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 "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
+}
+
+func stringtoslicebyte0() {
+       s := "foo"
+       x := []byte(s) // ERROR "\(\[\]byte\)\(s\) does not escape$" "zero-copy string->\[\]byte conversion"
+       _ = 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 "\(\[\]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 "\[\]rune{...} does not escape$"
+       s := string(r)       // ERROR "string\(r\) does not escape$"
+       _ = s
+}
+
+func slicerunetostring1() string {
+       r := []rune{1, 2, 3} // ERROR "\[\]rune{...} does not escape$"
+       return string(r)     // ERROR "string\(r\) escapes to heap$"
+}
+
+func slicerunetostring2() {
+       r := []rune{1, 2, 3} // ERROR "\[\]rune{...} does not escape$"
+       sink = string(r)     // ERROR "string\(r\) escapes to heap$"
+}
+
+func makemap0() {
+       m := make(map[int]int) // ERROR "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
+}
+
+func nonescapingEface(m map[interface{}]bool) bool { // ERROR "m does not escape$"
+       return m["foo"] // ERROR ".foo. does not escape$"
+}
+
+func nonescapingIface(m map[M]bool) bool { // ERROR "m does not escape$"
+       return m[MV(0)] // ERROR "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$"
+       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
+       }
+}