Source file test/escape_bloop.go
1 // errorcheck -0 -m 2 3 // Copyright 2026 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 b.Loop escape analysis behavior. 8 9 package bloop 10 11 import ( 12 "testing" 13 ) 14 15 // An example where mid-stack inlining allows stack allocation of a slice. 16 // This is from the example in go.dev/issue/73137. 17 18 func NewX(x int) []byte { // ERROR "can inline NewX" 19 out := make([]byte, 8) // ERROR "make\(\[\]byte, 8\) escapes to heap" 20 return use1(out) 21 } 22 23 //go:noinline 24 func use1(out []byte) []byte { // ERROR "leaking param: out to result ~r0 level=0" 25 return out 26 } 27 28 //go:noinline 29 func BenchmarkBloop(b *testing.B) { // ERROR "leaking param: b" 30 for b.Loop() { // ERROR "inlining call to testing.\(\*B\).Loop" 31 NewX(42) // ERROR "make\(\[\]byte, 8\) does not escape" "inlining call to NewX" 32 } 33 } 34 35 // A traditional b.N benchmark using a sink variable for comparison, 36 // also from the example in go.dev/issue/73137. 37 38 var sink byte 39 40 //go:noinline 41 func BenchmarkBN(b *testing.B) { // ERROR "b does not escape" 42 for i := 0; i < b.N; i++ { 43 out := NewX(42) // ERROR "make\(\[\]byte, 8\) does not escape" "inlining call to NewX" 44 sink = out[0] 45 } 46 } 47 48 // An example showing behavior of a simple function argument in the b.Loop body. 49 50 //go:noinline 51 func use2(x any) {} // ERROR "x does not escape" 52 53 //go:noinline 54 func BenchmarkBLoopFunctionArg(b *testing.B) { // ERROR "leaking param: b" 55 for b.Loop() { // ERROR "inlining call to testing.\(\*B\).Loop" 56 use2(42) // ERROR "42 does not escape" 57 } 58 } 59 60 // A similar call outside of b.Loop for comparison. 61 62 func simpleFunctionArg() { // ERROR "can inline simpleFunctionArg" 63 use2(42) // ERROR "42 does not escape" 64 } 65