diff options
Diffstat (limited to '')
-rw-r--r-- | test/escape_slice.go | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/test/escape_slice.go b/test/escape_slice.go new file mode 100644 index 0000000..055b60b --- /dev/null +++ b/test/escape_slice.go @@ -0,0 +1,177 @@ +// 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 slices. + +package escape + +import ( + "os" + "strings" +) + +var sink interface{} + +func slice0() { + var s []*int + // BAD: i should not escape + i := 0 // ERROR "moved to heap: i" + s = append(s, &i) + _ = s +} + +func slice1() *int { + var s []*int + i := 0 // ERROR "moved to heap: i" + s = append(s, &i) + return s[0] +} + +func slice2() []*int { + var s []*int + i := 0 // ERROR "moved to heap: i" + s = append(s, &i) + return s +} + +func slice3() *int { + var s []*int + i := 0 // ERROR "moved to heap: i" + s = append(s, &i) + for _, p := range s { + return p + } + return nil +} + +func slice4(s []*int) { // ERROR "s does not escape" + i := 0 // ERROR "moved to heap: i" + s[0] = &i +} + +func slice5(s []*int) { // ERROR "s does not escape" + if s != nil { + s = make([]*int, 10) // ERROR "make\(\[\]\*int, 10\) does not escape" + } + i := 0 // ERROR "moved to heap: i" + s[0] = &i +} + +func slice6() { + s := make([]*int, 10) // ERROR "make\(\[\]\*int, 10\) does not escape" + // BAD: i should not escape + i := 0 // ERROR "moved to heap: i" + s[0] = &i + _ = s +} + +func slice7() *int { + s := make([]*int, 10) // ERROR "make\(\[\]\*int, 10\) does not escape" + i := 0 // ERROR "moved to heap: i" + s[0] = &i + return s[0] +} + +func slice8() { + i := 0 + s := []*int{&i} // ERROR "\[\]\*int{...} does not escape" + _ = s +} + +func slice9() *int { + i := 0 // ERROR "moved to heap: i" + s := []*int{&i} // ERROR "\[\]\*int{...} does not escape" + return s[0] +} + +func slice10() []*int { + i := 0 // ERROR "moved to heap: i" + s := []*int{&i} // ERROR "\[\]\*int{...} escapes to heap" + return s +} + +func slice11() { + i := 2 + s := make([]int, 2, 3) // ERROR "make\(\[\]int, 2, 3\) does not escape" + s = make([]int, i, 3) // ERROR "make\(\[\]int, i, 3\) does not escape" + s = make([]int, i, 1) // ERROR "make\(\[\]int, i, 1\) does not escape" + _ = s +} + +func slice12(x []int) *[1]int { // ERROR "leaking param: x to result ~r0 level=0$" + return (*[1]int)(x) +} + +func envForDir(dir string) []string { // ERROR "dir does not escape" + env := os.Environ() + return mergeEnvLists([]string{"PWD=" + dir}, env) // ERROR ".PWD=. \+ dir escapes to heap" "\[\]string{...} does not escape" +} + +func mergeEnvLists(in, out []string) []string { // ERROR "leaking param content: in" "leaking param content: out" "leaking param: out to result ~r0 level=0" +NextVar: + for _, inkv := range in { + k := strings.SplitAfterN(inkv, "=", 2)[0] + for i, outkv := range out { + if strings.HasPrefix(outkv, k) { + out[i] = inkv + continue NextVar + } + } + out = append(out, inkv) + } + return out +} + +const ( + IPv4len = 4 + IPv6len = 16 +) + +var v4InV6Prefix = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff} + +func IPv4(a, b, c, d byte) IP { + p := make(IP, IPv6len) // ERROR "make\(IP, IPv6len\) escapes to heap" + copy(p, v4InV6Prefix) + p[12] = a + p[13] = b + p[14] = c + p[15] = d + return p +} + +type IP []byte + +type IPAddr struct { + IP IP + Zone string // IPv6 scoped addressing zone +} + +type resolveIPAddrTest struct { + network string + litAddrOrName string + addr *IPAddr + err error +} + +var resolveIPAddrTests = []resolveIPAddrTest{ + {"ip", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil}, + {"ip4", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil}, + {"ip4:icmp", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil}, +} + +func setupTestData() { + resolveIPAddrTests = append(resolveIPAddrTests, + []resolveIPAddrTest{ // ERROR "\[\]resolveIPAddrTest{...} does not escape" + {"ip", + "localhost", + &IPAddr{IP: IPv4(127, 0, 0, 1)}, // ERROR "&IPAddr{...} escapes to heap" + nil}, + {"ip4", + "localhost", + &IPAddr{IP: IPv4(127, 0, 0, 1)}, // ERROR "&IPAddr{...} escapes to heap" + nil}, + }...) +} |