summaryrefslogtreecommitdiff
path: root/test/escape_field.go
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2015-02-19 23:30:05 +0300
committerDmitry Vyukov <dvyukov@google.com>2015-03-28 13:31:26 +0000
commit097b1e0b733dd425f77c5ad7ef410ed521f31e31 (patch)
tree02b9292f94fc0fbc29153e2e15928436e05952cb /test/escape_field.go
parent0558f12123d8838575acb64fc7d9d58c59511b89 (diff)
downloadgo-git-097b1e0b733dd425f77c5ad7ef410ed521f31e31.tar.gz
test: add escape analysis tests for fields
False positives (var incorrectly escapes) are marked with BAD. Change-Id: I3027b6e0f5b48325e6169599400cc59e1394809f Reviewed-on: https://go-review.googlesource.com/5431 Reviewed-by: Keith Randall <khr@golang.org>
Diffstat (limited to 'test/escape_field.go')
-rw-r--r--test/escape_field.go175
1 files changed, 175 insertions, 0 deletions
diff --git a/test/escape_field.go b/test/escape_field.go
new file mode 100644
index 0000000000..0ad1144f28
--- /dev/null
+++ b/test/escape_field.go
@@ -0,0 +1,175 @@
+// 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
+}