// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Note the doubled -m; this tests the "because" explanations for escapes,
// and is likely to be annoyingly fragile under compiler change.
// As long as the explanations look reasonably sane, meaning eyeball verify output of
// go build -gcflags '-l -m -m' escape_because.go
// and investigate changes, feel free to update with
// go run run.go -update_errors -- escape_because.go
packagemain
funcmain(){
}
varsinkinterface{}
typepairstruct{
x,y*int
}
typePairyinterface{
EqualParts()bool
}
func(p*pair)EqualParts()bool{// ERROR "\(\*pair\).EqualParts p does not escape$"
returnp!=nil&&(p.x==p.y||*p.x==*p.y)
}
funcf1(p*int){// ERROR "from \[3\]\*int literal \(array literal element\) at escape_because.go:34$" "from a \(assigned\) at escape_because.go:34$" "from a \(interface-converted\) at escape_because.go:35$" "from sink \(assigned to top level variable\) at escape_because.go:19$" "leaking param: p$"
a:=[3]*int{p,nil,nil}
sink=a// ERROR "a escapes to heap$" "from sink \(assigned to top level variable\) at escape_because.go:19$"
}
funcf2(q*int){// ERROR "from &u \(address-of\) at escape_because.go:43$" "from &u \(interface-converted\) at escape_because.go:43$" "from pair literal \(struct literal element\) at escape_because.go:41$" "from s \(assigned\) at escape_because.go:40$" "from sink \(assigned to top level variable\) at escape_because.go:19$" "from t \(assigned\) at escape_because.go:41$" "from u \(assigned\) at escape_because.go:42$" "leaking param: q$"
s:=q
t:=pair{s,nil}
u:=t// ERROR "moved to heap: u$"
sink=&u// ERROR "&u escapes to heap$" "from &u \(interface-converted\) at escape_because.go:43$" "from sink \(assigned to top level variable\) at escape_because.go:19$"
}
funcf3(r*int)interface{}{// ERROR "from \[\]\*int literal \(slice-literal-element\) at escape_because.go:47$" "from c \(assigned\) at escape_because.go:47$" "from c \(interface-converted\) at escape_because.go:48$" "from ~r1 \(return\) at escape_because.go:46$" "leaking param: r to result ~r1 level=-1$"
c:=[]*int{r}// ERROR "\[\]\*int literal escapes to heap$" "from c \(assigned\) at escape_because.go:47$" "from c \(interface-converted\) at escape_because.go:48$" "from ~r1 \(return\) at escape_because.go:46$"
returnc// "return" // ERROR "c escapes to heap$" "from ~r1 \(return\) at escape_because.go:46$"
}
funcf4(a*int,s[]*int)int{// ERROR "from \*s \(indirection\) at escape_because.go:51$" "from append\(s, a\) \(appended to slice\) at escape_because.go:52$" "from append\(s, a\) \(appendee slice\) at escape_because.go:52$" "leaking param content: s$" "leaking param: a$"
s=append(s,a)
return*(s[0])
}
funcf5(s1,s2[]*int)int{// ERROR "from \*s1 \(indirection\) at escape_because.go:56$" "from \*s2 \(indirection\) at escape_because.go:56$" "from append\(s1, s2...\) \(appended slice...\) at escape_because.go:57$" "from append\(s1, s2...\) \(appendee slice\) at escape_because.go:57$" "leaking param content: s1$" "leaking param content: s2$"
s1=append(s1,s2...)
return*(s1[0])
}
funcf6(x,y*int)bool{// ERROR "f6 x does not escape$" "f6 y does not escape$"
p:=pair{x,y}
varPPairy=&p// ERROR "f6 &p does not escape$"
pp:=P.(*pair)
returnpp.EqualParts()
}
funcf7(xmap[int]*int,yint)*int{// ERROR "f7 x does not escape$"
z,ok:=x[y]
if!ok{
returnnil
}
returnz
}
funcf8(xint,y*int)*int{// ERROR "from ~r2 \(return\) at escape_because.go:76$" "from ~r2 \(returned from recursive function\) at escape_because.go:76$" "leaking param: y$" "moved to heap: x$"
ifx<=0{
returny
}
x--
returnf8(*y,&x)// ERROR "&x escapes to heap$" "from y \(arg to recursive call\) at escape_because.go:76$" "from ~r2 \(return\) at escape_because.go:76$" "from ~r2 \(returned from recursive function\) at escape_because.go:76$"
}
funcf9(xint,y...*int)*int{// ERROR "from y\[0\] \(dot of pointer\) at escape_because.go:86$" "from ~r2 \(return\) at escape_because.go:84$" "from ~r2 \(returned from recursive function\) at escape_because.go:84$" "leaking param content: y$" "leaking param: y to result ~r2 level=1$" "moved to heap: x$"
ifx<=0{
returny[0]
}
x--
returnf9(*y[0],&x)// ERROR "&x escapes to heap$" "f9 ... argument does not escape$" "from ... argument \(... arg to recursive call\) at escape_because.go:89$"
}
funcf10(xmap[*int]*int,y,z*int)*int{// ERROR "f10 x does not escape$" "from x\[y\] \(key of map put\) at escape_because.go:93$" "from x\[y\] \(value of map put\) at escape_because.go:93$" "leaking param: y$" "leaking param: z$"
x[y]=z
returnz
}
funcf11(xmap[*int]*int,y,z*int)map[*int]*int{// ERROR "f11 x does not escape$" "from map\[\*int\]\*int literal \(map literal key\) at escape_because.go:98$" "from map\[\*int\]\*int literal \(map literal value\) at escape_because.go:98$" "leaking param: y$" "leaking param: z$"
returnmap[*int]*int{y:z}// ERROR "from ~r3 \(return\) at escape_because.go:97$" "map\[\*int\]\*int literal escapes to heap$"
}
// The list below is all of the why-escapes messages seen building the escape analysis tests.