package foo
-import "runtime"
+import (
+ "runtime"
+ "unsafe"
+)
func noleak(p *int) int { // ERROR "p does not escape"
return *p
return p
}
-func leaktoret2(p *int) (*int, *int) { // ERROR "leaking param: p to result ~r1" "leaking param: p to result ~r2"
+func leaktoret2(p *int) (*int, *int) { // ERROR "leaking param: p to result ~r0" "leaking param: p to result ~r1"
return p, p
}
-func leaktoret22(p, q *int) (*int, *int) { // ERROR "leaking param: p to result ~r2" "leaking param: q to result ~r3"
+func leaktoret22(p, q *int) (*int, *int) { // ERROR "leaking param: p to result ~r0" "leaking param: q to result ~r1"
return p, q
}
-func leaktoret22b(p, q *int) (*int, *int) { // ERROR "leaking param: p to result ~r3" "leaking param: q to result ~r2"
+func leaktoret22b(p, q *int) (*int, *int) { // ERROR "leaking param: p to result ~r1" "leaking param: q to result ~r0"
return leaktoret22(q, p)
}
-func leaktoret22c(p, q *int) (*int, *int) { // ERROR "leaking param: p to result ~r3" "leaking param: q to result ~r2"
+func leaktoret22c(p, q *int) (*int, *int) { // ERROR "leaking param: p to result ~r1" "leaking param: q to result ~r0"
r, s := leaktoret22(q, p)
return r, s
}
func f1() {
var x int
- p := noleak(&x) // ERROR "&x does not escape"
+ p := noleak(&x)
_ = p
}
func f2() {
var x int
- p := leaktoret(&x) // ERROR "&x does not escape"
+ p := leaktoret(&x)
_ = p
}
func f3() {
- var x int // ERROR "moved to heap: x"
- p := leaktoret(&x) // ERROR "&x escapes to heap"
+ var x int // ERROR "moved to heap: x"
+ p := leaktoret(&x)
gp = p
}
func f4() {
- var x int // ERROR "moved to heap: x"
- p, q := leaktoret2(&x) // ERROR "&x escapes to heap"
+ var x int // ERROR "moved to heap: x"
+ p, q := leaktoret2(&x)
gp = p
gp = q
}
func f5() {
var x int
- leaktoret22(leaktoret2(&x)) // ERROR "&x does not escape"
+ leaktoret22(leaktoret2(&x))
}
func f6() {
- var x int // ERROR "moved to heap: x"
- px1, px2 := leaktoret22(leaktoret2(&x)) // ERROR "&x escapes to heap"
+ var x int // ERROR "moved to heap: x"
+ px1, px2 := leaktoret22(leaktoret2(&x))
gp = px1
_ = px2
}
Y *T1
}
-func f8(p *T1) (k T2) { // ERROR "leaking param: p to result k" "leaking param: p"
+func f8(p *T1) (k T2) { // ERROR "leaking param: p$"
if p == nil {
k = T2{}
return
}
// should make p leak always
- global = p // ERROR "p escapes to heap"
+ global = p
return T2{p}
}
func f9() {
var j T1 // ERROR "moved to heap: j"
- f8(&j) // ERROR "&j escapes to heap"
+ f8(&j)
}
func f10() {
// These don't escape but are too big for the stack
var x [1 << 30]byte // ERROR "moved to heap: x"
- var y = make([]byte, 1<<30) // ERROR "make\(\[\]byte, 1 << 30\) escapes to heap"
+ var y = make([]byte, 1<<30) // ERROR "make\(\[\]byte, 1073741824\) escapes to heap"
_ = x[0] + y[0]
}
}
func f13() {
var x *int
- f11(&x) // ERROR "&x does not escape"
- f12(&x) // ERROR "&x does not escape"
- runtime.KeepAlive(&x) // ERROR "&x does not escape"
+ f11(&x)
+ f12(&x)
+ runtime.KeepAlive(&x)
}
// Test for issue 24305 (passing to unnamed receivers does not escape).
func (*U) M() {}
func (_ *U) N() {}
-func _() {
+func fbad24305a() {
var u U
- u.M() // ERROR "u does not escape"
- u.N() // ERROR "u does not escape"
+ u.M()
+ u.N()
+}
+
+func fbad24305b() {
+ var u U
+ (*U).M(&u)
+ (*U).N(&u)
}
// Issue 24730: taking address in a loop causes unnecessary escape
}
func (t *T24730) g() { // ERROR "t does not escape"
- y := t.x[:] // ERROR "t\.x does not escape"
- for i := range t.x[:] { // ERROR "t\.x does not escape"
- y = t.x[:] // ERROR "t\.x does not escape"
+ y := t.x[:]
+ for i := range t.x[:] {
+ y = t.x[:]
y[i] = 1
}
var z *byte
- for i := range t.x[:] { // ERROR "t\.x does not escape"
- z = &t.x[i] // ERROR "t\.x\[i\] does not escape"
+ for i := range t.x[:] {
+ z = &t.x[i]
*z = 2
}
}
x := 1
f29000(2, x) // ERROR "x escapes to heap"
}
+
+// Issue 28369: taking an address of a parameter and converting it into a uintptr causes an
+// unnecessary escape.
+
+var sink28369 uintptr
+
+func f28369(n int) int {
+ if n == 0 {
+ sink28369 = uintptr(unsafe.Pointer(&n))
+ return n
+ }
+
+ return 1 + f28369(n-1)
+}
+
+// Issue 44614: parameters that flow to a heap-allocated result
+// parameter must be recorded as a heap-flow rather than a
+// result-flow.
+
+// N.B., must match "leaking param: p",
+// but *not* "leaking param: p to result r level=0".
+func f(p *int) (r *int) { // ERROR "leaking param: p$" "moved to heap: r"
+ sink4 = &r
+ return p
+}