From 097b1e0b733dd425f77c5ad7ef410ed521f31e31 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Thu, 19 Feb 2015 23:30:05 +0300 Subject: 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 --- test/escape_field.go | 175 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 test/escape_field.go (limited to 'test/escape_field.go') 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 +} -- cgit v1.2.1