github.com/MangoDowner/go-gm@v0.0.0-20180818020936-8baa2bd4408c/test/escape5.go (about) 1 // errorcheck -0 -m -l 2 3 // Copyright 2012 The Go Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file. 6 7 // Test, using compiler diagnostic flags, that the escape analysis is working. 8 // Compiles but does not run. Inlining is disabled. 9 10 package foo 11 12 import "runtime" 13 14 func noleak(p *int) int { // ERROR "p does not escape" 15 return *p 16 } 17 18 func leaktoret(p *int) *int { // ERROR "leaking param: p to result" 19 return p 20 } 21 22 func leaktoret2(p *int) (*int, *int) { // ERROR "leaking param: p to result ~r1" "leaking param: p to result ~r2" 23 return p, p 24 } 25 26 func leaktoret22(p, q *int) (*int, *int) { // ERROR "leaking param: p to result ~r2" "leaking param: q to result ~r3" 27 return p, q 28 } 29 30 func leaktoret22b(p, q *int) (*int, *int) { // ERROR "leaking param: p to result ~r3" "leaking param: q to result ~r2" 31 return leaktoret22(q, p) 32 } 33 34 func leaktoret22c(p, q *int) (*int, *int) { // ERROR "leaking param: p to result ~r3" "leaking param: q to result ~r2" 35 r, s := leaktoret22(q, p) 36 return r, s 37 } 38 39 func leaktoret22d(p, q *int) (r, s *int) { // ERROR "leaking param: p to result s" "leaking param: q to result r" 40 r, s = leaktoret22(q, p) 41 return 42 } 43 44 func leaktoret22e(p, q *int) (r, s *int) { // ERROR "leaking param: p to result s" "leaking param: q to result r" 45 r, s = leaktoret22(q, p) 46 return r, s 47 } 48 49 func leaktoret22f(p, q *int) (r, s *int) { // ERROR "leaking param: p to result s" "leaking param: q to result r" 50 rr, ss := leaktoret22(q, p) 51 return rr, ss 52 } 53 54 var gp *int 55 56 func leaktosink(p *int) *int { // ERROR "leaking param: p" 57 gp = p 58 return p 59 } 60 61 func f1() { 62 var x int 63 p := noleak(&x) // ERROR "&x does not escape" 64 _ = p 65 } 66 67 func f2() { 68 var x int 69 p := leaktoret(&x) // ERROR "&x does not escape" 70 _ = p 71 } 72 73 func f3() { 74 var x int // ERROR "moved to heap: x" 75 p := leaktoret(&x) // ERROR "&x escapes to heap" 76 gp = p 77 } 78 79 func f4() { 80 var x int // ERROR "moved to heap: x" 81 p, q := leaktoret2(&x) // ERROR "&x escapes to heap" 82 gp = p 83 gp = q 84 } 85 86 func f5() { 87 var x int 88 leaktoret22(leaktoret2(&x)) // ERROR "&x does not escape" 89 } 90 91 func f6() { 92 var x int // ERROR "moved to heap: x" 93 px1, px2 := leaktoret22(leaktoret2(&x)) // ERROR "&x escapes to heap" 94 gp = px1 95 _ = px2 96 } 97 98 type T struct{ x int } 99 100 func (t *T) Foo(u int) (*T, bool) { // ERROR "leaking param: t to result" 101 t.x += u 102 return t, true 103 } 104 105 func f7() *T { 106 r, _ := new(T).Foo(42) // ERROR "new.T. escapes to heap" 107 return r 108 } 109 110 func leakrecursive1(p, q *int) (*int, *int) { // ERROR "leaking param: p" "leaking param: q" 111 return leakrecursive2(q, p) 112 } 113 114 func leakrecursive2(p, q *int) (*int, *int) { // ERROR "leaking param: p" "leaking param: q" 115 if *p > *q { 116 return leakrecursive1(q, p) 117 } 118 // without this, leakrecursive? are safe for p and q, b/c in fact their graph does not have leaking edges. 119 return p, q 120 } 121 122 var global interface{} 123 124 type T1 struct { 125 X *int 126 } 127 128 type T2 struct { 129 Y *T1 130 } 131 132 func f8(p *T1) (k T2) { // ERROR "leaking param: p to result k" "leaking param: p" 133 if p == nil { 134 k = T2{} 135 return 136 } 137 138 // should make p leak always 139 global = p // ERROR "p escapes to heap" 140 return T2{p} 141 } 142 143 func f9() { 144 var j T1 // ERROR "moved to heap: j" 145 f8(&j) // ERROR "&j escapes to heap" 146 } 147 148 func f10() { 149 // These don't escape but are too big for the stack 150 var x [1 << 30]byte // ERROR "moved to heap: x" 151 var y = make([]byte, 1<<30) // ERROR "make\(\[\]byte, 1 << 30\) escapes to heap" 152 _ = x[0] + y[0] 153 } 154 155 // Test for issue 19687 (passing to unnamed parameters does not escape). 156 func f11(**int) { 157 } 158 func f12(_ **int) { 159 } 160 func f13() { 161 var x *int 162 f11(&x) // ERROR "&x does not escape" 163 f12(&x) // ERROR "&x does not escape" 164 runtime.KeepAlive(&x) // ERROR "&x does not escape" 165 }