mirror of
https://github.com/golang/go
synced 2024-11-23 10:30:03 -07:00
0349f29a55
Consider the following code: func f(x []*T) interface{} { return x } It returns an interface that holds a heap copy of x (by calling convT2I or friend), therefore x escape to heap. The current escape analysis only recognizes that x flows to the result. This is not sufficient, since if the result does not escape, x's content may be stack allocated and this will result a heap-to-stack pointer, which is bad. Fix this by realizing that if a CONVIFACE escapes and we're converting from a non-direct interface type, the data needs to escape to heap. Running "toolstash -cmp" on std & cmd, the generated machine code are identical for all packages. However, the export data (escape tags) differ in the following packages. It looks to me that all are similar to the "f" above, where the parameter should escape to heap. io/ioutil/ioutil.go:118 old: leaking param: r to result ~r1 level=0 new: leaking param: r image/image.go:943 old: leaking param: p to result ~r0 level=1 new: leaking param content: p net/url/url.go:200 old: leaking param: s to result ~r2 level=0 new: leaking param: s (as a consequence) net/url/url.go:183 old: leaking param: s to result ~r1 level=0 new: leaking param: s net/url/url.go:194 old: leaking param: s to result ~r1 level=0 new: leaking param: s net/url/url.go:699 old: leaking param: u to result ~r0 level=1 new: leaking param: u net/url/url.go:775 old: (*URL).String u does not escape new: leaking param content: u net/url/url.go:1038 old: leaking param: u to result ~r0 level=1 new: leaking param: u net/url/url.go:1099 old: (*URL).MarshalBinary u does not escape new: leaking param content: u flag/flag.go:235 old: leaking param: s to result ~r0 level=1 new: leaking param content: s go/scanner/errors.go:105 old: leaking param: p to result ~r0 level=0 new: leaking param: p database/sql/sql.go:204 old: leaking param: ns to result ~r0 level=0 new: leaking param: ns go/constant/value.go:303 old: leaking param: re to result ~r2 level=0, leaking param: im to result ~r2 level=0 new: leaking param: re, leaking param: im go/constant/value.go:846 old: leaking param: x to result ~r1 level=0 new: leaking param: x encoding/xml/xml.go:518 old: leaking param: d to result ~r1 level=2 new: leaking param content: d encoding/xml/xml.go:122 old: leaking param: leaking param: t to result ~r1 level=0 new: leaking param: t crypto/x509/verify.go:506 old: leaking param: c to result ~r8 level=0 new: leaking param: c crypto/x509/verify.go:563 old: leaking param: c to result ~r3 level=0, leaking param content: c new: leaking param: c crypto/x509/verify.go:615 old: (nothing) new: leaking closure reference c crypto/x509/verify.go:996 old: leaking param: c to result ~r1 level=0, leaking param content: c new: leaking param: c net/http/filetransport.go:30 old: leaking param: fs to result ~r1 level=0 new: leaking param: fs net/http/h2_bundle.go:2684 old: leaking param: mh to result ~r0 level=2 new: leaking param content: mh net/http/h2_bundle.go:7352 old: http2checkConnHeaders req does not escape new: leaking param content: req net/http/pprof/pprof.go:221 old: leaking param: name to result ~r1 level=0 new: leaking param: name cmd/internal/bio/must.go:21 old: leaking param: w to result ~r1 level=0 new: leaking param: w Fixes #29353. Change-Id: I7e7798ae773728028b0dcae5bccb3ada51189c68 Reviewed-on: https://go-review.googlesource.com/c/162829 Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com> Reviewed-by: David Chase <drchase@google.com> |
||
---|---|---|
.. | ||
alias3.dir | ||
bench | ||
chan | ||
closure3.dir | ||
codegen | ||
ddd2.dir | ||
dwarf | ||
fixedbugs | ||
import2.dir | ||
import4.dir | ||
interface | ||
intrinsic.dir | ||
ken | ||
linkname.dir | ||
method4.dir | ||
retjmp.dir | ||
stress | ||
syntax | ||
uintptrescapes.dir | ||
64bit.go | ||
235.go | ||
alg.go | ||
alias1.go | ||
alias2.go | ||
alias3.go | ||
alias.go | ||
align.go | ||
append1.go | ||
append.go | ||
args.go | ||
armimm.go | ||
assign1.go | ||
assign.go | ||
atomicload.go | ||
bigalg.go | ||
bigmap.go | ||
blank1.go | ||
blank.go | ||
bom.go | ||
bombad.go | ||
bounds.go | ||
chancap.go | ||
chanlinear.go | ||
char_lit1.go | ||
char_lit.go | ||
checkbce.go | ||
clearfat.go | ||
closedchan.go | ||
closure1.go | ||
closure2.go | ||
closure3.go | ||
closure4.go | ||
closure.go | ||
cmp6.go | ||
cmp.go | ||
cmplx.go | ||
cmplxdivide1.go | ||
cmplxdivide.c | ||
cmplxdivide.go | ||
complit1.go | ||
complit.go | ||
compos.go | ||
const1.go | ||
const2.go | ||
const3.go | ||
const4.go | ||
const5.go | ||
const6.go | ||
const.go | ||
convert1.go | ||
convert2.go | ||
convert3.go | ||
convert.go | ||
convlit1.go | ||
convlit.go | ||
convT2X.go | ||
copy1.go | ||
copy.go | ||
crlf.go | ||
ddd1.go | ||
ddd2.go | ||
ddd.go | ||
decl.go | ||
declbad.go | ||
defer.go | ||
deferfin.go | ||
deferprint.go | ||
deferprint.out | ||
devirt.go | ||
divide.go | ||
divmod.go | ||
empty.go | ||
env.go | ||
eof1.go | ||
eof.go | ||
escape2.go | ||
escape2n.go | ||
escape3.go | ||
escape4.go | ||
escape5.go | ||
escape_array.go | ||
escape_because.go | ||
escape_calls.go | ||
escape_closure.go | ||
escape_field.go | ||
escape_iface.go | ||
escape_indir.go | ||
escape_level.go | ||
escape_map.go | ||
escape_param.go | ||
escape_slice.go | ||
escape_struct_param1.go | ||
escape_struct_param2.go | ||
escape_struct_return.go | ||
escape.go | ||
fibo.go | ||
finprofiled.go | ||
float_lit2.go | ||
float_lit3.go | ||
float_lit.go | ||
floatcmp.go | ||
for.go | ||
func1.go | ||
func2.go | ||
func3.go | ||
func4.go | ||
func5.go | ||
func6.go | ||
func7.go | ||
func8.go | ||
func.go | ||
funcdup2.go | ||
funcdup.go | ||
gc1.go | ||
gc2.go | ||
gc.go | ||
gcgort.go | ||
gcstring.go | ||
goprint.go | ||
goprint.out | ||
goto.go | ||
heapsampling.go | ||
helloworld.go | ||
helloworld.out | ||
if.go | ||
import1.go | ||
import2.go | ||
import4.go | ||
import5.go | ||
import6.go | ||
import.go | ||
index0.go | ||
index1.go | ||
index2.go | ||
index.go | ||
indirect1.go | ||
indirect.go | ||
init1.go | ||
init.go | ||
initcomma.go | ||
initialize.go | ||
initializerr.go | ||
initloop.go | ||
inline_big.go | ||
inline_caller.go | ||
inline_callers.go | ||
inline_literal.go | ||
inline_math_bits_rotate.go | ||
inline_variadic.go | ||
inline.go | ||
int_lit.go | ||
intcvt.go | ||
intrinsic_atomic.go | ||
intrinsic.go | ||
iota.go | ||
label1.go | ||
label.go | ||
linkmain_run.go | ||
linkmain.go | ||
linkname.go | ||
linkobj.go | ||
linkx_run.go | ||
linkx.go | ||
literal2.go | ||
literal.go | ||
live1.go | ||
live2.go | ||
live_syscall.go | ||
live.go | ||
locklinear.go | ||
loopbce.go | ||
makechan.go | ||
makemap.go | ||
makenew.go | ||
mallocfin.go | ||
map1.go | ||
map.go | ||
mapclear.go | ||
maplinear.go | ||
mergemul.go | ||
method1.go | ||
method2.go | ||
method3.go | ||
method4.go | ||
method5.go | ||
method6.go | ||
method7.go | ||
method.go | ||
named1.go | ||
named.go | ||
nil.go | ||
nilcheck.go | ||
nilptr2.go | ||
nilptr3.go | ||
nilptr4.go | ||
nilptr5_aix.go | ||
nilptr5_wasm.go | ||
nilptr5.go | ||
nilptr_aix.go | ||
nilptr.go | ||
nosplit.go | ||
notinheap2.go | ||
notinheap3.go | ||
notinheap.go | ||
nowritebarrier.go | ||
nul1.go | ||
opt_branchlikely.go | ||
parentype.go | ||
peano.go | ||
phiopt.go | ||
print.go | ||
print.out | ||
printbig.go | ||
printbig.out | ||
prove.go | ||
range.go | ||
README.md | ||
recover1.go | ||
recover2.go | ||
recover3.go | ||
recover4.go | ||
recover5.go | ||
recover.go | ||
reflectmethod1.go | ||
reflectmethod2.go | ||
reflectmethod3.go | ||
reflectmethod4.go | ||
rename1.go | ||
rename.go | ||
reorder2.go | ||
reorder.go | ||
retjmp.go | ||
return.go | ||
rotate0.go | ||
rotate1.go | ||
rotate2.go | ||
rotate3.go | ||
rotate.go | ||
run.go | ||
rune.go | ||
runtime.go | ||
shift1.go | ||
shift2.go | ||
sieve.go | ||
sigchld.go | ||
sigchld.out | ||
simassign.go | ||
sinit_run.go | ||
sinit.go | ||
sizeof.go | ||
slice3.go | ||
slice3err.go | ||
slicecap.go | ||
sliceopt.go | ||
solitaire.go | ||
stack.go | ||
stackobj2.go | ||
stackobj3.go | ||
stackobj.go | ||
strcopy.go | ||
strength.go | ||
string_lit.go | ||
stringrange.go | ||
struct0.go | ||
switch2.go | ||
switch3.go | ||
switch4.go | ||
switch5.go | ||
switch6.go | ||
switch7.go | ||
switch.go | ||
tinyfin.go | ||
torture.go | ||
turing.go | ||
typecheck.go | ||
typecheckloop.go | ||
typeswitch1.go | ||
typeswitch2.go | ||
typeswitch3.go | ||
typeswitch.go | ||
uintptrescapes2.go | ||
uintptrescapes.go | ||
undef.go | ||
utf.go | ||
varerr.go | ||
varinit.go | ||
writebarrier.go | ||
zerodivide.go |
The test directory contains tests of the Go tool chain and runtime. It includes black box tests, regression tests, and error output tests. They are run as part of all.bash.
To run just these tests, execute:
../bin/go run run.go
Standard library tests should be written as regular Go tests in the appropriate package.
The tool chain and runtime also have regular Go tests in their packages. The main reasons to add a new test to this directory are:
- it is most naturally expressed using the test runner; or
- it is also applicable to
gccgo
and other Go tool chains.