1 // errorcheck -0 -N -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 // Registerization is disabled too (-N), which should 10 // have no effect on escape analysis. 11 12 package foo 13 14 import ( 15 "fmt" 16 "unsafe" 17 ) 18 19 var gxx *int 20 21 func foo1(x int) { // ERROR "moved to heap: x$" 22 gxx = &x // ERROR "&x escapes to heap$" 23 } 24 25 func foo2(yy *int) { // ERROR "leaking param: yy$" 26 gxx = yy 27 } 28 29 func foo3(x int) *int { // ERROR "moved to heap: x$" 30 return &x // ERROR "&x escapes to heap$" 31 } 32 33 type T *T 34 35 func foo3b(t T) { // ERROR "leaking param: t$" 36 *t = t 37 } 38 39 // xx isn't going anywhere, so use of yy is ok 40 func foo4(xx, yy *int) { // ERROR "foo4 xx does not escape$" "foo4 yy does not escape$" 41 xx = yy 42 } 43 44 // xx isn't going anywhere, so taking address of yy is ok 45 func foo5(xx **int, yy *int) { // ERROR "foo5 xx does not escape$" "foo5 yy does not escape$" 46 xx = &yy // ERROR "foo5 &yy does not escape$" 47 } 48 49 func foo6(xx **int, yy *int) { // ERROR "foo6 xx does not escape$" "leaking param: yy$" 50 *xx = yy 51 } 52 53 func foo7(xx **int, yy *int) { // ERROR "foo7 xx does not escape$" "foo7 yy does not escape$" 54 **xx = *yy 55 } 56 57 func foo8(xx, yy *int) int { // ERROR "foo8 xx does not escape$" "foo8 yy does not escape$" 58 xx = yy 59 return *xx 60 } 61 62 func foo9(xx, yy *int) *int { // ERROR "leaking param: xx to result ~r2 level=0$" "leaking param: yy to result ~r2 level=0$" 63 xx = yy 64 return xx 65 } 66 67 func foo10(xx, yy *int) { // ERROR "foo10 xx does not escape$" "foo10 yy does not escape$" 68 *xx = *yy 69 } 70 71 func foo11() int { 72 x, y := 0, 42 73 xx := &x // ERROR "foo11 &x does not escape$" 74 yy := &y // ERROR "foo11 &y does not escape$" 75 *xx = *yy 76 return x 77 } 78 79 var xxx **int 80 81 func foo12(yyy **int) { // ERROR "leaking param: yyy$" 82 xxx = yyy 83 } 84 85 // Must treat yyy as leaking because *yyy leaks, and the escape analysis 86 // summaries in exported metadata do not distinguish these two cases. 87 func foo13(yyy **int) { // ERROR "leaking param content: yyy$" 88 *xxx = *yyy 89 } 90 91 func foo14(yyy **int) { // ERROR "foo14 yyy does not escape$" 92 **xxx = **yyy 93 } 94 95 func foo15(yy *int) { // ERROR "moved to heap: yy$" 96 xxx = &yy // ERROR "&yy escapes to heap$" 97 } 98 99 func foo16(yy *int) { // ERROR "leaking param: yy$" 100 *xxx = yy 101 } 102 103 func foo17(yy *int) { // ERROR "foo17 yy does not escape$" 104 **xxx = *yy 105 } 106 107 func foo18(y int) { // ERROR "moved to heap: y$" 108 *xxx = &y // ERROR "&y escapes to heap$" 109 } 110 111 func foo19(y int) { 112 **xxx = y 113 } 114 115 type Bar struct { 116 i int 117 ii *int 118 } 119 120 func NewBar() *Bar { 121 return &Bar{42, nil} // ERROR "&Bar literal escapes to heap$" 122 } 123 124 func NewBarp(x *int) *Bar { // ERROR "leaking param: x to result ~r1 level=-1$" 125 return &Bar{42, x} // ERROR "&Bar literal escapes to heap$" 126 } 127 128 func NewBarp2(x *int) *Bar { // ERROR "NewBarp2 x does not escape$" 129 return &Bar{*x, nil} // ERROR "&Bar literal escapes to heap$" 130 } 131 132 func (b *Bar) NoLeak() int { // ERROR "\(\*Bar\).NoLeak b does not escape$" 133 return *(b.ii) 134 } 135 136 func (b *Bar) Leak() *int { // ERROR "leaking param: b to result ~r0 level=0$" 137 return &b.i // ERROR "&b.i escapes to heap$" 138 } 139 140 func (b *Bar) AlsoNoLeak() *int { // ERROR "leaking param: b to result ~r0 level=1$" 141 return b.ii 142 } 143 144 func (b Bar) AlsoLeak() *int { // ERROR "leaking param: b to result ~r0 level=0$" 145 return b.ii 146 } 147 148 func (b Bar) LeaksToo() *int { // ERROR "leaking param: b to result ~r0 level=0$" 149 v := 0 // ERROR "moved to heap: v$" 150 b.ii = &v // ERROR "&v escapes to heap$" 151 return b.ii 152 } 153 154 func (b *Bar) LeaksABit() *int { // ERROR "leaking param: b to result ~r0 level=1$" 155 v := 0 // ERROR "moved to heap: v$" 156 b.ii = &v // ERROR "&v escapes to heap$" 157 return b.ii 158 } 159 160 func (b Bar) StillNoLeak() int { // ERROR "Bar.StillNoLeak b does not escape$" 161 v := 0 162 b.ii = &v // ERROR "Bar.StillNoLeak &v does not escape$" 163 return b.i 164 } 165 166 func goLeak(b *Bar) { // ERROR "leaking param: b$" 167 go b.NoLeak() 168 } 169 170 type Bar2 struct { 171 i [12]int 172 ii []int 173 } 174 175 func NewBar2() *Bar2 { 176 return &Bar2{[12]int{42}, nil} // ERROR "&Bar2 literal escapes to heap$" 177 } 178 179 func (b *Bar2) NoLeak() int { // ERROR "\(\*Bar2\).NoLeak b does not escape$" 180 return b.i[0] 181 } 182 183 func (b *Bar2) Leak() []int { // ERROR "leaking param: b to result ~r0 level=0$" 184 return b.i[:] // ERROR "b.i escapes to heap$" 185 } 186 187 func (b *Bar2) AlsoNoLeak() []int { // ERROR "leaking param: b to result ~r0 level=1$" 188 return b.ii[0:1] 189 } 190 191 func (b Bar2) AgainNoLeak() [12]int { // ERROR "Bar2.AgainNoLeak b does not escape$" 192 return b.i 193 } 194 195 func (b *Bar2) LeakSelf() { // ERROR "leaking param: b$" 196 b.ii = b.i[0:4] // ERROR "b.i escapes to heap$" 197 } 198 199 func (b *Bar2) LeakSelf2() { // ERROR "leaking param: b$" 200 var buf []int 201 buf = b.i[0:] // ERROR "b.i escapes to heap$" 202 b.ii = buf 203 } 204 205 func foo21() func() int { 206 x := 42 207 return func() int { // ERROR "func literal escapes to heap$" 208 return x 209 } 210 } 211 212 func foo21a() func() int { 213 x := 42 // ERROR "moved to heap: x$" 214 return func() int { // ERROR "func literal escapes to heap$" 215 x++ // ERROR "&x escapes to heap$" 216 return x 217 } 218 } 219 220 func foo22() int { 221 x := 42 222 return func() int { // ERROR "foo22 func literal does not escape$" 223 return x 224 }() 225 } 226 227 func foo23(x int) func() int { 228 return func() int { // ERROR "func literal escapes to heap$" 229 return x 230 } 231 } 232 233 func foo23a(x int) func() int { 234 f := func() int { // ERROR "func literal escapes to heap$" 235 return x 236 } 237 return f 238 } 239 240 func foo23b(x int) *(func() int) { 241 f := func() int { return x } // ERROR "func literal escapes to heap$" "moved to heap: f$" 242 return &f // ERROR "&f escapes to heap$" 243 } 244 245 func foo23c(x int) func() int { // ERROR "moved to heap: x$" 246 return func() int { // ERROR "func literal escapes to heap$" 247 x++ // ERROR "&x escapes to heap$" 248 return x 249 } 250 } 251 252 func foo24(x int) int { 253 return func() int { // ERROR "foo24 func literal does not escape$" 254 return x 255 }() 256 } 257 258 var x *int 259 260 func fooleak(xx *int) int { // ERROR "leaking param: xx$" 261 x = xx 262 return *x 263 } 264 265 func foonoleak(xx *int) int { // ERROR "foonoleak xx does not escape$" 266 return *x + *xx 267 } 268 269 func foo31(x int) int { // ERROR "moved to heap: x$" 270 return fooleak(&x) // ERROR "&x escapes to heap$" 271 } 272 273 func foo32(x int) int { 274 return foonoleak(&x) // ERROR "foo32 &x does not escape$" 275 } 276 277 type Foo struct { 278 xx *int 279 x int 280 } 281 282 var F Foo 283 var pf *Foo 284 285 func (f *Foo) fooleak() { // ERROR "leaking param: f$" 286 pf = f 287 } 288 289 func (f *Foo) foonoleak() { // ERROR "\(\*Foo\).foonoleak f does not escape$" 290 F.x = f.x 291 } 292 293 func (f *Foo) Leak() { // ERROR "leaking param: f$" 294 f.fooleak() 295 } 296 297 func (f *Foo) NoLeak() { // ERROR "\(\*Foo\).NoLeak f does not escape$" 298 f.foonoleak() 299 } 300 301 func foo41(x int) { // ERROR "moved to heap: x$" 302 F.xx = &x // ERROR "&x escapes to heap$" 303 } 304 305 func (f *Foo) foo42(x int) { // ERROR "\(\*Foo\).foo42 f does not escape$" "moved to heap: x$" 306 f.xx = &x // ERROR "&x escapes to heap$" 307 } 308 309 func foo43(f *Foo, x int) { // ERROR "foo43 f does not escape$" "moved to heap: x$" 310 f.xx = &x // ERROR "&x escapes to heap$" 311 } 312 313 func foo44(yy *int) { // ERROR "leaking param: yy$" 314 F.xx = yy 315 } 316 317 func (f *Foo) foo45() { // ERROR "\(\*Foo\).foo45 f does not escape$" 318 F.x = f.x 319 } 320 321 // See foo13 above for explanation of why f leaks. 322 func (f *Foo) foo46() { // ERROR "leaking param content: f$" 323 F.xx = f.xx 324 } 325 326 func (f *Foo) foo47() { // ERROR "leaking param: f$" 327 f.xx = &f.x // ERROR "&f.x escapes to heap$" 328 } 329 330 var ptrSlice []*int 331 332 func foo50(i *int) { // ERROR "leaking param: i$" 333 ptrSlice[0] = i 334 } 335 336 var ptrMap map[*int]*int 337 338 func foo51(i *int) { // ERROR "leaking param: i$" 339 ptrMap[i] = i 340 } 341 342 func indaddr1(x int) *int { // ERROR "moved to heap: x$" 343 return &x // ERROR "&x escapes to heap$" 344 } 345 346 func indaddr2(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$" 347 return *&x // ERROR "indaddr2 &x does not escape$" 348 } 349 350 func indaddr3(x *int32) *int { // ERROR "leaking param: x to result ~r1 level=0$" 351 return *(**int)(unsafe.Pointer(&x)) // ERROR "indaddr3 &x does not escape$" 352 } 353 354 // From package math: 355 356 func Float32bits(f float32) uint32 { 357 return *(*uint32)(unsafe.Pointer(&f)) // ERROR "Float32bits &f does not escape$" 358 } 359 360 func Float32frombits(b uint32) float32 { 361 return *(*float32)(unsafe.Pointer(&b)) // ERROR "Float32frombits &b does not escape$" 362 } 363 364 func Float64bits(f float64) uint64 { 365 return *(*uint64)(unsafe.Pointer(&f)) // ERROR "Float64bits &f does not escape$" 366 } 367 368 func Float64frombits(b uint64) float64 { 369 return *(*float64)(unsafe.Pointer(&b)) // ERROR "Float64frombits &b does not escape$" 370 } 371 372 // contrast with 373 func float64bitsptr(f float64) *uint64 { // ERROR "moved to heap: f$" 374 return (*uint64)(unsafe.Pointer(&f)) // ERROR "&f escapes to heap$" 375 } 376 377 func float64ptrbitsptr(f *float64) *uint64 { // ERROR "leaking param: f to result ~r1 level=0$" 378 return (*uint64)(unsafe.Pointer(f)) 379 } 380 381 func typesw(i interface{}) *int { // ERROR "leaking param: i to result ~r1 level=0$" 382 switch val := i.(type) { 383 case *int: 384 return val 385 case *int8: 386 v := int(*val) // ERROR "moved to heap: v$" 387 return &v // ERROR "&v escapes to heap$" 388 } 389 return nil 390 } 391 392 func exprsw(i *int) *int { // ERROR "leaking param: i to result ~r1 level=0$" 393 switch j := i; *j + 110 { 394 case 12: 395 return j 396 case 42: 397 return nil 398 } 399 return nil 400 401 } 402 403 // assigning to an array element is like assigning to the array 404 func foo60(i *int) *int { // ERROR "leaking param: i to result ~r1 level=0$" 405 var a [12]*int 406 a[0] = i 407 return a[1] 408 } 409 410 func foo60a(i *int) *int { // ERROR "foo60a i does not escape$" 411 var a [12]*int 412 a[0] = i 413 return nil 414 } 415 416 // assigning to a struct field is like assigning to the struct 417 func foo61(i *int) *int { // ERROR "leaking param: i to result ~r1 level=0$" 418 type S struct { 419 a, b *int 420 } 421 var s S 422 s.a = i 423 return s.b 424 } 425 426 func foo61a(i *int) *int { // ERROR "foo61a i does not escape$" 427 type S struct { 428 a, b *int 429 } 430 var s S 431 s.a = i 432 return nil 433 } 434 435 // assigning to a struct field is like assigning to the struct but 436 // here this subtlety is lost, since s.a counts as an assignment to a 437 // track-losing dereference. 438 func foo62(i *int) *int { // ERROR "leaking param: i$" 439 type S struct { 440 a, b *int 441 } 442 s := new(S) // ERROR "foo62 new\(S\) does not escape$" 443 s.a = i 444 return nil // s.b 445 } 446 447 type M interface { 448 M() 449 } 450 451 func foo63(m M) { // ERROR "foo63 m does not escape$" 452 } 453 454 func foo64(m M) { // ERROR "leaking param: m$" 455 m.M() 456 } 457 458 func foo64b(m M) { // ERROR "leaking param: m$" 459 defer m.M() 460 } 461 462 type MV int 463 464 func (MV) M() {} 465 466 func foo65() { 467 var mv MV 468 foo63(&mv) // ERROR "foo65 &mv does not escape$" 469 } 470 471 func foo66() { 472 var mv MV // ERROR "moved to heap: mv$" 473 foo64(&mv) // ERROR "&mv escapes to heap$" 474 } 475 476 func foo67() { 477 var mv MV 478 foo63(mv) // ERROR "foo67 mv does not escape$" 479 } 480 481 func foo68() { 482 var mv MV 483 // escapes but it's an int so irrelevant 484 foo64(mv) // ERROR "mv escapes to heap$" 485 } 486 487 func foo69(m M) { // ERROR "leaking param: m$" 488 foo64(m) 489 } 490 491 func foo70(mv1 *MV, m M) { // ERROR "leaking param: m$" "leaking param: mv1$" 492 m = mv1 // ERROR "mv1 escapes to heap$" 493 foo64(m) 494 } 495 496 func foo71(x *int) []*int { // ERROR "leaking param: x$" 497 var y []*int 498 y = append(y, x) 499 return y 500 } 501 502 func foo71a(x int) []*int { // ERROR "moved to heap: x$" 503 var y []*int 504 y = append(y, &x) // ERROR "&x escapes to heap$" 505 return y 506 } 507 508 func foo72() { 509 var x int 510 var y [1]*int 511 y[0] = &x // ERROR "foo72 &x does not escape$" 512 } 513 514 func foo72aa() [10]*int { 515 var x int // ERROR "moved to heap: x$" 516 var y [10]*int 517 y[0] = &x // ERROR "&x escapes to heap$" 518 return y 519 } 520 521 func foo72a() { 522 var y [10]*int 523 for i := 0; i < 10; i++ { 524 // escapes its scope 525 x := i // ERROR "moved to heap: x$" 526 y[i] = &x // ERROR "&x escapes to heap$" 527 } 528 return 529 } 530 531 func foo72b() [10]*int { 532 var y [10]*int 533 for i := 0; i < 10; i++ { 534 x := i // ERROR "moved to heap: x$" 535 y[i] = &x // ERROR "&x escapes to heap$" 536 } 537 return y 538 } 539 540 // issue 2145 541 func foo73() { 542 s := []int{3, 2, 1} // ERROR "foo73 \[\]int literal does not escape$" 543 for _, v := range s { 544 vv := v 545 // actually just escapes its scope 546 defer func() { // ERROR "func literal escapes to heap$" 547 println(vv) 548 }() 549 } 550 } 551 552 func foo731() { 553 s := []int{3, 2, 1} // ERROR "foo731 \[\]int literal does not escape$" 554 for _, v := range s { 555 vv := v // ERROR "moved to heap: vv$" 556 // actually just escapes its scope 557 defer func() { // ERROR "func literal escapes to heap$" 558 vv = 42 // ERROR "&vv escapes to heap$" 559 println(vv) 560 }() 561 } 562 } 563 564 func foo74() { 565 s := []int{3, 2, 1} // ERROR "foo74 \[\]int literal does not escape$" 566 for _, v := range s { 567 vv := v 568 // actually just escapes its scope 569 fn := func() { // ERROR "func literal escapes to heap$" 570 println(vv) 571 } 572 defer fn() 573 } 574 } 575 576 func foo74a() { 577 s := []int{3, 2, 1} // ERROR "foo74a \[\]int literal does not escape$" 578 for _, v := range s { 579 vv := v // ERROR "moved to heap: vv$" 580 // actually just escapes its scope 581 fn := func() { // ERROR "func literal escapes to heap$" 582 vv += 1 // ERROR "&vv escapes to heap$" 583 println(vv) 584 } 585 defer fn() 586 } 587 } 588 589 // issue 3975 590 func foo74b() { 591 var array [3]func() 592 s := []int{3, 2, 1} // ERROR "foo74b \[\]int literal does not escape$" 593 for i, v := range s { 594 vv := v 595 // actually just escapes its scope 596 array[i] = func() { // ERROR "func literal escapes to heap$" 597 println(vv) 598 } 599 } 600 } 601 602 func foo74c() { 603 var array [3]func() 604 s := []int{3, 2, 1} // ERROR "foo74c \[\]int literal does not escape$" 605 for i, v := range s { 606 vv := v // ERROR "moved to heap: vv$" 607 // actually just escapes its scope 608 array[i] = func() { // ERROR "func literal escapes to heap$" 609 println(&vv) // ERROR "&vv escapes to heap$" "foo74c.func1 &vv does not escape$" 610 } 611 } 612 } 613 614 func myprint(y *int, x ...interface{}) *int { // ERROR "leaking param: y to result ~r2 level=0$" "myprint x does not escape$" 615 return y 616 } 617 618 func myprint1(y *int, x ...interface{}) *interface{} { // ERROR "leaking param: x to result ~r2 level=0$" "myprint1 y does not escape$" 619 return &x[0] // ERROR "&x\[0\] escapes to heap$" 620 } 621 622 func foo75(z *int) { // ERROR "foo75 z does not escape$" 623 myprint(z, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "foo75 ... argument does not escape$" 624 } 625 626 func foo75a(z *int) { // ERROR "foo75a z does not escape$" 627 myprint1(z, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "foo75a ... argument does not escape$" 628 } 629 630 func foo75esc(z *int) { // ERROR "leaking param: z$" 631 gxx = myprint(z, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "foo75esc ... argument does not escape$" 632 } 633 634 func foo75aesc(z *int) { // ERROR "foo75aesc z does not escape$" 635 var ppi **interface{} // assignments to pointer dereferences lose track 636 *ppi = myprint1(z, 1, 2, 3) // ERROR "... argument escapes to heap$" "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$" 637 } 638 639 func foo75aesc1(z *int) { // ERROR "foo75aesc1 z does not escape$" 640 sink = myprint1(z, 1, 2, 3) // ERROR "... argument escapes to heap$" "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$" "myprint1\(z, 1, 2, 3\) escapes to heap$" 641 } 642 643 func foo76(z *int) { // ERROR "z does not escape" 644 myprint(nil, z) // ERROR "foo76 ... argument does not escape$" "z does not escape" 645 } 646 647 func foo76a(z *int) { // ERROR "z does not escape" 648 myprint1(nil, z) // ERROR "foo76a ... argument does not escape$" "z does not escape" 649 } 650 651 func foo76b() { 652 myprint(nil, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "foo76b ... argument does not escape$" 653 } 654 655 func foo76c() { 656 myprint1(nil, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "foo76c ... argument does not escape$" 657 } 658 659 func foo76d() { 660 defer myprint(nil, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "foo76d ... argument does not escape$" 661 } 662 663 func foo76e() { 664 defer myprint1(nil, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "foo76e ... argument does not escape$" 665 } 666 667 func foo76f() { 668 for { 669 // TODO: This one really only escapes its scope, but we don't distinguish yet. 670 defer myprint(nil, 1, 2, 3) // ERROR "... argument escapes to heap$" "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$" 671 } 672 } 673 674 func foo76g() { 675 for { 676 defer myprint1(nil, 1, 2, 3) // ERROR "... argument escapes to heap$" "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$" 677 } 678 } 679 680 func foo77(z []interface{}) { // ERROR "foo77 z does not escape$" 681 myprint(nil, z...) // z does not escape 682 } 683 684 func foo77a(z []interface{}) { // ERROR "foo77a z does not escape$" 685 myprint1(nil, z...) 686 } 687 688 func foo77b(z []interface{}) { // ERROR "leaking param: z$" 689 var ppi **interface{} 690 *ppi = myprint1(nil, z...) 691 } 692 693 func foo77c(z []interface{}) { // ERROR "leaking param: z$" 694 sink = myprint1(nil, z...) // ERROR "myprint1\(nil, z...\) escapes to heap$" 695 } 696 697 func dotdotdot() { 698 i := 0 699 myprint(nil, &i) // ERROR "&i does not escape" "dotdotdot ... argument does not escape$" 700 701 j := 0 702 myprint1(nil, &j) // ERROR "&j does not escape" "dotdotdot ... argument does not escape$" 703 } 704 705 func foo78(z int) *int { // ERROR "moved to heap: z$" 706 return &z // ERROR "&z escapes to heap$" 707 } 708 709 func foo78a(z int) *int { // ERROR "moved to heap: z$" 710 y := &z // ERROR "&z escapes to heap$" 711 x := &y // ERROR "foo78a &y does not escape$" 712 return *x // really return y 713 } 714 715 func foo79() *int { 716 return new(int) // ERROR "new\(int\) escapes to heap$" 717 } 718 719 func foo80() *int { 720 var z *int 721 for { 722 // Really just escapes its scope but we don't distinguish 723 z = new(int) // ERROR "new\(int\) escapes to heap$" 724 } 725 _ = z 726 return nil 727 } 728 729 func foo81() *int { 730 for { 731 z := new(int) // ERROR "foo81 new\(int\) does not escape$" 732 _ = z 733 } 734 return nil 735 } 736 737 func tee(p *int) (x, y *int) { return p, p } // ERROR "leaking param: p to result x level=0$" "leaking param: p to result y level=0$" 738 739 func noop(x, y *int) {} // ERROR "noop x does not escape$" "noop y does not escape$" 740 741 func foo82() { 742 var x, y, z int // ERROR "moved to heap: x$" "moved to heap: y$" "moved to heap: z$" 743 go noop(tee(&z)) // ERROR "&z escapes to heap$" 744 go noop(&x, &y) // ERROR "&x escapes to heap$" "&y escapes to heap$" 745 for { 746 var u, v, w int // ERROR "moved to heap: u$" "moved to heap: v$" "moved to heap: w$" 747 defer noop(tee(&u)) // ERROR "&u escapes to heap$" 748 defer noop(&v, &w) // ERROR "&v escapes to heap$" "&w escapes to heap$" 749 } 750 } 751 752 type Fooer interface { 753 Foo() 754 } 755 756 type LimitedFooer struct { 757 Fooer 758 N int64 759 } 760 761 func LimitFooer(r Fooer, n int64) Fooer { // ERROR "leaking param: r to result ~r2 level=-1$" 762 return &LimitedFooer{r, n} // ERROR "&LimitedFooer literal escapes to heap$" 763 } 764 765 func foo90(x *int) map[*int]*int { // ERROR "leaking param: x$" 766 return map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int literal escapes to heap$" 767 } 768 769 func foo91(x *int) map[*int]*int { // ERROR "leaking param: x$" 770 return map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int literal escapes to heap$" 771 } 772 773 func foo92(x *int) [2]*int { // ERROR "leaking param: x to result ~r1 level=0$" 774 return [2]*int{x, nil} 775 } 776 777 // does not leak c 778 func foo93(c chan *int) *int { // ERROR "foo93 c does not escape$" 779 for v := range c { 780 return v 781 } 782 return nil 783 } 784 785 // does not leak m 786 func foo94(m map[*int]*int, b bool) *int { // ERROR "leaking param: m to result ~r2 level=1" 787 for k, v := range m { 788 if b { 789 return k 790 } 791 return v 792 } 793 return nil 794 } 795 796 // does leak x 797 func foo95(m map[*int]*int, x *int) { // ERROR "foo95 m does not escape$" "leaking param: x$" 798 m[x] = x 799 } 800 801 // does not leak m but does leak content 802 func foo96(m []*int) *int { // ERROR "leaking param: m to result ~r1 level=1" 803 return m[0] 804 } 805 806 // does leak m 807 func foo97(m [1]*int) *int { // ERROR "leaking param: m to result ~r1 level=0$" 808 return m[0] 809 } 810 811 // does not leak m 812 func foo98(m map[int]*int) *int { // ERROR "foo98 m does not escape$" 813 return m[0] 814 } 815 816 // does leak m 817 func foo99(m *[1]*int) []*int { // ERROR "leaking param: m to result ~r1 level=0$" 818 return m[:] 819 } 820 821 // does not leak m 822 func foo100(m []*int) *int { // ERROR "leaking param: m to result ~r1 level=1" 823 for _, v := range m { 824 return v 825 } 826 return nil 827 } 828 829 // does leak m 830 func foo101(m [1]*int) *int { // ERROR "leaking param: m to result ~r1 level=0$" 831 for _, v := range m { 832 return v 833 } 834 return nil 835 } 836 837 // does not leak m 838 func foo101a(m [1]*int) *int { // ERROR "foo101a m does not escape$" 839 for i := range m { // ERROR "moved to heap: i$" 840 return &i // ERROR "&i escapes to heap$" 841 } 842 return nil 843 } 844 845 // does leak x 846 func foo102(m []*int, x *int) { // ERROR "foo102 m does not escape$" "leaking param: x$" 847 m[0] = x 848 } 849 850 // does not leak x 851 func foo103(m [1]*int, x *int) { // ERROR "foo103 m does not escape$" "foo103 x does not escape$" 852 m[0] = x 853 } 854 855 var y []*int 856 857 // does not leak x but does leak content 858 func foo104(x []*int) { // ERROR "leaking param content: x" 859 copy(y, x) 860 } 861 862 // does not leak x but does leak content 863 func foo105(x []*int) { // ERROR "leaking param content: x" 864 _ = append(y, x...) 865 } 866 867 // does leak x 868 func foo106(x *int) { // ERROR "leaking param: x$" 869 _ = append(y, x) 870 } 871 872 func foo107(x *int) map[*int]*int { // ERROR "leaking param: x$" 873 return map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int literal escapes to heap$" 874 } 875 876 func foo108(x *int) map[*int]*int { // ERROR "leaking param: x$" 877 return map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int literal escapes to heap$" 878 } 879 880 func foo109(x *int) *int { // ERROR "leaking param: x$" 881 m := map[*int]*int{x: nil} // ERROR "foo109 map\[\*int\]\*int literal does not escape$" 882 for k, _ := range m { 883 return k 884 } 885 return nil 886 } 887 888 func foo110(x *int) *int { // ERROR "leaking param: x$" 889 m := map[*int]*int{nil: x} // ERROR "foo110 map\[\*int\]\*int literal does not escape$" 890 return m[nil] 891 } 892 893 func foo111(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0" 894 m := []*int{x} // ERROR "foo111 \[\]\*int literal does not escape$" 895 return m[0] 896 } 897 898 func foo112(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$" 899 m := [1]*int{x} 900 return m[0] 901 } 902 903 func foo113(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$" 904 m := Bar{ii: x} 905 return m.ii 906 } 907 908 func foo114(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$" 909 m := &Bar{ii: x} // ERROR "foo114 &Bar literal does not escape$" 910 return m.ii 911 } 912 913 func foo115(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$" 914 return (*int)(unsafe.Pointer(uintptr(unsafe.Pointer(x)) + 1)) 915 } 916 917 func foo116(b bool) *int { 918 if b { 919 x := 1 // ERROR "moved to heap: x$" 920 return &x // ERROR "&x escapes to heap$" 921 } else { 922 y := 1 // ERROR "moved to heap: y$" 923 return &y // ERROR "&y escapes to heap$" 924 } 925 return nil 926 } 927 928 func foo117(unknown func(interface{})) { // ERROR "foo117 unknown does not escape$" 929 x := 1 // ERROR "moved to heap: x$" 930 unknown(&x) // ERROR "&x escapes to heap$" 931 } 932 933 func foo118(unknown func(*int)) { // ERROR "foo118 unknown does not escape$" 934 x := 1 // ERROR "moved to heap: x$" 935 unknown(&x) // ERROR "&x escapes to heap$" 936 } 937 938 func external(*int) 939 940 func foo119(x *int) { // ERROR "leaking param: x$" 941 external(x) 942 } 943 944 func foo120() { 945 // formerly exponential time analysis 946 L1: 947 L2: 948 L3: 949 L4: 950 L5: 951 L6: 952 L7: 953 L8: 954 L9: 955 L10: 956 L11: 957 L12: 958 L13: 959 L14: 960 L15: 961 L16: 962 L17: 963 L18: 964 L19: 965 L20: 966 L21: 967 L22: 968 L23: 969 L24: 970 L25: 971 L26: 972 L27: 973 L28: 974 L29: 975 L30: 976 L31: 977 L32: 978 L33: 979 L34: 980 L35: 981 L36: 982 L37: 983 L38: 984 L39: 985 L40: 986 L41: 987 L42: 988 L43: 989 L44: 990 L45: 991 L46: 992 L47: 993 L48: 994 L49: 995 L50: 996 L51: 997 L52: 998 L53: 999 L54: 1000 L55: 1001 L56: 1002 L57: 1003 L58: 1004 L59: 1005 L60: 1006 L61: 1007 L62: 1008 L63: 1009 L64: 1010 L65: 1011 L66: 1012 L67: 1013 L68: 1014 L69: 1015 L70: 1016 L71: 1017 L72: 1018 L73: 1019 L74: 1020 L75: 1021 L76: 1022 L77: 1023 L78: 1024 L79: 1025 L80: 1026 L81: 1027 L82: 1028 L83: 1029 L84: 1030 L85: 1031 L86: 1032 L87: 1033 L88: 1034 L89: 1035 L90: 1036 L91: 1037 L92: 1038 L93: 1039 L94: 1040 L95: 1041 L96: 1042 L97: 1043 L98: 1044 L99: 1045 L100: 1046 // use the labels to silence compiler errors 1047 goto L1 1048 goto L2 1049 goto L3 1050 goto L4 1051 goto L5 1052 goto L6 1053 goto L7 1054 goto L8 1055 goto L9 1056 goto L10 1057 goto L11 1058 goto L12 1059 goto L13 1060 goto L14 1061 goto L15 1062 goto L16 1063 goto L17 1064 goto L18 1065 goto L19 1066 goto L20 1067 goto L21 1068 goto L22 1069 goto L23 1070 goto L24 1071 goto L25 1072 goto L26 1073 goto L27 1074 goto L28 1075 goto L29 1076 goto L30 1077 goto L31 1078 goto L32 1079 goto L33 1080 goto L34 1081 goto L35 1082 goto L36 1083 goto L37 1084 goto L38 1085 goto L39 1086 goto L40 1087 goto L41 1088 goto L42 1089 goto L43 1090 goto L44 1091 goto L45 1092 goto L46 1093 goto L47 1094 goto L48 1095 goto L49 1096 goto L50 1097 goto L51 1098 goto L52 1099 goto L53 1100 goto L54 1101 goto L55 1102 goto L56 1103 goto L57 1104 goto L58 1105 goto L59 1106 goto L60 1107 goto L61 1108 goto L62 1109 goto L63 1110 goto L64 1111 goto L65 1112 goto L66 1113 goto L67 1114 goto L68 1115 goto L69 1116 goto L70 1117 goto L71 1118 goto L72 1119 goto L73 1120 goto L74 1121 goto L75 1122 goto L76 1123 goto L77 1124 goto L78 1125 goto L79 1126 goto L80 1127 goto L81 1128 goto L82 1129 goto L83 1130 goto L84 1131 goto L85 1132 goto L86 1133 goto L87 1134 goto L88 1135 goto L89 1136 goto L90 1137 goto L91 1138 goto L92 1139 goto L93 1140 goto L94 1141 goto L95 1142 goto L96 1143 goto L97 1144 goto L98 1145 goto L99 1146 goto L100 1147 } 1148 1149 func foo121() { 1150 for i := 0; i < 10; i++ { 1151 defer myprint(nil, i) // ERROR "... argument escapes to heap$" "i escapes to heap$" 1152 go myprint(nil, i) // ERROR "... argument escapes to heap$" "i escapes to heap$" 1153 } 1154 } 1155 1156 // same as foo121 but check across import 1157 func foo121b() { 1158 for i := 0; i < 10; i++ { 1159 defer fmt.Printf("%d", i) // ERROR "... argument escapes to heap$" "i escapes to heap$" 1160 go fmt.Printf("%d", i) // ERROR "... argument escapes to heap$" "i escapes to heap$" 1161 } 1162 } 1163 1164 // a harmless forward jump 1165 func foo122() { 1166 var i *int 1167 1168 goto L1 1169 L1: 1170 i = new(int) // ERROR "foo122 new\(int\) does not escape$" 1171 _ = i 1172 } 1173 1174 // a backward jump, increases loopdepth 1175 func foo123() { 1176 var i *int 1177 1178 L1: 1179 i = new(int) // ERROR "new\(int\) escapes to heap$" 1180 1181 goto L1 1182 _ = i 1183 } 1184 1185 func foo124(x **int) { // ERROR "foo124 x does not escape$" 1186 var i int // ERROR "moved to heap: i$" 1187 p := &i // ERROR "&i escapes to heap$" 1188 func() { // ERROR "foo124 func literal does not escape$" 1189 *x = p // ERROR "leaking closure reference p$" 1190 }() 1191 } 1192 1193 func foo125(ch chan *int) { // ERROR "foo125 ch does not escape$" 1194 var i int // ERROR "moved to heap: i$" 1195 p := &i // ERROR "&i escapes to heap$" 1196 func() { // ERROR "foo125 func literal does not escape$" 1197 ch <- p // ERROR "leaking closure reference p$" 1198 }() 1199 } 1200 1201 func foo126() { 1202 var px *int // loopdepth 0 1203 for { 1204 // loopdepth 1 1205 var i int // ERROR "moved to heap: i$" 1206 func() { // ERROR "foo126 func literal does not escape$" 1207 px = &i // ERROR "&i escapes to heap$" "leaking closure reference i" 1208 }() 1209 } 1210 _ = px 1211 } 1212 1213 var px *int 1214 1215 func foo127() { 1216 var i int // ERROR "moved to heap: i$" 1217 p := &i // ERROR "&i escapes to heap$" 1218 q := p 1219 px = q 1220 } 1221 1222 func foo128() { 1223 var i int 1224 p := &i // ERROR "foo128 &i does not escape$" 1225 q := p 1226 _ = q 1227 } 1228 1229 func foo129() { 1230 var i int // ERROR "moved to heap: i$" 1231 p := &i // ERROR "&i escapes to heap$" 1232 func() { // ERROR "foo129 func literal does not escape$" 1233 q := p // ERROR "leaking closure reference p$" 1234 func() { // ERROR "foo129.func1 func literal does not escape$" 1235 r := q // ERROR "leaking closure reference q$" 1236 px = r 1237 }() 1238 }() 1239 } 1240 1241 func foo130() { 1242 for { 1243 var i int // ERROR "moved to heap: i$" 1244 func() { // ERROR "foo130 func literal does not escape$" 1245 px = &i // ERROR "&i escapes to heap$" "leaking closure reference i$" 1246 }() 1247 } 1248 } 1249 1250 func foo131() { 1251 var i int // ERROR "moved to heap: i$" 1252 func() { // ERROR "foo131 func literal does not escape$" 1253 px = &i // ERROR "&i escapes to heap$" "leaking closure reference i$" 1254 }() 1255 } 1256 1257 func foo132() { 1258 var i int // ERROR "moved to heap: i$" 1259 go func() { // ERROR "func literal escapes to heap$" 1260 px = &i // ERROR "&i escapes to heap$" "leaking closure reference i$" 1261 }() 1262 } 1263 1264 func foo133() { 1265 var i int // ERROR "moved to heap: i$" 1266 defer func() { // ERROR "foo133 func literal does not escape$" 1267 px = &i // ERROR "&i escapes to heap$" "leaking closure reference i$" 1268 }() 1269 } 1270 1271 func foo134() { 1272 var i int 1273 p := &i // ERROR "foo134 &i does not escape$" 1274 func() { // ERROR "foo134 func literal does not escape$" 1275 q := p 1276 func() { // ERROR "foo134.func1 func literal does not escape$" 1277 r := q 1278 _ = r 1279 }() 1280 }() 1281 } 1282 1283 func foo135() { 1284 var i int // ERROR "moved to heap: i$" 1285 p := &i // ERROR "&i escapes to heap$" 1286 go func() { // ERROR "func literal escapes to heap$" 1287 q := p 1288 func() { // ERROR "foo135.func1 func literal does not escape$" 1289 r := q 1290 _ = r 1291 }() 1292 }() 1293 } 1294 1295 func foo136() { 1296 var i int // ERROR "moved to heap: i$" 1297 p := &i // ERROR "&i escapes to heap$" 1298 go func() { // ERROR "func literal escapes to heap$" 1299 q := p // ERROR "leaking closure reference p$" 1300 func() { // ERROR "foo136.func1 func literal does not escape$" 1301 r := q // ERROR "leaking closure reference q$" 1302 px = r 1303 }() 1304 }() 1305 } 1306 1307 func foo137() { 1308 var i int // ERROR "moved to heap: i$" 1309 p := &i // ERROR "&i escapes to heap$" 1310 func() { // ERROR "foo137 func literal does not escape$" 1311 q := p // ERROR "leaking closure reference p$" 1312 go func() { // ERROR "func literal escapes to heap$" 1313 r := q 1314 _ = r 1315 }() 1316 }() 1317 } 1318 1319 func foo138() *byte { 1320 type T struct { 1321 x [1]byte 1322 } 1323 t := new(T) // ERROR "new\(T\) escapes to heap$" 1324 return &t.x[0] // ERROR "&t.x\[0\] escapes to heap$" 1325 } 1326 1327 func foo139() *byte { 1328 type T struct { 1329 x struct { 1330 y byte 1331 } 1332 } 1333 t := new(T) // ERROR "new\(T\) escapes to heap$" 1334 return &t.x.y // ERROR "&t.x.y escapes to heap$" 1335 } 1336 1337 // issue 4751 1338 func foo140() interface{} { 1339 type T struct { 1340 X string 1341 } 1342 type U struct { 1343 X string 1344 T *T 1345 } 1346 t := &T{} // ERROR "&T literal escapes to heap$" 1347 return U{ // ERROR "U literal escapes to heap$" 1348 X: t.X, 1349 T: t, 1350 } 1351 } 1352 1353 //go:noescape 1354 1355 func F1([]byte) 1356 1357 func F2([]byte) 1358 1359 //go:noescape 1360 1361 func F3(x []byte) // ERROR "F3 x does not escape$" 1362 1363 func F4(x []byte) 1364 1365 func G() { 1366 var buf1 [10]byte 1367 F1(buf1[:]) // ERROR "G buf1 does not escape$" 1368 1369 var buf2 [10]byte // ERROR "moved to heap: buf2$" 1370 F2(buf2[:]) // ERROR "buf2 escapes to heap$" 1371 1372 var buf3 [10]byte 1373 F3(buf3[:]) // ERROR "G buf3 does not escape$" 1374 1375 var buf4 [10]byte // ERROR "moved to heap: buf4$" 1376 F4(buf4[:]) // ERROR "buf4 escapes to heap$" 1377 } 1378 1379 type Tm struct { 1380 x int 1381 } 1382 1383 func (t *Tm) M() { // ERROR "\(\*Tm\).M t does not escape$" 1384 } 1385 1386 func foo141() { 1387 var f func() 1388 1389 t := new(Tm) // ERROR "new\(Tm\) escapes to heap$" 1390 f = t.M // ERROR "foo141 t.M does not escape$" 1391 _ = f 1392 } 1393 1394 var gf func() 1395 1396 func foo142() { 1397 t := new(Tm) // ERROR "new\(Tm\) escapes to heap$" 1398 gf = t.M // ERROR "t.M escapes to heap$" 1399 } 1400 1401 // issue 3888. 1402 func foo143() { 1403 for i := 0; i < 1000; i++ { 1404 func() { // ERROR "foo143 func literal does not escape$" 1405 for i := 0; i < 1; i++ { 1406 var t Tm 1407 t.M() // ERROR "foo143.func1 t does not escape$" 1408 } 1409 }() 1410 } 1411 } 1412 1413 // issue 5773 1414 // Check that annotations take effect regardless of whether they 1415 // are before or after the use in the source code. 1416 1417 //go:noescape 1418 1419 func foo144a(*int) 1420 1421 func foo144() { 1422 var x int 1423 foo144a(&x) // ERROR "foo144 &x does not escape$" 1424 var y int 1425 foo144b(&y) // ERROR "foo144 &y does not escape$" 1426 } 1427 1428 //go:noescape 1429 1430 func foo144b(*int) 1431 1432 // issue 7313: for loop init should not be treated as "in loop" 1433 1434 type List struct { 1435 Next *List 1436 } 1437 1438 func foo145(l List) { // ERROR "foo145 l does not escape$" 1439 var p *List 1440 for p = &l; p.Next != nil; p = p.Next { // ERROR "foo145 &l does not escape$" 1441 } 1442 } 1443 1444 func foo146(l List) { // ERROR "foo146 l does not escape$" 1445 var p *List 1446 p = &l // ERROR "foo146 &l does not escape$" 1447 for ; p.Next != nil; p = p.Next { 1448 } 1449 } 1450 1451 func foo147(l List) { // ERROR "foo147 l does not escape$" 1452 var p *List 1453 p = &l // ERROR "foo147 &l does not escape$" 1454 for p.Next != nil { 1455 p = p.Next 1456 } 1457 } 1458 1459 func foo148(l List) { // ERROR "foo148 l does not escape$" 1460 for p := &l; p.Next != nil; p = p.Next { // ERROR "foo148 &l does not escape$" 1461 } 1462 } 1463 1464 // related: address of variable should have depth of variable, not of loop 1465 1466 func foo149(l List) { // ERROR "foo149 l does not escape$" 1467 var p *List 1468 for { 1469 for p = &l; p.Next != nil; p = p.Next { // ERROR "foo149 &l does not escape$" 1470 } 1471 } 1472 } 1473 1474 // issue 7934: missed ... if element type had no pointers 1475 1476 var save150 []byte 1477 1478 func foo150(x ...byte) { // ERROR "leaking param: x$" 1479 save150 = x 1480 } 1481 1482 func bar150() { 1483 foo150(1, 2, 3) // ERROR "... argument escapes to heap$" 1484 } 1485 1486 // issue 7931: bad handling of slice of array 1487 1488 var save151 *int 1489 1490 func foo151(x *int) { // ERROR "leaking param: x$" 1491 save151 = x 1492 } 1493 1494 func bar151() { 1495 var a [64]int // ERROR "moved to heap: a$" 1496 a[4] = 101 1497 foo151(&(&a)[4:8][0]) // ERROR "&\(&a\)\[4:8\]\[0\] escapes to heap$" "&a escapes to heap$" 1498 } 1499 1500 func bar151b() { 1501 var a [10]int // ERROR "moved to heap: a$" 1502 b := a[:] // ERROR "a escapes to heap$" 1503 foo151(&b[4:8][0]) // ERROR "&b\[4:8\]\[0\] escapes to heap$" 1504 } 1505 1506 func bar151c() { 1507 var a [64]int // ERROR "moved to heap: a$" 1508 a[4] = 101 1509 foo151(&(&a)[4:8:8][0]) // ERROR "&\(&a\)\[4:8:8\]\[0\] escapes to heap$" "&a escapes to heap$" 1510 } 1511 1512 func bar151d() { 1513 var a [10]int // ERROR "moved to heap: a$" 1514 b := a[:] // ERROR "a escapes to heap$" 1515 foo151(&b[4:8:8][0]) // ERROR "&b\[4:8:8\]\[0\] escapes to heap$" 1516 } 1517 1518 // issue 8120 1519 1520 type U struct { 1521 s *string 1522 } 1523 1524 func (u *U) String() *string { // ERROR "leaking param: u to result ~r0 level=1$" 1525 return u.s 1526 } 1527 1528 type V struct { 1529 s *string 1530 } 1531 1532 // BAD -- level of leak ought to be 0 1533 func NewV(u U) *V { // ERROR "leaking param: u to result ~r1 level=-1" 1534 return &V{u.String()} // ERROR "&V literal escapes to heap$" "NewV u does not escape" 1535 } 1536 1537 func foo152() { 1538 a := "a" // ERROR "moved to heap: a$" 1539 u := U{&a} // ERROR "&a escapes to heap$" 1540 v := NewV(u) 1541 println(v) 1542 } 1543 1544 // issue 8176 - &x in type switch body not marked as escaping 1545 1546 func foo153(v interface{}) *int { // ERROR "leaking param: v to result ~r1 level=-1$" 1547 switch x := v.(type) { 1548 case int: // ERROR "moved to heap: x$" 1549 return &x // ERROR "&x escapes to heap$" 1550 } 1551 panic(0) 1552 } 1553 1554 // issue 8185 - &result escaping into result 1555 1556 func f() (x int, y *int) { // ERROR "moved to heap: x$" 1557 y = &x // ERROR "&x escapes to heap$" 1558 return 1559 } 1560 1561 func g() (x interface{}) { // ERROR "moved to heap: x$" 1562 x = &x // ERROR "&x escapes to heap$" 1563 return 1564 } 1565 1566 var sink interface{} 1567 1568 type Lit struct { 1569 p *int 1570 } 1571 1572 func ptrlitNoescape() { 1573 // Both literal and element do not escape. 1574 i := 0 1575 x := &Lit{&i} // ERROR "ptrlitNoescape &Lit literal does not escape$" "ptrlitNoescape &i does not escape$" 1576 _ = x 1577 } 1578 1579 func ptrlitNoEscape2() { 1580 // Literal does not escape, but element does. 1581 i := 0 // ERROR "moved to heap: i$" 1582 x := &Lit{&i} // ERROR "&i escapes to heap$" "ptrlitNoEscape2 &Lit literal does not escape$" 1583 sink = *x // ERROR "\*x escapes to heap$" 1584 } 1585 1586 func ptrlitEscape() { 1587 // Both literal and element escape. 1588 i := 0 // ERROR "moved to heap: i$" 1589 x := &Lit{&i} // ERROR "&Lit literal escapes to heap$" "&i escapes to heap$" 1590 sink = x // ERROR "x escapes to heap$" 1591 } 1592 1593 // self-assignments 1594 1595 type Buffer struct { 1596 arr [64]byte 1597 buf1 []byte 1598 buf2 []byte 1599 str1 string 1600 str2 string 1601 } 1602 1603 func (b *Buffer) foo() { // ERROR "\(\*Buffer\).foo b does not escape$" 1604 b.buf1 = b.buf1[1:2] // ERROR "\(\*Buffer\).foo ignoring self-assignment to b.buf1$" 1605 b.buf1 = b.buf1[1:2:3] // ERROR "\(\*Buffer\).foo ignoring self-assignment to b.buf1$" 1606 b.buf1 = b.buf2[1:2] // ERROR "\(\*Buffer\).foo ignoring self-assignment to b.buf1$" 1607 b.buf1 = b.buf2[1:2:3] // ERROR "\(\*Buffer\).foo ignoring self-assignment to b.buf1$" 1608 } 1609 1610 func (b *Buffer) bar() { // ERROR "leaking param: b$" 1611 b.buf1 = b.arr[1:2] // ERROR "b.arr escapes to heap$" 1612 } 1613 1614 func (b *Buffer) baz() { // ERROR "\(\*Buffer\).baz b does not escape$" 1615 b.str1 = b.str1[1:2] // ERROR "\(\*Buffer\).baz ignoring self-assignment to b.str1$" 1616 b.str1 = b.str2[1:2] // ERROR "\(\*Buffer\).baz ignoring self-assignment to b.str1$" 1617 } 1618 1619 func (b *Buffer) bat() { // ERROR "leaking param content: b$" 1620 o := new(Buffer) // ERROR "new\(Buffer\) escapes to heap$" 1621 o.buf1 = b.buf1[1:2] 1622 sink = o // ERROR "o escapes to heap$" 1623 } 1624 1625 func quux(sp *string, bp *[]byte) { // ERROR "quux bp does not escape$" "quux sp does not escape$" 1626 *sp = (*sp)[1:2] // ERROR "quux ignoring self-assignment to \*sp$" 1627 *bp = (*bp)[1:2] // ERROR "quux ignoring self-assignment to \*bp$" 1628 } 1629 1630 type StructWithString struct { 1631 p *int 1632 s string 1633 } 1634 1635 // This is escape analysis false negative. 1636 // We assign the pointer to x.p but leak x.s. Escape analysis coarsens flows 1637 // to just x, and thus &i looks escaping. 1638 func fieldFlowTracking() { 1639 var x StructWithString 1640 i := 0 // ERROR "moved to heap: i$" 1641 x.p = &i // ERROR "&i escapes to heap$" 1642 sink = x.s // ERROR "x.s escapes to heap$" 1643 } 1644 1645 // String operations. 1646 1647 func slicebytetostring0() { 1648 b := make([]byte, 20) // ERROR "slicebytetostring0 make\(\[\]byte, 20\) does not escape$" 1649 s := string(b) // ERROR "slicebytetostring0 string\(b\) does not escape$" 1650 _ = s 1651 } 1652 1653 func slicebytetostring1() { 1654 b := make([]byte, 20) // ERROR "slicebytetostring1 make\(\[\]byte, 20\) does not escape$" 1655 s := string(b) // ERROR "slicebytetostring1 string\(b\) does not escape$" 1656 s1 := s[0:1] 1657 _ = s1 1658 } 1659 1660 func slicebytetostring2() { 1661 b := make([]byte, 20) // ERROR "slicebytetostring2 make\(\[\]byte, 20\) does not escape$" 1662 s := string(b) // ERROR "string\(b\) escapes to heap$" 1663 s1 := s[0:1] // ERROR "moved to heap: s1$" 1664 sink = &s1 // ERROR "&s1 escapes to heap$" 1665 } 1666 1667 func slicebytetostring3() { 1668 b := make([]byte, 20) // ERROR "slicebytetostring3 make\(\[\]byte, 20\) does not escape$" 1669 s := string(b) // ERROR "string\(b\) escapes to heap$" 1670 s1 := s[0:1] 1671 sink = s1 // ERROR "s1 escapes to heap$" 1672 } 1673 1674 func addstr0() { 1675 s0 := "a" 1676 s1 := "b" 1677 s := s0 + s1 // ERROR "addstr0 s0 \+ s1 does not escape$" 1678 _ = s 1679 } 1680 1681 func addstr1() { 1682 s0 := "a" 1683 s1 := "b" 1684 s := "c" 1685 s += s0 + s1 // ERROR "addstr1 s0 \+ s1 does not escape$" 1686 _ = s 1687 } 1688 1689 func addstr2() { 1690 b := make([]byte, 20) // ERROR "addstr2 make\(\[\]byte, 20\) does not escape$" 1691 s0 := "a" 1692 s := string(b) + s0 // ERROR "addstr2 string\(b\) \+ s0 does not escape$" "addstr2 string\(b\) does not escape$" 1693 _ = s 1694 } 1695 1696 func addstr3() { 1697 s0 := "a" 1698 s1 := "b" 1699 s := s0 + s1 // ERROR "s0 \+ s1 escapes to heap$" 1700 s2 := s[0:1] 1701 sink = s2 // ERROR "s2 escapes to heap$" 1702 } 1703 1704 func intstring0() bool { 1705 // string does not escape 1706 x := '0' 1707 s := string(x) // ERROR "intstring0 string\(x\) does not escape$" 1708 return s == "0" 1709 } 1710 1711 func intstring1() string { 1712 // string does not escape, but the buffer does 1713 x := '0' 1714 s := string(x) // ERROR "string\(x\) escapes to heap$" 1715 return s 1716 } 1717 1718 func intstring2() { 1719 // string escapes to heap 1720 x := '0' 1721 s := string(x) // ERROR "moved to heap: s$" "string\(x\) escapes to heap$" 1722 sink = &s // ERROR "&s escapes to heap$" 1723 } 1724 1725 func stringtoslicebyte0() { 1726 s := "foo" 1727 x := []byte(s) // ERROR "stringtoslicebyte0 \(\[\]byte\)\(s\) does not escape$" 1728 _ = x 1729 } 1730 1731 func stringtoslicebyte1() []byte { 1732 s := "foo" 1733 return []byte(s) // ERROR "\(\[\]byte\)\(s\) escapes to heap$" 1734 } 1735 1736 func stringtoslicebyte2() { 1737 s := "foo" 1738 sink = []byte(s) // ERROR "\(\[\]byte\)\(s\) escapes to heap$" 1739 } 1740 1741 func stringtoslicerune0() { 1742 s := "foo" 1743 x := []rune(s) // ERROR "stringtoslicerune0 \(\[\]rune\)\(s\) does not escape$" 1744 _ = x 1745 } 1746 1747 func stringtoslicerune1() []rune { 1748 s := "foo" 1749 return []rune(s) // ERROR "\(\[\]rune\)\(s\) escapes to heap$" 1750 } 1751 1752 func stringtoslicerune2() { 1753 s := "foo" 1754 sink = []rune(s) // ERROR "\(\[\]rune\)\(s\) escapes to heap$" 1755 } 1756 1757 func slicerunetostring0() { 1758 r := []rune{1, 2, 3} // ERROR "slicerunetostring0 \[\]rune literal does not escape$" 1759 s := string(r) // ERROR "slicerunetostring0 string\(r\) does not escape$" 1760 _ = s 1761 } 1762 1763 func slicerunetostring1() string { 1764 r := []rune{1, 2, 3} // ERROR "slicerunetostring1 \[\]rune literal does not escape$" 1765 return string(r) // ERROR "string\(r\) escapes to heap$" 1766 } 1767 1768 func slicerunetostring2() { 1769 r := []rune{1, 2, 3} // ERROR "slicerunetostring2 \[\]rune literal does not escape$" 1770 sink = string(r) // ERROR "string\(r\) escapes to heap$" 1771 } 1772 1773 func makemap0() { 1774 m := make(map[int]int) // ERROR "makemap0 make\(map\[int\]int\) does not escape$" 1775 m[0] = 0 1776 m[1]++ 1777 delete(m, 1) 1778 sink = m[0] // ERROR "m\[0\] escapes to heap$" 1779 } 1780 1781 func makemap1() map[int]int { 1782 return make(map[int]int) // ERROR "make\(map\[int\]int\) escapes to heap$" 1783 } 1784 1785 func makemap2() { 1786 m := make(map[int]int) // ERROR "make\(map\[int\]int\) escapes to heap$" 1787 sink = m // ERROR "m escapes to heap$" 1788 } 1789 1790 func nonescapingEface(m map[interface{}]bool) bool { // ERROR "nonescapingEface m does not escape$" 1791 return m["foo"] // ERROR "nonescapingEface .foo. does not escape$" 1792 } 1793 1794 func nonescapingIface(m map[M]bool) bool { // ERROR "nonescapingIface m does not escape$" 1795 return m[MV(0)] // ERROR "nonescapingIface MV\(0\) does not escape$" 1796 } 1797 1798 func issue10353() { 1799 x := new(int) // ERROR "new\(int\) escapes to heap$" 1800 issue10353a(x)() 1801 } 1802 1803 func issue10353a(x *int) func() { // ERROR "leaking param: x to result ~r1 level=-1$" 1804 return func() { // ERROR "func literal escapes to heap$" 1805 println(*x) 1806 } 1807 } 1808 1809 func issue10353b() { 1810 var f func() 1811 for { 1812 x := new(int) // ERROR "new\(int\) escapes to heap$" 1813 f = func() { // ERROR "func literal escapes to heap$" 1814 println(*x) 1815 } 1816 } 1817 _ = f 1818 } 1819 1820 func issue11387(x int) func() int { 1821 f := func() int { return x } // ERROR "func literal escapes to heap" 1822 slice1 := []func() int{f} // ERROR "\[\].* does not escape" 1823 slice2 := make([]func() int, 1) // ERROR "make\(.*\) does not escape" 1824 copy(slice2, slice1) 1825 return slice2[0] 1826 } 1827