Commit 606019cb authored by Matthew Dempsky's avatar Matthew Dempsky

cmd/compile: trim function name prefix from escape diagnostics

This information is redundant with the position information already
provided. Also, no other -m diagnostics print out function name.

While here, report parameter leak diagnostics against the parameter
declaration position rather than the function, and use Warnl for
"moved to heap" messages.

Test cases updated programmatically by removing the first word from
every "no match for" error emitted by run.go:

go run run.go |& \
  sed -E -n 's/^(.*):(.*): no match for `([^ ]* (.*))` in:$/\1!\2!\3!\4/p' | \
  while IFS='!' read -r fn line before after; do
    before=$(echo "$before" | sed 's/[.[\*^$()+?{|]/\\&/g')
    after=$(echo "$after" | sed -E 's/(\&|\\)/\\&/g')
    fn=$(find . -name "${fn}" | head -1)
    sed -i -E -e "${line}s/\"${before}\"/\"${after}\"/" "${fn}"
  done

Passes toolstash-check.

Change-Id: I6e02486b1409e4a8dbb2b9b816d22095835426b5
Reviewed-on: https://go-review.googlesource.com/c/go/+/195040
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarCherry Zhang <cherryyz@google.com>
parent 4ae25ff1
...@@ -392,7 +392,7 @@ func moveToHeap(n *Node) { ...@@ -392,7 +392,7 @@ func moveToHeap(n *Node) {
n.Name.Param.Heapaddr = heapaddr n.Name.Param.Heapaddr = heapaddr
n.Esc = EscHeap n.Esc = EscHeap
if Debug['m'] != 0 { if Debug['m'] != 0 {
fmt.Printf("%v: moved to heap: %v\n", n.Line(), n) Warnl(n.Pos, "moved to heap: %v", n)
} }
} }
...@@ -422,7 +422,7 @@ func (e *Escape) paramTag(fn *Node, narg int, f *types.Field) string { ...@@ -422,7 +422,7 @@ func (e *Escape) paramTag(fn *Node, narg int, f *types.Field) string {
// argument and pass those annotations along to importing code. // argument and pass those annotations along to importing code.
if f.Type.Etype == TUINTPTR { if f.Type.Etype == TUINTPTR {
if Debug['m'] != 0 { if Debug['m'] != 0 {
Warnl(fn.Pos, "%v assuming %v is unsafe uintptr", funcSym(fn), name()) Warnl(f.Pos, "assuming %v is unsafe uintptr", name())
} }
return unsafeUintptrTag return unsafeUintptrTag
} }
...@@ -435,13 +435,13 @@ func (e *Escape) paramTag(fn *Node, narg int, f *types.Field) string { ...@@ -435,13 +435,13 @@ func (e *Escape) paramTag(fn *Node, narg int, f *types.Field) string {
// //go:noescape is given before the declaration. // //go:noescape is given before the declaration.
if fn.Noescape() { if fn.Noescape() {
if Debug['m'] != 0 && f.Sym != nil { if Debug['m'] != 0 && f.Sym != nil {
Warnl(fn.Pos, "%S %v does not escape", funcSym(fn), name()) Warnl(f.Pos, "%v does not escape", name())
} }
return mktag(EscNone) return mktag(EscNone)
} }
if Debug['m'] != 0 && f.Sym != nil { if Debug['m'] != 0 && f.Sym != nil {
Warnl(fn.Pos, "leaking param: %v", name()) Warnl(f.Pos, "leaking param: %v", name())
} }
return mktag(EscHeap) return mktag(EscHeap)
} }
...@@ -449,14 +449,14 @@ func (e *Escape) paramTag(fn *Node, narg int, f *types.Field) string { ...@@ -449,14 +449,14 @@ func (e *Escape) paramTag(fn *Node, narg int, f *types.Field) string {
if fn.Func.Pragma&UintptrEscapes != 0 { if fn.Func.Pragma&UintptrEscapes != 0 {
if f.Type.Etype == TUINTPTR { if f.Type.Etype == TUINTPTR {
if Debug['m'] != 0 { if Debug['m'] != 0 {
Warnl(fn.Pos, "%v marking %v as escaping uintptr", funcSym(fn), name()) Warnl(f.Pos, "marking %v as escaping uintptr", name())
} }
return uintptrEscapesTag return uintptrEscapesTag
} }
if f.IsDDD() && f.Type.Elem().Etype == TUINTPTR { if f.IsDDD() && f.Type.Elem().Etype == TUINTPTR {
// final argument is ...uintptr. // final argument is ...uintptr.
if Debug['m'] != 0 { if Debug['m'] != 0 {
Warnl(fn.Pos, "%v marking %v as escaping ...uintptr", funcSym(fn), name()) Warnl(f.Pos, "marking %v as escaping ...uintptr", name())
} }
return uintptrEscapesTag return uintptrEscapesTag
} }
...@@ -477,17 +477,17 @@ func (e *Escape) paramTag(fn *Node, narg int, f *types.Field) string { ...@@ -477,17 +477,17 @@ func (e *Escape) paramTag(fn *Node, narg int, f *types.Field) string {
if Debug['m'] != 0 && !loc.escapes { if Debug['m'] != 0 && !loc.escapes {
if esc == EscNone { if esc == EscNone {
Warnl(n.Pos, "%S %S does not escape", funcSym(fn), n) Warnl(f.Pos, "%v does not escape", name())
} else if esc == EscHeap { } else if esc == EscHeap {
Warnl(n.Pos, "leaking param: %S", n) Warnl(f.Pos, "leaking param: %v", name())
} else { } else {
if esc&EscContentEscapes != 0 { if esc&EscContentEscapes != 0 {
Warnl(n.Pos, "leaking param content: %S", n) Warnl(f.Pos, "leaking param content: %v", name())
} }
for i := 0; i < numEscReturns; i++ { for i := 0; i < numEscReturns; i++ {
if x := getEscReturn(esc, i); x >= 0 { if x := getEscReturn(esc, i); x >= 0 {
res := n.Name.Curfn.Type.Results().Field(i).Sym res := fn.Type.Results().Field(i).Sym
Warnl(n.Pos, "leaking param: %S to result %v level=%d", n, res, x) Warnl(f.Pos, "leaking param: %v to result %v level=%d", name(), res, x)
} }
} }
} }
......
...@@ -1289,7 +1289,7 @@ func (e *Escape) finish(fns []*Node) { ...@@ -1289,7 +1289,7 @@ func (e *Escape) finish(fns []*Node) {
addrescapes(n) addrescapes(n)
} else { } else {
if Debug['m'] != 0 && n.Op != ONAME && n.Op != OTYPESW && n.Op != ORANGE && n.Op != ODEFER { if Debug['m'] != 0 && n.Op != ONAME && n.Op != OTYPESW && n.Op != ORANGE && n.Op != ODEFER {
Warnl(n.Pos, "%S %S does not escape", funcSym(loc.curfn), n) Warnl(n.Pos, "%S does not escape", n)
} }
n.Esc = EscNone n.Esc = EscNone
if loc.transient { if loc.transient {
......
This diff is collapsed.
This diff is collapsed.
...@@ -71,7 +71,7 @@ func fuo(x *U, y *U) *string { // ERROR "leaking param: x to result ~r2 level=1$ ...@@ -71,7 +71,7 @@ func fuo(x *U, y *U) *string { // ERROR "leaking param: x to result ~r2 level=1$
// pointers stored in small array literals do not escape; // pointers stored in small array literals do not escape;
// large array literals are heap allocated; // large array literals are heap allocated;
// pointers stored in large array literals escape. // pointers stored in large array literals escape.
func hugeLeaks1(x **string, y **string) { // ERROR "leaking param content: x" "hugeLeaks1 y does not escape" func hugeLeaks1(x **string, y **string) { // ERROR "leaking param content: x" "y does not escape"
a := [10]*string{*y} a := [10]*string{*y}
_ = a _ = a
// 4 x 4,000,000 exceeds MaxStackVarSize, therefore it must be heap allocated if pointers are 4 bytes or larger. // 4 x 4,000,000 exceeds MaxStackVarSize, therefore it must be heap allocated if pointers are 4 bytes or larger.
...@@ -79,7 +79,7 @@ func hugeLeaks1(x **string, y **string) { // ERROR "leaking param content: x" "h ...@@ -79,7 +79,7 @@ func hugeLeaks1(x **string, y **string) { // ERROR "leaking param content: x" "h
_ = b _ = b
} }
func hugeLeaks2(x *string, y *string) { // ERROR "leaking param: x" "hugeLeaks2 y does not escape" func hugeLeaks2(x *string, y *string) { // ERROR "leaking param: x" "y does not escape"
a := [10]*string{y} a := [10]*string{y}
_ = a _ = a
// 4 x 4,000,000 exceeds MaxStackVarSize, therefore it must be heap allocated if pointers are 4 bytes or larger. // 4 x 4,000,000 exceeds MaxStackVarSize, therefore it must be heap allocated if pointers are 4 bytes or larger.
......
...@@ -44,7 +44,7 @@ func walk(np **Node) int { // ERROR "leaking param content: np" ...@@ -44,7 +44,7 @@ func walk(np **Node) int { // ERROR "leaking param content: np"
} }
// Test for bug where func var f used prototype's escape analysis results. // Test for bug where func var f used prototype's escape analysis results.
func prototype(xyz []string) {} // ERROR "prototype xyz does not escape" func prototype(xyz []string) {} // ERROR "xyz does not escape"
func bar() { func bar() {
var got [][]string var got [][]string
f := prototype f := prototype
......
...@@ -139,28 +139,28 @@ func ClosureCallArgs15() { ...@@ -139,28 +139,28 @@ func ClosureCallArgs15() {
}(&p) }(&p)
} }
func ClosureLeak1(s string) string { // ERROR "ClosureLeak1 s does not escape" func ClosureLeak1(s string) string { // ERROR "s does not escape"
t := s + "YYYY" // ERROR "escapes to heap" t := s + "YYYY" // ERROR "escapes to heap"
return ClosureLeak1a(t) // ERROR "ClosureLeak1 ... argument does not escape" return ClosureLeak1a(t) // ERROR "... argument does not escape"
} }
// See #14409 -- returning part of captured var leaks it. // See #14409 -- returning part of captured var leaks it.
func ClosureLeak1a(a ...string) string { // ERROR "leaking param: a to result ~r1 level=1$" 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 func() string { // ERROR "func literal does not escape"
return a[0] return a[0]
}() }()
} }
func ClosureLeak2(s string) string { // ERROR "ClosureLeak2 s does not escape" func ClosureLeak2(s string) string { // ERROR "s does not escape"
t := s + "YYYY" // ERROR "escapes to heap" t := s + "YYYY" // ERROR "escapes to heap"
c := ClosureLeak2a(t) // ERROR "ClosureLeak2 ... argument does not escape" c := ClosureLeak2a(t) // ERROR "... argument does not escape"
return c return c
} }
func ClosureLeak2a(a ...string) string { // ERROR "leaking param content: a" func ClosureLeak2a(a ...string) string { // ERROR "leaking param content: a"
return ClosureLeak2b(func() string { // ERROR "ClosureLeak2a func literal does not escape" return ClosureLeak2b(func() string { // ERROR "func literal does not escape"
return a[0] return a[0]
}) })
} }
func ClosureLeak2b(f func() string) string { // ERROR "ClosureLeak2b f does not escape" func ClosureLeak2b(f func() string) string { // ERROR "f does not escape"
return f() return f()
} }
...@@ -127,14 +127,14 @@ func field12() { ...@@ -127,14 +127,14 @@ func field12() {
func field13() { func field13() {
i := 0 // ERROR "moved to heap: i$" i := 0 // ERROR "moved to heap: i$"
x := &X{p1: &i} // ERROR "field13 &X literal does not escape$" x := &X{p1: &i} // ERROR "&X literal does not escape$"
sink = x.p1 sink = x.p1
} }
func field14() { func field14() {
i := 0 // ERROR "moved to heap: i$" i := 0 // ERROR "moved to heap: i$"
// BAD: &i should not escape // BAD: &i should not escape
x := &X{p1: &i} // ERROR "field14 &X literal does not escape$" x := &X{p1: &i} // ERROR "&X literal does not escape$"
sink = x.p2 sink = x.p2
} }
...@@ -149,7 +149,7 @@ func field16() { ...@@ -149,7 +149,7 @@ func field16() {
var x X var x X
// BAD: &i should not escape // BAD: &i should not escape
x.p1 = &i x.p1 = &i
var iface interface{} = x // ERROR "field16 x does not escape" var iface interface{} = x // ERROR "x does not escape"
x1 := iface.(X) x1 := iface.(X)
sink = x1.p2 sink = x1.p2
} }
...@@ -158,7 +158,7 @@ func field17() { ...@@ -158,7 +158,7 @@ func field17() {
i := 0 // ERROR "moved to heap: i$" i := 0 // ERROR "moved to heap: i$"
var x X var x X
x.p1 = &i x.p1 = &i
var iface interface{} = x // ERROR "field17 x does not escape" var iface interface{} = x // ERROR "x does not escape"
x1 := iface.(X) x1 := iface.(X)
sink = x1.p1 sink = x1.p1
} }
...@@ -168,7 +168,7 @@ func field18() { ...@@ -168,7 +168,7 @@ func field18() {
var x X var x X
// BAD: &i should not escape // BAD: &i should not escape
x.p1 = &i x.p1 = &i
var iface interface{} = x // ERROR "field18 x does not escape" var iface interface{} = x // ERROR "x does not escape"
y, _ := iface.(Y) // Put X, but extracted Y. The cast will fail, so y is zero initialized. y, _ := iface.(Y) // Put X, but extracted Y. The cast will fail, so y is zero initialized.
sink = y // ERROR "y escapes to heap" sink = y // ERROR "y escapes to heap"
} }
...@@ -110,7 +110,7 @@ func efaceEscape1() { ...@@ -110,7 +110,7 @@ func efaceEscape1() {
{ {
i := 0 // ERROR "moved to heap: i" i := 0 // ERROR "moved to heap: i"
v := M1{&i, 0} v := M1{&i, 0}
var x M = v // ERROR "efaceEscape1 v does not escape" var x M = v // ERROR "v does not escape"
v1 := x.(M1) v1 := x.(M1)
sink = v1 // ERROR "v1 escapes to heap" sink = v1 // ERROR "v1 escapes to heap"
} }
......
...@@ -127,7 +127,7 @@ func constptr11() *ConstPtr { ...@@ -127,7 +127,7 @@ func constptr11() *ConstPtr {
return p return p
} }
func foo(p **int) { // ERROR "foo p does not escape" func foo(p **int) { // ERROR "p does not escape"
i := 0 // ERROR "moved to heap: i" i := 0 // ERROR "moved to heap: i"
y := p y := p
*y = &i *y = &i
......
...@@ -42,7 +42,7 @@ func caller1() { ...@@ -42,7 +42,7 @@ func caller1() {
} }
// in -> other in // in -> other in
func param2(p1 *int, p2 **int) { // ERROR "leaking param: p1$" "param2 p2 does not escape$" func param2(p1 *int, p2 **int) { // ERROR "leaking param: p1$" "p2 does not escape$"
*p2 = p1 *p2 = p1
} }
...@@ -137,7 +137,7 @@ type Pair struct { ...@@ -137,7 +137,7 @@ type Pair struct {
p2 *int p2 *int
} }
func param3(p *Pair) { // ERROR "param3 p does not escape" func param3(p *Pair) { // ERROR "p does not escape"
p.p1 = p.p2 // ERROR "param3 ignoring self-assignment in p.p1 = p.p2" p.p1 = p.p2 // ERROR "param3 ignoring self-assignment in p.p1 = p.p2"
} }
...@@ -158,7 +158,7 @@ func caller3b() { ...@@ -158,7 +158,7 @@ func caller3b() {
} }
// in -> rcvr // in -> rcvr
func (p *Pair) param4(i *int) { // ERROR "\(\*Pair\).param4 p does not escape$" "leaking param: i$" func (p *Pair) param4(i *int) { // ERROR "p does not escape$" "leaking param: i$"
p.p1 = i p.p1 = i
} }
...@@ -211,7 +211,7 @@ func caller7() { ...@@ -211,7 +211,7 @@ func caller7() {
} }
// **in -> heap // **in -> heap
func param8(i **int) { // ERROR "param8 i does not escape$" func param8(i **int) { // ERROR "i does not escape$"
sink = **i // ERROR "\* \(\*i\) escapes to heap" sink = **i // ERROR "\* \(\*i\) escapes to heap"
} }
...@@ -294,7 +294,7 @@ type Indir struct { ...@@ -294,7 +294,7 @@ type Indir struct {
p ***int p ***int
} }
func (r *Indir) param12(i **int) { // ERROR "\(\*Indir\).param12 r does not escape$" "moved to heap: i$" func (r *Indir) param12(i **int) { // ERROR "r does not escape$" "moved to heap: i$"
r.p = &i r.p = &i
} }
...@@ -309,7 +309,7 @@ func caller12a() { ...@@ -309,7 +309,7 @@ func caller12a() {
func caller12b() { func caller12b() {
i := 0 // ERROR "moved to heap: i$" i := 0 // ERROR "moved to heap: i$"
p := &i // ERROR "moved to heap: p$" p := &i // ERROR "moved to heap: p$"
r := &Indir{} // ERROR "caller12b &Indir literal does not escape$" r := &Indir{} // ERROR "&Indir literal does not escape$"
r.param12(&p) r.param12(&p)
_ = r _ = r
} }
...@@ -335,7 +335,7 @@ type Val struct { ...@@ -335,7 +335,7 @@ type Val struct {
p **int p **int
} }
func (v Val) param13(i *int) { // ERROR "Val.param13 v does not escape$" "leaking param: i$" func (v Val) param13(i *int) { // ERROR "v does not escape$" "leaking param: i$"
*v.p = i *v.p = i
} }
...@@ -359,7 +359,7 @@ func caller13b() { ...@@ -359,7 +359,7 @@ func caller13b() {
func caller13c() { func caller13c() {
i := 0 // ERROR "moved to heap: i$" i := 0 // ERROR "moved to heap: i$"
var p *int var p *int
v := &Val{&p} // ERROR "caller13c &Val literal does not escape$" v := &Val{&p} // ERROR "&Val literal does not escape$"
v.param13(&i) v.param13(&i)
_ = v _ = v
} }
...@@ -400,7 +400,7 @@ func caller13g() { ...@@ -400,7 +400,7 @@ func caller13g() {
func caller13h() { func caller13h() {
i := 0 // ERROR "moved to heap: i$" i := 0 // ERROR "moved to heap: i$"
var p *int var p *int
v := &Val{&p} // ERROR "caller13h &Val literal does not escape$" v := &Val{&p} // ERROR "&Val literal does not escape$"
v.param13(&i) v.param13(&i)
sink = **v.p // ERROR "\* \(\*v\.p\) escapes to heap" sink = **v.p // ERROR "\* \(\*v\.p\) escapes to heap"
} }
...@@ -420,7 +420,7 @@ func g(x *Node) *Node { // ERROR "leaking param content: x" ...@@ -420,7 +420,7 @@ func g(x *Node) *Node { // ERROR "leaking param content: x"
} }
func h(x *Node) { // ERROR "leaking param: x" func h(x *Node) { // ERROR "leaking param: x"
y := &Node{x} // ERROR "h &Node literal does not escape" y := &Node{x} // ERROR "&Node literal does not escape"
Sink = g(y) Sink = g(y)
f(y) f(y)
} }
......
...@@ -38,7 +38,7 @@ func tSPPi() { ...@@ -38,7 +38,7 @@ func tSPPi() {
s := "cat" // ERROR "moved to heap: s$" s := "cat" // ERROR "moved to heap: s$"
ps := &s ps := &s
pps := &ps pps := &ps
pu := &U{ps, pps} // ERROR "tSPPi &U literal does not escape$" pu := &U{ps, pps} // ERROR "&U literal does not escape$"
Ssink = pu.SPPi() Ssink = pu.SPPi()
} }
...@@ -46,7 +46,7 @@ func tiSPP() { ...@@ -46,7 +46,7 @@ func tiSPP() {
s := "cat" // ERROR "moved to heap: s$" s := "cat" // ERROR "moved to heap: s$"
ps := &s ps := &s
pps := &ps pps := &ps
pu := &U{ps, pps} // ERROR "tiSPP &U literal does not escape$" pu := &U{ps, pps} // ERROR "&U literal does not escape$"
Ssink = *pu.SPP() Ssink = *pu.SPP()
} }
...@@ -55,7 +55,7 @@ func tSP() { ...@@ -55,7 +55,7 @@ func tSP() {
s := "cat" // ERROR "moved to heap: s$" s := "cat" // ERROR "moved to heap: s$"
ps := &s // ERROR "moved to heap: ps$" ps := &s // ERROR "moved to heap: ps$"
pps := &ps pps := &ps
pu := &U{ps, pps} // ERROR "tSP &U literal does not escape$" pu := &U{ps, pps} // ERROR "&U literal does not escape$"
Ssink = pu.SP() Ssink = pu.SP()
} }
...@@ -123,9 +123,9 @@ func tUPiSPa() { ...@@ -123,9 +123,9 @@ func tUPiSPa() {
ps4 := &s4 // ERROR "moved to heap: ps4$" ps4 := &s4 // ERROR "moved to heap: ps4$"
ps6 := &s6 // ERROR "moved to heap: ps6$" ps6 := &s6 // ERROR "moved to heap: ps6$"
u1 := U{&s1, &ps2} u1 := U{&s1, &ps2}
u2 := &U{&s3, &ps4} // ERROR "tUPiSPa &U literal does not escape$" u2 := &U{&s3, &ps4} // ERROR "&U literal does not escape$"
u3 := &U{&s5, &ps6} // ERROR "&U literal escapes to heap$" u3 := &U{&s5, &ps6} // ERROR "&U literal escapes to heap$"
v := &V{u1, u2, &u3} // ERROR "tUPiSPa &V literal does not escape$" v := &V{u1, u2, &u3} // ERROR "&V literal does not escape$"
Ssink = v.UPiSPa() // Ssink = &s3 (only &s3 really escapes) Ssink = v.UPiSPa() // Ssink = &s3 (only &s3 really escapes)
} }
...@@ -141,9 +141,9 @@ func tUPiSPb() { ...@@ -141,9 +141,9 @@ func tUPiSPb() {
ps4 := &s4 // ERROR "moved to heap: ps4$" ps4 := &s4 // ERROR "moved to heap: ps4$"
ps6 := &s6 // ERROR "moved to heap: ps6$" ps6 := &s6 // ERROR "moved to heap: ps6$"
u1 := U{&s1, &ps2} u1 := U{&s1, &ps2}
u2 := &U{&s3, &ps4} // ERROR "tUPiSPb &U literal does not escape$" u2 := &U{&s3, &ps4} // ERROR "&U literal does not escape$"
u3 := &U{&s5, &ps6} // ERROR "&U literal escapes to heap$" u3 := &U{&s5, &ps6} // ERROR "&U literal escapes to heap$"
v := &V{u1, u2, &u3} // ERROR "tUPiSPb &V literal does not escape$" v := &V{u1, u2, &u3} // ERROR "&V literal does not escape$"
Ssink = v.UPiSPb() // Ssink = &s3 (only &s3 really escapes) Ssink = v.UPiSPb() // Ssink = &s3 (only &s3 really escapes)
} }
...@@ -159,9 +159,9 @@ func tUPiSPc() { ...@@ -159,9 +159,9 @@ func tUPiSPc() {
ps4 := &s4 // ERROR "moved to heap: ps4$" ps4 := &s4 // ERROR "moved to heap: ps4$"
ps6 := &s6 // ERROR "moved to heap: ps6$" ps6 := &s6 // ERROR "moved to heap: ps6$"
u1 := U{&s1, &ps2} u1 := U{&s1, &ps2}
u2 := &U{&s3, &ps4} // ERROR "tUPiSPc &U literal does not escape$" u2 := &U{&s3, &ps4} // ERROR "&U literal does not escape$"
u3 := &U{&s5, &ps6} // ERROR "&U literal escapes to heap$" u3 := &U{&s5, &ps6} // ERROR "&U literal escapes to heap$"
v := &V{u1, u2, &u3} // ERROR "tUPiSPc &V literal does not escape$" v := &V{u1, u2, &u3} // ERROR "&V literal does not escape$"
Ssink = v.UPiSPc() // Ssink = &s3 (only &s3 really escapes) Ssink = v.UPiSPc() // Ssink = &s3 (only &s3 really escapes)
} }
...@@ -177,9 +177,9 @@ func tUPiSPd() { ...@@ -177,9 +177,9 @@ func tUPiSPd() {
ps4 := &s4 // ERROR "moved to heap: ps4$" ps4 := &s4 // ERROR "moved to heap: ps4$"
ps6 := &s6 // ERROR "moved to heap: ps6$" ps6 := &s6 // ERROR "moved to heap: ps6$"
u1 := U{&s1, &ps2} u1 := U{&s1, &ps2}
u2 := &U{&s3, &ps4} // ERROR "tUPiSPd &U literal does not escape$" u2 := &U{&s3, &ps4} // ERROR "&U literal does not escape$"
u3 := &U{&s5, &ps6} // ERROR "&U literal escapes to heap$" u3 := &U{&s5, &ps6} // ERROR "&U literal escapes to heap$"
v := &V{u1, u2, &u3} // ERROR "tUPiSPd &V literal does not escape$" v := &V{u1, u2, &u3} // ERROR "&V literal does not escape$"
Ssink = v.UPiSPd() // Ssink = &s3 (only &s3 really escapes) Ssink = v.UPiSPd() // Ssink = &s3 (only &s3 really escapes)
} }
...@@ -211,9 +211,9 @@ func tUPiSPPia() { ...@@ -211,9 +211,9 @@ func tUPiSPPia() {
ps4 := &s4 ps4 := &s4
ps6 := &s6 // ERROR "moved to heap: ps6$" ps6 := &s6 // ERROR "moved to heap: ps6$"
u1 := U{&s1, &ps2} u1 := U{&s1, &ps2}
u2 := &U{&s3, &ps4} // ERROR "tUPiSPPia &U literal does not escape$" u2 := &U{&s3, &ps4} // ERROR "&U literal does not escape$"
u3 := &U{&s5, &ps6} // ERROR "tUPiSPPia &U literal does not escape$" u3 := &U{&s5, &ps6} // ERROR "&U literal does not escape$"
v := &V{u1, u2, &u3} // ERROR "tUPiSPPia &V literal does not escape$" v := &V{u1, u2, &u3} // ERROR "&V literal does not escape$"
Ssink = v.UPiSPPia() // Ssink = *&ps4 = &s4 (only &s4 really escapes) Ssink = v.UPiSPPia() // Ssink = *&ps4 = &s4 (only &s4 really escapes)
} }
...@@ -229,9 +229,9 @@ func tUPiSPPib() { ...@@ -229,9 +229,9 @@ func tUPiSPPib() {
ps4 := &s4 ps4 := &s4
ps6 := &s6 // ERROR "moved to heap: ps6$" ps6 := &s6 // ERROR "moved to heap: ps6$"
u1 := U{&s1, &ps2} u1 := U{&s1, &ps2}
u2 := &U{&s3, &ps4} // ERROR "tUPiSPPib &U literal does not escape$" u2 := &U{&s3, &ps4} // ERROR "&U literal does not escape$"
u3 := &U{&s5, &ps6} // ERROR "tUPiSPPib &U literal does not escape$" u3 := &U{&s5, &ps6} // ERROR "&U literal does not escape$"
v := &V{u1, u2, &u3} // ERROR "tUPiSPPib &V literal does not escape$" v := &V{u1, u2, &u3} // ERROR "&V literal does not escape$"
Ssink = v.UPiSPPib() // Ssink = *&ps4 = &s4 (only &s4 really escapes) Ssink = v.UPiSPPib() // Ssink = *&ps4 = &s4 (only &s4 really escapes)
} }
...@@ -247,9 +247,9 @@ func tUPiSPPic() { ...@@ -247,9 +247,9 @@ func tUPiSPPic() {
ps4 := &s4 ps4 := &s4
ps6 := &s6 // ERROR "moved to heap: ps6$" ps6 := &s6 // ERROR "moved to heap: ps6$"
u1 := U{&s1, &ps2} u1 := U{&s1, &ps2}
u2 := &U{&s3, &ps4} // ERROR "tUPiSPPic &U literal does not escape$" u2 := &U{&s3, &ps4} // ERROR "&U literal does not escape$"
u3 := &U{&s5, &ps6} // ERROR "tUPiSPPic &U literal does not escape$" u3 := &U{&s5, &ps6} // ERROR "&U literal does not escape$"
v := &V{u1, u2, &u3} // ERROR "tUPiSPPic &V literal does not escape$" v := &V{u1, u2, &u3} // ERROR "&V literal does not escape$"
Ssink = v.UPiSPPic() // Ssink = *&ps4 = &s4 (only &s4 really escapes) Ssink = v.UPiSPPic() // Ssink = *&ps4 = &s4 (only &s4 really escapes)
} }
...@@ -265,9 +265,9 @@ func tUPiSPPid() { ...@@ -265,9 +265,9 @@ func tUPiSPPid() {
ps4 := &s4 ps4 := &s4
ps6 := &s6 // ERROR "moved to heap: ps6$" ps6 := &s6 // ERROR "moved to heap: ps6$"
u1 := U{&s1, &ps2} u1 := U{&s1, &ps2}
u2 := &U{&s3, &ps4} // ERROR "tUPiSPPid &U literal does not escape$" u2 := &U{&s3, &ps4} // ERROR "&U literal does not escape$"
u3 := &U{&s5, &ps6} // ERROR "tUPiSPPid &U literal does not escape$" u3 := &U{&s5, &ps6} // ERROR "&U literal does not escape$"
v := &V{u1, u2, &u3} // ERROR "tUPiSPPid &V literal does not escape$" v := &V{u1, u2, &u3} // ERROR "&V literal does not escape$"
Ssink = v.UPiSPPid() // Ssink = *&ps4 = &s4 (only &s4 really escapes) Ssink = v.UPiSPPid() // Ssink = *&ps4 = &s4 (only &s4 really escapes)
} }
...@@ -291,8 +291,8 @@ func tUPPiSPPia() { ...@@ -291,8 +291,8 @@ func tUPPiSPPia() {
ps4 := &s4 ps4 := &s4
ps6 := &s6 ps6 := &s6
u1 := U{&s1, &ps2} u1 := U{&s1, &ps2}
u2 := &U{&s3, &ps4} // ERROR "tUPPiSPPia &U literal does not escape$" u2 := &U{&s3, &ps4} // ERROR "&U literal does not escape$"
u3 := &U{&s5, &ps6} // ERROR "tUPPiSPPia &U literal does not escape$" u3 := &U{&s5, &ps6} // ERROR "&U literal does not escape$"
v := &V{u1, u2, &u3} // ERROR "tUPPiSPPia &V literal does not escape$" v := &V{u1, u2, &u3} // ERROR "&V literal does not escape$"
Ssink = v.UPPiSPPia() // Ssink = *&ps6 = &s6 (only &s6 really escapes) Ssink = v.UPPiSPPia() // Ssink = *&ps6 = &s6 (only &s6 really escapes)
} }
...@@ -38,7 +38,7 @@ func tSPPi() { ...@@ -38,7 +38,7 @@ func tSPPi() {
s := "cat" // ERROR "moved to heap: s$" s := "cat" // ERROR "moved to heap: s$"
ps := &s ps := &s
pps := &ps pps := &ps
pu := &U{ps, pps} // ERROR "tSPPi &U literal does not escape$" pu := &U{ps, pps} // ERROR "&U literal does not escape$"
Ssink = pu.SPPi() Ssink = pu.SPPi()
} }
...@@ -46,7 +46,7 @@ func tiSPP() { ...@@ -46,7 +46,7 @@ func tiSPP() {
s := "cat" // ERROR "moved to heap: s$" s := "cat" // ERROR "moved to heap: s$"
ps := &s ps := &s
pps := &ps pps := &ps
pu := &U{ps, pps} // ERROR "tiSPP &U literal does not escape$" pu := &U{ps, pps} // ERROR "&U literal does not escape$"
Ssink = *pu.SPP() Ssink = *pu.SPP()
} }
...@@ -55,7 +55,7 @@ func tSP() { ...@@ -55,7 +55,7 @@ func tSP() {
s := "cat" // ERROR "moved to heap: s$" s := "cat" // ERROR "moved to heap: s$"
ps := &s // ERROR "moved to heap: ps$" ps := &s // ERROR "moved to heap: ps$"
pps := &ps pps := &ps
pu := &U{ps, pps} // ERROR "tSP &U literal does not escape$" pu := &U{ps, pps} // ERROR "&U literal does not escape$"
Ssink = pu.SP() Ssink = pu.SP()
} }
...@@ -123,9 +123,9 @@ func tUPiSPa() { ...@@ -123,9 +123,9 @@ func tUPiSPa() {
ps4 := &s4 // ERROR "moved to heap: ps4$" ps4 := &s4 // ERROR "moved to heap: ps4$"
ps6 := &s6 // ERROR "moved to heap: ps6$" ps6 := &s6 // ERROR "moved to heap: ps6$"
u1 := U{&s1, &ps2} u1 := U{&s1, &ps2}
u2 := &U{&s3, &ps4} // ERROR "tUPiSPa &U literal does not escape$" u2 := &U{&s3, &ps4} // ERROR "&U literal does not escape$"
u3 := &U{&s5, &ps6} // ERROR "&U literal escapes to heap$" u3 := &U{&s5, &ps6} // ERROR "&U literal escapes to heap$"
v := &V{u1, u2, &u3} // ERROR "tUPiSPa &V literal does not escape$" v := &V{u1, u2, &u3} // ERROR "&V literal does not escape$"
Ssink = v.UPiSPa() // Ssink = &s3 (only &s3 really escapes) Ssink = v.UPiSPa() // Ssink = &s3 (only &s3 really escapes)
} }
...@@ -141,9 +141,9 @@ func tUPiSPb() { ...@@ -141,9 +141,9 @@ func tUPiSPb() {
ps4 := &s4 // ERROR "moved to heap: ps4$" ps4 := &s4 // ERROR "moved to heap: ps4$"
ps6 := &s6 // ERROR "moved to heap: ps6$" ps6 := &s6 // ERROR "moved to heap: ps6$"
u1 := U{&s1, &ps2} u1 := U{&s1, &ps2}
u2 := &U{&s3, &ps4} // ERROR "tUPiSPb &U literal does not escape$" u2 := &U{&s3, &ps4} // ERROR "&U literal does not escape$"
u3 := &U{&s5, &ps6} // ERROR "&U literal escapes to heap$" u3 := &U{&s5, &ps6} // ERROR "&U literal escapes to heap$"
v := &V{u1, u2, &u3} // ERROR "tUPiSPb &V literal does not escape$" v := &V{u1, u2, &u3} // ERROR "&V literal does not escape$"
Ssink = v.UPiSPb() // Ssink = &s3 (only &s3 really escapes) Ssink = v.UPiSPb() // Ssink = &s3 (only &s3 really escapes)
} }
...@@ -159,9 +159,9 @@ func tUPiSPc() { ...@@ -159,9 +159,9 @@ func tUPiSPc() {
ps4 := &s4 // ERROR "moved to heap: ps4$" ps4 := &s4 // ERROR "moved to heap: ps4$"
ps6 := &s6 // ERROR "moved to heap: ps6$" ps6 := &s6 // ERROR "moved to heap: ps6$"
u1 := U{&s1, &ps2} u1 := U{&s1, &ps2}
u2 := &U{&s3, &ps4} // ERROR "tUPiSPc &U literal does not escape$" u2 := &U{&s3, &ps4} // ERROR "&U literal does not escape$"
u3 := &U{&s5, &ps6} // ERROR "&U literal escapes to heap$" u3 := &U{&s5, &ps6} // ERROR "&U literal escapes to heap$"
v := &V{u1, u2, &u3} // ERROR "tUPiSPc &V literal does not escape$" v := &V{u1, u2, &u3} // ERROR "&V literal does not escape$"
Ssink = v.UPiSPc() // Ssink = &s3 (only &s3 really escapes) Ssink = v.UPiSPc() // Ssink = &s3 (only &s3 really escapes)
} }
...@@ -177,9 +177,9 @@ func tUPiSPd() { ...@@ -177,9 +177,9 @@ func tUPiSPd() {
ps4 := &s4 // ERROR "moved to heap: ps4$" ps4 := &s4 // ERROR "moved to heap: ps4$"
ps6 := &s6 // ERROR "moved to heap: ps6$" ps6 := &s6 // ERROR "moved to heap: ps6$"
u1 := U{&s1, &ps2} u1 := U{&s1, &ps2}
u2 := &U{&s3, &ps4} // ERROR "tUPiSPd &U literal does not escape$" u2 := &U{&s3, &ps4} // ERROR "&U literal does not escape$"
u3 := &U{&s5, &ps6} // ERROR "&U literal escapes to heap$" u3 := &U{&s5, &ps6} // ERROR "&U literal escapes to heap$"
v := &V{u1, u2, &u3} // ERROR "tUPiSPd &V literal does not escape$" v := &V{u1, u2, &u3} // ERROR "&V literal does not escape$"
Ssink = v.UPiSPd() // Ssink = &s3 (only &s3 really escapes) Ssink = v.UPiSPd() // Ssink = &s3 (only &s3 really escapes)
} }
...@@ -211,9 +211,9 @@ func tUPiSPPia() { ...@@ -211,9 +211,9 @@ func tUPiSPPia() {
ps4 := &s4 ps4 := &s4
ps6 := &s6 // ERROR "moved to heap: ps6$" ps6 := &s6 // ERROR "moved to heap: ps6$"
u1 := U{&s1, &ps2} u1 := U{&s1, &ps2}
u2 := &U{&s3, &ps4} // ERROR "tUPiSPPia &U literal does not escape$" u2 := &U{&s3, &ps4} // ERROR "&U literal does not escape$"
u3 := &U{&s5, &ps6} // ERROR "tUPiSPPia &U literal does not escape$" u3 := &U{&s5, &ps6} // ERROR "&U literal does not escape$"
v := &V{u1, u2, &u3} // ERROR "tUPiSPPia &V literal does not escape$" v := &V{u1, u2, &u3} // ERROR "&V literal does not escape$"
Ssink = v.UPiSPPia() // Ssink = *&ps4 = &s4 (only &s4 really escapes) Ssink = v.UPiSPPia() // Ssink = *&ps4 = &s4 (only &s4 really escapes)
} }
...@@ -229,9 +229,9 @@ func tUPiSPPib() { ...@@ -229,9 +229,9 @@ func tUPiSPPib() {
ps4 := &s4 ps4 := &s4
ps6 := &s6 // ERROR "moved to heap: ps6$" ps6 := &s6 // ERROR "moved to heap: ps6$"
u1 := U{&s1, &ps2} u1 := U{&s1, &ps2}
u2 := &U{&s3, &ps4} // ERROR "tUPiSPPib &U literal does not escape$" u2 := &U{&s3, &ps4} // ERROR "&U literal does not escape$"
u3 := &U{&s5, &ps6} // ERROR "tUPiSPPib &U literal does not escape$" u3 := &U{&s5, &ps6} // ERROR "&U literal does not escape$"
v := &V{u1, u2, &u3} // ERROR "tUPiSPPib &V literal does not escape$" v := &V{u1, u2, &u3} // ERROR "&V literal does not escape$"
Ssink = v.UPiSPPib() // Ssink = *&ps4 = &s4 (only &s4 really escapes) Ssink = v.UPiSPPib() // Ssink = *&ps4 = &s4 (only &s4 really escapes)
} }
...@@ -247,9 +247,9 @@ func tUPiSPPic() { ...@@ -247,9 +247,9 @@ func tUPiSPPic() {
ps4 := &s4 ps4 := &s4
ps6 := &s6 // ERROR "moved to heap: ps6$" ps6 := &s6 // ERROR "moved to heap: ps6$"
u1 := U{&s1, &ps2} u1 := U{&s1, &ps2}
u2 := &U{&s3, &ps4} // ERROR "tUPiSPPic &U literal does not escape$" u2 := &U{&s3, &ps4} // ERROR "&U literal does not escape$"
u3 := &U{&s5, &ps6} // ERROR "tUPiSPPic &U literal does not escape$" u3 := &U{&s5, &ps6} // ERROR "&U literal does not escape$"
v := &V{u1, u2, &u3} // ERROR "tUPiSPPic &V literal does not escape$" v := &V{u1, u2, &u3} // ERROR "&V literal does not escape$"
Ssink = v.UPiSPPic() // Ssink = *&ps4 = &s4 (only &s4 really escapes) Ssink = v.UPiSPPic() // Ssink = *&ps4 = &s4 (only &s4 really escapes)
} }
...@@ -265,9 +265,9 @@ func tUPiSPPid() { ...@@ -265,9 +265,9 @@ func tUPiSPPid() {
ps4 := &s4 ps4 := &s4
ps6 := &s6 // ERROR "moved to heap: ps6$" ps6 := &s6 // ERROR "moved to heap: ps6$"
u1 := U{&s1, &ps2} u1 := U{&s1, &ps2}
u2 := &U{&s3, &ps4} // ERROR "tUPiSPPid &U literal does not escape$" u2 := &U{&s3, &ps4} // ERROR "&U literal does not escape$"
u3 := &U{&s5, &ps6} // ERROR "tUPiSPPid &U literal does not escape$" u3 := &U{&s5, &ps6} // ERROR "&U literal does not escape$"
v := &V{u1, u2, &u3} // ERROR "tUPiSPPid &V literal does not escape$" v := &V{u1, u2, &u3} // ERROR "&V literal does not escape$"
Ssink = v.UPiSPPid() // Ssink = *&ps4 = &s4 (only &s4 really escapes) Ssink = v.UPiSPPid() // Ssink = *&ps4 = &s4 (only &s4 really escapes)
} }
...@@ -291,8 +291,8 @@ func tUPPiSPPia() { // This test is sensitive to the level cap in function summa ...@@ -291,8 +291,8 @@ func tUPPiSPPia() { // This test is sensitive to the level cap in function summa
ps4 := &s4 ps4 := &s4
ps6 := &s6 ps6 := &s6
u1 := U{&s1, &ps2} u1 := U{&s1, &ps2}
u2 := &U{&s3, &ps4} // ERROR "tUPPiSPPia &U literal does not escape$" u2 := &U{&s3, &ps4} // ERROR "&U literal does not escape$"
u3 := &U{&s5, &ps6} // ERROR "tUPPiSPPia &U literal does not escape$" u3 := &U{&s5, &ps6} // ERROR "&U literal does not escape$"
v := &V{u1, u2, &u3} // ERROR "tUPPiSPPia &V literal does not escape$" v := &V{u1, u2, &u3} // ERROR "&V literal does not escape$"
Ssink = v.UPPiSPPia() // Ssink = *&ps6 = &s6 (only &s6 really escapes) Ssink = v.UPPiSPPia() // Ssink = *&ps6 = &s6 (only &s6 really escapes)
} }
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
package foo package foo
func FooN(vals ...*int) (s int) { // ERROR "FooN vals does not escape" func FooN(vals ...*int) (s int) { // ERROR "vals does not escape"
for _, v := range vals { for _, v := range vals {
s += *v s += *v
} }
...@@ -37,14 +37,14 @@ func FooNz(vals ...*int) (s int) { // ERROR "leaking param: vals" ...@@ -37,14 +37,14 @@ func FooNz(vals ...*int) (s int) { // ERROR "leaking param: vals"
func TFooN() { func TFooN() {
for i := 0; i < 1000; i++ { for i := 0; i < 1000; i++ {
var i, j int var i, j int
FooN(&i, &j) // ERROR "TFooN ... argument does not escape" FooN(&i, &j) // ERROR "... argument does not escape"
} }
} }
func TFooNx() { func TFooNx() {
for i := 0; i < 1000; i++ { for i := 0; i < 1000; i++ {
var i, j, k int // ERROR "moved to heap: i" "moved to heap: j" "moved to heap: k" 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" FooNx(&k, &i, &j) // ERROR "... argument does not escape"
} }
} }
...@@ -84,7 +84,7 @@ func TFooI() { ...@@ -84,7 +84,7 @@ func TFooI() {
a := int32(1) // ERROR "moved to heap: a" a := int32(1) // ERROR "moved to heap: a"
b := "cat" b := "cat"
c := &a c := &a
FooI(a, b, c) // ERROR "a escapes to heap" "b escapes to heap" "TFooI ... argument does not escape" FooI(a, b, c) // ERROR "a escapes to heap" "b escapes to heap" "... argument does not escape"
} }
func FooJ(args ...interface{}) *int32 { // ERROR "leaking param: args to result ~r1 level=1" func FooJ(args ...interface{}) *int32 { // ERROR "leaking param: args to result ~r1 level=1"
...@@ -108,14 +108,14 @@ func TFooJ1() { ...@@ -108,14 +108,14 @@ func TFooJ1() {
a := int32(1) a := int32(1)
b := "cat" b := "cat"
c := &a c := &a
FooJ(a, b, c) // ERROR "TFooJ1 a does not escape" "TFooJ1 b does not escape" "TFooJ1 ... argument does not escape" FooJ(a, b, c) // ERROR "a does not escape" "b does not escape" "... argument does not escape"
} }
func TFooJ2() { func TFooJ2() {
a := int32(1) // ERROR "moved to heap: a" a := int32(1) // ERROR "moved to heap: a"
b := "cat" b := "cat"
c := &a c := &a
isink = FooJ(a, b, c) // ERROR "a escapes to heap" "b escapes to heap" "TFooJ2 ... argument does not escape" isink = FooJ(a, b, c) // ERROR "a escapes to heap" "b escapes to heap" "... argument does not escape"
} }
type fakeSlice struct { type fakeSlice struct {
...@@ -144,7 +144,7 @@ func TFooK2() { ...@@ -144,7 +144,7 @@ func TFooK2() {
a := int32(1) // ERROR "moved to heap: a" a := int32(1) // ERROR "moved to heap: a"
b := "cat" b := "cat"
c := &a c := &a
fs := fakeSlice{3, &[4]interface{}{a, b, c, nil}} // ERROR "a escapes to heap" "b escapes to heap" "TFooK2 &\[4\]interface {} literal does not escape" fs := fakeSlice{3, &[4]interface{}{a, b, c, nil}} // ERROR "a escapes to heap" "b escapes to heap" "&\[4\]interface {} literal does not escape"
isink = FooK(fs) isink = FooK(fs)
} }
...@@ -169,6 +169,6 @@ func TFooL2() { ...@@ -169,6 +169,6 @@ func TFooL2() {
a := int32(1) // ERROR "moved to heap: a" a := int32(1) // ERROR "moved to heap: a"
b := "cat" b := "cat"
c := &a c := &a
s := []interface{}{a, b, c} // ERROR "a escapes to heap" "b escapes to heap" "TFooL2 \[\]interface {} literal does not escape" s := []interface{}{a, b, c} // ERROR "a escapes to heap" "b escapes to heap" "\[\]interface {} literal does not escape"
isink = FooL(s) isink = FooL(s)
} }
...@@ -26,7 +26,7 @@ func f(a A) int { ...@@ -26,7 +26,7 @@ func f(a A) int {
return 0 return 0
} }
func g(a *A) int { // ERROR "g a does not escape" func g(a *A) int { // ERROR "a does not escape"
for i, x := range &a.b { for i, x := range &a.b {
if x != 0 { if x != 0 {
return 64*i + int(x) return 64*i + int(x)
......
...@@ -20,7 +20,7 @@ func main() { ...@@ -20,7 +20,7 @@ func main() {
// (sometimes it takes 1 time, sometimes it takes ~4,000+). // (sometimes it takes 1 time, sometimes it takes ~4,000+).
for iter := 0; ; iter++ { for iter := 0; ; iter++ {
if iter%50 == 0 { if iter%50 == 0 {
fmt.Println(iter) // ERROR "iter escapes to heap$" "main ... argument does not escape$" fmt.Println(iter) // ERROR "iter escapes to heap$" "... argument does not escape$"
} }
test1(iter) test1(iter)
test2(iter) test2(iter)
...@@ -60,20 +60,20 @@ func test1(iter int) { ...@@ -60,20 +60,20 @@ func test1(iter int) {
} }
if len(m) != maxI { if len(m) != maxI {
panic(fmt.Sprintf("iter %d: maxI = %d, len(m) = %d", iter, maxI, len(m))) // ERROR "iter escapes to heap$" "len\(m\) escapes to heap$" "maxI escapes to heap$" "test1 ... argument does not escape$" panic(fmt.Sprintf("iter %d: maxI = %d, len(m) = %d", iter, maxI, len(m))) // ERROR "iter escapes to heap$" "len\(m\) escapes to heap$" "maxI escapes to heap$" "... argument does not escape$"
} }
} }
func test2(iter int) { func test2(iter int) {
const maxI = 500 const maxI = 500
m := make(map[int][]int) // ERROR "test2 make\(map\[int\]\[\]int\) does not escape$" m := make(map[int][]int) // ERROR "make\(map\[int\]\[\]int\) does not escape$"
// var fn func() // var fn func()
for i := 0; i < maxI; i++ { for i := 0; i < maxI; i++ {
var fn func() // this makes it work, because fn stays off heap var fn func() // this makes it work, because fn stays off heap
j := 0 j := 0
fn = func() { // ERROR "test2 func literal does not escape$" fn = func() { // ERROR "func literal does not escape$"
m[i] = append(m[i], 0) m[i] = append(m[i], 0)
if j < 25 { if j < 25 {
j++ j++
...@@ -84,7 +84,7 @@ func test2(iter int) { ...@@ -84,7 +84,7 @@ func test2(iter int) {
} }
if len(m) != maxI { if len(m) != maxI {
panic(fmt.Sprintf("iter %d: maxI = %d, len(m) = %d", iter, maxI, len(m))) // ERROR "iter escapes to heap$" "len\(m\) escapes to heap$" "maxI escapes to heap$" "test2 ... argument does not escape$" panic(fmt.Sprintf("iter %d: maxI = %d, len(m) = %d", iter, maxI, len(m))) // ERROR "iter escapes to heap$" "len\(m\) escapes to heap$" "maxI escapes to heap$" "... argument does not escape$"
} }
} }
...@@ -110,7 +110,7 @@ func test3(iter int) { ...@@ -110,7 +110,7 @@ func test3(iter int) {
} }
if *m != maxI { if *m != maxI {
panic(fmt.Sprintf("iter %d: maxI = %d, *m = %d", iter, maxI, *m)) // ERROR "\*m escapes to heap$" "iter escapes to heap$" "maxI escapes to heap$" "test3 ... argument does not escape$" panic(fmt.Sprintf("iter %d: maxI = %d, *m = %d", iter, maxI, *m)) // ERROR "\*m escapes to heap$" "iter escapes to heap$" "maxI escapes to heap$" "... argument does not escape$"
} }
} }
...@@ -124,7 +124,7 @@ func test4(iter int) { ...@@ -124,7 +124,7 @@ func test4(iter int) {
for i := 0; i < maxI; i++ { for i := 0; i < maxI; i++ {
var fn func() // this makes it work, because fn stays off heap var fn func() // this makes it work, because fn stays off heap
j := 0 j := 0
fn = func() { // ERROR "test4 func literal does not escape$" fn = func() { // ERROR "func literal does not escape$"
if j < 100 { if j < 100 {
j++ j++
fn() fn()
...@@ -136,7 +136,7 @@ func test4(iter int) { ...@@ -136,7 +136,7 @@ func test4(iter int) {
} }
if *m != maxI { if *m != maxI {
panic(fmt.Sprintf("iter %d: maxI = %d, *m = %d", iter, maxI, *m)) // ERROR "\*m escapes to heap$" "iter escapes to heap$" "maxI escapes to heap$" "test4 ... argument does not escape$" panic(fmt.Sprintf("iter %d: maxI = %d, *m = %d", iter, maxI, *m)) // ERROR "\*m escapes to heap$" "iter escapes to heap$" "maxI escapes to heap$" "... argument does not escape$"
} }
} }
...@@ -144,7 +144,7 @@ type str struct { ...@@ -144,7 +144,7 @@ type str struct {
m *int m *int
} }
func recur1(j int, s *str) { // ERROR "recur1 s does not escape" func recur1(j int, s *str) { // ERROR "s does not escape"
if j < 100 { if j < 100 {
j++ j++
recur1(j, s) recur1(j, s)
...@@ -167,7 +167,7 @@ func test5(iter int) { ...@@ -167,7 +167,7 @@ func test5(iter int) {
} }
if *m != maxI { if *m != maxI {
panic(fmt.Sprintf("iter %d: maxI = %d, *m = %d", iter, maxI, *m)) // ERROR "\*m escapes to heap$" "iter escapes to heap$" "maxI escapes to heap$" "test5 ... argument does not escape$" panic(fmt.Sprintf("iter %d: maxI = %d, *m = %d", iter, maxI, *m)) // ERROR "\*m escapes to heap$" "iter escapes to heap$" "maxI escapes to heap$" "... argument does not escape$"
} }
} }
...@@ -185,6 +185,6 @@ func test6(iter int) { ...@@ -185,6 +185,6 @@ func test6(iter int) {
} }
if *m != maxI { if *m != maxI {
panic(fmt.Sprintf("iter %d: maxI = %d, *m = %d", iter, maxI, *m)) // ERROR "\*m escapes to heap$" "iter escapes to heap$" "maxI escapes to heap$" "test6 ... argument does not escape$" panic(fmt.Sprintf("iter %d: maxI = %d, *m = %d", iter, maxI, *m)) // ERROR "\*m escapes to heap$" "iter escapes to heap$" "maxI escapes to heap$" "... argument does not escape$"
} }
} }
...@@ -22,12 +22,12 @@ type closure func(i, j int) ent ...@@ -22,12 +22,12 @@ type closure func(i, j int) ent
type ent int type ent int
func (e ent) String() string { func (e ent) String() string {
return fmt.Sprintf("%d", int(e)) // ERROR "ent.String ... argument does not escape$" "int\(e\) escapes to heap$" return fmt.Sprintf("%d", int(e)) // ERROR "... argument does not escape$" "int\(e\) escapes to heap$"
} }
//go:noinline //go:noinline
func foo(ops closure, j int) (err fmt.Stringer) { // ERROR "foo ops does not escape" func foo(ops closure, j int) (err fmt.Stringer) { // ERROR "ops does not escape"
enqueue := func(i int) fmt.Stringer { // ERROR "foo func literal does not escape" enqueue := func(i int) fmt.Stringer { // ERROR "func literal does not escape"
return ops(i, j) // ERROR "ops\(i, j\) escapes to heap$" return ops(i, j) // ERROR "ops\(i, j\) escapes to heap$"
} }
err = enqueue(4) err = enqueue(4)
...@@ -39,9 +39,9 @@ func foo(ops closure, j int) (err fmt.Stringer) { // ERROR "foo ops does not esc ...@@ -39,9 +39,9 @@ func foo(ops closure, j int) (err fmt.Stringer) { // ERROR "foo ops does not esc
func main() { func main() {
// 3 identical functions, to get different escape behavior. // 3 identical functions, to get different escape behavior.
f := func(i, j int) ent { // ERROR "main func literal does not escape" f := func(i, j int) ent { // ERROR "func literal does not escape"
return ent(i + j) return ent(i + j)
} }
i := foo(f, 3).(ent) 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$" fmt.Printf("foo(f,3)=%d\n", int(i)) // ERROR "int\(i\) escapes to heap$" "... argument does not escape$"
} }
...@@ -10,14 +10,14 @@ package p ...@@ -10,14 +10,14 @@ package p
type S struct{} type S struct{}
func (s *S) Inc() {} // ERROR "\(\*S\).Inc s does not escape" func (s *S) Inc() {} // ERROR "s does not escape"
var N int var N int
func F1() { func F1() {
var s S // ERROR "moved to heap: s" var s S // ERROR "moved to heap: s"
for i := 0; i < N; i++ { for i := 0; i < N; i++ {
fs := []func(){ // ERROR "F1 \[\]func\(\) literal does not escape" fs := []func(){ // ERROR "\[\]func\(\) literal does not escape"
s.Inc, // ERROR "F1 s.Inc does not escape" s.Inc, // ERROR "s.Inc does not escape"
} }
for _, f := range fs { for _, f := range fs {
f() f()
...@@ -28,8 +28,8 @@ func F1() { ...@@ -28,8 +28,8 @@ func F1() {
func F2() { func F2() {
var s S // ERROR "moved to heap: s" var s S // ERROR "moved to heap: s"
for i := 0; i < N; i++ { for i := 0; i < N; i++ {
for _, f := range []func(){ // ERROR "F2 \[\]func\(\) literal does not escape" for _, f := range []func(){ // ERROR "\[\]func\(\) literal does not escape"
s.Inc, // ERROR "F2 s.Inc does not escape" s.Inc, // ERROR "s.Inc does not escape"
} { } {
f() f()
} }
......
...@@ -18,20 +18,20 @@ func bufferNotEscape() string { ...@@ -18,20 +18,20 @@ func bufferNotEscape() string {
// can be stack-allocated. // can be stack-allocated.
var b bytes.Buffer var b bytes.Buffer
b.WriteString("123") b.WriteString("123")
b.Write([]byte{'4'}) // ERROR "bufferNotEscape \[\]byte literal does not escape$" b.Write([]byte{'4'}) // ERROR "\[\]byte literal does not escape$"
return b.String() // ERROR "inlining call to bytes.\(\*Buffer\).String$" "string\(bytes.b.buf\[bytes.b.off:\]\) escapes to heap$" return b.String() // ERROR "inlining call to bytes.\(\*Buffer\).String$" "string\(bytes.b.buf\[bytes.b.off:\]\) escapes to heap$"
} }
func bufferNoEscape2(xs []string) int { // ERROR "bufferNoEscape2 xs does not escape$" func bufferNoEscape2(xs []string) int { // ERROR "xs does not escape$"
b := bytes.NewBuffer(make([]byte, 0, 64)) // ERROR "bufferNoEscape2 &bytes.Buffer literal does not escape$" "bufferNoEscape2 make\(\[\]byte, 0, 64\) does not escape$" "inlining call to bytes.NewBuffer$" b := bytes.NewBuffer(make([]byte, 0, 64)) // ERROR "&bytes.Buffer literal does not escape$" "make\(\[\]byte, 0, 64\) does not escape$" "inlining call to bytes.NewBuffer$"
for _, x := range xs { for _, x := range xs {
b.WriteString(x) b.WriteString(x)
} }
return b.Len() // ERROR "inlining call to bytes.\(\*Buffer\).Len$" return b.Len() // ERROR "inlining call to bytes.\(\*Buffer\).Len$"
} }
func bufferNoEscape3(xs []string) string { // ERROR "bufferNoEscape3 xs does not escape$" func bufferNoEscape3(xs []string) string { // ERROR "xs does not escape$"
b := bytes.NewBuffer(make([]byte, 0, 64)) // ERROR "bufferNoEscape3 &bytes.Buffer literal does not escape$" "bufferNoEscape3 make\(\[\]byte, 0, 64\) does not escape$" "inlining call to bytes.NewBuffer$" b := bytes.NewBuffer(make([]byte, 0, 64)) // ERROR "&bytes.Buffer literal does not escape$" "make\(\[\]byte, 0, 64\) does not escape$" "inlining call to bytes.NewBuffer$"
for _, x := range xs { for _, x := range xs {
b.WriteString(x) b.WriteString(x)
b.WriteByte(',') b.WriteByte(',')
...@@ -47,11 +47,11 @@ func bufferNoEscape4() []byte { ...@@ -47,11 +47,11 @@ func bufferNoEscape4() []byte {
} }
func bufferNoEscape5() { // ERROR "can inline bufferNoEscape5$" func bufferNoEscape5() { // ERROR "can inline bufferNoEscape5$"
b := bytes.NewBuffer(make([]byte, 0, 128)) // ERROR "bufferNoEscape5 &bytes.Buffer literal does not escape$" "bufferNoEscape5 make\(\[\]byte, 0, 128\) does not escape$" "inlining call to bytes.NewBuffer$" b := bytes.NewBuffer(make([]byte, 0, 128)) // ERROR "&bytes.Buffer literal does not escape$" "make\(\[\]byte, 0, 128\) does not escape$" "inlining call to bytes.NewBuffer$"
useBuffer(b) useBuffer(b)
} }
//go:noinline //go:noinline
func useBuffer(b *bytes.Buffer) { // ERROR "useBuffer b does not escape$" func useBuffer(b *bytes.Buffer) { // ERROR "b does not escape$"
b.WriteString("1234") b.WriteString("1234")
} }
...@@ -95,15 +95,15 @@ func p() int { ...@@ -95,15 +95,15 @@ func p() int {
} }
func q(x int) int { func q(x int) int {
foo := func() int { return x * 2 } // ERROR "can inline q.func1" "q func literal does not escape" foo := func() int { return x * 2 } // ERROR "can inline q.func1" "func literal does not escape"
return foo() // ERROR "inlining call to q.func1" return foo() // ERROR "inlining call to q.func1"
} }
func r(z int) int { func r(z int) int {
foo := func(x int) int { // ERROR "can inline r.func1" "r func literal does not escape" foo := func(x int) int { // ERROR "can inline r.func1" "func literal does not escape"
return x + z return x + z
} }
bar := func(x int) int { // ERROR "r func literal does not escape" bar := func(x int) int { // ERROR "func literal does not escape"
return x + func(y int) int { // ERROR "can inline r.func2.1" return x + func(y int) int { // ERROR "can inline r.func2.1"
return 2*y + x*z return 2*y + x*z
}(x) // ERROR "inlining call to r.func2.1" }(x) // ERROR "inlining call to r.func2.1"
...@@ -112,7 +112,7 @@ func r(z int) int { ...@@ -112,7 +112,7 @@ func r(z int) int {
} }
func s0(x int) int { func s0(x int) int {
foo := func() { // ERROR "can inline s0.func1" "s0 func literal does not escape" foo := func() { // ERROR "can inline s0.func1" "func literal does not escape"
x = x + 1 x = x + 1
} }
foo() // ERROR "inlining call to s0.func1" foo() // ERROR "inlining call to s0.func1"
...@@ -120,7 +120,7 @@ func s0(x int) int { ...@@ -120,7 +120,7 @@ func s0(x int) int {
} }
func s1(x int) int { func s1(x int) int {
foo := func() int { // ERROR "can inline s1.func1" "s1 func literal does not escape" foo := func() int { // ERROR "can inline s1.func1" "func literal does not escape"
return x return x
} }
x = x + 1 x = x + 1
...@@ -145,7 +145,7 @@ func switchBreak(x, y int) int { ...@@ -145,7 +145,7 @@ func switchBreak(x, y int) int {
} }
// can't currently inline functions with a type switch // can't currently inline functions with a type switch
func switchType(x interface{}) int { // ERROR "switchType x does not escape" func switchType(x interface{}) int { // ERROR "x does not escape"
switch x.(type) { switch x.(type) {
case int: case int:
return x.(int) return x.(int)
......
...@@ -9,18 +9,18 @@ ...@@ -9,18 +9,18 @@
package foo package foo
func small(a []int) int { // ERROR "can inline small as:.*" "small a does not escape" func small(a []int) int { // ERROR "can inline small as:.*" "a does not escape"
// Cost 16 body (need cost < 20). // Cost 16 body (need cost < 20).
// See cmd/compile/internal/gc/inl.go:inlineBigFunction* // See cmd/compile/internal/gc/inl.go:inlineBigFunction*
return a[0] + a[1] + a[2] + a[3] return a[0] + a[1] + a[2] + a[3]
} }
func medium(a []int) int { // ERROR "can inline medium as:.*" "medium a does not escape" func medium(a []int) int { // ERROR "can inline medium as:.*" "a does not escape"
// Cost 32 body (need cost > 20 and cost < 80). // Cost 32 body (need cost > 20 and cost < 80).
// See cmd/compile/internal/gc/inl.go:inlineBigFunction* // See cmd/compile/internal/gc/inl.go:inlineBigFunction*
return a[0] + a[1] + a[2] + a[3] + a[4] + a[5] + a[6] + a[7] return a[0] + a[1] + a[2] + a[3] + a[4] + a[5] + a[6] + a[7]
} }
func f(a []int) int { // ERROR "cannot inline f:.*" "f a does not escape" func f(a []int) int { // ERROR "cannot inline f:.*" "a does not escape"
// Add lots of nodes to f's body. We need >5000. // Add lots of nodes to f's body. We need >5000.
// See cmd/compile/internal/gc/inl.go:inlineBigFunction* // See cmd/compile/internal/gc/inl.go:inlineBigFunction*
a[0] = 0 a[0] = 0
......
package x package x
func indexByte(xs []byte, b byte) int { // ERROR "indexByte xs does not escape" func indexByte(xs []byte, b byte) int { // ERROR "xs does not escape"
for i, x := range xs { for i, x := range xs {
if x == b { if x == b {
return i return i
......
...@@ -15,7 +15,7 @@ import ( ...@@ -15,7 +15,7 @@ import (
"unsafe" "unsafe"
) )
func f(uintptr) // ERROR "f assuming arg#1 is unsafe uintptr" func f(uintptr) // ERROR "assuming arg#1 is unsafe uintptr"
func g() { // ERROR "can inline g" func g() { // ERROR "can inline g"
var t int var t int
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment