1// errorcheck -0 -m 2 3//go:build !gcflags_noopt && !goexperiment.newinliner 4 5// Copyright 2018 The Go Authors. All rights reserved. 6// Use of this source code is governed by a BSD-style 7// license that can be found in the LICENSE file. 8 9package foo 10 11import "bytes" 12 13// In order to get desired results, we need a combination of 14// both escape analysis and inlining. 15 16func bufferNotEscape() string { 17 // b itself does not escape, only its buf field will be 18 // copied during String() call, but object "handle" itself 19 // can be stack-allocated. 20 var b bytes.Buffer 21 b.WriteString("123") 22 b.Write([]byte{'4'}) // ERROR "\[\]byte{...} does not escape$" 23 return b.String() // ERROR "inlining call to bytes.\(\*Buffer\).String$" "string\(bytes.b.buf\[bytes.b.off:\]\) escapes to heap$" 24} 25 26func bufferNoEscape2(xs []string) int { // ERROR "xs does not escape$" 27 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$" 28 for _, x := range xs { 29 b.WriteString(x) 30 } 31 return b.Len() // ERROR "inlining call to bytes.\(\*Buffer\).Len$" 32} 33 34func bufferNoEscape3(xs []string) string { // ERROR "xs does not escape$" 35 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$" 36 for _, x := range xs { 37 b.WriteString(x) 38 b.WriteByte(',') 39 } 40 return b.String() // ERROR "inlining call to bytes.\(\*Buffer\).String$" "string\(bytes.b.buf\[bytes.b.off:\]\) escapes to heap$" 41} 42 43func bufferNoEscape4() []byte { 44 var b bytes.Buffer 45 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` 46 useBuffer(&b) 47 return b.Bytes() // ERROR "inlining call to bytes.\(\*Buffer\).Bytes$" 48} 49 50func bufferNoEscape5() { // ERROR "can inline bufferNoEscape5$" 51 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$" 52 useBuffer(b) 53} 54 55//go:noinline 56func useBuffer(b *bytes.Buffer) { // ERROR "b does not escape$" 57 b.WriteString("1234") 58} 59