summaryrefslogtreecommitdiffstats
path: root/test/escape_field.go
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-16 19:25:22 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-16 19:25:22 +0000
commitf6ad4dcef54c5ce997a4bad5a6d86de229015700 (patch)
tree7cfa4e31ace5c2bd95c72b154d15af494b2bcbef /test/escape_field.go
parentInitial commit. (diff)
downloadgolang-1.22-f6ad4dcef54c5ce997a4bad5a6d86de229015700.tar.xz
golang-1.22-f6ad4dcef54c5ce997a4bad5a6d86de229015700.zip
Adding upstream version 1.22.1.upstream/1.22.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'test/escape_field.go')
-rw-r--r--test/escape_field.go174
1 files changed, 174 insertions, 0 deletions
diff --git a/test/escape_field.go b/test/escape_field.go
new file mode 100644
index 0000000..95d0784
--- /dev/null
+++ b/test/escape_field.go
@@ -0,0 +1,174 @@
+// 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
+ sink = x.p1
+}
+
+func field1() {
+ i := 0 // ERROR "moved to heap: i$"
+ var x X
+ // BAD: &i should not escape
+ x.p1 = &i
+ sink = x.p2
+}
+
+func field3() {
+ i := 0 // ERROR "moved to heap: i$"
+ var x X
+ x.p1 = &i
+ sink = x // ERROR "x escapes to heap"
+}
+
+func field4() {
+ i := 0 // ERROR "moved to heap: i$"
+ var y Y
+ y.x.p1 = &i
+ x := y.x
+ sink = x // ERROR "x escapes to heap"
+}
+
+func field5() {
+ i := 0 // ERROR "moved to heap: i$"
+ var x X
+ // BAD: &i should not escape here
+ x.a[0] = &i
+ sink = x.a[1]
+}
+
+// BAD: we are not leaking param x, only x.p2
+func field6(x *X) { // ERROR "leaking param content: x$"
+ sink = x.p2
+}
+
+func field6a() {
+ i := 0 // ERROR "moved to heap: i$"
+ var x X
+ // BAD: &i should not escape
+ x.p1 = &i
+ field6(&x)
+}
+
+func field7() {
+ i := 0
+ var y Y
+ y.x.p1 = &i
+ 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
+ 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
+ x := y.x
+ var y1 Y
+ y1.x = x
+ sink = y1.x // ERROR "y1\.x escapes to heap"
+}
+
+func field10() {
+ i := 0 // ERROR "moved to heap: i$"
+ var y Y
+ // BAD: &i should not escape
+ y.x.p1 = &i
+ 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}
+ sink = x.p1
+}
+
+func field12() {
+ i := 0 // ERROR "moved to heap: i$"
+ // BAD: &i should not escape
+ x := X{p1: &i}
+ sink = x.p2
+}
+
+func field13() {
+ i := 0 // ERROR "moved to heap: i$"
+ x := &X{p1: &i} // ERROR "&X{...} 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 "&X{...} does not escape$"
+ sink = x.p2
+}
+
+func field15() {
+ i := 0 // ERROR "moved to heap: i$"
+ x := &X{p1: &i} // ERROR "&X{...} 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
+ var iface interface{} = x // ERROR "x does not escape"
+ x1 := iface.(X)
+ sink = x1.p2
+}
+
+func field17() {
+ i := 0 // ERROR "moved to heap: i$"
+ var x X
+ x.p1 = &i
+ var iface interface{} = x // ERROR "x does not escape"
+ 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
+ var iface interface{} = x // ERROR "x does not escape"
+ y, _ := iface.(Y) // Put X, but extracted Y. The cast will fail, so y is zero initialized.
+ sink = y // ERROR "y escapes to heap"
+}