diff options
author | Matthew Dempsky <mdempsky@google.com> | 2020-09-22 02:12:03 -0700 |
---|---|---|
committer | Matthew Dempsky <mdempsky@google.com> | 2020-10-15 18:26:06 +0000 |
commit | c0417df15664a84c3cc6de8292f78debce111def (patch) | |
tree | a108212a44ad9e938a2c6c22c71e30da3a998470 /test/escape_closure.go | |
parent | cced777026e1fc094ed21d99ae1efa4cf19146d2 (diff) | |
download | go-git-c0417df15664a84c3cc6de8292f78debce111def.tar.gz |
cmd/compile: improve escape analysis of known calls
Escape analysis is currently very naive about identifying calls to
known functions: it only recognizes direct calls to a declared
function, or direct calls to a closure.
This CL adds a new "staticValue" helper function that can trace back
through local variables that were initialized and never reassigned
based on a similar optimization already used by inlining. (And to be
used by inlining in a followup CL.)
Updates #41474.
Change-Id: I8204fd3b1e150ab77a27f583985cf099a8572b2e
Reviewed-on: https://go-review.googlesource.com/c/go/+/256458
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: David Chase <drchase@google.com>
Diffstat (limited to 'test/escape_closure.go')
-rw-r--r-- | test/escape_closure.go | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/test/escape_closure.go b/test/escape_closure.go index 3b14027fa4..9152319fe0 100644 --- a/test/escape_closure.go +++ b/test/escape_closure.go @@ -50,7 +50,7 @@ func ClosureCallArgs4() { } func ClosureCallArgs5() { - x := 0 // ERROR "moved to heap: x" + x := 0 // ERROR "moved to heap: x" // TODO(mdempsky): We get "leaking param: p" here because the new escape analysis pass // can tell that p flows directly to sink, but it's a little weird. Re-evaluate. sink = func(p *int) *int { // ERROR "leaking param: p" "func literal does not escape" @@ -132,7 +132,7 @@ func ClosureCallArgs14() { } func ClosureCallArgs15() { - x := 0 // ERROR "moved to heap: x" + x := 0 // ERROR "moved to heap: x" p := &x sink = func(p **int) *int { // ERROR "leaking param content: p" "func literal does not escape" return *p @@ -164,3 +164,16 @@ func ClosureLeak2a(a ...string) string { // ERROR "leaking param content: a" func ClosureLeak2b(f func() string) string { // ERROR "f does not escape" return f() } + +func ClosureIndirect() { + f := func(p *int) {} // ERROR "p does not escape" "func literal does not escape" + f(new(int)) // ERROR "new\(int\) does not escape" + + g := f + g(new(int)) // ERROR "new\(int\) does not escape" + + h := nopFunc + h(new(int)) // ERROR "new\(int\) does not escape" +} + +func nopFunc(p *int) {} // ERROR "p does not escape" |