/usr/share/go-1.6/test/escape5.go is in golang-1.6-src 1.6.1-0ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | // 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 ~r1" "leaking param: p to result ~r2"
return p, p
}
func leaktoret22(p, q *int) (*int, *int) { // ERROR "leaking param: p to result ~r2" "leaking param: q to result ~r3"
return p, q
}
func leaktoret22b(p, q *int) (*int, *int) { // ERROR "leaking param: p to result ~r3" "leaking param: q to result ~r2"
return leaktoret22(q, p)
}
func leaktoret22c(p, q *int) (*int, *int) { // ERROR "leaking param: p to result ~r3" "leaking param: q to result ~r2"
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
}
var global interface{}
type T1 struct {
X *int
}
type T2 struct {
Y *T1
}
func f8(p *T1) (k T2) { // ERROR "leaking param: p to result k" "leaking param: p"
if p == nil {
k = T2{}
return
}
// should make p leak always
global = p // ERROR "p escapes to heap"
return T2{p}
}
func f9() {
var j T1 // ERROR "moved to heap: j"
f8(&j) // ERROR "&j escapes to heap"
}
func f10() {
// These don't escape but are too big for the stack
var x [1 << 30]byte // ERROR "moved to heap: x"
var y = make([]byte, 1<<30) // ERROR "make\(\[\]byte, 1 << 30\) escapes to heap"
_ = x[0] + y[0]
}
|