diff options
Diffstat (limited to '')
-rw-r--r-- | test/fixedbugs/issue17318.go | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/test/fixedbugs/issue17318.go b/test/fixedbugs/issue17318.go new file mode 100644 index 0000000..21df729 --- /dev/null +++ b/test/fixedbugs/issue17318.go @@ -0,0 +1,47 @@ +// errorcheck -0 -N -m -l + +// Copyright 2016 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. + +// The escape analyzer needs to run till its root set settles +// (this is not that often, it turns out). +// This test is likely to become stale because the leak depends +// on a spurious-escape bug -- return an interface as a named +// output parameter appears to cause the called closure to escape, +// where returning it as a regular type does not. + +package main + +import ( + "fmt" +) + +type closure func(i, j int) ent + +type ent int + +func (e ent) String() string { + return fmt.Sprintf("%d", int(e)) // ERROR "... argument does not escape$" "int\(e\) escapes to heap$" +} + +//go:noinline +func foo(ops closure, j int) (err fmt.Stringer) { // ERROR "ops does not escape" + enqueue := func(i int) fmt.Stringer { // ERROR "func literal does not escape" + return ops(i, j) // ERROR "ops\(i, j\) escapes to heap$" + } + err = enqueue(4) + if err != nil { + return err + } + return // return result of enqueue, a fmt.Stringer +} + +func main() { + // 3 identical functions, to get different escape behavior. + f := func(i, j int) ent { // ERROR "func literal does not escape" + return ent(i + j) + } + i := foo(f, 3).(ent) + fmt.Printf("foo(f,3)=%d\n", int(i)) // ERROR "int\(i\) escapes to heap$" "... argument does not escape$" +} |