diff options
author | Dmitry Vyukov <dvyukov@google.com> | 2015-02-19 23:30:05 +0300 |
---|---|---|
committer | Dmitry Vyukov <dvyukov@google.com> | 2015-03-28 13:31:26 +0000 |
commit | 097b1e0b733dd425f77c5ad7ef410ed521f31e31 (patch) | |
tree | 02b9292f94fc0fbc29153e2e15928436e05952cb /test/escape_field.go | |
parent | 0558f12123d8838575acb64fc7d9d58c59511b89 (diff) | |
download | go-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.go | 175 |
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 +} |