mirror of
https://github.com/golang/go
synced 2024-10-02 22:25:08 +00:00
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>
This commit is contained in:
parent
0558f12123
commit
097b1e0b73
175
test/escape_field.go
Normal file
175
test/escape_field.go
Normal file
|
@ -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
|
||||
}
|
Loading…
Reference in a new issue