go/test/escape_calls.go
David Chase b19ec6842d cmd/internal/gc: make indirect calls properly escape-y
Indirect function and method calls should leak everything,
but they didn't.

This fix had no particular effect on the cost of running the
compiler on html/template/*.go and added a single new "escape"
to the standard library:

    syscall/syscall_unix.go:85: &b[0] escapes to heap
in
	if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])),
	                     uintptr(len(b))); errno != nil {

Added specific escape testing to escape_calls.go
(and verified that it fails without this patch)

I also did a little code cleanup around the changes in esc.c.

Fixes #10925

Change-Id: I9984b701621ad4c49caed35b01e359295c210033
Reviewed-on: https://go-review.googlesource.com/10295
Reviewed-by: Russ Cox <rsc@golang.org>
2015-05-22 01:36:11 +00:00

55 lines
1.4 KiB
Go

// errorcheck -0 -m -l
// Copyright 2015 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.
// Test escape analysis for function parameters.
// In this test almost everything is BAD except the simplest cases
// where input directly flows to output.
package foo
func f(buf []byte) []byte { // ERROR "leaking param: buf to result ~r1 level=0$"
return buf
}
func g(*byte) string
func h(e int) {
var x [32]byte // ERROR "moved to heap: x$"
g(&f(x[:])[0]) // ERROR "&f\(x\[:\]\)\[0\] escapes to heap$" "x escapes to heap$"
}
type Node struct {
s string
left, right *Node
}
func walk(np **Node) int { // ERROR "leaking param content: np"
n := *np
w := len(n.s)
if n == nil {
return 0
}
wl := walk(&n.left) // ERROR "walk &n.left does not escape"
wr := walk(&n.right) // ERROR "walk &n.right does not escape"
if wl < wr {
n.left, n.right = n.right, n.left
wl, wr = wr, wl
}
*np = n
return w + wl + wr
}
// Test for bug where func var f used prototype's escape analysis results.
func prototype(xyz []string) {} // ERROR "prototype xyz does not escape"
func bar() {
var got [][]string
f := prototype
f = func(ss []string) { got = append(got, ss) } // ERROR "leaking param: ss" "func literal does not escape"
s := "string"
f([]string{s}) // ERROR "\[\]string literal escapes to heap"
}