// errorcheck -0 -m -l // Copyright 2015 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // Test escape analysis with respect to field assignments. package escape var sink interface{} type X struct { p1 *int p2 *int a [2]*int } type Y struct { x X } func field0() { i := 0 // ERROR "moved to heap: i$" var x X x.p1 = &i // ERROR "&i escapes to heap$" sink = x.p1 } func field1() { i := 0 // ERROR "moved to heap: i$" var x X // BAD: &i should not escape x.p1 = &i // ERROR "&i escapes to heap$" sink = x.p2 } func field3() { i := 0 // ERROR "moved to heap: i$" var x X x.p1 = &i // ERROR "&i escapes to heap$" sink = x } func field4() { i := 0 // ERROR "moved to heap: i$" var y Y y.x.p1 = &i // ERROR "&i escapes to heap$" x := y.x sink = x } func field5() { i := 0 // ERROR "moved to heap: i$" var x X // BAD: &i should not escape here x.a[0] = &i // ERROR "&i escapes to heap$" sink = x.a[1] } // BAD: we are not leaking param x, only x.p2 func field6(x *X) { // ERROR "leaking param: x$" sink = x.p2 } func field6a() { i := 0 // ERROR "moved to heap: i$" var x X // ERROR "moved to heap: x$" // BAD: &i should not escape x.p1 = &i // ERROR "&i escapes to heap$" // BAD: &x should not escape field6(&x) // ERROR "&x escapes to heap$" } func field7() { i := 0 var y Y y.x.p1 = &i // ERROR "field7 &i does not escape$" x := y.x var y1 Y y1.x = x _ = y1.x.p1 } func field8() { i := 0 // ERROR "moved to heap: i$" var y Y y.x.p1 = &i // ERROR "&i escapes to heap$" x := y.x var y1 Y y1.x = x sink = y1.x.p1 } func field9() { i := 0 // ERROR "moved to heap: i$" var y Y y.x.p1 = &i // ERROR "&i escapes to heap$" x := y.x var y1 Y y1.x = x sink = y1.x } func field10() { i := 0 // ERROR "moved to heap: i$" var y Y // BAD: &i should not escape y.x.p1 = &i // ERROR "&i escapes to heap$" x := y.x var y1 Y y1.x = x sink = y1.x.p2 } func field11() { i := 0 // ERROR "moved to heap: i$" x := X{p1: &i} // ERROR "&i escapes to heap$" sink = x.p1 } func field12() { i := 0 // ERROR "moved to heap: i$" // BAD: &i should not escape x := X{p1: &i} // ERROR "&i escapes to heap$" sink = x.p2 } func field13() { i := 0 // ERROR "moved to heap: i$" x := &X{p1: &i} // ERROR "&i escapes to heap$" "field13 &X literal does not escape$" sink = x.p1 } func field14() { i := 0 // ERROR "moved to heap: i$" // BAD: &i should not escape x := &X{p1: &i} // ERROR "&i escapes to heap$" "field14 &X literal does not escape$" sink = x.p2 } func field15() { i := 0 // ERROR "moved to heap: i$" x := &X{p1: &i} // ERROR "&X literal escapes to heap$" "&i escapes to heap$" sink = x } func field16() { i := 0 // ERROR "moved to heap: i$" var x X // BAD: &i should not escape x.p1 = &i // ERROR "&i escapes to heap$" var iface interface{} = x x1 := iface.(X) sink = x1.p2 } func field17() { i := 0 // ERROR "moved to heap: i$" var x X x.p1 = &i // ERROR "&i escapes to heap$" var iface interface{} = x x1 := iface.(X) sink = x1.p1 } func field18() { i := 0 // ERROR "moved to heap: i$" var x X // BAD: &i should not escape x.p1 = &i // ERROR "&i escapes to heap$" var iface interface{} = x y, _ := iface.(Y) // Put X, but extracted Y. The cast will fail, so y is zero initialized. sink = y }