3 // Copyright 2022 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 reflect Value operations.
19 v := reflect.ValueOf(x) // ERROR "x does not escape"
23 func kind(x int) reflect.Kind {
24 v := reflect.ValueOf(x) // ERROR "x does not escape"
28 func int1(x int) int {
29 v := reflect.ValueOf(x) // ERROR "x does not escape"
33 func ptr(x *int) *int { // ERROR "leaking param: x to result ~r0 level=0"
34 v := reflect.ValueOf(x)
35 return (*int)(v.UnsafePointer())
38 func bytes1(x []byte) byte { // ERROR "x does not escape"
39 v := reflect.ValueOf(x) // ERROR "x does not escape"
43 // Unfortunate: should only escape content. x (the interface storage) should not escape.
44 func bytes2(x []byte) []byte { // ERROR "leaking param: x$"
45 v := reflect.ValueOf(x) // ERROR "x escapes to heap"
49 func string1(x string) string { // ERROR "leaking param: x to result ~r0 level=0"
50 v := reflect.ValueOf(x) // ERROR "x does not escape"
54 func string2(x int) string {
55 v := reflect.ValueOf(x) // ERROR "x does not escape"
59 // Unfortunate: should only escape to result.
60 func interface1(x any) any { // ERROR "leaking param: x$"
61 v := reflect.ValueOf(x)
65 func interface2(x int) any {
66 v := reflect.ValueOf(x) // ERROR "x escapes to heap"
70 // Unfortunate: should not escape.
71 func interface3(x int) int {
72 v := reflect.ValueOf(x) // ERROR "x escapes to heap"
73 return v.Interface().(int)
76 // Unfortunate: should only escape to result.
77 func interface4(x *int) any { // ERROR "leaking param: x$"
78 v := reflect.ValueOf(x)
82 func addr(x *int) reflect.Value { // ERROR "leaking param: x to result ~r0 level=0"
83 v := reflect.ValueOf(x).Elem()
87 // functions returning pointer as uintptr have to escape.
88 func uintptr1(x *int) uintptr { // ERROR "leaking param: x$"
89 v := reflect.ValueOf(x)
93 func unsafeaddr(x *int) uintptr { // ERROR "leaking param: x$"
94 v := reflect.ValueOf(x).Elem()
98 func ifacedata(x any) [2]uintptr { // ERROR "moved to heap: x"
99 v := reflect.ValueOf(&x).Elem()
100 return v.InterfaceData()
103 func can(x int) bool {
104 v := reflect.ValueOf(x) // ERROR "x does not escape"
105 return v.CanAddr() || v.CanInt() || v.CanSet() || v.CanInterface()
108 func is(x int) bool {
109 v := reflect.ValueOf(x) // ERROR "x does not escape"
110 return v.IsValid() || v.IsNil() || v.IsZero()
113 func is2(x [2]int) bool {
114 v := reflect.ValueOf(x) // ERROR "x does not escape"
115 return v.IsValid() || v.IsNil() || v.IsZero()
118 func is3(x struct{ a, b int }) bool {
119 v := reflect.ValueOf(x) // ERROR "x does not escape"
120 return v.IsValid() || v.IsNil() || v.IsZero()
123 func overflow(x int) bool {
124 v := reflect.ValueOf(x) // ERROR "x does not escape"
125 return v.OverflowInt(1 << 62)
128 func len1(x []int) int { // ERROR "x does not escape"
129 v := reflect.ValueOf(x) // ERROR "x does not escape"
133 func len2(x [3]int) int {
134 v := reflect.ValueOf(x) // ERROR "x does not escape"
138 func len3(x string) int { // ERROR "x does not escape"
139 v := reflect.ValueOf(x) // ERROR "x does not escape"
143 func len4(x map[int]int) int { // ERROR "x does not escape"
144 v := reflect.ValueOf(x)
148 func len5(x chan int) int { // ERROR "x does not escape"
149 v := reflect.ValueOf(x)
153 func cap1(x []int) int { // ERROR "x does not escape"
154 v := reflect.ValueOf(x) // ERROR "x does not escape"
158 func cap2(x [3]int) int {
159 v := reflect.ValueOf(x) // ERROR "x does not escape"
163 func cap3(x chan int) int { // ERROR "x does not escape"
164 v := reflect.ValueOf(x)
168 func setlen(x *[]int, n int) { // ERROR "x does not escape"
169 v := reflect.ValueOf(x).Elem()
173 func setcap(x *[]int, n int) { // ERROR "x does not escape"
174 v := reflect.ValueOf(x).Elem()
178 // Unfortunate: x doesn't need to escape to heap, just to result.
179 func slice1(x []byte) []byte { // ERROR "leaking param: x$"
180 v := reflect.ValueOf(x) // ERROR "x escapes to heap"
181 return v.Slice(1, 2).Bytes()
184 // Unfortunate: x doesn't need to escape to heap, just to result.
185 func slice2(x string) string { // ERROR "leaking param: x$"
186 v := reflect.ValueOf(x) // ERROR "x escapes to heap"
187 return v.Slice(1, 2).String()
190 func slice3(x [10]byte) []byte {
191 v := reflect.ValueOf(x) // ERROR "x escapes to heap"
192 return v.Slice(1, 2).Bytes()
195 func elem1(x *int) int { // ERROR "x does not escape"
196 v := reflect.ValueOf(x)
197 return int(v.Elem().Int())
200 func elem2(x *string) string { // ERROR "leaking param: x to result ~r0 level=1"
201 v := reflect.ValueOf(x)
202 return string(v.Elem().String())
213 func field1(x S) int { // ERROR "x does not escape"
214 v := reflect.ValueOf(x) // ERROR "x does not escape"
215 return int(v.Field(0).Int())
218 func field2(x S) string { // ERROR "leaking param: x to result ~r0 level=0"
219 v := reflect.ValueOf(x) // ERROR "x does not escape"
220 return v.Field(2).String()
223 func numfield(x S) int { // ERROR "x does not escape"
224 v := reflect.ValueOf(x) // ERROR "x does not escape"
228 func index1(x []int) int { // ERROR "x does not escape"
229 v := reflect.ValueOf(x) // ERROR "x does not escape"
230 return int(v.Index(0).Int())
233 // Unfortunate: should only leak content (level=1)
234 func index2(x []string) string { // ERROR "leaking param: x to result ~r0 level=0"
235 v := reflect.ValueOf(x) // ERROR "x does not escape"
236 return v.Index(0).String()
239 func index3(x [3]int) int {
240 v := reflect.ValueOf(x) // ERROR "x does not escape"
241 return int(v.Index(0).Int())
244 func index4(x [3]string) string { // ERROR "leaking param: x to result ~r0 level=0"
245 v := reflect.ValueOf(x) // ERROR "x does not escape"
246 return v.Index(0).String()
249 func index5(x string) byte { // ERROR "x does not escape"
250 v := reflect.ValueOf(x) // ERROR "x does not escape"
251 return byte(v.Index(0).Uint())
254 // Unfortunate: x (the interface storage) doesn't need to escape as the function takes a scalar arg.
255 func call1(f func(int), x int) { // ERROR "leaking param: f$"
256 fv := reflect.ValueOf(f)
257 v := reflect.ValueOf(x) // ERROR "x escapes to heap"
258 fv.Call([]reflect.Value{v}) // ERROR "\[\]reflect\.Value{\.\.\.} does not escape"
261 func call2(f func(*int), x *int) { // ERROR "leaking param: f$" "leaking param: x$"
262 fv := reflect.ValueOf(f)
263 v := reflect.ValueOf(x)
264 fv.Call([]reflect.Value{v}) // ERROR "\[\]reflect.Value{\.\.\.} does not escape"
267 func method(x S) reflect.Value { // ERROR "leaking param: x$"
268 v := reflect.ValueOf(x) // ERROR "x escapes to heap"
272 func nummethod(x S) int { // ERROR "x does not escape"
273 v := reflect.ValueOf(x) // ERROR "x does not escape"
277 // Unfortunate: k doesn't need to escape.
278 func mapindex(m map[string]string, k string) string { // ERROR "m does not escape" "leaking param: k$"
279 mv := reflect.ValueOf(m)
280 kv := reflect.ValueOf(k) // ERROR "k escapes to heap"
281 return mv.MapIndex(kv).String()
284 func mapkeys(m map[string]string) []reflect.Value { // ERROR "m does not escape"
285 mv := reflect.ValueOf(m)
289 func mapiter1(m map[string]string) *reflect.MapIter { // ERROR "leaking param: m$"
290 mv := reflect.ValueOf(m)
294 func mapiter2(m map[string]string) string { // ERROR "leaking param: m$"
295 mv := reflect.ValueOf(m)
298 return it.Key().String()
303 func mapiter3(m map[string]string, it *reflect.MapIter) { // ERROR "leaking param: m$" "it does not escape"
304 mv := reflect.ValueOf(m)
308 func recv1(ch chan string) string { // ERROR "ch does not escape"
309 v := reflect.ValueOf(ch)
314 func recv2(ch chan string) string { // ERROR "ch does not escape"
315 v := reflect.ValueOf(ch)
320 // Unfortunate: x (the interface storage) doesn't need to escape.
321 func send1(ch chan string, x string) { // ERROR "ch does not escape" "leaking param: x$"
322 vc := reflect.ValueOf(ch)
323 vx := reflect.ValueOf(x) // ERROR "x escapes to heap"
327 // Unfortunate: x (the interface storage) doesn't need to escape.
328 func send2(ch chan string, x string) bool { // ERROR "ch does not escape" "leaking param: x$"
329 vc := reflect.ValueOf(ch)
330 vx := reflect.ValueOf(x) // ERROR "x escapes to heap"
331 return vc.TrySend(vx)
334 func close1(ch chan string) { // ERROR "ch does not escape"
335 v := reflect.ValueOf(ch)
339 func select1(ch chan string) string { // ERROR "leaking param: ch$"
340 v := reflect.ValueOf(ch)
341 cas := reflect.SelectCase{Dir: reflect.SelectRecv, Chan: v}
342 _, r, _ := reflect.Select([]reflect.SelectCase{cas}) // ERROR "\[\]reflect.SelectCase{...} does not escape"
346 // Unfortunate: x (the interface storage) doesn't need to escape.
347 func select2(ch chan string, x string) { // ERROR "leaking param: ch$" "leaking param: x$"
348 vc := reflect.ValueOf(ch)
349 vx := reflect.ValueOf(x) // ERROR "x escapes to heap"
350 cas := reflect.SelectCase{Dir: reflect.SelectSend, Chan: vc, Send: vx}
351 reflect.Select([]reflect.SelectCase{cas}) // ERROR "\[\]reflect.SelectCase{...} does not escape"
355 intTyp = reflect.TypeOf(int(0)) // ERROR "0 does not escape"
356 uintTyp = reflect.TypeOf(uint(0)) // ERROR "uint\(0\) does not escape"
357 stringTyp = reflect.TypeOf(string("")) // ERROR ".. does not escape"
358 bytesTyp = reflect.TypeOf([]byte{}) // ERROR "\[\]byte{} does not escape"
361 // Unfortunate: should not escape.
362 func convert1(x int) uint {
363 v := reflect.ValueOf(x) // ERROR "x escapes to heap"
364 return uint(v.Convert(uintTyp).Uint())
367 // Unfortunate: should only escape content to result.
368 func convert2(x []byte) string { // ERROR "leaking param: x$"
369 v := reflect.ValueOf(x) // ERROR "x escapes to heap"
370 return v.Convert(stringTyp).String()
373 // Unfortunate: v doesn't need to leak, x (the interface storage) doesn't need to escape.
374 func set1(v reflect.Value, x int) { // ERROR "leaking param: v$"
375 vx := reflect.ValueOf(x) // ERROR "x escapes to heap"
379 // Unfortunate: a can be stack allocated, x (the interface storage) doesn't need to escape.
380 func set2(x int) int64 {
381 var a int // ERROR "moved to heap: a"
382 v := reflect.ValueOf(&a).Elem()
383 vx := reflect.ValueOf(x) // ERROR "x escapes to heap"
388 func set3(v reflect.Value, x int) { // ERROR "v does not escape"
392 func set4(x int) int {
394 v := reflect.ValueOf(&a).Elem() // a should not escape, no error printed
399 func set5(v reflect.Value, x string) { // ERROR "v does not escape" "leaking param: x$"
403 func set6(v reflect.Value, x []byte) { // ERROR "v does not escape" "leaking param: x$"
407 func set7(v reflect.Value, x unsafe.Pointer) { // ERROR "v does not escape" "leaking param: x$"
411 func setmapindex(m map[string]string, k, e string) { // ERROR "m does not escape" "leaking param: k$" "leaking param: e$"
412 mv := reflect.ValueOf(m)
413 kv := reflect.ValueOf(k) // ERROR "k escapes to heap"
414 ev := reflect.ValueOf(e) // ERROR "e escapes to heap"
415 mv.SetMapIndex(kv, ev)
418 // Unfortunate: k doesn't need to escape.
419 func mapdelete(m map[string]string, k string) { // ERROR "m does not escape" "leaking param: k$"
420 mv := reflect.ValueOf(m)
421 kv := reflect.ValueOf(k) // ERROR "k escapes to heap"
422 mv.SetMapIndex(kv, reflect.Value{})
425 // Unfortunate: v doesn't need to leak.
426 func setiterkey1(v reflect.Value, it *reflect.MapIter) { // ERROR "leaking param: v$" "it does not escape"
430 // Unfortunate: v doesn't need to leak.
431 func setiterkey2(v reflect.Value, m map[string]string) { // ERROR "leaking param: v$" "leaking param: m$"
432 it := reflect.ValueOf(m).MapRange()
436 // Unfortunate: v doesn't need to leak.
437 func setitervalue1(v reflect.Value, it *reflect.MapIter) { // ERROR "leaking param: v$" "it does not escape"
441 // Unfortunate: v doesn't need to leak.
442 func setitervalue2(v reflect.Value, m map[string]string) { // ERROR "leaking param: v$" "leaking param: m$"
443 it := reflect.ValueOf(m).MapRange()
447 // Unfortunate: s doesn't need escape, only leak to result.
448 // And x (interface storage) doesn't need to escape.
449 func append1(s []int, x int) []int { // ERROR "leaking param: s$"
450 sv := reflect.ValueOf(s) // ERROR "s escapes to heap"
451 xv := reflect.ValueOf(x) // ERROR "x escapes to heap"
452 rv := reflect.Append(sv, xv) // ERROR "... argument does not escape"
453 return rv.Interface().([]int)
456 // Unfortunate: s doesn't need escape, only leak to result.
457 func append2(s, x []int) []int { // ERROR "leaking param: s$" "x does not escape"
458 sv := reflect.ValueOf(s) // ERROR "s escapes to heap"
459 xv := reflect.ValueOf(x) // ERROR "x does not escape"
460 rv := reflect.AppendSlice(sv, xv)
461 return rv.Interface().([]int)