]> Cypherpunks.ru repositories - gostls13.git/blob - test/escape_slice.go
[dev.typeparams] all: merge master (912f075) into dev.typeparams
[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 envForDir(dir string) []string { // ERROR "dir does not escape"
109         env := os.Environ()
110         return mergeEnvLists([]string{"PWD=" + dir}, env) // ERROR ".PWD=. \+ dir escapes to heap" "\[\]string{...} does not escape"
111 }
112
113 func mergeEnvLists(in, out []string) []string { // ERROR "leaking param content: in" "leaking param content: out" "leaking param: out to result ~r0 level=0"
114 NextVar:
115         for _, inkv := range in {
116                 k := strings.SplitAfterN(inkv, "=", 2)[0]
117                 for i, outkv := range out {
118                         if strings.HasPrefix(outkv, k) {
119                                 out[i] = inkv
120                                 continue NextVar
121                         }
122                 }
123                 out = append(out, inkv)
124         }
125         return out
126 }
127
128 const (
129         IPv4len = 4
130         IPv6len = 16
131 )
132
133 var v4InV6Prefix = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff}
134
135 func IPv4(a, b, c, d byte) IP {
136         p := make(IP, IPv6len) // ERROR "make\(IP, IPv6len\) escapes to heap"
137         copy(p, v4InV6Prefix)
138         p[12] = a
139         p[13] = b
140         p[14] = c
141         p[15] = d
142         return p
143 }
144
145 type IP []byte
146
147 type IPAddr struct {
148         IP   IP
149         Zone string // IPv6 scoped addressing zone
150 }
151
152 type resolveIPAddrTest struct {
153         network       string
154         litAddrOrName string
155         addr          *IPAddr
156         err           error
157 }
158
159 var resolveIPAddrTests = []resolveIPAddrTest{
160         {"ip", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil},
161         {"ip4", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil},
162         {"ip4:icmp", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil},
163 }
164
165 func setupTestData() {
166         resolveIPAddrTests = append(resolveIPAddrTests,
167                 []resolveIPAddrTest{ // ERROR "\[\]resolveIPAddrTest{...} does not escape"
168                         {"ip",
169                                 "localhost",
170                                 &IPAddr{IP: IPv4(127, 0, 0, 1)}, // ERROR "&IPAddr{...} escapes to heap"
171                                 nil},
172                         {"ip4",
173                                 "localhost",
174                                 &IPAddr{IP: IPv4(127, 0, 0, 1)}, // ERROR "&IPAddr{...} escapes to heap"
175                                 nil},
176                 }...)
177 }