blob: 2b1144ad2c5aa2d45c2f25832e1cd86118805b5c [file] [log] [blame]
Dmitry Vyukovedcc0622015-02-19 16:27:32 +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 interface conversions.
8
9package escape
10
11var sink interface{}
12
13type M interface {
14 M()
15}
16
17func mescapes(m M) { // ERROR "leaking param: m"
18 sink = m // ERROR "m escapes to heap"
19}
20
21func mdoesnotescape(m M) { // ERROR "m does not escape"
22}
23
24// Tests for type stored directly in iface and with value receiver method.
25type M0 struct {
26 p *int
27}
28
29func (M0) M() {
30}
31
32func efaceEscape0() {
33 {
34 i := 0
35 v := M0{&i} // ERROR "&i does not escape"
36 var x M = v // ERROR "v does not escape"
37 _ = x
38 }
39 {
40 i := 0 // ERROR "moved to heap: i"
41 v := M0{&i} // ERROR "&i escapes to heap"
42 var x M = v // ERROR "v escapes to heap"
43 sink = x // ERROR "x escapes to heap"
44 }
45 {
46 i := 0
47 v := M0{&i} // ERROR "&i does not escape"
48 var x M = v // ERROR "v does not escape"
49 v1 := x.(M0)
50 _ = v1
51 }
52 {
53 i := 0 // ERROR "moved to heap: i"
54 v := M0{&i} // ERROR "&i escapes to heap"
55 // BAD: v does not escape to heap here
56 var x M = v // ERROR "v escapes to heap"
57 v1 := x.(M0)
58 sink = v1 // ERROR "v1 escapes to heap"
59 }
60 {
61 i := 0 // ERROR "moved to heap: i"
62 v := M0{&i} // ERROR "&i escapes to heap"
63 // BAD: v does not escape to heap here
64 var x M = v // ERROR "v escapes to heap"
65 x.M()
66 }
67 {
68 i := 0 // ERROR "moved to heap: i"
69 v := M0{&i} // ERROR "&i escapes to heap"
70 var x M = v // ERROR "v escapes to heap"
71 mescapes(x)
72 }
73 {
74 i := 0
75 v := M0{&i} // ERROR "&i does not escape"
76 var x M = v // ERROR "v does not escape"
77 mdoesnotescape(x)
78 }
79}
80
81// Tests for type stored indirectly in iface and with value receiver method.
82type M1 struct {
83 p *int
84 x int
85}
86
87func (M1) M() {
88}
89
90func efaceEscape1() {
91 {
92 i := 0
93 v := M1{&i, 0} // ERROR "&i does not escape"
94 var x M = v // ERROR "v does not escape"
95 _ = x
96 }
97 {
98 i := 0 // ERROR "moved to heap: i"
99 v := M1{&i, 0} // ERROR "&i escapes to heap"
100 var x M = v // ERROR "v escapes to heap"
101 sink = x // ERROR "x escapes to heap"
102 }
103 {
104 i := 0
105 v := M1{&i, 0} // ERROR "&i does not escape"
106 var x M = v // ERROR "v does not escape"
107 v1 := x.(M1)
108 _ = v1
109 }
110 {
111 i := 0 // ERROR "moved to heap: i"
112 v := M1{&i, 0} // ERROR "&i escapes to heap"
113 // BAD: v does not escape to heap here
114 var x M = v // ERROR "v escapes to heap"
115 v1 := x.(M1)
116 sink = v1 // ERROR "v1 escapes to heap"
117 }
118 {
119 i := 0 // ERROR "moved to heap: i"
120 v := M1{&i, 0} // ERROR "&i escapes to heap"
121 // BAD: v does not escape to heap here
122 var x M = v // ERROR "v escapes to heap"
123 x.M()
124 }
125 {
126 i := 0 // ERROR "moved to heap: i"
127 v := M1{&i, 0} // ERROR "&i escapes to heap"
128 var x M = v // ERROR "v escapes to heap"
129 mescapes(x)
130 }
131 {
132 i := 0
133 v := M1{&i, 0} // ERROR "&i does not escape"
134 var x M = v // ERROR "v does not escape"
135 mdoesnotescape(x)
136 }
137}
138
139// Tests for type stored directly in iface and with pointer receiver method.
140type M2 struct {
141 p *int
142}
143
144func (*M2) M() {
145}
146
147func efaceEscape2() {
148 {
149 i := 0
150 v := &M2{&i} // ERROR "&i does not escape" "&M2 literal does not escape"
151 var x M = v // ERROR "v does not escape"
152 _ = x
153 }
154 {
155 i := 0 // ERROR "moved to heap: i"
156 v := &M2{&i} // ERROR "&i escapes to heap" "&M2 literal escapes to heap"
157 var x M = v // ERROR "v escapes to heap"
158 sink = x // ERROR "x escapes to heap"
159 }
160 {
161 i := 0
162 v := &M2{&i} // ERROR "&i does not escape" "&M2 literal does not escape"
163 var x M = v // ERROR "v does not escape"
164 v1 := x.(*M2)
165 _ = v1
166 }
167 {
168 i := 0 // ERROR "moved to heap: i"
169 v := &M2{&i} // ERROR "&i escapes to heap" "&M2 literal escapes to heap"
170 // BAD: v does not escape to heap here
171 var x M = v // ERROR "v escapes to heap"
172 v1 := x.(*M2)
173 sink = v1 // ERROR "v1 escapes to heap"
174 }
175 {
176 i := 0 // ERROR "moved to heap: i"
177 v := &M2{&i} // ERROR "&i escapes to heap" "&M2 literal does not escape"
178 // BAD: v does not escape to heap here
179 var x M = v // ERROR "v does not escape"
180 v1 := x.(*M2)
181 sink = *v1 // ERROR "v1 escapes to heap"
182 }
183 {
184 i := 0 // ERROR "moved to heap: i"
185 v := &M2{&i} // ERROR "&i escapes to heap" "&M2 literal does not escape"
186 // BAD: v does not escape to heap here
187 var x M = v // ERROR "v does not escape"
188 v1, ok := x.(*M2)
189 sink = *v1 // ERROR "v1 escapes to heap"
190 _ = ok
191 }
192 {
193 i := 0 // ERROR "moved to heap: i"
194 v := &M2{&i} // ERROR "&i escapes to heap" "&M2 literal escapes to heap"
195 // BAD: v does not escape to heap here
196 var x M = v // ERROR "v escapes to heap"
197 x.M()
198 }
199 {
200 i := 0 // ERROR "moved to heap: i"
201 v := &M2{&i} // ERROR "&i escapes to heap" "&M2 literal escapes to heap"
202 var x M = v // ERROR "v escapes to heap"
203 mescapes(x)
204 }
205 {
206 i := 0
207 v := &M2{&i} // ERROR "&i does not escape" "&M2 literal does not escape"
208 var x M = v // ERROR "v does not escape"
209 mdoesnotescape(x)
210 }
211}
David Chase6f6bcad2015-07-30 12:31:18 -0400212
213type T1 struct {
214 p *int
215}
216
217type T2 struct {
218 T1 T1
219}
220
221func dotTypeEscape() *T2 { // #11931
222 var x interface{}
223 x = &T1{p: new(int)} // ERROR "new\(int\) escapes to heap" "&T1 literal does not escape"
224 return &T2{
225 T1: *(x.(*T1)), // ERROR "&T2 literal escapes to heap"
226 }
227}