aboutsummaryrefslogtreecommitdiff
path: root/test/escape_closure.go
diff options
context:
space:
mode:
authorDavid Chase <drchase@google.com>2016-03-01 16:53:37 -0500
committerDavid Chase <drchase@google.com>2016-04-05 18:10:09 +0000
commitd8c815d8b5df75c9c030a318fbc566f38c58526f (patch)
treed20da6a4d0a0824823b84c3dd666178878e669d8 /test/escape_closure.go
parenteb876dd83cb8413335d64e50aae5d38337d1ebb4 (diff)
downloadgo-d8c815d8b5df75c9c030a318fbc566f38c58526f.tar.gz
go-d8c815d8b5df75c9c030a318fbc566f38c58526f.zip
cmd/compile: note escape of parts of closured-capture vars
Missed a case for closure calls (OCALLFUNC && indirect) in esc.go:esccall. Cleanup to runtime code for windows to more thoroughly hide a technical escape. Also made code pickier about failing to late non-optional kernel32.dll. Fixes #14409. Change-Id: Ie75486a2c8626c4583224e02e4872c2875f7bca5 Reviewed-on: https://go-review.googlesource.com/20102 Run-TryBot: David Chase <drchase@google.com> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Diffstat (limited to 'test/escape_closure.go')
-rw-r--r--test/escape_closure.go26
1 files changed, 26 insertions, 0 deletions
diff --git a/test/escape_closure.go b/test/escape_closure.go
index 4cdb06e4c5..f36073e7d0 100644
--- a/test/escape_closure.go
+++ b/test/escape_closure.go
@@ -145,3 +145,29 @@ func ClosureCallArgs15() {
// BAD: p should not escape here
}(&p) // ERROR "&p escapes to heap" "\(func literal\)\(&p\) escapes to heap"
}
+
+func ClosureLeak1(s string) string { // ERROR "ClosureLeak1 s does not escape"
+ t := s + "YYYY" // ERROR "escapes to heap"
+ return ClosureLeak1a(t) // ERROR "ClosureLeak1 ... argument does not escape"
+}
+
+// See #14409 -- returning part of captured var leaks it.
+func ClosureLeak1a(a ...string) string { // ERROR "leaking param: a to result ~r1 level=1"
+ return func() string { // ERROR "ClosureLeak1a func literal does not escape"
+ return a[0]
+ }()
+}
+
+func ClosureLeak2(s string) string { // ERROR "ClosureLeak2 s does not escape"
+ t := s + "YYYY" // ERROR "escapes to heap"
+ c := ClosureLeak2a(t) // ERROR "ClosureLeak2 ... argument does not escape"
+ return c
+}
+func ClosureLeak2a(a ...string) string { // ERROR "leaking param: a to result ~r1 level=1"
+ return ClosureLeak2b(func() string { // ERROR "ClosureLeak2a func literal does not escape"
+ return a[0]
+ })
+}
+func ClosureLeak2b(f func() string) string { // ERROR "leaking param: f to result ~r1 level=1"
+ return f()
+}