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 content: 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 69 // BAD: &i should not escape 70 x.p1 = &i // ERROR "&i escapes to heap$" 71 field6(&x) // ERROR "field6a &x does not escape" 72 } 73 74 func field7() { 75 i := 0 76 var y Y 77 y.x.p1 = &i // ERROR "field7 &i does not escape$" 78 x := y.x 79 var y1 Y 80 y1.x = x 81 _ = y1.x.p1 82 } 83 84 func field8() { 85 i := 0 // ERROR "moved to heap: i$" 86 var y Y 87 y.x.p1 = &i // ERROR "&i escapes to heap$" 88 x := y.x 89 var y1 Y 90 y1.x = x 91 sink = y1.x.p1 // ERROR "y1\.x\.p1 escapes to heap" 92 } 93 94 func field9() { 95 i := 0 // ERROR "moved to heap: i$" 96 var y Y 97 y.x.p1 = &i // ERROR "&i escapes to heap$" 98 x := y.x 99 var y1 Y 100 y1.x = x 101 sink = y1.x // ERROR "y1\.x escapes to heap" 102 } 103 104 func field10() { 105 i := 0 // ERROR "moved to heap: i$" 106 var y Y 107 // BAD: &i should not escape 108 y.x.p1 = &i // ERROR "&i escapes to heap$" 109 x := y.x 110 var y1 Y 111 y1.x = x 112 sink = y1.x.p2 // ERROR "y1\.x\.p2 escapes to heap" 113 } 114 115 func field11() { 116 i := 0 // ERROR "moved to heap: i$" 117 x := X{p1: &i} // ERROR "&i escapes to heap$" 118 sink = x.p1 // ERROR "x\.p1 escapes to heap" 119 } 120 121 func field12() { 122 i := 0 // ERROR "moved to heap: i$" 123 // BAD: &i should not escape 124 x := X{p1: &i} // ERROR "&i escapes to heap$" 125 sink = x.p2 // ERROR "x\.p2 escapes to heap" 126 } 127 128 func field13() { 129 i := 0 // ERROR "moved to heap: i$" 130 x := &X{p1: &i} // ERROR "&i escapes to heap$" "field13 &X literal does not escape$" 131 sink = x.p1 // ERROR "x\.p1 escapes to heap" 132 } 133 134 func field14() { 135 i := 0 // ERROR "moved to heap: i$" 136 // BAD: &i should not escape 137 x := &X{p1: &i} // ERROR "&i escapes to heap$" "field14 &X literal does not escape$" 138 sink = x.p2 // ERROR "x\.p2 escapes to heap" 139 } 140 141 func field15() { 142 i := 0 // ERROR "moved to heap: i$" 143 x := &X{p1: &i} // ERROR "&X literal escapes to heap$" "&i escapes to heap$" 144 sink = x // ERROR "x escapes to heap" 145 } 146 147 func field16() { 148 i := 0 // ERROR "moved to heap: i$" 149 var x X 150 // BAD: &i should not escape 151 x.p1 = &i // ERROR "&i escapes to heap$" 152 var iface interface{} = x // ERROR "x escapes to heap" 153 x1 := iface.(X) 154 sink = x1.p2 // ERROR "x1\.p2 escapes to heap" 155 } 156 157 func field17() { 158 i := 0 // ERROR "moved to heap: i$" 159 var x X 160 x.p1 = &i // ERROR "&i escapes to heap$" 161 var iface interface{} = x // ERROR "x escapes to heap" 162 x1 := iface.(X) 163 sink = x1.p1 // ERROR "x1\.p1 escapes to heap" 164 } 165 166 func field18() { 167 i := 0 // ERROR "moved to heap: i$" 168 var x X 169 // BAD: &i should not escape 170 x.p1 = &i // ERROR "&i escapes to heap$" 171 var iface interface{} = x // ERROR "x escapes to heap" 172 y, _ := iface.(Y) // Put X, but extracted Y. The cast will fail, so y is zero initialized. 173 sink = y // ERROR "y escapes to heap" 174 } 175