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 9package escape 10 11var sink interface{} 12 13type X struct { 14 p1 *int 15 p2 *int 16 a [2]*int 17} 18 19type Y struct { 20 x X 21} 22 23func field0() { 24 i := 0 // ERROR "moved to heap: i$" 25 var x X 26 x.p1 = &i 27 sink = x.p1 28} 29 30func field1() { 31 i := 0 // ERROR "moved to heap: i$" 32 var x X 33 // BAD: &i should not escape 34 x.p1 = &i 35 sink = x.p2 36} 37 38func field3() { 39 i := 0 // ERROR "moved to heap: i$" 40 var x X 41 x.p1 = &i 42 sink = x // ERROR "x escapes to heap" 43} 44 45func field4() { 46 i := 0 // ERROR "moved to heap: i$" 47 var y Y 48 y.x.p1 = &i 49 x := y.x 50 sink = x // ERROR "x escapes to heap" 51} 52 53func 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 58 sink = x.a[1] 59} 60 61// BAD: we are not leaking param x, only x.p2 62func field6(x *X) { // ERROR "leaking param content: x$" 63 sink = x.p2 64} 65 66func field6a() { 67 i := 0 // ERROR "moved to heap: i$" 68 var x X 69 // BAD: &i should not escape 70 x.p1 = &i 71 field6(&x) 72} 73 74func field7() { 75 i := 0 76 var y Y 77 y.x.p1 = &i 78 x := y.x 79 var y1 Y 80 y1.x = x 81 _ = y1.x.p1 82} 83 84func field8() { 85 i := 0 // ERROR "moved to heap: i$" 86 var y Y 87 y.x.p1 = &i 88 x := y.x 89 var y1 Y 90 y1.x = x 91 sink = y1.x.p1 92} 93 94func field9() { 95 i := 0 // ERROR "moved to heap: i$" 96 var y Y 97 y.x.p1 = &i 98 x := y.x 99 var y1 Y 100 y1.x = x 101 sink = y1.x // ERROR "y1\.x escapes to heap" 102} 103 104func field10() { 105 i := 0 // ERROR "moved to heap: i$" 106 var y Y 107 // BAD: &i should not escape 108 y.x.p1 = &i 109 x := y.x 110 var y1 Y 111 y1.x = x 112 sink = y1.x.p2 113} 114 115func field11() { 116 i := 0 // ERROR "moved to heap: i$" 117 x := X{p1: &i} 118 sink = x.p1 119} 120 121func field12() { 122 i := 0 // ERROR "moved to heap: i$" 123 // BAD: &i should not escape 124 x := X{p1: &i} 125 sink = x.p2 126} 127 128func field13() { 129 i := 0 // ERROR "moved to heap: i$" 130 x := &X{p1: &i} // ERROR "&X{...} does not escape$" 131 sink = x.p1 132} 133 134func field14() { 135 i := 0 // ERROR "moved to heap: i$" 136 // BAD: &i should not escape 137 x := &X{p1: &i} // ERROR "&X{...} does not escape$" 138 sink = x.p2 139} 140 141func field15() { 142 i := 0 // ERROR "moved to heap: i$" 143 x := &X{p1: &i} // ERROR "&X{...} escapes to heap$" 144 sink = x 145} 146 147func field16() { 148 i := 0 // ERROR "moved to heap: i$" 149 var x X 150 // BAD: &i should not escape 151 x.p1 = &i 152 var iface interface{} = x // ERROR "x does not escape" 153 x1 := iface.(X) 154 sink = x1.p2 155} 156 157func field17() { 158 i := 0 // ERROR "moved to heap: i$" 159 var x X 160 x.p1 = &i 161 var iface interface{} = x // ERROR "x does not escape" 162 x1 := iface.(X) 163 sink = x1.p1 164} 165 166func field18() { 167 i := 0 // ERROR "moved to heap: i$" 168 var x X 169 // BAD: &i should not escape 170 x.p1 = &i 171 var iface interface{} = x // ERROR "x does not escape" 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