2018-09-24 10:48:54 -06:00
// +build !gcflags_noopt
2018-09-06 04:28:17 -06: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 12:58:33 -06:00
b . WriteString ( "123" )
2019-09-12 11:18:03 -06:00
b . Write ( [ ] byte { '4' } ) // ERROR "\[\]byte literal does not escape$"
2019-04-01 12:58:33 -06:00
return b . String ( ) // ERROR "inlining call to bytes.\(\*Buffer\).String$" "string\(bytes.b.buf\[bytes.b.off:\]\) escapes to heap$"
2018-09-06 04:28:17 -06:00
}
2019-09-12 11:18:03 -06:00
func bufferNoEscape2 ( xs [ ] string ) int { // ERROR "xs does not escape$"
b := bytes . NewBuffer ( make ( [ ] byte , 0 , 64 ) ) // ERROR "&bytes.Buffer literal does not escape$" "make\(\[\]byte, 0, 64\) does not escape$" "inlining call to bytes.NewBuffer$"
2018-09-06 04:28:17 -06:00
for _ , x := range xs {
b . WriteString ( x )
}
2018-11-30 06:36:00 -07:00
return b . Len ( ) // ERROR "inlining call to bytes.\(\*Buffer\).Len$"
2018-09-06 04:28:17 -06:00
}
2019-09-12 11:18:03 -06:00
func bufferNoEscape3 ( xs [ ] string ) string { // ERROR "xs does not escape$"
b := bytes . NewBuffer ( make ( [ ] byte , 0 , 64 ) ) // ERROR "&bytes.Buffer literal does not escape$" "make\(\[\]byte, 0, 64\) does not escape$" "inlining call to bytes.NewBuffer$"
2018-09-06 04:28:17 -06:00
for _ , x := range xs {
b . WriteString ( x )
b . WriteByte ( ',' )
}
2018-11-30 06:36:00 -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 04:28:17 -06:00
}
2018-09-07 11:36:56 -06:00
func bufferNoEscape4 ( ) [ ] byte {
var b bytes . Buffer
2019-04-01 12:58:33 -06:00
b . Grow ( 64 ) // ERROR "bufferNoEscape4 ignoring self-assignment in bytes.b.buf = bytes.b.buf\[:bytes.m·3\]$" "inlining call to bytes.\(\*Buffer\).Grow$"
useBuffer ( & b )
return b . Bytes ( ) // ERROR "inlining call to bytes.\(\*Buffer\).Bytes$"
2018-09-07 11:36:56 -06:00
}
2018-11-30 06:36:00 -07:00
func bufferNoEscape5 ( ) { // ERROR "can inline bufferNoEscape5$"
2019-09-12 11:18:03 -06:00
b := bytes . NewBuffer ( make ( [ ] byte , 0 , 128 ) ) // ERROR "&bytes.Buffer literal does not escape$" "make\(\[\]byte, 0, 128\) does not escape$" "inlining call to bytes.NewBuffer$"
2018-09-07 11:36:56 -06:00
useBuffer ( b )
}
//go:noinline
2019-09-12 11:18:03 -06:00
func useBuffer ( b * bytes . Buffer ) { // ERROR "b does not escape$"
2018-09-07 11:36:56 -06:00
b . WriteString ( "1234" )
}