// errorcheck -0 -m -l
-// Copyright 2015 The Go Authors. All rights reserved.
+// 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.
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) // ERROR "&i escapes to heap"
+ 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) // ERROR "&i escapes to heap"
+ 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) // ERROR "&i escapes to heap"
+ 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) // ERROR "&i escapes to heap"
+ i := 0 // ERROR "moved to heap: i"
+ s = append(s, &i)
for _, p := range s {
return p
}
}
func slice4(s []*int) { // ERROR "s does not escape"
- i := 0 // ERROR "moved to heap: i"
- s[0] = &i // ERROR "&i escapes to heap"
+ 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 // ERROR "&i escapes to heap"
+ 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 // ERROR "&i escapes to heap"
+ 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 // ERROR "&i escapes to heap"
+ s[0] = &i
return s[0]
}
func slice8() {
- // BAD: i should not escape here
- i := 0 // ERROR "moved to heap: i"
- s := []*int{&i} // ERROR "&i escapes to heap" "literal does not escape"
+ 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 "&i escapes to heap" "literal does not escape"
+ 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 "&i escapes to heap" "literal escapes to heap"
+ 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 slice13(x []*int) [1]*int { // ERROR "leaking param: x to result ~r0 level=1$"
+ 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, 16\) 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},
+ }...)
+}