diff options
Diffstat (limited to '')
-rw-r--r-- | test/escape_field.go | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/test/escape_field.go b/test/escape_field.go new file mode 100644 index 0000000..95d0784 --- /dev/null +++ b/test/escape_field.go @@ -0,0 +1,174 @@ +// 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 + sink = x.p1 +} + +func field1() { + i := 0 // ERROR "moved to heap: i$" + var x X + // BAD: &i should not escape + x.p1 = &i + sink = x.p2 +} + +func field3() { + i := 0 // ERROR "moved to heap: i$" + var x X + x.p1 = &i + sink = x // ERROR "x escapes to heap" +} + +func field4() { + i := 0 // ERROR "moved to heap: i$" + var y Y + y.x.p1 = &i + x := y.x + sink = x // ERROR "x escapes to heap" +} + +func field5() { + i := 0 // ERROR "moved to heap: i$" + var x X + // BAD: &i should not escape here + x.a[0] = &i + sink = x.a[1] +} + +// BAD: we are not leaking param x, only x.p2 +func field6(x *X) { // ERROR "leaking param content: x$" + sink = x.p2 +} + +func field6a() { + i := 0 // ERROR "moved to heap: i$" + var x X + // BAD: &i should not escape + x.p1 = &i + field6(&x) +} + +func field7() { + i := 0 + var y Y + y.x.p1 = &i + 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 + 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 + x := y.x + var y1 Y + y1.x = x + sink = y1.x // ERROR "y1\.x escapes to heap" +} + +func field10() { + i := 0 // ERROR "moved to heap: i$" + var y Y + // BAD: &i should not escape + y.x.p1 = &i + 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} + sink = x.p1 +} + +func field12() { + i := 0 // ERROR "moved to heap: i$" + // BAD: &i should not escape + x := X{p1: &i} + sink = x.p2 +} + +func field13() { + i := 0 // ERROR "moved to heap: i$" + x := &X{p1: &i} // ERROR "&X{...} 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 "&X{...} does not escape$" + sink = x.p2 +} + +func field15() { + i := 0 // ERROR "moved to heap: i$" + x := &X{p1: &i} // ERROR "&X{...} 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 + var iface interface{} = x // ERROR "x does not escape" + x1 := iface.(X) + sink = x1.p2 +} + +func field17() { + i := 0 // ERROR "moved to heap: i$" + var x X + x.p1 = &i + var iface interface{} = x // ERROR "x does not escape" + 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 + var iface interface{} = x // ERROR "x does not escape" + y, _ := iface.(Y) // Put X, but extracted Y. The cast will fail, so y is zero initialized. + sink = y // ERROR "y escapes to heap" +} |