mirror of
https://github.com/golang/go
synced 2024-11-26 12:48:11 -07:00
120 lines
2.9 KiB
Go
120 lines
2.9 KiB
Go
|
// errorcheck -0 -m -l
|
||
|
|
||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||
|
// Use of this source code is governed by a BSD-style
|
||
|
// license that can be found in the LICENSE file.
|
||
|
|
||
|
// Test, using compiler diagnostic flags, that the escape analysis is working.
|
||
|
// Compiles but does not run. Inlining is disabled.
|
||
|
|
||
|
package foo
|
||
|
|
||
|
func noleak(p *int) int { // ERROR "p does not escape"
|
||
|
return *p
|
||
|
}
|
||
|
|
||
|
func leaktoret(p *int) *int { // ERROR "leaking param: p to result"
|
||
|
return p
|
||
|
}
|
||
|
|
||
|
func leaktoret2(p *int) (*int, *int) { // ERROR "leaking param: p to result .anon1" "leaking param: p to result .anon2"
|
||
|
return p, p
|
||
|
}
|
||
|
|
||
|
func leaktoret22(p, q *int) (*int, *int) { // ERROR "leaking param: p to result .anon2" "leaking param: q to result .anon3"
|
||
|
return p, q
|
||
|
}
|
||
|
|
||
|
func leaktoret22b(p, q *int) (*int, *int) { // ERROR "leaking param: p to result .anon3" "leaking param: q to result .anon2"
|
||
|
return leaktoret22(q, p)
|
||
|
}
|
||
|
|
||
|
func leaktoret22c(p, q *int) (*int, *int) { // ERROR "leaking param: p to result .anon3" "leaking param: q to result .anon2"
|
||
|
r, s := leaktoret22(q, p)
|
||
|
return r, s
|
||
|
}
|
||
|
|
||
|
func leaktoret22d(p, q *int) (r, s *int) { // ERROR "leaking param: p to result s" "leaking param: q to result r"
|
||
|
r, s = leaktoret22(q, p)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func leaktoret22e(p, q *int) (r, s *int) { // ERROR "leaking param: p to result s" "leaking param: q to result r"
|
||
|
r, s = leaktoret22(q, p)
|
||
|
return r, s
|
||
|
}
|
||
|
|
||
|
func leaktoret22f(p, q *int) (r, s *int) { // ERROR "leaking param: p to result s" "leaking param: q to result r"
|
||
|
rr, ss := leaktoret22(q, p)
|
||
|
return rr, ss
|
||
|
}
|
||
|
|
||
|
var gp *int
|
||
|
|
||
|
func leaktosink(p *int) *int { // ERROR "leaking param: p"
|
||
|
gp = p
|
||
|
return p
|
||
|
}
|
||
|
|
||
|
func f1() {
|
||
|
var x int
|
||
|
p := noleak(&x) // ERROR "&x does not escape"
|
||
|
_ = p
|
||
|
}
|
||
|
|
||
|
func f2() {
|
||
|
var x int
|
||
|
p := leaktoret(&x) // ERROR "&x does not escape"
|
||
|
_ = p
|
||
|
}
|
||
|
|
||
|
func f3() {
|
||
|
var x int // ERROR "moved to heap: x"
|
||
|
p := leaktoret(&x) // ERROR "&x escapes to heap"
|
||
|
gp = p
|
||
|
}
|
||
|
|
||
|
func f4() {
|
||
|
var x int // ERROR "moved to heap: x"
|
||
|
p, q := leaktoret2(&x) // ERROR "&x escapes to heap"
|
||
|
gp = p
|
||
|
gp = q
|
||
|
}
|
||
|
|
||
|
func f5() {
|
||
|
var x int
|
||
|
leaktoret22(leaktoret2(&x)) // ERROR "&x does not escape"
|
||
|
}
|
||
|
|
||
|
func f6() {
|
||
|
var x int // ERROR "moved to heap: x"
|
||
|
px1, px2 := leaktoret22(leaktoret2(&x)) // ERROR "&x escapes to heap"
|
||
|
gp = px1
|
||
|
_ = px2
|
||
|
}
|
||
|
|
||
|
type T struct{ x int }
|
||
|
|
||
|
func (t *T) Foo(u int) (*T, bool) { // ERROR "leaking param: t to result"
|
||
|
t.x += u
|
||
|
return t, true
|
||
|
}
|
||
|
|
||
|
func f7() *T {
|
||
|
r, _ := new(T).Foo(42) // ERROR "new.T. escapes to heap"
|
||
|
return r
|
||
|
}
|
||
|
|
||
|
func leakrecursive1(p, q *int) (*int, *int) { // ERROR "leaking param: p" "leaking param: q"
|
||
|
return leakrecursive2(q, p)
|
||
|
}
|
||
|
|
||
|
func leakrecursive2(p, q *int) (*int, *int) { // ERROR "leaking param: p" "leaking param: q"
|
||
|
if *p > *q {
|
||
|
return leakrecursive1(q, p)
|
||
|
}
|
||
|
// without this, leakrecursive? are safe for p and q, b/c in fact their graph does not have leaking edges.
|
||
|
return p, q
|
||
|
}
|
||
|
|