mirror of
https://github.com/golang/go
synced 2024-11-05 18:36:08 +00:00
test: add tests for escape analysis of function parameters
False positives (var incorrectly escapes) are marked with BAD. Change-Id: I002ac5965ec6748adafa2c4c657c97d8f7ff75d0 Reviewed-on: https://go-review.googlesource.com/5311 Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
09b7f4f12a
commit
d593f4a4d5
1 changed files with 326 additions and 0 deletions
326
test/escape_param.go
Normal file
326
test/escape_param.go
Normal file
|
@ -0,0 +1,326 @@
|
|||
// errorcheck -0 -m -l
|
||||
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Test escape analysis for function parameters.
|
||||
|
||||
// In this test almost everything is BAD except the simplest cases
|
||||
// where input directly flows to output.
|
||||
|
||||
package escape
|
||||
|
||||
var sink interface{}
|
||||
|
||||
// in -> out
|
||||
func param0(p *int) *int { // ERROR "leaking param: p to result ~r1$"
|
||||
return p
|
||||
}
|
||||
|
||||
func caller0a() {
|
||||
i := 0
|
||||
_ = param0(&i) // ERROR "caller0a &i does not escape$"
|
||||
}
|
||||
|
||||
func caller0b() {
|
||||
i := 0 // ERROR "moved to heap: i$"
|
||||
sink = param0(&i) // ERROR "&i escapes to heap$" "param0\(&i\) escapes to heap"
|
||||
}
|
||||
|
||||
// in, in -> out, out
|
||||
func param1(p1, p2 *int) (*int, *int) { // ERROR "leaking param: p1 to result ~r2$" "leaking param: p2 to result ~r3$"
|
||||
return p1, p2
|
||||
}
|
||||
|
||||
func caller1() {
|
||||
i := 0 // ERROR "moved to heap: i$"
|
||||
j := 0
|
||||
sink, _ = param1(&i, &j) // ERROR "&i escapes to heap$" "caller1 &j does not escape$"
|
||||
}
|
||||
|
||||
// in -> other in
|
||||
func param2(p1 *int, p2 **int) { // ERROR "leaking param: p1$" "param2 p2 does not escape$"
|
||||
*p2 = p1
|
||||
}
|
||||
|
||||
func caller2a() {
|
||||
i := 0 // ERROR "moved to heap: i$"
|
||||
var p *int
|
||||
param2(&i, &p) // ERROR "&i escapes to heap$" "caller2a &p does not escape$"
|
||||
_ = p
|
||||
}
|
||||
|
||||
func caller2b() {
|
||||
i := 0 // ERROR "moved to heap: i$"
|
||||
var p *int
|
||||
param2(&i, &p) // ERROR "&i escapes to heap$" "caller2b &p does not escape$"
|
||||
sink = p // ERROR "p escapes to heap$"
|
||||
}
|
||||
|
||||
// in -> in
|
||||
type Pair struct {
|
||||
p1 *int
|
||||
p2 *int
|
||||
}
|
||||
|
||||
func param3(p *Pair) { // ERROR "leaking param: p$"
|
||||
p.p1 = p.p2
|
||||
}
|
||||
|
||||
func caller3a() {
|
||||
i := 0 // ERROR "moved to heap: i$"
|
||||
j := 0 // ERROR "moved to heap: j$"
|
||||
p := Pair{&i, &j} // ERROR "&i escapes to heap$" "&j escapes to heap$" "moved to heap: p$"
|
||||
param3(&p) // ERROR "&p escapes to heap$"
|
||||
_ = p
|
||||
}
|
||||
|
||||
func caller3b() {
|
||||
i := 0 // ERROR "moved to heap: i$"
|
||||
j := 0 // ERROR "moved to heap: j$"
|
||||
p := Pair{&i, &j} // ERROR "&i escapes to heap$" "&j escapes to heap$" "moved to heap: p$"
|
||||
param3(&p) // ERROR "&p escapes to heap$"
|
||||
sink = p // ERROR "p escapes to heap$"
|
||||
}
|
||||
|
||||
// in -> rcvr
|
||||
func (p *Pair) param4(i *int) { // ERROR "\(\*Pair\).param4 p does not escape$" "leaking param: i$"
|
||||
p.p1 = i
|
||||
}
|
||||
|
||||
func caller4a() {
|
||||
i := 0 // ERROR "moved to heap: i$"
|
||||
p := Pair{}
|
||||
p.param4(&i) // ERROR "&i escapes to heap$" "caller4a p does not escape$"
|
||||
_ = p
|
||||
}
|
||||
|
||||
func caller4b() {
|
||||
i := 0 // ERROR "moved to heap: i$"
|
||||
p := Pair{}
|
||||
p.param4(&i) // ERROR "&i escapes to heap$" "caller4b p does not escape$"
|
||||
sink = p // ERROR "p escapes to heap$"
|
||||
}
|
||||
|
||||
// in -> heap
|
||||
func param5(i *int) { // ERROR "leaking param: i$"
|
||||
sink = i // ERROR "i escapes to heap$"
|
||||
}
|
||||
|
||||
func caller5() {
|
||||
i := 0 // ERROR "moved to heap: i$"
|
||||
param5(&i) // ERROR "&i escapes to heap$"
|
||||
}
|
||||
|
||||
// *in -> heap
|
||||
func param6(i ***int) { // ERROR "leaking param: i$"
|
||||
sink = *i // ERROR "\*i escapes to heap$"
|
||||
}
|
||||
|
||||
func caller6a() {
|
||||
i := 0 // ERROR "moved to heap: i$"
|
||||
p := &i // ERROR "&i escapes to heap$" "moved to heap: p$"
|
||||
p2 := &p // ERROR "&p escapes to heap$" "moved to heap: p2$"
|
||||
param6(&p2) // ERROR "&p2 escapes to heap$"
|
||||
}
|
||||
|
||||
// **in -> heap
|
||||
func param7(i ***int) { // ERROR "leaking param: i$"
|
||||
sink = **i // ERROR "\* \(\*i\) escapes to heap"
|
||||
}
|
||||
|
||||
func caller7() {
|
||||
i := 0 // ERROR "moved to heap: i$"
|
||||
p := &i // ERROR "&i escapes to heap$" "moved to heap: p$"
|
||||
p2 := &p // ERROR "&p escapes to heap$" "moved to heap: p2$"
|
||||
param7(&p2) // ERROR "&p2 escapes to heap$"
|
||||
}
|
||||
|
||||
// **in -> heap
|
||||
func param8(i **int) { // ERROR "param8 i does not escape$"
|
||||
sink = **i // ERROR "\* \(\*i\) escapes to heap"
|
||||
}
|
||||
|
||||
func caller8() {
|
||||
i := 0
|
||||
p := &i // ERROR "caller8 &i does not escape$"
|
||||
param8(&p) // ERROR "caller8 &p does not escape$"
|
||||
}
|
||||
|
||||
// *in -> out
|
||||
func param9(p ***int) **int { // ERROR "param9 leaking param p content to result ~r1$"
|
||||
return *p
|
||||
}
|
||||
|
||||
func caller9a() {
|
||||
i := 0 // ERROR "moved to heap: i$"
|
||||
p := &i // ERROR "&i escapes to heap$" "moved to heap: p$"
|
||||
p2 := &p // ERROR "&p escapes to heap$"
|
||||
_ = param9(&p2) // ERROR "caller9a &p2 does not escape$"
|
||||
}
|
||||
|
||||
func caller9b() {
|
||||
i := 0 // ERROR "moved to heap: i$"
|
||||
p := &i // ERROR "&i escapes to heap$" "moved to heap: p$"
|
||||
p2 := &p // ERROR "&p escapes to heap$"
|
||||
sink = param9(&p2) // ERROR "caller9b &p2 does not escape$" "param9\(&p2\) escapes to heap"
|
||||
}
|
||||
|
||||
// **in -> out
|
||||
func param10(p ***int) *int { // ERROR "param10 leaking param p content to result ~r1$"
|
||||
return **p
|
||||
}
|
||||
|
||||
func caller10a() {
|
||||
i := 0 // ERROR "moved to heap: i$"
|
||||
p := &i // ERROR "&i escapes to heap$" "moved to heap: p$"
|
||||
p2 := &p // ERROR "&p escapes to heap$"
|
||||
_ = param10(&p2) // ERROR "caller10a &p2 does not escape$"
|
||||
}
|
||||
|
||||
func caller10b() {
|
||||
i := 0 // ERROR "moved to heap: i$"
|
||||
p := &i // ERROR "&i escapes to heap$" "moved to heap: p$"
|
||||
p2 := &p // ERROR "&p escapes to heap$"
|
||||
sink = param10(&p2) // ERROR "caller10b &p2 does not escape$" "param10\(&p2\) escapes to heap"
|
||||
}
|
||||
|
||||
// &in -> out
|
||||
func param11(i **int) ***int { // ERROR "moved to heap: i$"
|
||||
return &i // ERROR "&i escapes to heap$"
|
||||
}
|
||||
|
||||
func caller11a() {
|
||||
i := 0 // ERROR "moved to heap: i$"
|
||||
p := &i // ERROR "&i escapes to heap$" "moved to heap: p$"
|
||||
_ = param11(&p) // ERROR "&p escapes to heap$"
|
||||
}
|
||||
|
||||
func caller11b() {
|
||||
i := 0 // ERROR "moved to heap: i$"
|
||||
p := &i // ERROR "&i escapes to heap$" "moved to heap: p$"
|
||||
sink = param11(&p) // ERROR "&p escapes to heap$" "param11\(&p\) escapes to heap"
|
||||
}
|
||||
|
||||
func caller11c() {
|
||||
i := 0 // ERROR "moved to heap: i$"
|
||||
p := &i // ERROR "&i escapes to heap$" "moved to heap: p$"
|
||||
sink = *param11(&p) // ERROR "&p escapes to heap$" "\*param11\(&p\) escapes to heap"
|
||||
}
|
||||
|
||||
// &in -> rcvr
|
||||
type Indir struct {
|
||||
p ***int
|
||||
}
|
||||
|
||||
func (r *Indir) param12(i **int) { // ERROR "\(\*Indir\).param12 r does not escape$" "moved to heap: i$"
|
||||
r.p = &i // ERROR "&i escapes to heap$"
|
||||
}
|
||||
|
||||
func caller12a() {
|
||||
i := 0 // ERROR "moved to heap: i$"
|
||||
p := &i // ERROR "&i escapes to heap$" "moved to heap: p$"
|
||||
var r Indir
|
||||
r.param12(&p) // ERROR "&p escapes to heap$" "caller12a r does not escape$"
|
||||
_ = r
|
||||
}
|
||||
|
||||
func caller12b() {
|
||||
i := 0 // ERROR "moved to heap: i$"
|
||||
p := &i // ERROR "&i escapes to heap$" "moved to heap: p$"
|
||||
r := &Indir{} // ERROR "caller12b &Indir literal does not escape$"
|
||||
r.param12(&p) // ERROR "&p escapes to heap$"
|
||||
_ = r
|
||||
}
|
||||
|
||||
func caller12c() {
|
||||
i := 0 // ERROR "moved to heap: i$"
|
||||
p := &i // ERROR "&i escapes to heap$" "moved to heap: p$"
|
||||
r := Indir{}
|
||||
r.param12(&p) // ERROR "&p escapes to heap$" "caller12c r does not escape$"
|
||||
sink = r // ERROR "r escapes to heap$"
|
||||
}
|
||||
|
||||
func caller12d() {
|
||||
i := 0 // ERROR "moved to heap: i$"
|
||||
p := &i // ERROR "&i escapes to heap$" "moved to heap: p$"
|
||||
r := Indir{}
|
||||
r.param12(&p) // ERROR "&p escapes to heap$" "caller12d r does not escape$"
|
||||
sink = **r.p // ERROR "\* \(\*r\.p\) escapes to heap"
|
||||
}
|
||||
|
||||
// in -> value rcvr
|
||||
type Val struct {
|
||||
p **int
|
||||
}
|
||||
|
||||
func (v Val) param13(i *int) { // ERROR "Val.param13 v does not escape$" "leaking param: i$"
|
||||
*v.p = i
|
||||
}
|
||||
|
||||
func caller13a() {
|
||||
i := 0 // ERROR "moved to heap: i$"
|
||||
var p *int
|
||||
var v Val
|
||||
v.p = &p // ERROR "caller13a &p does not escape$"
|
||||
v.param13(&i) // ERROR "&i escapes to heap$"
|
||||
_ = v
|
||||
}
|
||||
|
||||
func caller13b() {
|
||||
i := 0 // ERROR "moved to heap: i$"
|
||||
var p *int
|
||||
v := Val{&p} // ERROR "caller13b &p does not escape$"
|
||||
v.param13(&i) // ERROR "&i escapes to heap$"
|
||||
_ = v
|
||||
}
|
||||
|
||||
func caller13c() {
|
||||
i := 0 // ERROR "moved to heap: i$"
|
||||
var p *int
|
||||
v := &Val{&p} // ERROR "caller13c &Val literal does not escape$" "caller13c &p does not escape$"
|
||||
v.param13(&i) // ERROR "&i escapes to heap$"
|
||||
_ = v
|
||||
}
|
||||
|
||||
func caller13d() {
|
||||
i := 0 // ERROR "moved to heap: i$"
|
||||
var p *int // ERROR "moved to heap: p$"
|
||||
var v Val
|
||||
v.p = &p // ERROR "&p escapes to heap$"
|
||||
v.param13(&i) // ERROR "&i escapes to heap$"
|
||||
sink = v // ERROR "v escapes to heap$"
|
||||
}
|
||||
|
||||
func caller13e() {
|
||||
i := 0 // ERROR "moved to heap: i$"
|
||||
var p *int // ERROR "moved to heap: p$"
|
||||
v := Val{&p} // ERROR "&p escapes to heap$"
|
||||
v.param13(&i) // ERROR "&i escapes to heap$"
|
||||
sink = v // ERROR "v escapes to heap$"
|
||||
}
|
||||
|
||||
func caller13f() {
|
||||
i := 0 // ERROR "moved to heap: i$"
|
||||
var p *int // ERROR "moved to heap: p$"
|
||||
v := &Val{&p} // ERROR "&Val literal escapes to heap$" "&p escapes to heap$"
|
||||
v.param13(&i) // ERROR "&i escapes to heap$"
|
||||
sink = v // ERROR "v escapes to heap$"
|
||||
}
|
||||
|
||||
func caller13g() {
|
||||
i := 0 // ERROR "moved to heap: i$"
|
||||
var p *int
|
||||
v := Val{&p} // ERROR "caller13g &p does not escape$"
|
||||
v.param13(&i) // ERROR "&i escapes to heap$"
|
||||
sink = *v.p // ERROR "\*v\.p escapes to heap"
|
||||
}
|
||||
|
||||
func caller13h() {
|
||||
i := 0 // ERROR "moved to heap: i$"
|
||||
var p *int
|
||||
v := &Val{&p} // ERROR "caller13h &Val literal does not escape$" "caller13h &p does not escape$"
|
||||
v.param13(&i) // ERROR "&i escapes to heap$"
|
||||
sink = **v.p // ERROR "\* \(\*v\.p\) escapes to heap"
|
||||
}
|
Loading…
Reference in a new issue