blob: 0b6599719dc9cee4bf2aabbfe9c5eddca5553e06 [file] [log] [blame]
Dmitry Vyukov0558f122015-02-19 18:30:08 +03001// errorcheck -0 -m -l
2
3// Copyright 2015 The Go Authors. All rights reserved.
4// Use of this source code is governed by a BSD-style
5// license that can be found in the LICENSE file.
6
7// Test escape analysis for slices.
8
9package escape
10
David Chasea21cf5b2015-05-15 12:19:07 -040011import (
12 "os"
13 "strings"
14)
15
Dmitry Vyukov0558f122015-02-19 18:30:08 +030016var sink interface{}
17
18func slice0() {
19 var s []*int
20 // BAD: i should not escape
21 i := 0 // ERROR "moved to heap: i"
22 s = append(s, &i) // ERROR "&i escapes to heap"
23 _ = s
24}
25
26func slice1() *int {
27 var s []*int
28 i := 0 // ERROR "moved to heap: i"
29 s = append(s, &i) // ERROR "&i escapes to heap"
30 return s[0]
31}
32
33func slice2() []*int {
34 var s []*int
35 i := 0 // ERROR "moved to heap: i"
36 s = append(s, &i) // ERROR "&i escapes to heap"
37 return s
38}
39
40func slice3() *int {
41 var s []*int
42 i := 0 // ERROR "moved to heap: i"
43 s = append(s, &i) // ERROR "&i escapes to heap"
44 for _, p := range s {
45 return p
46 }
47 return nil
48}
49
50func slice4(s []*int) { // ERROR "s does not escape"
51 i := 0 // ERROR "moved to heap: i"
52 s[0] = &i // ERROR "&i escapes to heap"
53}
54
55func slice5(s []*int) { // ERROR "s does not escape"
56 if s != nil {
57 s = make([]*int, 10) // ERROR "make\(\[\]\*int, 10\) does not escape"
58 }
59 i := 0 // ERROR "moved to heap: i"
60 s[0] = &i // ERROR "&i escapes to heap"
61}
62
63func slice6() {
64 s := make([]*int, 10) // ERROR "make\(\[\]\*int, 10\) does not escape"
65 // BAD: i should not escape
66 i := 0 // ERROR "moved to heap: i"
67 s[0] = &i // ERROR "&i escapes to heap"
68 _ = s
69}
70
71func slice7() *int {
72 s := make([]*int, 10) // ERROR "make\(\[\]\*int, 10\) does not escape"
73 i := 0 // ERROR "moved to heap: i"
74 s[0] = &i // ERROR "&i escapes to heap"
75 return s[0]
76}
77
78func slice8() {
David Chasea21cf5b2015-05-15 12:19:07 -040079 i := 0
80 s := []*int{&i} // ERROR "&i does not escape" "literal does not escape"
Dmitry Vyukov0558f122015-02-19 18:30:08 +030081 _ = s
82}
83
84func slice9() *int {
85 i := 0 // ERROR "moved to heap: i"
86 s := []*int{&i} // ERROR "&i escapes to heap" "literal does not escape"
87 return s[0]
88}
89
90func slice10() []*int {
91 i := 0 // ERROR "moved to heap: i"
92 s := []*int{&i} // ERROR "&i escapes to heap" "literal escapes to heap"
93 return s
94}
David Chasea21cf5b2015-05-15 12:19:07 -040095
96func envForDir(dir string) []string { // ERROR "dir does not escape"
97 env := os.Environ()
98 return mergeEnvLists([]string{"PWD=" + dir}, env) // ERROR ".PWD=. \+ dir escapes to heap" "\[\]string literal does not escape"
99}
100
101func mergeEnvLists(in, out []string) []string { // ERROR "leaking param content: in" "leaking param content: out" "leaking param: out to result ~r2 level=0"
102NextVar:
103 for _, inkv := range in {
104 k := strings.SplitAfterN(inkv, "=", 2)[0]
105 for i, outkv := range out {
106 if strings.HasPrefix(outkv, k) {
107 out[i] = inkv
108 continue NextVar
109 }
110 }
111 out = append(out, inkv)
112 }
113 return out
114}
115
116const (
117 IPv4len = 4
118 IPv6len = 16
119)
120
121var v4InV6Prefix = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff}
122
123func IPv4(a, b, c, d byte) IP {
124 p := make(IP, IPv6len) // ERROR "make\(IP, IPv6len\) escapes to heap"
125 copy(p, v4InV6Prefix)
126 p[12] = a
127 p[13] = b
128 p[14] = c
129 p[15] = d
130 return p
131}
132
133type IP []byte
134
135type IPAddr struct {
136 IP IP
137 Zone string // IPv6 scoped addressing zone
138}
139
140type resolveIPAddrTest struct {
141 network string
142 litAddrOrName string
143 addr *IPAddr
144 err error
145}
146
147var resolveIPAddrTests = []resolveIPAddrTest{
148 {"ip", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil},
149 {"ip4", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil},
150 {"ip4:icmp", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil},
151}
152
153func setupTestData() {
154 resolveIPAddrTests = append(resolveIPAddrTests,
155 []resolveIPAddrTest{ // ERROR "\[\]resolveIPAddrTest literal does not escape"
156 {"ip",
157 "localhost",
158 &IPAddr{IP: IPv4(127, 0, 0, 1)}, // ERROR "&IPAddr literal escapes to heap"
159 nil},
160 {"ip4",
161 "localhost",
162 &IPAddr{IP: IPv4(127, 0, 0, 1)}, // ERROR "&IPAddr literal escapes to heap"
163 nil},
164 }...)
165}