]> Cypherpunks repositories - gostls13.git/commitdiff
test: add escape analysis tests for fields
authorDmitry Vyukov <dvyukov@google.com>
Thu, 19 Feb 2015 20:30:05 +0000 (23:30 +0300)
committerDmitry Vyukov <dvyukov@google.com>
Sat, 28 Mar 2015 13:31:26 +0000 (13:31 +0000)
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>
test/escape_field.go [new file with mode: 0644]

diff --git a/test/escape_field.go b/test/escape_field.go
new file mode 100644 (file)
index 0000000..0ad1144
--- /dev/null
@@ -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
+}