]> Cypherpunks.ru repositories - gostls13.git/blob - test/escape_slice.go
0b6599719dc9cee4bf2aabbfe9c5eddca5553e06
[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) // ERROR "&i escapes to heap"
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) // ERROR "&i escapes to heap"
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) // ERROR "&i escapes to heap"
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) // ERROR "&i escapes to heap"
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 // ERROR "&i escapes to heap"
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 // ERROR "&i escapes to heap"
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 // ERROR "&i escapes to heap"
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             // ERROR "&i escapes to heap"
75         return s[0]
76 }
77
78 func slice8() {
79         i := 0
80         s := []*int{&i} // ERROR "&i does not escape" "literal does not escape"
81         _ = s
82 }
83
84 func 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
90 func 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 }
95
96 func 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
101 func mergeEnvLists(in, out []string) []string { // ERROR "leaking param content: in" "leaking param content: out" "leaking param: out to result ~r2 level=0"
102 NextVar:
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
116 const (
117         IPv4len = 4
118         IPv6len = 16
119 )
120
121 var v4InV6Prefix = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff}
122
123 func 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
133 type IP []byte
134
135 type IPAddr struct {
136         IP   IP
137         Zone string // IPv6 scoped addressing zone
138 }
139
140 type resolveIPAddrTest struct {
141         network       string
142         litAddrOrName string
143         addr          *IPAddr
144         err           error
145 }
146
147 var 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
153 func 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 }