Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(913)

Delta Between Two Patch Sets: test/escape2.go

Issue 4634073: code review 4634073: gc: Escape analysis. (Closed)
Left Patch Set: diff -r 2afebca6d967 https://go.googlecode.com/hg/ Created 13 years, 8 months ago
Right Patch Set: diff -r adfa9f5cca40 https://go.googlecode.com/hg/ Created 13 years, 7 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Right: Side by side diff | Download
« no previous file with change/comment | « src/cmd/gc/typecheck.c ('k') | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
(no file at all)
1 // errchk -0 $G -sm $D/$F.go
2
3 // Copyright 2010 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 package foo
8
9 import "unsafe"
10
11 var gxx *int
12
13 func foo1(x int) { // ERROR "moved to heap: NAME-x"
14 gxx = &x
15 }
16
17 func foo2(yy *int) { // ERROR "leaking param: NAME-yy"
18 gxx = yy
19 }
20
21 func foo3(x int) *int { // ERROR "moved to heap: NAME-x"
22 return &x
23 }
24
25 type T *T
26 func foo3b(t T) { // ERROR "leaking param: NAME-t"
27 *t = t
28 }
29
30 // xx isn't going anywhere, so use of yy is ok
31 func foo4(xx, yy *int) {
32 xx = yy
33 }
34
35 // xx isn't going anywhere, so taking address of yy is ok
36 func foo5(xx **int, yy *int) {
37 xx = &yy
38 }
39
40 func foo6(xx **int, yy *int) { // ERROR "leaking param: NAME-yy"
41 *xx = yy
42 }
43
44 func foo7(xx **int, yy *int) {
45 **xx = *yy
46 }
47
48 func foo8(xx, yy *int) int {
49 xx = yy
50 return *xx
51 }
52
53 func foo9(xx, yy *int) *int { // ERROR "leaking param: NAME-xx" "leaking param: NAME-yy"
54 xx = yy
55 return xx
56 }
57
58 func foo10(xx, yy *int) {
59 *xx = *yy
60 }
61
62 func foo11() int {
63 x, y := 0, 42
64 xx := &x
65 yy := &y
66 *xx = *yy
67 return x
68 }
69
70
71 var xxx **int
72
73 func foo12(yyy **int) { // ERROR "leaking param: NAME-yyy"
74 xxx = yyy
75 }
76
77 func foo13(yyy **int) {
78 *xxx = *yyy
79 }
80
81 func foo14(yyy **int) {
82 **xxx = **yyy
83 }
84
85 func foo15(yy *int) { // ERROR "moved to heap: NAME-yy"
86 xxx = &yy
87 }
88
89 func foo16(yy *int) { // ERROR "leaking param: NAME-yy"
90 *xxx = yy
91 }
92
93 func foo17(yy *int) {
94 **xxx = *yy
95 }
96
97 func foo18(y int) { // ERROR "moved to heap: "NAME-y"
98 *xxx = &y
99 }
100
101 func foo19(y int) {
102 **xxx = y
103 }
104
105 type Bar struct {
106 i int
107 ii *int
108 }
109
110 func NewBar() *Bar {
111 return &Bar{ 42, nil }
112 }
113
114 func NewBarp(x *int) *Bar { // ERROR "leaking param: NAME-x"
115 return &Bar{ 42, x }
116 }
117
118 func NewBarp2(x *int) *Bar {
119 return &Bar{ *x, nil }
120 }
121
122 func (b *Bar) NoLeak() int {
123 return *(b.ii)
124 }
125
126 func (b *Bar) AlsoNoLeak() *int {
127 return b.ii
128 }
129
130 type Bar2 struct {
131 i [12]int
132 ii []int
133 }
134
135 func NewBar2() *Bar2 {
136 return &Bar2{ [12]int{ 42 }, nil }
137 }
138
139 func (b *Bar2) NoLeak() int {
140 return b.i[0]
141 }
142
143 func (b *Bar2) Leak() []int { // ERROR "leaking param: NAME-b"
144 return b.i[:]
145 }
146
147 func (b *Bar2) AlsoNoLeak() []int {
148 return b.ii[0:1]
149 }
150
151 func (b *Bar2) LeakSelf() { // ERROR "leaking param: NAME-b"
152 b.ii = b.i[0:4]
153 }
154
155 func (b *Bar2) LeakSelf2() { // ERROR "leaking param: NAME-b"
156 var buf []int
157 buf = b.i[0:]
158 b.ii = buf
159 }
160
161 func foo21() func() int {
162 x := 42 // ERROR "moved to heap: NAME-x"
163 return func() int {
164 return x
165 }
166 }
167
168 func foo22() int {
169 x := 42
170 return func() int {
171 return x
172 }()
173 }
174
175 func foo23(x int) func() int { // ERROR "moved to heap: NAME-x"
176 return func() int {
177 return x
178 }
179 }
180
181 func foo23a(x int) (func() int) { // ERROR "moved to heap: NAME-x"
182 f := func() int {
183 return x
184 }
185 return f
186 }
187
188 func foo23b(x int) *(func() int) { // ERROR "moved to heap: NAME-x"
189 f := func() int { return x } // ERROR "moved to heap: NAME-f"
190 return &f
191 }
192
193 func foo24(x int) int {
194 return func() int {
195 return x
196 }()
197 }
198
199
200 var x *int
201
202 func fooleak(xx *int) int { // ERROR "leaking param: NAME-xx"
203 x = xx
204 return *x
205 }
206
207 func foonoleak(xx *int) int {
208 return *x + *xx
209 }
210
211 func foo31(x int) int { // ERROR "moved to heap: NAME-x"
212 return fooleak(&x)
213 }
214
215 func foo32(x int) int {
216 return foonoleak(&x)
217 }
218
219 type Foo struct {
220 xx *int
221 x int
222 }
223
224 var F Foo
225 var pf *Foo
226
227 func (f *Foo) fooleak() { // ERROR "leaking param: NAME-f"
228 pf = f
229 }
230
231 func (f *Foo) foonoleak() {
232 F.x = f.x
233 }
234
235 func (f *Foo) Leak() { // ERROR "leaking param: NAME-f"
236 f.fooleak()
237 }
238
239 func (f *Foo) NoLeak() {
240 f.foonoleak()
241 }
242
243
244 func foo41(x int) { // ERROR "moved to heap: NAME-x"
245 F.xx = &x
246 }
247
248 func (f *Foo) foo42(x int) { // ERROR "moved to heap: NAME-x"
249 f.xx = &x
250 }
251
252 func foo43(f *Foo, x int) { // ERROR "moved to heap: NAME-x"
253 f.xx = &x
254 }
255
256 func foo44(yy *int) { // ERROR "leaking param: NAME-yy"
257 F.xx = yy
258 }
259
260 func (f *Foo) foo45() {
261 F.x = f.x·
262 }
263
264 func (f *Foo) foo46() {
265 F.xx = f.xx·
266 }
267
268 func (f *Foo) foo47() { // ERROR "leaking param: NAME-f"
269 f.xx = &f.x
270 }
271
272
273 var ptrSlice []*int
274
275 func foo50(i *int) { // ERROR "leaking param: NAME-i"
276 ptrSlice[0] = i
277 }
278
279
280 var ptrMap map[*int]*int
281
282 func foo51(i *int) { // ERROR "leaking param: NAME-i"
283 ptrMap[i] = i
284 }
285
286
287 func indaddr1(x int) *int { // ERROR "moved to heap: NAME-x"
288 return &x
289 }
290
291 func indaddr2(x *int) *int { // ERROR "leaking param: NAME-x"
292 return *&x
293 }
294
295 func indaddr3(x *int32) *int { // ERROR "leaking param: NAME-x"
296 return *(**int)(unsafe.Pointer(&x))
297 }
298
299 // From package math:
300
301 func Float32bits(f float32) uint32 {
302 return *(*uint32)(unsafe.Pointer(&f))
303 }
304
305 func Float32frombits(b uint32) float32 {
306 return *(*float32)(unsafe.Pointer(&b))
307 }
308
309 func Float64bits(f float64) uint64 {
310 return *(*uint64)(unsafe.Pointer(&f))
311 }
312
313 func Float64frombits(b uint64) float64 {
314 return *(*float64)(unsafe.Pointer(&b))
315 }
316
317 // contrast with
318 func float64bitsptr(f float64) *uint64 { // ERROR "moved to heap: NAME-f"
319 return (*uint64)(unsafe.Pointer(&f))
320 }
321
322 func float64ptrbitsptr(f *float64) *uint64 { // ERROR "leaking param: NAME-f"
323 return (*uint64)(unsafe.Pointer(f))
324 }
325
326 func typesw(i interface{}) *int { // ERROR "leaking param: NAME-i"
327 switch val := i.(type) {
328 case *int:
329 return val
330 case *int8:
331 v := int(*val) // ERROR "moved to heap: NAME-v"
332 return &v
333 }
334 return nil
335 }
336
337 func exprsw(i *int) *int { // ERROR "leaking param: NAME-i"
338 switch j := i; *j + 110 {
339 case 12:
340 return j
341 case 42:
342 return nil
343 }
344 return nil
345
346 }
347
348 // assigning to an array element is like assigning to the array
349 func foo60(i *int) *int { // ERROR "leaking param: NAME-i"
350 var a [12]*int
351 a[0] = i
352 return a[1]
353 }
354
355 func foo60a(i *int) *int {
356 var a [12]*int
357 a[0] = i
358 return nil
359 }
360
361 // assigning to a struct field is like assigning to the struct
362 func foo61(i *int) *int { // ERROR "leaking param: NAME-i"
363 type S struct {
364 a,b *int
365 }
366 var s S
367 s.a = i
368 return s.b
369 }
370
371 func foo61a(i *int) *int {
372 type S struct {
373 a,b *int
374 }
375 var s S
376 s.a = i
377 return nil
378 }
379
380 // assigning to a struct field is like assigning to the struct but
381 // here this subtlety is lost, since s.a counts as an assignment to a
382 // track-losing dereference.
383 func foo62(i *int) *int { // ERROR "leaking param: NAME-i"
384 type S struct {
385 a,b *int
386 }
387 s := new(S)
388 s.a = i
389 return nil // s.b
390 }
391
392
393 type M interface { M() }
394
395 func foo63(m M) {
396 }
397
398 func foo64(m M) { // ERROR "leaking param: NAME-m"
399 m.M()
400 }
401
402 type MV int
403 func (MV) M() {}
404
405 func foo65() {
406 var mv MV
407 foo63(&mv)
408 }
409
410 func foo66() {
411 var mv MV // ERROR "moved to heap: NAME-mv"
412 foo64(&mv)
413 }
414
415 func foo67() {
416 var mv MV
417 foo63(mv)
418 }
419
420 func foo68() {
421 var mv MV
422 foo64(mv) // escapes but it's an int so irrelevant
423 }
424
425 func foo69(m M) { // ERROR "leaking param: NAME-m"
426 foo64(m)
427 }
428
429 func foo70(mv1 *MV, m M) { // ERROR "leaking param: NAME-mv1" "leaking param: N AME-m"
430 m = mv1
431 foo64(m)
432 }
433
434 func foo71(x *int) []*int { // ERROR "leaking param: NAME-x"
435 var y []*int
436 y = append(y, x)
437 return y
438 }
439
440 func foo71a(x int) []*int { // ERROR "moved to heap: NAME-x"
441 var y []*int
442 y = append(y, &x)
443 return y
444 }
445
446 func foo72() {
447 var x int
448 var y [1]*int
449 y[0] = &x
450 }
451
452 func foo72aa() [10]*int {
453 var x int // ERROR "moved to heap: NAME-x"
454 var y [10]*int
455 y[0] = &x
456 return y
457 }
458
459 func foo72a() {
460 var y [10]*int
461 for i := 0; i < 10; i++ {
462 x := i // not moved to heap b/c y goes nowhere
463 y[i] = &x
464 }
465 return
466 }
467
468 func foo72b() [10]*int {
469 var y [10]*int
470 for i := 0; i < 10; i++ {
471 x := i // ERROR "moved to heap: NAME-x"
472 y[i] = &x
473 }
474 return y
475 }
476
477
478 // issue 2145
479 func foo73() {
480 s := []int{3,2,1}
481 for _, v := range s {
482 vv := v // ERROR "moved to heap: NAME-vv"
483 defer func() { // "func literal escapes its scope" "&vv escape s its scope"
484 println(vv)
485 }()
486 }
487 }
488
489 func foo74() {
490 s := []int{3,2,1}
491 for _, v := range s {
492 vv := v // ERROR "moved to heap: NAME-vv"
493 fn := func() { // "func literal escapes its scope" "&vv escape s its scope"
494 println(vv)
495 }
496 defer fn()
497 }
498 }
499
500 func myprint(y *int, x ...interface{}) *int { // ERROR "leaking param: NAME-y"
501 return y
502 }
503
504 func myprint1(y *int, x ...interface{}) *interface{} { // ERROR "leaking param: NAME-x"
505 return &x[0]
506 }
507
508 func foo75(z *int) { // ERROR "leaking param: NAME-z"
509 myprint(z, 1, 2, 3)
510 }
511
512 func foo75a(z *int) {
513 myprint1(z, 1, 2, 3) // "[.][.][.] argument escapes to heap"
514 }
515
516 func foo76(z *int) {
517 myprint(nil, z)
518 }
519
520 func foo76a(z *int) { // ERROR "leaking param: NAME-z"
521 myprint1(nil, z) // "[.][.][.] argument escapes to heap"
522 }
523
524 func foo76b() {
525 myprint(nil, 1, 2, 3)
526 }
527
528 func foo76c() {
529 myprint1(nil, 1, 2, 3) // "[.][.][.] argument escapes to heap"
530 }
531
532 func foo76d() {
533 defer myprint(nil, 1, 2, 3)
534 }
535
536 func foo76e() {
537 defer myprint1(nil, 1, 2, 3) // "[.][.][.] argument escapes to heap"
538 }
539
540 func foo76f() {
541 for {
542 defer myprint(nil, 1, 2, 3) // "[.][.][.] argument escapes its s cope"
543 }
544 }
545
546 func foo76g() {
547 for {
548 defer myprint1(nil, 1, 2, 3) // "[.][.][.] argument escapes to h eap"
549 }
550 }
551
552 func foo77(z []interface{}) {
553 myprint(nil, z...) // z does not escape
554 }
555
556 func foo77a(z []interface{}) { // ERROR "leaking param: NAME-z"
557 myprint1(nil, z...)
558 }
559
560 func foo78(z int) *int { // ERROR "moved to heap: NAME-z"
561 return &z // "&z escapes"
562 }
563
564 func foo78a(z int) *int { // ERROR "moved to heap: NAME-z"
565 y := &z
566 x := &y
567 return *x // really return y
568 }
569
570 func foo79() *int {
571 return new(int) // "moved to heap: new[(]int[)]"
572 }
573
574 func foo80() *int {
575 var z *int
576 for {
577 z = new(int) // "new[(]int[)] escapes its scope"
578 }
579 _ = z
580 return nil
581 }
582
583 func foo81() *int {
584 for {
585 z := new(int)
586 _ = z
587 }
588 return nil
589 }
590
591 type Fooer interface {
592 Foo()
593 }
594
595 type LimitedFooer struct {
596 Fooer
597 N int64
598 }
599
600 func LimitFooer(r Fooer, n int64) Fooer { // ERROR "leaking param: NAME-r"
601 return &LimitedFooer{r, n}
602 }
603
604 func foo90(x *int) map[*int]*int { // ERROR "leaking param: NAME-x"
605 return map[*int]*int{ nil: x }
606 }
607
608 func foo91(x *int) map[*int]*int { // ERROR "leaking param: NAME-x"
609 return map[*int]*int{ x:nil }
610 }
611
612 func foo92(x *int) [2]*int { // ERROR "leaking param: NAME-x"
613 return [2]*int{ x, nil }
614 }
615
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b