3 // Copyright 2015 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.
7 // Test escape analysis for closure arguments.
13 func ClosureCallArgs0() {
15 func(p *int) { // ERROR "p does not escape" "func literal does not escape"
20 func ClosureCallArgs1() {
23 func(p *int) { // ERROR "p does not escape" "func literal does not escape"
29 func ClosureCallArgs2() {
32 func(p *int) { // ERROR "p does not escape" "func literal does not escape"
38 func ClosureCallArgs3() {
39 x := 0 // ERROR "moved to heap: x"
40 func(p *int) { // ERROR "leaking param: p" "func literal does not escape"
45 func ClosureCallArgs4() {
47 _ = func(p *int) *int { // ERROR "leaking param: p to result ~r0" "func literal does not escape"
52 func ClosureCallArgs5() {
53 x := 0 // ERROR "moved to heap: x"
54 // TODO(mdempsky): We get "leaking param: p" here because the new escape analysis pass
55 // can tell that p flows directly to sink, but it's a little weird. Re-evaluate.
56 sink = func(p *int) *int { // ERROR "leaking param: p" "func literal does not escape"
61 func ClosureCallArgs6() {
62 x := 0 // ERROR "moved to heap: x"
63 func(p *int) { // ERROR "moved to heap: p" "func literal does not escape"
68 func ClosureCallArgs7() {
71 x := 0 // ERROR "moved to heap: x"
72 func(p *int) { // ERROR "leaking param: p" "func literal does not escape"
79 func ClosureCallArgs8() {
81 defer func(p *int) { // ERROR "p does not escape" "func literal does not escape"
86 func ClosureCallArgs9() {
87 // BAD: x should not leak
88 x := 0 // ERROR "moved to heap: x"
90 defer func(p *int) { // ERROR "func literal escapes to heap" "p does not escape"
96 func ClosureCallArgs10() {
98 x := 0 // ERROR "moved to heap: x"
99 defer func(p *int) { // ERROR "func literal escapes to heap" "p does not escape"
105 func ClosureCallArgs11() {
106 x := 0 // ERROR "moved to heap: x"
107 defer func(p *int) { // ERROR "leaking param: p" "func literal does not escape"
112 func ClosureCallArgs12() {
114 defer func(p *int) *int { // ERROR "leaking param: p to result ~r0" "func literal does not escape"
119 func ClosureCallArgs13() {
120 x := 0 // ERROR "moved to heap: x"
121 defer func(p *int) { // ERROR "moved to heap: p" "func literal does not escape"
126 func ClosureCallArgs14() {
129 _ = func(p **int) *int { // ERROR "leaking param: p to result ~r0 level=1" "func literal does not escape"
134 func ClosureCallArgs15() {
135 x := 0 // ERROR "moved to heap: x"
137 sink = func(p **int) *int { // ERROR "leaking param content: p" "func literal does not escape"
142 func ClosureLeak1(s string) string { // ERROR "s does not escape"
143 t := s + "YYYY" // ERROR "escapes to heap"
144 return ClosureLeak1a(t) // ERROR "... argument does not escape"
147 // See #14409 -- returning part of captured var leaks it.
148 func ClosureLeak1a(a ...string) string { // ERROR "leaking param: a to result ~r0 level=1$"
149 return func() string { // ERROR "func literal does not escape"
154 func ClosureLeak2(s string) string { // ERROR "s does not escape"
155 t := s + "YYYY" // ERROR "escapes to heap"
156 c := ClosureLeak2a(t) // ERROR "... argument does not escape"
159 func ClosureLeak2a(a ...string) string { // ERROR "leaking param content: a"
160 return ClosureLeak2b(func() string { // ERROR "func literal does not escape"
164 func ClosureLeak2b(f func() string) string { // ERROR "f does not escape"
168 func ClosureIndirect() {
169 f := func(p *int) {} // ERROR "p does not escape" "func literal does not escape"
170 f(new(int)) // ERROR "new\(int\) does not escape"
173 g(new(int)) // ERROR "new\(int\) does not escape"
176 h(new(int)) // ERROR "new\(int\) does not escape"
179 func nopFunc(p *int) {} // ERROR "p does not escape"
181 func ClosureIndirect2() {
182 f := func(p *int) *int { return p } // ERROR "leaking param: p to result ~r0 level=0" "func literal does not escape"
184 f(new(int)) // ERROR "new\(int\) does not escape"
187 g(new(int)) // ERROR "new\(int\) does not escape"
190 h(new(int)) // ERROR "new\(int\) does not escape"
193 func nopFunc2(p *int) *int { return p } // ERROR "leaking param: p to result ~r0 level=0"