github.com/rsc/go@v0.0.0-20150416155037-e040fd465409/test/escape_field.go (about) 1 // errorcheck -0 -m -l 2 3 // Copyright 2015 The Go Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file. 6 7 // Test escape analysis with respect to field assignments. 8 9 package escape 10 11 var sink interface{} 12 13 type X struct { 14 p1 *int 15 p2 *int 16 a [2]*int 17 } 18 19 type Y struct { 20 x X 21 } 22 23 func field0() { 24 i := 0 // ERROR "moved to heap: i$" 25 var x X 26 x.p1 = &i // ERROR "&i escapes to heap$" 27 sink = x.p1 // ERROR "x\.p1 escapes to heap" 28 } 29 30 func field1() { 31 i := 0 // ERROR "moved to heap: i$" 32 var x X 33 // BAD: &i should not escape 34 x.p1 = &i // ERROR "&i escapes to heap$" 35 sink = x.p2 // ERROR "x\.p2 escapes to heap" 36 } 37 38 func field3() { 39 i := 0 // ERROR "moved to heap: i$" 40 var x X 41 x.p1 = &i // ERROR "&i escapes to heap$" 42 sink = x // ERROR "x escapes to heap" 43 } 44 45 func field4() { 46 i := 0 // ERROR "moved to heap: i$" 47 var y Y 48 y.x.p1 = &i // ERROR "&i escapes to heap$" 49 x := y.x 50 sink = x // ERROR "x escapes to heap" 51 } 52 53 func field5() { 54 i := 0 // ERROR "moved to heap: i$" 55 var x X 56 // BAD: &i should not escape here 57 x.a[0] = &i // ERROR "&i escapes to heap$" 58 sink = x.a[1] // ERROR "x\.a\[1\] escapes to heap" 59 } 60 61 // BAD: we are not leaking param x, only x.p2 62 func field6(x *X) { // ERROR "leaking param: x$" 63 sink = x.p2 // ERROR "x\.p2 escapes to heap" 64 } 65 66 func field6a() { 67 i := 0 // ERROR "moved to heap: i$" 68 var x X // ERROR "moved to heap: x$" 69 // BAD: &i should not escape 70 x.p1 = &i // ERROR "&i escapes to heap$" 71 // BAD: &x should not escape 72 field6(&x) // ERROR "&x escapes to heap$" 73 } 74 75 func field7() { 76 i := 0 77 var y Y 78 y.x.p1 = &i // ERROR "field7 &i does not escape$" 79 x := y.x 80 var y1 Y 81 y1.x = x 82 _ = y1.x.p1 83 } 84 85 func field8() { 86 i := 0 // ERROR "moved to heap: i$" 87 var y Y 88 y.x.p1 = &i // ERROR "&i escapes to heap$" 89 x := y.x 90 var y1 Y 91 y1.x = x 92 sink = y1.x.p1 // ERROR "y1\.x\.p1 escapes to heap" 93 } 94 95 func field9() { 96 i := 0 // ERROR "moved to heap: i$" 97 var y Y 98 y.x.p1 = &i // ERROR "&i escapes to heap$" 99 x := y.x 100 var y1 Y 101 y1.x = x 102 sink = y1.x // ERROR "y1\.x escapes to heap" 103 } 104 105 func field10() { 106 i := 0 // ERROR "moved to heap: i$" 107 var y Y 108 // BAD: &i should not escape 109 y.x.p1 = &i // ERROR "&i escapes to heap$" 110 x := y.x 111 var y1 Y 112 y1.x = x 113 sink = y1.x.p2 // ERROR "y1\.x\.p2 escapes to heap" 114 } 115 116 func field11() { 117 i := 0 // ERROR "moved to heap: i$" 118 x := X{p1: &i} // ERROR "&i escapes to heap$" 119 sink = x.p1 // ERROR "x\.p1 escapes to heap" 120 } 121 122 func field12() { 123 i := 0 // ERROR "moved to heap: i$" 124 // BAD: &i should not escape 125 x := X{p1: &i} // ERROR "&i escapes to heap$" 126 sink = x.p2 // ERROR "x\.p2 escapes to heap" 127 } 128 129 func field13() { 130 i := 0 // ERROR "moved to heap: i$" 131 x := &X{p1: &i} // ERROR "&i escapes to heap$" "field13 &X literal does not escape$" 132 sink = x.p1 // ERROR "x\.p1 escapes to heap" 133 } 134 135 func field14() { 136 i := 0 // ERROR "moved to heap: i$" 137 // BAD: &i should not escape 138 x := &X{p1: &i} // ERROR "&i escapes to heap$" "field14 &X literal does not escape$" 139 sink = x.p2 // ERROR "x\.p2 escapes to heap" 140 } 141 142 func field15() { 143 i := 0 // ERROR "moved to heap: i$" 144 x := &X{p1: &i} // ERROR "&X literal escapes to heap$" "&i escapes to heap$" 145 sink = x // ERROR "x escapes to heap" 146 } 147 148 func field16() { 149 i := 0 // ERROR "moved to heap: i$" 150 var x X 151 // BAD: &i should not escape 152 x.p1 = &i // ERROR "&i escapes to heap$" 153 var iface interface{} = x // ERROR "x escapes to heap" 154 x1 := iface.(X) 155 sink = x1.p2 // ERROR "x1\.p2 escapes to heap" 156 } 157 158 func field17() { 159 i := 0 // ERROR "moved to heap: i$" 160 var x X 161 x.p1 = &i // ERROR "&i escapes to heap$" 162 var iface interface{} = x // ERROR "x escapes to heap" 163 x1 := iface.(X) 164 sink = x1.p1 // ERROR "x1\.p1 escapes to heap" 165 } 166 167 func field18() { 168 i := 0 // ERROR "moved to heap: i$" 169 var x X 170 // BAD: &i should not escape 171 x.p1 = &i // ERROR "&i escapes to heap$" 172 var iface interface{} = x // ERROR "x escapes to heap" 173 y, _ := iface.(Y) // Put X, but extracted Y. The cast will fail, so y is zero initialized. 174 sink = y // ERROR "y escapes to heap" 175 }