]> Cypherpunks.ru repositories - gostls13.git/blob - test/escape_slice.go
cmd/compile/internal/inline: score call sites exposed by inlines
[gostls13.git] / test / escape_slice.go
1 // 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
9 package escape
10
11 import (
12         "os"
13         "strings"
14 )
15
16 var sink interface{}
17
18 func slice0() {
19         var s []*int
20         // BAD: i should not escape
21         i := 0 // ERROR "moved to heap: i"
22         s = append(s, &i)
23         _ = s
24 }
25
26 func slice1() *int {
27         var s []*int
28         i := 0 // ERROR "moved to heap: i"
29         s = append(s, &i)
30         return s[0]
31 }
32
33 func slice2() []*int {
34         var s []*int
35         i := 0 // ERROR "moved to heap: i"
36         s = append(s, &i)
37         return s
38 }
39
40 func slice3() *int {
41         var s []*int
42         i := 0 // ERROR "moved to heap: i"
43         s = append(s, &i)
44         for _, p := range s {
45                 return p
46         }
47         return nil
48 }
49
50 func slice4(s []*int) { // ERROR "s does not escape"
51         i := 0 // ERROR "moved to heap: i"
52         s[0] = &i
53 }
54
55 func 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
61 }
62
63 func 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
68         _ = s
69 }
70
71 func 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
75         return s[0]
76 }
77
78 func slice8() {
79         i := 0
80         s := []*int{&i} // ERROR "\[\]\*int{...} does not escape"
81         _ = s
82 }
83
84 func slice9() *int {
85         i := 0          // ERROR "moved to heap: i"
86         s := []*int{&i} // ERROR "\[\]\*int{...} does not escape"
87         return s[0]
88 }
89
90 func slice10() []*int {
91         i := 0          // ERROR "moved to heap: i"
92         s := []*int{&i} // ERROR "\[\]\*int{...} escapes to heap"
93         return s
94 }
95
96 func slice11() {
97         i := 2
98         s := make([]int, 2, 3) // ERROR "make\(\[\]int, 2, 3\) does not escape"
99         s = make([]int, i, 3)  // ERROR "make\(\[\]int, i, 3\) does not escape"
100         s = make([]int, i, 1)  // ERROR "make\(\[\]int, i, 1\) does not escape"
101         _ = s
102 }
103
104 func slice12(x []int) *[1]int { // ERROR "leaking param: x to result ~r0 level=0$"
105         return (*[1]int)(x)
106 }
107
108 func slice13(x []*int) [1]*int { // ERROR "leaking param: x to result ~r0 level=1$"
109         return [1]*int(x)
110 }
111
112 func envForDir(dir string) []string { // ERROR "dir does not escape"
113         env := os.Environ()
114         return mergeEnvLists([]string{"PWD=" + dir}, env) // ERROR ".PWD=. \+ dir escapes to heap" "\[\]string{...} does not escape"
115 }
116
117 func mergeEnvLists(in, out []string) []string { // ERROR "leaking param content: in" "leaking param content: out" "leaking param: out to result ~r0 level=0"
118 NextVar:
119         for _, inkv := range in {
120                 k := strings.SplitAfterN(inkv, "=", 2)[0]
121                 for i, outkv := range out {
122                         if strings.HasPrefix(outkv, k) {
123                                 out[i] = inkv
124                                 continue NextVar
125                         }
126                 }
127                 out = append(out, inkv)
128         }
129         return out
130 }
131
132 const (
133         IPv4len = 4
134         IPv6len = 16
135 )
136
137 var v4InV6Prefix = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff}
138
139 func IPv4(a, b, c, d byte) IP {
140         p := make(IP, IPv6len) // ERROR "make\(IP, 16\) escapes to heap"
141         copy(p, v4InV6Prefix)
142         p[12] = a
143         p[13] = b
144         p[14] = c
145         p[15] = d
146         return p
147 }
148
149 type IP []byte
150
151 type IPAddr struct {
152         IP   IP
153         Zone string // IPv6 scoped addressing zone
154 }
155
156 type resolveIPAddrTest struct {
157         network       string
158         litAddrOrName string
159         addr          *IPAddr
160         err           error
161 }
162
163 var resolveIPAddrTests = []resolveIPAddrTest{
164         {"ip", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil},
165         {"ip4", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil},
166         {"ip4:icmp", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil},
167 }
168
169 func setupTestData() {
170         resolveIPAddrTests = append(resolveIPAddrTests,
171                 []resolveIPAddrTest{ // ERROR "\[\]resolveIPAddrTest{...} does not escape"
172                         {"ip",
173                                 "localhost",
174                                 &IPAddr{IP: IPv4(127, 0, 0, 1)}, // ERROR "&IPAddr{...} escapes to heap"
175                                 nil},
176                         {"ip4",
177                                 "localhost",
178                                 &IPAddr{IP: IPv4(127, 0, 0, 1)}, // ERROR "&IPAddr{...} escapes to heap"
179                                 nil},
180                 }...)
181 }