2018-09-24 16:48:54 +00:00
// +build !gcflags_noopt
2018-09-06 13:28:17 +03:00
// errorcheck -0 -m
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package foo
import "bytes"
// In order to get desired results, we need a combination of
// both escape analysis and inlining.
func bufferNotEscape ( ) string {
// b itself does not escape, only its buf field will be
// copied during String() call, but object "handle" itself
// can be stack-allocated.
var b bytes . Buffer
2019-04-01 11:58:33 -07:00
b . WriteString ( "123" )
2020-09-09 11:09:01 +07:00
b . Write ( [ ] byte { '4' } ) // ERROR "\[\]byte{...} does not escape$"
2019-04-01 11:58:33 -07:00
return b . String ( ) // ERROR "inlining call to bytes.\(\*Buffer\).String$" "string\(bytes.b.buf\[bytes.b.off:\]\) escapes to heap$"
2018-09-06 13:28:17 +03:00
}
2019-09-12 10:18:03 -07:00
func bufferNoEscape2 ( xs [ ] string ) int { // ERROR "xs does not escape$"
2020-09-09 11:09:01 +07:00
b := bytes . NewBuffer ( make ( [ ] byte , 0 , 64 ) ) // ERROR "&bytes.Buffer{...} does not escape$" "make\(\[\]byte, 0, 64\) does not escape$" "inlining call to bytes.NewBuffer$"
2018-09-06 13:28:17 +03:00
for _ , x := range xs {
b . WriteString ( x )
}
2018-11-30 08:36:00 -05:00
return b . Len ( ) // ERROR "inlining call to bytes.\(\*Buffer\).Len$"
2018-09-06 13:28:17 +03:00
}
2019-09-12 10:18:03 -07:00
func bufferNoEscape3 ( xs [ ] string ) string { // ERROR "xs does not escape$"
2020-09-09 11:09:01 +07:00
b := bytes . NewBuffer ( make ( [ ] byte , 0 , 64 ) ) // ERROR "&bytes.Buffer{...} does not escape$" "make\(\[\]byte, 0, 64\) does not escape$" "inlining call to bytes.NewBuffer$"
2018-09-06 13:28:17 +03:00
for _ , x := range xs {
b . WriteString ( x )
b . WriteByte ( ',' )
}
2018-11-30 08:36:00 -05:00
return b . String ( ) // ERROR "inlining call to bytes.\(\*Buffer\).String$" "string\(bytes.b.buf\[bytes.b.off:\]\) escapes to heap$"
2018-09-06 13:28:17 +03:00
}
2018-09-07 20:36:56 +03:00
func bufferNoEscape4 ( ) [ ] byte {
var b bytes . Buffer
2022-06-07 14:57:11 +07:00
b . Grow ( 64 ) // ERROR "bufferNoEscape4 ignoring self-assignment in bytes.b.buf = bytes.b.buf\[:bytes.m\]$" "inlining call to bytes.\(\*Buffer\).Grow$" `".+" escapes to heap`
2019-04-01 11:58:33 -07:00
useBuffer ( & b )
return b . Bytes ( ) // ERROR "inlining call to bytes.\(\*Buffer\).Bytes$"
2018-09-07 20:36:56 +03:00
}
2018-11-30 08:36:00 -05:00
func bufferNoEscape5 ( ) { // ERROR "can inline bufferNoEscape5$"
2020-09-09 11:09:01 +07:00
b := bytes . NewBuffer ( make ( [ ] byte , 0 , 128 ) ) // ERROR "&bytes.Buffer{...} does not escape$" "make\(\[\]byte, 0, 128\) does not escape$" "inlining call to bytes.NewBuffer$"
2018-09-07 20:36:56 +03:00
useBuffer ( b )
}
//go:noinline
2019-09-12 10:18:03 -07:00
func useBuffer ( b * bytes . Buffer ) { // ERROR "b does not escape$"
2018-09-07 20:36:56 +03:00
b . WriteString ( "1234" )
}