]> Cypherpunks.ru repositories - gostls13.git/blob - test/escape_closure.go
all: make copyright headers consistent with one space after period
[gostls13.git] / test / escape_closure.go
1 // errorcheck -0 -m -l
2
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.
6
7 // Test escape analysis for closure arguments.
8
9 package escape
10
11 var sink interface{}
12
13 func ClosureCallArgs0() {
14         x := 0         // ERROR "moved to heap: x"
15         func(p *int) { // ERROR "p does not escape" "func literal does not escape"
16                 *p = 1
17                 // BAD: x should not escape to heap here
18         }(&x) // ERROR "&x escapes to heap"
19 }
20
21 func ClosureCallArgs1() {
22         x := 0 // ERROR "moved to heap: x"
23         for {
24                 func(p *int) { // ERROR "p does not escape" "func literal does not escape"
25                         *p = 1
26                         // BAD: x should not escape to heap here
27                 }(&x) // ERROR "&x escapes to heap"
28         }
29 }
30
31 func ClosureCallArgs2() {
32         for {
33                 // BAD: x should not escape here
34                 x := 0         // ERROR "moved to heap: x"
35                 func(p *int) { // ERROR "p does not escape" "func literal does not escape"
36                         *p = 1
37                 }(&x) // ERROR "&x escapes to heap"
38         }
39 }
40
41 func ClosureCallArgs3() {
42         x := 0         // ERROR "moved to heap: x"
43         func(p *int) { // ERROR "leaking param: p" "func literal does not escape"
44                 sink = p // ERROR "p escapes to heap"
45         }(&x) // ERROR "&x escapes to heap"
46 }
47
48 func ClosureCallArgs4() {
49         // BAD: x should not leak here
50         x := 0                  // ERROR "moved to heap: x"
51         _ = func(p *int) *int { // ERROR "leaking param: p to result ~r1" "func literal does not escape"
52                 return p
53         }(&x) // ERROR "&x escapes to heap"
54 }
55
56 func ClosureCallArgs5() {
57         x := 0                     // ERROR "moved to heap: x"
58         sink = func(p *int) *int { // ERROR "leaking param: p to result ~r1" "func literal does not escape"
59                 return p
60         }(&x) // ERROR "&x escapes to heap" "\(func literal\)\(&x\) escapes to heap"
61 }
62
63 func ClosureCallArgs6() {
64         x := 0         // ERROR "moved to heap: x"
65         func(p *int) { // ERROR "moved to heap: p" "func literal does not escape"
66                 sink = &p // ERROR "&p escapes to heap"
67         }(&x) // ERROR "&x escapes to heap"
68 }
69
70 func ClosureCallArgs7() {
71         var pp *int
72         for {
73                 x := 0         // ERROR "moved to heap: x"
74                 func(p *int) { // ERROR "leaking param: p" "func literal does not escape"
75                         pp = p
76                 }(&x) // ERROR "&x escapes to heap"
77         }
78         _ = pp
79 }
80
81 func ClosureCallArgs8() {
82         x := 0               // ERROR "moved to heap: x"
83         defer func(p *int) { // ERROR "p does not escape" "func literal does not escape"
84                 *p = 1
85                 // BAD: x should not escape to heap here
86         }(&x) // ERROR "&x escapes to heap"
87 }
88
89 func ClosureCallArgs9() {
90         // BAD: x should not leak
91         x := 0 // ERROR "moved to heap: x"
92         for {
93                 defer func(p *int) { // ERROR "func literal escapes to heap" "p does not escape"
94                         *p = 1
95                 }(&x) // ERROR "&x escapes to heap"
96         }
97 }
98
99 func ClosureCallArgs10() {
100         for {
101                 x := 0               // ERROR "moved to heap: x"
102                 defer func(p *int) { // ERROR "func literal escapes to heap" "p does not escape"
103                         *p = 1
104                 }(&x) // ERROR "&x escapes to heap"
105         }
106 }
107
108 func ClosureCallArgs11() {
109         x := 0               // ERROR "moved to heap: x"
110         defer func(p *int) { // ERROR "leaking param: p" "func literal does not escape"
111                 sink = p // ERROR "p escapes to heap"
112         }(&x) // ERROR "&x escapes to heap"
113 }
114
115 func ClosureCallArgs12() {
116         // BAD: x should not leak
117         x := 0                    // ERROR "moved to heap: x"
118         defer func(p *int) *int { // ERROR "leaking param: p to result ~r1" "func literal does not escape"
119                 return p
120         }(&x) // ERROR "&x escapes to heap"
121 }
122
123 func ClosureCallArgs13() {
124         x := 0               // ERROR "moved to heap: x"
125         defer func(p *int) { // ERROR "moved to heap: p" "func literal does not escape"
126                 sink = &p // ERROR "&p escapes to heap"
127         }(&x) // ERROR "&x escapes to heap"
128 }
129
130 func ClosureCallArgs14() {
131         x := 0 // ERROR "moved to heap: x"
132         // BAD: &x should not escape here
133         p := &x                  // ERROR "moved to heap: p" "&x escapes to heap"
134         _ = func(p **int) *int { // ERROR "leaking param: p to result ~r1 level=1" "func literal does not escape"
135                 return *p
136                 // BAD: p should not escape here
137         }(&p) // ERROR "&p escapes to heap"
138 }
139
140 func ClosureCallArgs15() {
141         x := 0                      // ERROR "moved to heap: x"
142         p := &x                     // ERROR "moved to heap: p" "&x escapes to heap"
143         sink = func(p **int) *int { // ERROR "leaking param: p to result ~r1 level=1" "func literal does not escape"
144                 return *p
145                 // BAD: p should not escape here
146         }(&p) // ERROR "&p escapes to heap" "\(func literal\)\(&p\) escapes to heap"
147 }
148
149 func ClosureLeak1(s string) string { // ERROR "ClosureLeak1 s does not escape"
150         t := s + "YYYY"         // ERROR "escapes to heap"
151         return ClosureLeak1a(t) // ERROR "ClosureLeak1 ... argument does not escape"
152 }
153
154 // See #14409 -- returning part of captured var leaks it.
155 func ClosureLeak1a(a ...string) string { // ERROR "leaking param: a to result ~r1 level=1"
156         return func() string { // ERROR "ClosureLeak1a func literal does not escape"
157                 return a[0]
158         }()
159 }
160
161 func ClosureLeak2(s string) string { // ERROR "ClosureLeak2 s does not escape"
162         t := s + "YYYY"       // ERROR "escapes to heap"
163         c := ClosureLeak2a(t) // ERROR "ClosureLeak2 ... argument does not escape"
164         return c
165 }
166 func ClosureLeak2a(a ...string) string { // ERROR "leaking param: a to result ~r1 level=1"
167         return ClosureLeak2b(func() string { // ERROR "ClosureLeak2a func literal does not escape"
168                 return a[0]
169         })
170 }
171 func ClosureLeak2b(f func() string) string { // ERROR "leaking param: f to result ~r1 level=1"
172         return f()
173 }