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 for interface conversions. 8 9 package escape 10 11 var sink interface{} 12 13 type M interface { 14 M() 15 } 16 17 func mescapes(m M) { // ERROR "leaking param: m" 18 sink = m // ERROR "m escapes to heap" 19 } 20 21 func mdoesnotescape(m M) { // ERROR "m does not escape" 22 } 23 24 // Tests for type stored directly in iface and with value receiver method. 25 type M0 struct { 26 p *int 27 } 28 29 func (M0) M() { 30 } 31 32 func efaceEscape0() { 33 { 34 i := 0 35 v := M0{&i} // ERROR "&i does not escape" 36 var x M = v // ERROR "v does not escape" 37 _ = x 38 } 39 { 40 i := 0 // ERROR "moved to heap: i" 41 v := M0{&i} // ERROR "&i escapes to heap" 42 var x M = v // ERROR "v escapes to heap" 43 sink = x // ERROR "x escapes to heap" 44 } 45 { 46 i := 0 47 v := M0{&i} // ERROR "&i does not escape" 48 var x M = v // ERROR "v does not escape" 49 v1 := x.(M0) 50 _ = v1 51 } 52 { 53 i := 0 // ERROR "moved to heap: i" 54 v := M0{&i} // ERROR "&i escapes to heap" 55 // BAD: v does not escape to heap here 56 var x M = v // ERROR "v escapes to heap" 57 v1 := x.(M0) 58 sink = v1 // ERROR "v1 escapes to heap" 59 } 60 { 61 i := 0 // ERROR "moved to heap: i" 62 v := M0{&i} // ERROR "&i escapes to heap" 63 // BAD: v does not escape to heap here 64 var x M = v // ERROR "v escapes to heap" 65 x.M() 66 } 67 { 68 i := 0 // ERROR "moved to heap: i" 69 v := M0{&i} // ERROR "&i escapes to heap" 70 var x M = v // ERROR "v escapes to heap" 71 mescapes(x) 72 } 73 { 74 i := 0 75 v := M0{&i} // ERROR "&i does not escape" 76 var x M = v // ERROR "v does not escape" 77 mdoesnotescape(x) 78 } 79 } 80 81 // Tests for type stored indirectly in iface and with value receiver method. 82 type M1 struct { 83 p *int 84 x int 85 } 86 87 func (M1) M() { 88 } 89 90 func efaceEscape1() { 91 { 92 i := 0 93 v := M1{&i, 0} // ERROR "&i does not escape" 94 var x M = v // ERROR "v does not escape" 95 _ = x 96 } 97 { 98 i := 0 // ERROR "moved to heap: i" 99 v := M1{&i, 0} // ERROR "&i escapes to heap" 100 var x M = v // ERROR "v escapes to heap" 101 sink = x // ERROR "x escapes to heap" 102 } 103 { 104 i := 0 105 v := M1{&i, 0} // ERROR "&i does not escape" 106 var x M = v // ERROR "v does not escape" 107 v1 := x.(M1) 108 _ = v1 109 } 110 { 111 i := 0 // ERROR "moved to heap: i" 112 v := M1{&i, 0} // ERROR "&i escapes to heap" 113 // BAD: v does not escape to heap here 114 var x M = v // ERROR "v escapes to heap" 115 v1 := x.(M1) 116 sink = v1 // ERROR "v1 escapes to heap" 117 } 118 { 119 i := 0 // ERROR "moved to heap: i" 120 v := M1{&i, 0} // ERROR "&i escapes to heap" 121 // BAD: v does not escape to heap here 122 var x M = v // ERROR "v escapes to heap" 123 x.M() 124 } 125 { 126 i := 0 // ERROR "moved to heap: i" 127 v := M1{&i, 0} // ERROR "&i escapes to heap" 128 var x M = v // ERROR "v escapes to heap" 129 mescapes(x) 130 } 131 { 132 i := 0 133 v := M1{&i, 0} // ERROR "&i does not escape" 134 var x M = v // ERROR "v does not escape" 135 mdoesnotescape(x) 136 } 137 } 138 139 // Tests for type stored directly in iface and with pointer receiver method. 140 type M2 struct { 141 p *int 142 } 143 144 func (*M2) M() { 145 } 146 147 func efaceEscape2() { 148 { 149 i := 0 150 v := &M2{&i} // ERROR "&i does not escape" "&M2 literal does not escape" 151 var x M = v // ERROR "v does not escape" 152 _ = x 153 } 154 { 155 i := 0 // ERROR "moved to heap: i" 156 v := &M2{&i} // ERROR "&i escapes to heap" "&M2 literal escapes to heap" 157 var x M = v // ERROR "v escapes to heap" 158 sink = x // ERROR "x escapes to heap" 159 } 160 { 161 i := 0 162 v := &M2{&i} // ERROR "&i does not escape" "&M2 literal does not escape" 163 var x M = v // ERROR "v does not escape" 164 v1 := x.(*M2) 165 _ = v1 166 } 167 { 168 i := 0 // ERROR "moved to heap: i" 169 v := &M2{&i} // ERROR "&i escapes to heap" "&M2 literal escapes to heap" 170 // BAD: v does not escape to heap here 171 var x M = v // ERROR "v escapes to heap" 172 v1 := x.(*M2) 173 sink = v1 // ERROR "v1 escapes to heap" 174 } 175 { 176 i := 0 // ERROR "moved to heap: i" 177 v := &M2{&i} // ERROR "&i escapes to heap" "&M2 literal does not escape" 178 // BAD: v does not escape to heap here 179 var x M = v // ERROR "v does not escape" 180 v1 := x.(*M2) 181 sink = *v1 // ERROR "v1 escapes to heap" 182 } 183 { 184 i := 0 // ERROR "moved to heap: i" 185 v := &M2{&i} // ERROR "&i escapes to heap" "&M2 literal does not escape" 186 // BAD: v does not escape to heap here 187 var x M = v // ERROR "v does not escape" 188 v1, ok := x.(*M2) 189 sink = *v1 // ERROR "v1 escapes to heap" 190 _ = ok 191 } 192 { 193 i := 0 // ERROR "moved to heap: i" 194 v := &M2{&i} // ERROR "&i escapes to heap" "&M2 literal escapes to heap" 195 // BAD: v does not escape to heap here 196 var x M = v // ERROR "v escapes to heap" 197 x.M() 198 } 199 { 200 i := 0 // ERROR "moved to heap: i" 201 v := &M2{&i} // ERROR "&i escapes to heap" "&M2 literal escapes to heap" 202 var x M = v // ERROR "v escapes to heap" 203 mescapes(x) 204 } 205 { 206 i := 0 207 v := &M2{&i} // ERROR "&i does not escape" "&M2 literal does not escape" 208 var x M = v // ERROR "v does not escape" 209 mdoesnotescape(x) 210 } 211 } 212 213 type T1 struct { 214 p *int 215 } 216 217 type T2 struct { 218 T1 T1 219 } 220 221 func dotTypeEscape() *T2 { // #11931 222 var x interface{} 223 x = &T1{p: new(int)} // ERROR "new\(int\) escapes to heap" "&T1 literal does not escape" 224 return &T2{ 225 T1: *(x.(*T1)), // ERROR "&T2 literal escapes to heap" 226 } 227 } 228