1// errorcheck -0 -m -l 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// Test, using compiler diagnostic flags, that the escape analysis is working. 8// Compiles but does not run. Inlining is disabled. 9 10package foo 11 12import ( 13 "fmt" 14 "unsafe" 15) 16 17var gxx *int 18 19func foo1(x int) { // ERROR "moved to heap: x" 20 gxx = &x // ERROR "&x escapes to heap" 21} 22 23func foo2(yy *int) { // ERROR "leaking param: yy" 24 gxx = yy 25} 26 27func foo3(x int) *int { // ERROR "moved to heap: x" 28 return &x // ERROR "&x escapes to heap" 29} 30 31type T *T 32 33func foo3b(t T) { // ERROR "leaking param: t" 34 *t = t 35} 36 37// xx isn't going anywhere, so use of yy is ok 38func foo4(xx, yy *int) { // ERROR "xx does not escape" "yy does not escape" 39 xx = yy 40} 41 42// xx isn't going anywhere, so taking address of yy is ok 43func foo5(xx **int, yy *int) { // ERROR "xx does not escape" "yy does not escape" 44 xx = &yy // ERROR "&yy does not escape" 45} 46 47func foo6(xx **int, yy *int) { // ERROR "xx does not escape" "leaking param: yy" 48 *xx = yy 49} 50 51func foo7(xx **int, yy *int) { // ERROR "xx does not escape" "yy does not escape" 52 **xx = *yy 53} 54 55func foo8(xx, yy *int) int { // ERROR "xx does not escape" "yy does not escape" 56 xx = yy 57 return *xx 58} 59 60func foo9(xx, yy *int) *int { // ERROR "leaking param: xx" "leaking param: yy" 61 xx = yy 62 return xx 63} 64 65func foo10(xx, yy *int) { // ERROR "xx does not escape" "yy does not escape" 66 *xx = *yy 67} 68 69func foo11() int { 70 x, y := 0, 42 71 xx := &x // ERROR "&x does not escape" 72 yy := &y // ERROR "&y does not escape" 73 *xx = *yy 74 return x 75} 76 77var xxx **int 78 79func foo12(yyy **int) { // ERROR "leaking param: yyy" 80 xxx = yyy 81} 82 83// Must treat yyy as leaking because *yyy leaks, and the escape analysis 84// summaries in exported metadata do not distinguish these two cases. 85func foo13(yyy **int) { // ERROR "leaking param: yyy" 86 *xxx = *yyy 87} 88 89func foo14(yyy **int) { // ERROR "yyy does not escape" 90 **xxx = **yyy 91} 92 93func foo15(yy *int) { // ERROR "moved to heap: yy" 94 xxx = &yy // ERROR "&yy escapes to heap" 95} 96 97func foo16(yy *int) { // ERROR "leaking param: yy" 98 *xxx = yy 99} 100 101func foo17(yy *int) { // ERROR "yy does not escape" 102 **xxx = *yy 103} 104 105func foo18(y int) { // ERROR "moved to heap: "y" 106 *xxx = &y // ERROR "&y escapes to heap" 107} 108 109func foo19(y int) { 110 **xxx = y 111} 112 113type Bar struct { 114 i int 115 ii *int 116} 117 118func NewBar() *Bar { 119 return &Bar{42, nil} // ERROR "&Bar literal escapes to heap" 120} 121 122func NewBarp(x *int) *Bar { // ERROR "leaking param: x" 123 return &Bar{42, x} // ERROR "&Bar literal escapes to heap" 124} 125 126func NewBarp2(x *int) *Bar { // ERROR "x does not escape" 127 return &Bar{*x, nil} // ERROR "&Bar literal escapes to heap" 128} 129 130func (b *Bar) NoLeak() int { // ERROR "b does not escape" 131 return *(b.ii) 132} 133 134func (b *Bar) Leak() *int { // ERROR "leaking param: b" 135 return &b.i // ERROR "&b.i escapes to heap" 136} 137 138func (b *Bar) AlsoNoLeak() *int { // ERROR "b does not escape" 139 return b.ii 140} 141 142func (b Bar) AlsoLeak() *int { // ERROR "leaking param: b" 143 return b.ii 144} 145 146func (b Bar) LeaksToo() *int { // ERROR "leaking param: b" 147 v := 0 // ERROR "moved to heap: v" 148 b.ii = &v // ERROR "&v escapes" 149 return b.ii 150} 151 152func (b *Bar) LeaksABit() *int { // ERROR "b does not escape" 153 v := 0 // ERROR "moved to heap: v" 154 b.ii = &v // ERROR "&v escapes" 155 return b.ii 156} 157 158func (b Bar) StillNoLeak() int { // ERROR "b does not escape" 159 v := 0 160 b.ii = &v // ERROR "&v does not escape" 161 return b.i 162} 163 164func goLeak(b *Bar) { // ERROR "leaking param: b" 165 go b.NoLeak() 166} 167 168type Bar2 struct { 169 i [12]int 170 ii []int 171} 172 173func NewBar2() *Bar2 { 174 return &Bar2{[12]int{42}, nil} // ERROR "&Bar2 literal escapes to heap" 175} 176 177func (b *Bar2) NoLeak() int { // ERROR "b does not escape" 178 return b.i[0] 179} 180 181func (b *Bar2) Leak() []int { // ERROR "leaking param: b" 182 return b.i[:] // ERROR "b.i escapes to heap" 183} 184 185func (b *Bar2) AlsoNoLeak() []int { // ERROR "b does not escape" 186 return b.ii[0:1] 187} 188 189func (b Bar2) AgainNoLeak() [12]int { // ERROR "b does not escape" 190 return b.i 191} 192 193func (b *Bar2) LeakSelf() { // ERROR "leaking param: b" 194 b.ii = b.i[0:4] // ERROR "b.i escapes to heap" 195} 196 197func (b *Bar2) LeakSelf2() { // ERROR "leaking param: b" 198 var buf []int 199 buf = b.i[0:] // ERROR "b.i escapes to heap" 200 b.ii = buf 201} 202 203func foo21() func() int { 204 x := 42 // ERROR "moved to heap: x" 205 return func() int { // ERROR "func literal escapes to heap" 206 return x // ERROR "&x escapes to heap" 207 } 208} 209 210func foo22() int { 211 x := 42 212 return func() int { // ERROR "func literal does not escape" 213 return x 214 }() 215} 216 217func foo23(x int) func() int { // ERROR "moved to heap: x" 218 return func() int { // ERROR "func literal escapes to heap" 219 return x // ERROR "&x escapes to heap" 220 } 221} 222 223func foo23a(x int) func() int { // ERROR "moved to heap: x" 224 f := func() int { // ERROR "func literal escapes to heap" 225 return x // ERROR "&x escapes to heap" 226 } 227 return f 228} 229 230func foo23b(x int) *(func() int) { // ERROR "moved to heap: x" 231 f := func() int { return x } // ERROR "moved to heap: f" "func literal escapes to heap" "&x escapes to heap" 232 return &f // ERROR "&f escapes to heap" 233} 234 235func foo24(x int) int { 236 return func() int { // ERROR "func literal does not escape" 237 return x 238 }() 239} 240 241var x *int 242 243func fooleak(xx *int) int { // ERROR "leaking param: xx" 244 x = xx 245 return *x 246} 247 248func foonoleak(xx *int) int { // ERROR "xx does not escape" 249 return *x + *xx 250} 251 252func foo31(x int) int { // ERROR "moved to heap: x" 253 return fooleak(&x) // ERROR "&x escapes to heap" 254} 255 256func foo32(x int) int { 257 return foonoleak(&x) // ERROR "&x does not escape" 258} 259 260type Foo struct { 261 xx *int 262 x int 263} 264 265var F Foo 266var pf *Foo 267 268func (f *Foo) fooleak() { // ERROR "leaking param: f" 269 pf = f 270} 271 272func (f *Foo) foonoleak() { // ERROR "f does not escape" 273 F.x = f.x 274} 275 276func (f *Foo) Leak() { // ERROR "leaking param: f" 277 f.fooleak() 278} 279 280func (f *Foo) NoLeak() { // ERROR "f does not escape" 281 f.foonoleak() 282} 283 284func foo41(x int) { // ERROR "moved to heap: x" 285 F.xx = &x // ERROR "&x escapes to heap" 286} 287 288func (f *Foo) foo42(x int) { // ERROR "f does not escape" "moved to heap: x" 289 f.xx = &x // ERROR "&x escapes to heap" 290} 291 292func foo43(f *Foo, x int) { // ERROR "f does not escape" "moved to heap: x" 293 f.xx = &x // ERROR "&x escapes to heap" 294} 295 296func foo44(yy *int) { // ERROR "leaking param: yy" 297 F.xx = yy 298} 299 300func (f *Foo) foo45() { // ERROR "f does not escape" 301 F.x = f.x 302} 303 304// See foo13 above for explanation of why f leaks. 305func (f *Foo) foo46() { // ERROR "leaking param: f" 306 F.xx = f.xx 307} 308 309func (f *Foo) foo47() { // ERROR "leaking param: f" 310 f.xx = &f.x // ERROR "&f.x escapes to heap" 311} 312 313var ptrSlice []*int 314 315func foo50(i *int) { // ERROR "leaking param: i" 316 ptrSlice[0] = i 317} 318 319var ptrMap map[*int]*int 320 321func foo51(i *int) { // ERROR "leaking param: i" 322 ptrMap[i] = i 323} 324 325func indaddr1(x int) *int { // ERROR "moved to heap: x" 326 return &x // ERROR "&x escapes to heap" 327} 328 329func indaddr2(x *int) *int { // ERROR "leaking param: x" 330 return *&x // ERROR "&x does not escape" 331} 332 333func indaddr3(x *int32) *int { // ERROR "leaking param: x" 334 return *(**int)(unsafe.Pointer(&x)) // ERROR "&x does not escape" 335} 336 337// From package math: 338 339func Float32bits(f float32) uint32 { 340 return *(*uint32)(unsafe.Pointer(&f)) // ERROR "&f does not escape" 341} 342 343func Float32frombits(b uint32) float32 { 344 return *(*float32)(unsafe.Pointer(&b)) // ERROR "&b does not escape" 345} 346 347func Float64bits(f float64) uint64 { 348 return *(*uint64)(unsafe.Pointer(&f)) // ERROR "&f does not escape" 349} 350 351func Float64frombits(b uint64) float64 { 352 return *(*float64)(unsafe.Pointer(&b)) // ERROR "&b does not escape" 353} 354 355// contrast with 356func float64bitsptr(f float64) *uint64 { // ERROR "moved to heap: f" 357 return (*uint64)(unsafe.Pointer(&f)) // ERROR "&f escapes to heap" 358} 359 360func float64ptrbitsptr(f *float64) *uint64 { // ERROR "leaking param: f" 361 return (*uint64)(unsafe.Pointer(f)) 362} 363 364func typesw(i interface{}) *int { // ERROR "leaking param: i" 365 switch val := i.(type) { 366 case *int: 367 return val 368 case *int8: 369 v := int(*val) // ERROR "moved to heap: v" 370 return &v // ERROR "&v escapes to heap" 371 } 372 return nil 373} 374 375func exprsw(i *int) *int { // ERROR "leaking param: i" 376 switch j := i; *j + 110 { 377 case 12: 378 return j 379 case 42: 380 return nil 381 } 382 return nil 383 384} 385 386// assigning to an array element is like assigning to the array 387func foo60(i *int) *int { // ERROR "leaking param: i" 388 var a [12]*int 389 a[0] = i 390 return a[1] 391} 392 393func foo60a(i *int) *int { // ERROR "i does not escape" 394 var a [12]*int 395 a[0] = i 396 return nil 397} 398 399// assigning to a struct field is like assigning to the struct 400func foo61(i *int) *int { // ERROR "leaking param: i" 401 type S struct { 402 a, b *int 403 } 404 var s S 405 s.a = i 406 return s.b 407} 408 409func foo61a(i *int) *int { // ERROR "i does not escape" 410 type S struct { 411 a, b *int 412 } 413 var s S 414 s.a = i 415 return nil 416} 417 418// assigning to a struct field is like assigning to the struct but 419// here this subtlety is lost, since s.a counts as an assignment to a 420// track-losing dereference. 421func foo62(i *int) *int { // ERROR "leaking param: i" 422 type S struct { 423 a, b *int 424 } 425 s := new(S) // ERROR "new[(]S[)] does not escape" 426 s.a = i 427 return nil // s.b 428} 429 430type M interface { 431 M() 432} 433 434func foo63(m M) { // ERROR "m does not escape" 435} 436 437func foo64(m M) { // ERROR "leaking param: m" 438 m.M() 439} 440 441func foo64b(m M) { // ERROR "leaking param: m" 442 defer m.M() 443} 444 445type MV int 446 447func (MV) M() {} 448 449func foo65() { 450 var mv MV 451 foo63(&mv) // ERROR "&mv does not escape" 452} 453 454func foo66() { 455 var mv MV // ERROR "moved to heap: mv" 456 foo64(&mv) // ERROR "&mv escapes to heap" 457} 458 459func foo67() { 460 var mv MV 461 foo63(mv) 462} 463 464func foo68() { 465 var mv MV 466 foo64(mv) // escapes but it's an int so irrelevant 467} 468 469func foo69(m M) { // ERROR "leaking param: m" 470 foo64(m) 471} 472 473func foo70(mv1 *MV, m M) { // ERROR "leaking param: mv1" "leaking param: m" 474 m = mv1 475 foo64(m) 476} 477 478func foo71(x *int) []*int { // ERROR "leaking param: x" 479 var y []*int 480 y = append(y, x) 481 return y 482} 483 484func foo71a(x int) []*int { // ERROR "moved to heap: x" 485 var y []*int 486 y = append(y, &x) // ERROR "&x escapes to heap" 487 return y 488} 489 490func foo72() { 491 var x int 492 var y [1]*int 493 y[0] = &x // ERROR "&x does not escape" 494} 495 496func foo72aa() [10]*int { 497 var x int // ERROR "moved to heap: x" 498 var y [10]*int 499 y[0] = &x // ERROR "&x escapes to heap" 500 return y 501} 502 503func foo72a() { 504 var y [10]*int 505 for i := 0; i < 10; i++ { 506 // escapes its scope 507 x := i // ERROR "moved to heap: x" 508 y[i] = &x // ERROR "&x escapes to heap" 509 } 510 return 511} 512 513func foo72b() [10]*int { 514 var y [10]*int 515 for i := 0; i < 10; i++ { 516 x := i // ERROR "moved to heap: x" 517 y[i] = &x // ERROR "&x escapes to heap" 518 } 519 return y 520} 521 522// issue 2145 523func foo73() { 524 s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape" 525 for _, v := range s { 526 vv := v // ERROR "moved to heap: vv" 527 // actually just escapes its scope 528 defer func() { // ERROR "func literal escapes to heap" 529 println(vv) // ERROR "&vv escapes to heap" 530 }() 531 } 532} 533 534func foo74() { 535 s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape" 536 for _, v := range s { 537 vv := v // ERROR "moved to heap: vv" 538 // actually just escapes its scope 539 fn := func() { // ERROR "func literal escapes to heap" 540 println(vv) // ERROR "&vv escapes to heap" 541 } 542 defer fn() 543 } 544} 545 546// issue 3975 547func foo74b() { 548 var array [3]func() 549 s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape" 550 for i, v := range s { 551 vv := v // ERROR "moved to heap: vv" 552 // actually just escapes its scope 553 array[i] = func() { // ERROR "func literal escapes to heap" 554 println(vv) // ERROR "&vv escapes to heap" 555 } 556 } 557} 558 559func myprint(y *int, x ...interface{}) *int { // ERROR "x does not escape" "leaking param: y" 560 return y 561} 562 563func myprint1(y *int, x ...interface{}) *interface{} { // ERROR "y does not escape" "leaking param: x" 564 return &x[0] // ERROR "&x.0. escapes to heap" 565} 566 567func foo75(z *int) { // ERROR "z does not escape" 568 myprint(z, 1, 2, 3) // ERROR "[.][.][.] argument does not escape" 569} 570 571func foo75a(z *int) { // ERROR "z does not escape" 572 myprint1(z, 1, 2, 3) // ERROR "[.][.][.] argument does not escape" 573} 574 575func foo75esc(z *int) { // ERROR "leaking param: z" 576 gxx = myprint(z, 1, 2, 3) // ERROR "[.][.][.] argument does not escape" 577} 578 579func foo75aesc(z *int) { // ERROR "z does not escape" 580 var ppi **interface{} // assignments to pointer dereferences lose track 581 *ppi = myprint1(z, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap" 582} 583 584func foo76(z *int) { // ERROR "leaking param: z" 585 myprint(nil, z) // ERROR "[.][.][.] argument does not escape" 586} 587 588func foo76a(z *int) { // ERROR "leaking param: z" 589 myprint1(nil, z) // ERROR "[.][.][.] argument does not escape" 590} 591 592func foo76b() { 593 myprint(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape" 594} 595 596func foo76c() { 597 myprint1(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape" 598} 599 600func foo76d() { 601 defer myprint(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape" 602} 603 604func foo76e() { 605 defer myprint1(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape" 606} 607 608func foo76f() { 609 for { 610 // TODO: This one really only escapes its scope, but we don't distinguish yet. 611 defer myprint(nil, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap" 612 } 613} 614 615func foo76g() { 616 for { 617 defer myprint1(nil, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap" 618 } 619} 620 621func foo77(z []interface{}) { // ERROR "z does not escape" 622 myprint(nil, z...) // z does not escape 623} 624 625func foo77a(z []interface{}) { // ERROR "z does not escape" 626 myprint1(nil, z...) 627} 628 629func foo77b(z []interface{}) { // ERROR "leaking param: z" 630 var ppi **interface{} 631 *ppi = myprint1(nil, z...) 632} 633 634func foo78(z int) *int { // ERROR "moved to heap: z" 635 return &z // ERROR "&z escapes to heap" 636} 637 638func foo78a(z int) *int { // ERROR "moved to heap: z" 639 y := &z // ERROR "&z escapes to heap" 640 x := &y // ERROR "&y does not escape" 641 return *x // really return y 642} 643 644func foo79() *int { 645 return new(int) // ERROR "new[(]int[)] escapes to heap" 646} 647 648func foo80() *int { 649 var z *int 650 for { 651 // Really just escapes its scope but we don't distinguish 652 z = new(int) // ERROR "new[(]int[)] escapes to heap" 653 } 654 _ = z 655 return nil 656} 657 658func foo81() *int { 659 for { 660 z := new(int) // ERROR "new[(]int[)] does not escape" 661 _ = z 662 } 663 return nil 664} 665 666func tee(p *int) (x, y *int) { return p, p } // ERROR "leaking param" 667 668func noop(x, y *int) {} // ERROR "does not escape" 669 670func foo82() { 671 var x, y, z int // ERROR "moved to heap" 672 go noop(tee(&z)) // ERROR "&z escapes to heap" 673 go noop(&x, &y) // ERROR "escapes to heap" 674 for { 675 var u, v, w int // ERROR "moved to heap" 676 defer noop(tee(&u)) // ERROR "&u escapes to heap" 677 defer noop(&v, &w) // ERROR "escapes to heap" 678 } 679} 680 681type Fooer interface { 682 Foo() 683} 684 685type LimitedFooer struct { 686 Fooer 687 N int64 688} 689 690func LimitFooer(r Fooer, n int64) Fooer { // ERROR "leaking param: r" 691 return &LimitedFooer{r, n} // ERROR "&LimitedFooer literal escapes to heap" 692} 693 694func foo90(x *int) map[*int]*int { // ERROR "leaking param: x" 695 return map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int literal escapes to heap" 696} 697 698func foo91(x *int) map[*int]*int { // ERROR "leaking param: x" 699 return map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int literal escapes to heap" 700} 701 702func foo92(x *int) [2]*int { // ERROR "leaking param: x" 703 return [2]*int{x, nil} 704} 705 706// does not leak c 707func foo93(c chan *int) *int { // ERROR "c does not escape" 708 for v := range c { 709 return v 710 } 711 return nil 712} 713 714// does not leak m 715func foo94(m map[*int]*int, b bool) *int { // ERROR "m does not escape" 716 for k, v := range m { 717 if b { 718 return k 719 } 720 return v 721 } 722 return nil 723} 724 725// does leak x 726func foo95(m map[*int]*int, x *int) { // ERROR "m does not escape" "leaking param: x" 727 m[x] = x 728} 729 730// does not leak m 731func foo96(m []*int) *int { // ERROR "m does not escape" 732 return m[0] 733} 734 735// does leak m 736func foo97(m [1]*int) *int { // ERROR "leaking param: m" 737 return m[0] 738} 739 740// does not leak m 741func foo98(m map[int]*int) *int { // ERROR "m does not escape" 742 return m[0] 743} 744 745// does leak m 746func foo99(m *[1]*int) []*int { // ERROR "leaking param: m" 747 return m[:] 748} 749 750// does not leak m 751func foo100(m []*int) *int { // ERROR "m does not escape" 752 for _, v := range m { 753 return v 754 } 755 return nil 756} 757 758// does leak m 759func foo101(m [1]*int) *int { // ERROR "leaking param: m" 760 for _, v := range m { 761 return v 762 } 763 return nil 764} 765 766// does not leak m 767func foo101a(m [1]*int) *int { // ERROR "m does not escape" 768 for i := range m { // ERROR "moved to heap: i" 769 return &i // ERROR "&i escapes to heap" 770 } 771 return nil 772} 773 774// does leak x 775func foo102(m []*int, x *int) { // ERROR "m does not escape" "leaking param: x" 776 m[0] = x 777} 778 779// does not leak x 780func foo103(m [1]*int, x *int) { // ERROR "m does not escape" "x does not escape" 781 m[0] = x 782} 783 784var y []*int 785 786// does not leak x 787func foo104(x []*int) { // ERROR "x does not escape" 788 copy(y, x) 789} 790 791// does not leak x 792func foo105(x []*int) { // ERROR "x does not escape" 793 _ = append(y, x...) 794} 795 796// does leak x 797func foo106(x *int) { // ERROR "leaking param: x" 798 _ = append(y, x) 799} 800 801func foo107(x *int) map[*int]*int { // ERROR "leaking param: x" 802 return map[*int]*int{x: nil} // ERROR "map.* literal escapes to heap" 803} 804 805func foo108(x *int) map[*int]*int { // ERROR "leaking param: x" 806 return map[*int]*int{nil: x} // ERROR "map.* literal escapes to heap" 807} 808 809func foo109(x *int) *int { // ERROR "leaking param: x" 810 m := map[*int]*int{x: nil} // ERROR "map.* literal does not escape" 811 for k, _ := range m { 812 return k 813 } 814 return nil 815} 816 817func foo110(x *int) *int { // ERROR "leaking param: x" 818 m := map[*int]*int{nil: x} // ERROR "map.* literal does not escape" 819 return m[nil] 820} 821 822func foo111(x *int) *int { // ERROR "leaking param: x" 823 m := []*int{x} // ERROR "\[\]\*int literal does not escape" 824 return m[0] 825} 826 827func foo112(x *int) *int { // ERROR "leaking param: x" 828 m := [1]*int{x} 829 return m[0] 830} 831 832func foo113(x *int) *int { // ERROR "leaking param: x" 833 m := Bar{ii: x} 834 return m.ii 835} 836 837func foo114(x *int) *int { // ERROR "leaking param: x" 838 m := &Bar{ii: x} // ERROR "&Bar literal does not escape" 839 return m.ii 840} 841 842func foo115(x *int) *int { // ERROR "leaking param: x" 843 return (*int)(unsafe.Pointer(uintptr(unsafe.Pointer(x)) + 1)) 844} 845 846func foo116(b bool) *int { 847 if b { 848 x := 1 // ERROR "moved to heap: x" 849 return &x // ERROR "&x escapes to heap" 850 } else { 851 y := 1 // ERROR "moved to heap: y" 852 return &y // ERROR "&y escapes to heap" 853 } 854 return nil 855} 856 857func foo117(unknown func(interface{})) { // ERROR "unknown does not escape" 858 x := 1 // ERROR "moved to heap: x" 859 unknown(&x) // ERROR "&x escapes to heap" 860} 861 862func foo118(unknown func(*int)) { // ERROR "unknown does not escape" 863 x := 1 // ERROR "moved to heap: x" 864 unknown(&x) // ERROR "&x escapes to heap" 865} 866 867func external(*int) 868 869func foo119(x *int) { // ERROR "leaking param: x" 870 external(x) 871} 872 873func foo120() { 874 // formerly exponential time analysis 875L1: 876L2: 877L3: 878L4: 879L5: 880L6: 881L7: 882L8: 883L9: 884L10: 885L11: 886L12: 887L13: 888L14: 889L15: 890L16: 891L17: 892L18: 893L19: 894L20: 895L21: 896L22: 897L23: 898L24: 899L25: 900L26: 901L27: 902L28: 903L29: 904L30: 905L31: 906L32: 907L33: 908L34: 909L35: 910L36: 911L37: 912L38: 913L39: 914L40: 915L41: 916L42: 917L43: 918L44: 919L45: 920L46: 921L47: 922L48: 923L49: 924L50: 925L51: 926L52: 927L53: 928L54: 929L55: 930L56: 931L57: 932L58: 933L59: 934L60: 935L61: 936L62: 937L63: 938L64: 939L65: 940L66: 941L67: 942L68: 943L69: 944L70: 945L71: 946L72: 947L73: 948L74: 949L75: 950L76: 951L77: 952L78: 953L79: 954L80: 955L81: 956L82: 957L83: 958L84: 959L85: 960L86: 961L87: 962L88: 963L89: 964L90: 965L91: 966L92: 967L93: 968L94: 969L95: 970L96: 971L97: 972L98: 973L99: 974L100: 975 // use the labels to silence compiler errors 976 goto L1 977 goto L2 978 goto L3 979 goto L4 980 goto L5 981 goto L6 982 goto L7 983 goto L8 984 goto L9 985 goto L10 986 goto L11 987 goto L12 988 goto L13 989 goto L14 990 goto L15 991 goto L16 992 goto L17 993 goto L18 994 goto L19 995 goto L20 996 goto L21 997 goto L22 998 goto L23 999 goto L24 1000 goto L25 1001 goto L26 1002 goto L27 1003 goto L28 1004 goto L29 1005 goto L30 1006 goto L31 1007 goto L32 1008 goto L33 1009 goto L34 1010 goto L35 1011 goto L36 1012 goto L37 1013 goto L38 1014 goto L39 1015 goto L40 1016 goto L41 1017 goto L42 1018 goto L43 1019 goto L44 1020 goto L45 1021 goto L46 1022 goto L47 1023 goto L48 1024 goto L49 1025 goto L50 1026 goto L51 1027 goto L52 1028 goto L53 1029 goto L54 1030 goto L55 1031 goto L56 1032 goto L57 1033 goto L58 1034 goto L59 1035 goto L60 1036 goto L61 1037 goto L62 1038 goto L63 1039 goto L64 1040 goto L65 1041 goto L66 1042 goto L67 1043 goto L68 1044 goto L69 1045 goto L70 1046 goto L71 1047 goto L72 1048 goto L73 1049 goto L74 1050 goto L75 1051 goto L76 1052 goto L77 1053 goto L78 1054 goto L79 1055 goto L80 1056 goto L81 1057 goto L82 1058 goto L83 1059 goto L84 1060 goto L85 1061 goto L86 1062 goto L87 1063 goto L88 1064 goto L89 1065 goto L90 1066 goto L91 1067 goto L92 1068 goto L93 1069 goto L94 1070 goto L95 1071 goto L96 1072 goto L97 1073 goto L98 1074 goto L99 1075 goto L100 1076} 1077 1078func foo121() { 1079 for i := 0; i < 10; i++ { 1080 defer myprint(nil, i) // ERROR "[.][.][.] argument escapes to heap" 1081 go myprint(nil, i) // ERROR "[.][.][.] argument escapes to heap" 1082 } 1083} 1084 1085// same as foo121 but check across import 1086func foo121b() { 1087 for i := 0; i < 10; i++ { 1088 defer fmt.Printf("%d", i) // ERROR "[.][.][.] argument escapes to heap" 1089 go fmt.Printf("%d", i) // ERROR "[.][.][.] argument escapes to heap" 1090 } 1091} 1092 1093// a harmless forward jump 1094func foo122() { 1095 var i *int 1096 1097 goto L1 1098L1: 1099 i = new(int) // ERROR "new.int. does not escape" 1100 _ = i 1101} 1102 1103// a backward jump, increases loopdepth 1104func foo123() { 1105 var i *int 1106 1107L1: 1108 i = new(int) // ERROR "new.int. escapes to heap" 1109 1110 goto L1 1111 _ = i 1112} 1113 1114func foo124(x **int) { // ERROR "x does not escape" 1115 var i int // ERROR "moved to heap: i" 1116 p := &i // ERROR "&i escapes" 1117 func() { // ERROR "func literal does not escape" 1118 *x = p // ERROR "leaking closure reference p" 1119 }() 1120} 1121 1122func foo125(ch chan *int) { // ERROR "does not escape" 1123 var i int // ERROR "moved to heap" 1124 p := &i // ERROR "&i escapes to heap" 1125 func() { // ERROR "func literal does not escape" 1126 ch <- p // ERROR "leaking closure reference p" 1127 }() 1128} 1129 1130func foo126() { 1131 var px *int // loopdepth 0 1132 for { 1133 // loopdepth 1 1134 var i int // ERROR "moved to heap" 1135 func() { // ERROR "func literal does not escape" 1136 px = &i // ERROR "&i escapes" 1137 }() 1138 } 1139 _ = px 1140} 1141 1142var px *int 1143 1144func foo127() { 1145 var i int // ERROR "moved to heap: i" 1146 p := &i // ERROR "&i escapes to heap" 1147 q := p 1148 px = q 1149} 1150 1151func foo128() { 1152 var i int 1153 p := &i // ERROR "&i does not escape" 1154 q := p 1155 _ = q 1156} 1157 1158func foo129() { 1159 var i int // ERROR "moved to heap: i" 1160 p := &i // ERROR "&i escapes to heap" 1161 func() { // ERROR "func literal does not escape" 1162 q := p // ERROR "leaking closure reference p" 1163 func() { // ERROR "func literal does not escape" 1164 r := q // ERROR "leaking closure reference q" 1165 px = r 1166 }() 1167 }() 1168} 1169 1170func foo130() { 1171 for { 1172 var i int // ERROR "moved to heap" 1173 func() { // ERROR "func literal does not escape" 1174 px = &i // ERROR "&i escapes" "leaking closure reference i" 1175 }() 1176 } 1177} 1178 1179func foo131() { 1180 var i int // ERROR "moved to heap" 1181 func() { // ERROR "func literal does not escape" 1182 px = &i // ERROR "&i escapes" "leaking closure reference i" 1183 }() 1184} 1185 1186func foo132() { 1187 var i int // ERROR "moved to heap" 1188 go func() { // ERROR "func literal escapes to heap" 1189 px = &i // ERROR "&i escapes" "leaking closure reference i" 1190 }() 1191} 1192 1193func foo133() { 1194 var i int // ERROR "moved to heap" 1195 defer func() { // ERROR "func literal does not escape" 1196 px = &i // ERROR "&i escapes" "leaking closure reference i" 1197 }() 1198} 1199 1200func foo134() { 1201 var i int 1202 p := &i // ERROR "&i does not escape" 1203 func() { // ERROR "func literal does not escape" 1204 q := p 1205 func() { // ERROR "func literal does not escape" 1206 r := q 1207 _ = r 1208 }() 1209 }() 1210} 1211 1212func foo135() { 1213 var i int // ERROR "moved to heap: i" 1214 p := &i // ERROR "&i escapes to heap" "moved to heap: p" 1215 go func() { // ERROR "func literal escapes to heap" 1216 q := p // ERROR "&p escapes to heap" 1217 func() { // ERROR "func literal does not escape" 1218 r := q 1219 _ = r 1220 }() 1221 }() 1222} 1223 1224func foo136() { 1225 var i int // ERROR "moved to heap: i" 1226 p := &i // ERROR "&i escapes to heap" "moved to heap: p" 1227 go func() { // ERROR "func literal escapes to heap" 1228 q := p // ERROR "&p escapes to heap" "leaking closure reference p" 1229 func() { // ERROR "func literal does not escape" 1230 r := q // ERROR "leaking closure reference q" 1231 px = r 1232 }() 1233 }() 1234} 1235 1236func foo137() { 1237 var i int // ERROR "moved to heap: i" 1238 p := &i // ERROR "&i escapes to heap" 1239 func() { // ERROR "func literal does not escape" 1240 q := p // ERROR "leaking closure reference p" "moved to heap: q" 1241 go func() { // ERROR "func literal escapes to heap" 1242 r := q // ERROR "&q escapes to heap" 1243 _ = r 1244 }() 1245 }() 1246} 1247 1248func foo138() *byte { 1249 type T struct { 1250 x [1]byte 1251 } 1252 t := new(T) // ERROR "new.T. escapes to heap" 1253 return &t.x[0] // ERROR "&t.x.0. escapes to heap" 1254} 1255 1256func foo139() *byte { 1257 type T struct { 1258 x struct { 1259 y byte 1260 } 1261 } 1262 t := new(T) // ERROR "new.T. escapes to heap" 1263 return &t.x.y // ERROR "&t.x.y escapes to heap" 1264} 1265 1266// issue 4751 1267func foo140() interface{} { 1268 type T struct { 1269 X string 1270 } 1271 type U struct { 1272 X string 1273 T *T 1274 } 1275 t := &T{} // ERROR "&T literal escapes to heap" 1276 return U{ 1277 X: t.X, 1278 T: t, 1279 } 1280} 1281 1282//go:noescape 1283 1284func F1([]byte) 1285 1286func F2([]byte) 1287 1288//go:noescape 1289 1290func F3(x []byte) // ERROR "F3 x does not escape" 1291 1292func F4(x []byte) 1293 1294func G() { 1295 var buf1 [10]byte 1296 F1(buf1[:]) // ERROR "buf1 does not escape" 1297 1298 var buf2 [10]byte // ERROR "moved to heap: buf2" 1299 F2(buf2[:]) // ERROR "buf2 escapes to heap" 1300 1301 var buf3 [10]byte 1302 F3(buf3[:]) // ERROR "buf3 does not escape" 1303 1304 var buf4 [10]byte // ERROR "moved to heap: buf4" 1305 F4(buf4[:]) // ERROR "buf4 escapes to heap" 1306} 1307 1308type Tm struct { 1309 x int 1310} 1311 1312func (t *Tm) M() { // ERROR "t does not escape" 1313} 1314 1315func foo141() { 1316 var f func() 1317 1318 t := new(Tm) // ERROR "escapes to heap" 1319 f = t.M // ERROR "t.M does not escape" 1320 _ = f 1321} 1322 1323var gf func() 1324 1325func foo142() { 1326 t := new(Tm) // ERROR "escapes to heap" 1327 gf = t.M // ERROR "t.M escapes to heap" 1328} 1329 1330// issue 3888. 1331func foo143() { 1332 for i := 0; i < 1000; i++ { 1333 func() { // ERROR "func literal does not escape" 1334 for i := 0; i < 1; i++ { 1335 var t Tm 1336 t.M() // ERROR "t does not escape" 1337 } 1338 }() 1339 } 1340} 1341 1342// issue 5773 1343// Check that annotations take effect regardless of whether they 1344// are before or after the use in the source code. 1345 1346//go:noescape 1347 1348func foo144a(*int) 1349 1350func foo144() { 1351 var x int 1352 foo144a(&x) // ERROR "&x does not escape" 1353 var y int 1354 foo144b(&y) // ERROR "&y does not escape" 1355} 1356 1357//go:noescape 1358 1359func foo144b(*int) 1360