blob: f15bb74ba1896f804bc005bce8923a1e7b0c60dc [file] [log] [blame]
Russ Coxfcb4cab2014-09-11 12:17:45 -04001// errorcheck -0 -l -live -wb=0
Russ Coxca9975a2014-01-16 10:32:30 -05002
3// Copyright 2014 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
Russ Coxeb540792014-06-02 21:26:32 -04007// liveness tests with inlining disabled.
8// see also live2.go.
9
Russ Coxca9975a2014-01-16 10:32:30 -050010package main
11
12func f1() {
13 var x *int
14 print(&x) // ERROR "live at call to printpointer: x$"
15 print(&x) // ERROR "live at call to printpointer: x$"
16}
17
18func f2(b bool) {
19 if b {
20 print(0) // nothing live here
21 return
22 }
23 var x *int
24 print(&x) // ERROR "live at call to printpointer: x$"
25 print(&x) // ERROR "live at call to printpointer: x$"
26}
27
28func f3(b bool) {
Russ Cox28f18682014-04-03 20:33:25 -040029 // Because x and y are ambiguously live, they appear
30 // live throughout the function, to avoid being poisoned
31 // in GODEBUG=gcdead=1 mode.
32
33 print(0) // ERROR "live at call to printint: x y$"
Russ Coxca9975a2014-01-16 10:32:30 -050034 if b == false {
Russ Cox28f18682014-04-03 20:33:25 -040035 print(0) // ERROR "live at call to printint: x y$"
Russ Coxca9975a2014-01-16 10:32:30 -050036 return
37 }
38
39 if b {
40 var x *int
Russ Cox28f18682014-04-03 20:33:25 -040041 print(&x) // ERROR "live at call to printpointer: x y$"
42 print(&x) // ERROR "live at call to printpointer: x y$"
Russ Coxca9975a2014-01-16 10:32:30 -050043 } else {
44 var y *int
Russ Cox28f18682014-04-03 20:33:25 -040045 print(&y) // ERROR "live at call to printpointer: x y$"
46 print(&y) // ERROR "live at call to printpointer: x y$"
Russ Coxca9975a2014-01-16 10:32:30 -050047 }
Russ Cox6722d452014-03-27 14:05:57 -040048 print(0) // ERROR "live at call to printint: x y$" "x \(type \*int\) is ambiguously live" "y \(type \*int\) is ambiguously live"
Russ Coxca9975a2014-01-16 10:32:30 -050049}
50
51// The old algorithm treated x as live on all code that
52// could flow to a return statement, so it included the
53// function entry and code above the declaration of x
54// but would not include an indirect use of x in an infinite loop.
55// Check that these cases are handled correctly.
56
57func f4(b1, b2 bool) { // x not live here
58 if b2 {
59 print(0) // x not live here
60 return
61 }
62 var z **int
63 x := new(int)
64 *x = 42
65 z = &x
66 print(**z) // ERROR "live at call to printint: x z$"
67 if b2 {
68 print(1) // ERROR "live at call to printint: x$"
69 return
70 }
71 for {
72 print(**z) // ERROR "live at call to printint: x z$"
73 }
74}
75
76func f5(b1 bool) {
77 var z **int
78 if b1 {
79 x := new(int)
80 *x = 42
81 z = &x
82 } else {
83 y := new(int)
84 *y = 54
85 z = &y
86 }
Russ Cox6722d452014-03-27 14:05:57 -040087 print(**z) // ERROR "live at call to printint: x y$" "x \(type \*int\) is ambiguously live" "y \(type \*int\) is ambiguously live"
Russ Coxca9975a2014-01-16 10:32:30 -050088}
Russ Coxa069cf02014-02-13 20:59:39 -050089
90// confusion about the _ result used to cause spurious "live at entry to f6: _".
91
92func f6() (_, y string) {
93 y = "hello"
94 return
95}
Russ Cox824e9182014-02-13 21:11:50 -050096
97// confusion about addressed results used to cause "live at entry to f7: x".
98
99func f7() (x string) {
100 _ = &x
101 x = "hello"
102 return
103}
104
Russ Cox91b1f7c2014-02-13 22:45:16 -0500105// ignoring block returns used to cause "live at entry to f8: x, y".
106
107func f8() (x, y string) {
108 return g8()
109}
110
111func g8() (string, string)
112
113// ignoring block assignments used to cause "live at entry to f9: x"
114// issue 7205
115
116var i9 interface{}
117
118func f9() bool {
119 g8()
120 x := i9
Russ Cox1806a572014-08-18 21:13:11 -0400121 // using complex number in comparison so that
122 // there is always a convT2E, no matter what the
123 // interface rules are.
124 return x != 99.0i // ERROR "live at call to convT2E: x"
Russ Cox91b1f7c2014-02-13 22:45:16 -0500125}
Russ Coxab9e8d02014-02-13 23:56:53 -0500126
127// liveness formerly confused by UNDEF followed by RET,
128// leading to "live at entry to f10: ~r1" (unnamed result).
129
130func f10() string {
131 panic(1)
132}
133
Russ Coxaf545662014-02-14 00:38:24 -0500134// liveness formerly confused by select, thinking runtime.selectgo
135// can return to next instruction; it always jumps elsewhere.
136// note that you have to use at least two cases in the select
137// to get a true select; smaller selects compile to optimized helper functions.
138
139var c chan *int
140var b bool
141
142// this used to have a spurious "live at entry to f11a: ~r0"
143func f11a() *int {
Dmitriy Vyukov40d7d5a2014-07-20 15:07:10 +0400144 select { // ERROR "live at call to newselect: autotmp" "live at call to selectgo: autotmp"
Russ Coxaf545662014-02-14 00:38:24 -0500145 case <-c: // ERROR "live at call to selectrecv: autotmp"
146 return nil
147 case <-c: // ERROR "live at call to selectrecv: autotmp"
148 return nil
149 }
150}
151
152func f11b() *int {
153 p := new(int)
154 if b {
155 // At this point p is dead: the code here cannot
156 // get to the bottom of the function.
157 // This used to have a spurious "live at call to printint: p".
158 print(1) // nothing live here!
Dmitriy Vyukov40d7d5a2014-07-20 15:07:10 +0400159 select { // ERROR "live at call to newselect: autotmp" "live at call to selectgo: autotmp"
Russ Coxaf545662014-02-14 00:38:24 -0500160 case <-c: // ERROR "live at call to selectrecv: autotmp"
161 return nil
162 case <-c: // ERROR "live at call to selectrecv: autotmp"
163 return nil
164 }
165 }
166 println(*p)
167 return nil
168}
169
170func f11c() *int {
171 p := new(int)
172 if b {
173 // Unlike previous, the cases in this select fall through,
174 // so we can get to the println, so p is not dead.
175 print(1) // ERROR "live at call to printint: p"
Dmitriy Vyukov40d7d5a2014-07-20 15:07:10 +0400176 select { // ERROR "live at call to newselect: autotmp.* p" "live at call to selectgo: autotmp.* p"
Russ Coxaf545662014-02-14 00:38:24 -0500177 case <-c: // ERROR "live at call to selectrecv: autotmp.* p"
178 case <-c: // ERROR "live at call to selectrecv: autotmp.* p"
179 }
180 }
181 println(*p)
182 return nil
183}
184
185// similarly, select{} does not fall through.
186// this used to have a spurious "live at entry to f12: ~r0".
187
188func f12() *int {
189 if b {
Russ Cox1806a572014-08-18 21:13:11 -0400190 select {}
Russ Coxaf545662014-02-14 00:38:24 -0500191 } else {
192 return nil
193 }
194}
Russ Cox7a7c0ff2014-02-15 10:58:55 -0500195
196// incorrectly placed VARDEF annotations can cause missing liveness annotations.
197// this used to be missing the fact that s is live during the call to g13 (because it is
198// needed for the call to h13).
199
200func f13() {
201 s := "hello"
202 s = h13(s, g13(s)) // ERROR "live at call to g13: s"
203}
204
205func g13(string) string
206func h13(string, string) string
Russ Cox6722d452014-03-27 14:05:57 -0400207
208// more incorrectly placed VARDEF.
209
210func f14() {
211 x := g14()
212 print(&x) // ERROR "live at call to printpointer: x"
213}
214
215func g14() string
216
217func f15() {
218 var x string
219 _ = &x
220 x = g15() // ERROR "live at call to g15: x"
Russ Cox1806a572014-08-18 21:13:11 -0400221 print(x) // ERROR "live at call to printstring: x"
Russ Cox6722d452014-03-27 14:05:57 -0400222}
223
224func g15() string
Russ Coxb700cb42014-04-01 13:31:38 -0400225
226// Checking that various temporaries do not persist or cause
227// ambiguously live values that must be zeroed.
228// The exact temporary names are inconsequential but we are
229// trying to check that there is only one at any given site,
230// and also that none show up in "ambiguously live" messages.
231
232var m map[string]int
233
234func f16() {
235 if b {
236 delete(m, "hi") // ERROR "live at call to mapdelete: autotmp_[0-9]+$"
237 }
238 delete(m, "hi") // ERROR "live at call to mapdelete: autotmp_[0-9]+$"
239 delete(m, "hi") // ERROR "live at call to mapdelete: autotmp_[0-9]+$"
240}
241
242var m2s map[string]*byte
243var m2 map[[2]string]*byte
244var x2 [2]string
245var bp *byte
246
247func f17a() {
248 // value temporary only
249 if b {
250 m2[x2] = nil // ERROR "live at call to mapassign1: autotmp_[0-9]+$"
251 }
252 m2[x2] = nil // ERROR "live at call to mapassign1: autotmp_[0-9]+$"
253 m2[x2] = nil // ERROR "live at call to mapassign1: autotmp_[0-9]+$"
254}
255
256func f17b() {
257 // key temporary only
258 if b {
259 m2s["x"] = bp // ERROR "live at call to mapassign1: autotmp_[0-9]+$"
260 }
261 m2s["x"] = bp // ERROR "live at call to mapassign1: autotmp_[0-9]+$"
262 m2s["x"] = bp // ERROR "live at call to mapassign1: autotmp_[0-9]+$"
263}
264
265func f17c() {
266 // key and value temporaries
267 if b {
268 m2s["x"] = nil // ERROR "live at call to mapassign1: autotmp_[0-9]+ autotmp_[0-9]+$"
269 }
270 m2s["x"] = nil // ERROR "live at call to mapassign1: autotmp_[0-9]+ autotmp_[0-9]+$"
271 m2s["x"] = nil // ERROR "live at call to mapassign1: autotmp_[0-9]+ autotmp_[0-9]+$"
272}
273
274func g18() [2]string
275
276func f18() {
277 // key temporary for mapaccess.
278 // temporary introduced by orderexpr.
279 var z *byte
280 if b {
281 z = m2[g18()] // ERROR "live at call to mapaccess1: autotmp_[0-9]+$"
282 }
283 z = m2[g18()] // ERROR "live at call to mapaccess1: autotmp_[0-9]+$"
284 z = m2[g18()] // ERROR "live at call to mapaccess1: autotmp_[0-9]+$"
285 print(z)
286}
287
288var ch chan *byte
289
290func f19() {
291 // dest temporary for channel receive.
292 var z *byte
Russ Cox1806a572014-08-18 21:13:11 -0400293
Russ Coxb700cb42014-04-01 13:31:38 -0400294 if b {
295 z = <-ch // ERROR "live at call to chanrecv1: autotmp_[0-9]+$"
296 }
297 z = <-ch // ERROR "live at call to chanrecv1: autotmp_[0-9]+$"
298 z = <-ch // ERROR "live at call to chanrecv1: autotmp_[0-9]+$"
299 print(z)
300}
301
302func f20() {
303 // src temporary for channel send
304 if b {
305 ch <- nil // ERROR "live at call to chansend1: autotmp_[0-9]+$"
306 }
307 ch <- nil // ERROR "live at call to chansend1: autotmp_[0-9]+$"
308 ch <- nil // ERROR "live at call to chansend1: autotmp_[0-9]+$"
309}
310
311func f21() {
312 // key temporary for mapaccess using array literal key.
313 var z *byte
314 if b {
315 z = m2[[2]string{"x", "y"}] // ERROR "live at call to mapaccess1: autotmp_[0-9]+$"
316 }
317 z = m2[[2]string{"x", "y"}] // ERROR "live at call to mapaccess1: autotmp_[0-9]+$"
318 z = m2[[2]string{"x", "y"}] // ERROR "live at call to mapaccess1: autotmp_[0-9]+$"
319 print(z)
320}
321
322func f23() {
323 // key temporary for two-result map access using array literal key.
324 var z *byte
325 var ok bool
326 if b {
327 z, ok = m2[[2]string{"x", "y"}] // ERROR "live at call to mapaccess2: autotmp_[0-9]+$"
328 }
329 z, ok = m2[[2]string{"x", "y"}] // ERROR "live at call to mapaccess2: autotmp_[0-9]+$"
330 z, ok = m2[[2]string{"x", "y"}] // ERROR "live at call to mapaccess2: autotmp_[0-9]+$"
331 print(z, ok)
332}
333
334func f24() {
335 // key temporary for map access using array literal key.
336 // value temporary too.
337 if b {
338 m2[[2]string{"x", "y"}] = nil // ERROR "live at call to mapassign1: autotmp_[0-9]+ autotmp_[0-9]+$"
339 }
340 m2[[2]string{"x", "y"}] = nil // ERROR "live at call to mapassign1: autotmp_[0-9]+ autotmp_[0-9]+$"
341 m2[[2]string{"x", "y"}] = nil // ERROR "live at call to mapassign1: autotmp_[0-9]+ autotmp_[0-9]+$"
342}
Russ Coxdaca06f2014-04-01 20:02:54 -0400343
344// defer should not cause spurious ambiguously live variables
345
346func f25(b bool) {
347 defer g25()
348 if b {
349 return
350 }
351 var x string
352 _ = &x
353 x = g15() // ERROR "live at call to g15: x"
Russ Cox1806a572014-08-18 21:13:11 -0400354 print(x) // ERROR "live at call to printstring: x"
Russ Coxdaca06f2014-04-01 20:02:54 -0400355} // ERROR "live at call to deferreturn: x"
356
357func g25()
Russ Cox1806a572014-08-18 21:13:11 -0400358
Russ Coxdaca06f2014-04-01 20:02:54 -0400359// non-escaping ... slices passed to function call should die on return,
360// so that the temporaries do not stack and do not cause ambiguously
361// live variables.
362
363func f26(b bool) {
364 if b {
Russ Cox1806a572014-08-18 21:13:11 -0400365 print26((*int)(nil), (*int)(nil), (*int)(nil)) // ERROR "live at call to print26: autotmp_[0-9]+$"
Russ Coxdaca06f2014-04-01 20:02:54 -0400366 }
Russ Cox1806a572014-08-18 21:13:11 -0400367 print26((*int)(nil), (*int)(nil), (*int)(nil)) // ERROR "live at call to print26: autotmp_[0-9]+$"
368 print26((*int)(nil), (*int)(nil), (*int)(nil)) // ERROR "live at call to print26: autotmp_[0-9]+$"
Russ Coxdaca06f2014-04-01 20:02:54 -0400369 println()
370}
371
372//go:noescape
373func print26(...interface{})
374
375// non-escaping closures passed to function call should die on return
376
377func f27(b bool) {
378 x := 0
379 if b {
Russ Cox1806a572014-08-18 21:13:11 -0400380 call27(func() { x++ }) // ERROR "live at call to call27: autotmp_[0-9]+$"
Russ Coxdaca06f2014-04-01 20:02:54 -0400381 }
Russ Cox1806a572014-08-18 21:13:11 -0400382 call27(func() { x++ }) // ERROR "live at call to call27: autotmp_[0-9]+$"
383 call27(func() { x++ }) // ERROR "live at call to call27: autotmp_[0-9]+$"
Russ Cox28f18682014-04-03 20:33:25 -0400384 println()
385}
386
387// but defer does escape to later execution in the function
388
389func f27defer(b bool) {
390 x := 0
391 if b {
Russ Cox1806a572014-08-18 21:13:11 -0400392 defer call27(func() { x++ }) // ERROR "live at call to deferproc: autotmp_[0-9]+$" "live at call to deferreturn: autotmp_[0-9]+$"
Russ Cox28f18682014-04-03 20:33:25 -0400393 }
Russ Cox1806a572014-08-18 21:13:11 -0400394 defer call27(func() { x++ }) // ERROR "live at call to deferproc: autotmp_[0-9]+ autotmp_[0-9]+$" "live at call to deferreturn: autotmp_[0-9]+ autotmp_[0-9]+$" "ambiguously live"
395 println() // ERROR "live at call to printnl: autotmp_[0-9]+ autotmp_[0-9]+$"
Russ Cox28f18682014-04-03 20:33:25 -0400396} // ERROR "live at call to deferreturn: autotmp_[0-9]+ autotmp_[0-9]+$"
397
398// and newproc (go) escapes to the heap
399
400func f27go(b bool) {
401 x := 0
402 if b {
Russ Cox1806a572014-08-18 21:13:11 -0400403 go call27(func() { x++ }) // ERROR "live at call to newobject: &x" "live at call to newproc: &x$"
Russ Cox28f18682014-04-03 20:33:25 -0400404 }
Russ Cox1806a572014-08-18 21:13:11 -0400405 go call27(func() { x++ }) // ERROR "live at call to newobject: &x"
Russ Cox28f18682014-04-03 20:33:25 -0400406 println()
Russ Coxdaca06f2014-04-01 20:02:54 -0400407}
408
409//go:noescape
410func call27(func())
411
412// concatstring slice should die on return
413
414var s1, s2, s3, s4, s5, s6, s7, s8, s9, s10 string
415
416func f28(b bool) {
417 if b {
Russ Cox1806a572014-08-18 21:13:11 -0400418 print(s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10) // ERROR "live at call to concatstrings: autotmp_[0-9]+$" "live at call to printstring: autotmp_[0-9]+$"
Russ Coxdaca06f2014-04-01 20:02:54 -0400419 }
Russ Cox1806a572014-08-18 21:13:11 -0400420 print(s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10) // ERROR "live at call to concatstrings: autotmp_[0-9]+$" "live at call to printstring: autotmp_[0-9]+$"
421 print(s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10) // ERROR "live at call to concatstrings: autotmp_[0-9]+$" "live at call to printstring: autotmp_[0-9]+$"
422}
Russ Coxdaca06f2014-04-01 20:02:54 -0400423
424// map iterator should die on end of range loop
425
426func f29(b bool) {
427 if b {
428 for k := range m { // ERROR "live at call to mapiterinit: autotmp_[0-9]+$" "live at call to mapiternext: autotmp_[0-9]+$"
429 print(k) // ERROR "live at call to printstring: autotmp_[0-9]+$"
430 }
431 }
432 for k := range m { // ERROR "live at call to mapiterinit: autotmp_[0-9]+$" "live at call to mapiternext: autotmp_[0-9]+$"
433 print(k) // ERROR "live at call to printstring: autotmp_[0-9]+$"
434 }
435 for k := range m { // ERROR "live at call to mapiterinit: autotmp_[0-9]+$" "live at call to mapiternext: autotmp_[0-9]+$"
436 print(k) // ERROR "live at call to printstring: autotmp_[0-9]+$"
437 }
438}
439
440// copy of array of pointers should die at end of range loop
441
442var ptrarr [10]*int
443
444func f30(b bool) {
445 // two live temps during print(p):
446 // the copy of ptrarr and the internal iterator pointer.
447 if b {
448 for _, p := range ptrarr {
449 print(p) // ERROR "live at call to printpointer: autotmp_[0-9]+ autotmp_[0-9]+$"
450 }
451 }
452 for _, p := range ptrarr {
453 print(p) // ERROR "live at call to printpointer: autotmp_[0-9]+ autotmp_[0-9]+$"
454 }
455 for _, p := range ptrarr {
456 print(p) // ERROR "live at call to printpointer: autotmp_[0-9]+ autotmp_[0-9]+$"
457 }
458}
Russ Cox96d90d02014-04-02 14:09:42 -0400459
460// conversion to interface should not leave temporary behind
461
462func f31(b1, b2, b3 bool) {
463 if b1 {
464 g31("a") // ERROR "live at call to convT2E: autotmp_[0-9]+$" "live at call to g31: autotmp_[0-9]+$"
465 }
466 if b2 {
Keith Randall4aa50432014-07-30 09:01:52 -0700467 h31("b") // ERROR "live at call to newobject: autotmp_[0-9]+$" "live at call to convT2E: autotmp_[0-9]+ autotmp_[0-9]+$" "live at call to h31: autotmp_[0-9]+$"
Russ Cox96d90d02014-04-02 14:09:42 -0400468 }
469 if b3 {
Keith Randall8217b4a2014-09-05 10:04:16 -0400470 panic("asdf") // ERROR "live at call to convT2E: autotmp_[0-9]+$" "live at call to gopanic: autotmp_[0-9]+$"
Russ Cox96d90d02014-04-02 14:09:42 -0400471 }
472 print(b3)
473}
474
475func g31(interface{})
476func h31(...interface{})
477
478// non-escaping partial functions passed to function call should die on return
479
480type T32 int
481
482func (t *T32) Inc() { // ERROR "live at entry"
483 *t++
484}
485
486var t32 T32
487
488func f32(b bool) {
489 if b {
490 call32(t32.Inc) // ERROR "live at call to call32: autotmp_[0-9]+$"
491 }
492 call32(t32.Inc) // ERROR "live at call to call32: autotmp_[0-9]+$"
493 call32(t32.Inc) // ERROR "live at call to call32: autotmp_[0-9]+$"
494}
495
496//go:noescape
497func call32(func())
498
499// temporaries introduced during if conditions and && || expressions
500// should die once the condition has been acted upon.
501
502var m33 map[interface{}]int
503
504func f33() {
505 if m33[nil] == 0 { // ERROR "live at call to mapaccess1: autotmp_[0-9]+$"
506 println()
507 return
508 } else {
509 println()
510 }
511 println()
512}
513
514func f34() {
515 if m33[nil] == 0 { // ERROR "live at call to mapaccess1: autotmp_[0-9]+$"
516 println()
517 return
518 }
519 println()
520}
521
522func f35() {
523 if m33[nil] == 0 && m33[nil] == 0 { // ERROR "live at call to mapaccess1: autotmp_[0-9]+$"
524 println()
525 return
526 }
527 println()
528}
529
530func f36() {
531 if m33[nil] == 0 || m33[nil] == 0 { // ERROR "live at call to mapaccess1: autotmp_[0-9]+$"
532 println()
533 return
534 }
535 println()
536}
537
538func f37() {
539 if (m33[nil] == 0 || m33[nil] == 0) && m33[nil] == 0 { // ERROR "live at call to mapaccess1: autotmp_[0-9]+$"
540 println()
541 return
542 }
543 println()
544}
545
546// select temps should disappear in the case bodies
547
548var c38 chan string
549
550func fc38() chan string
551func fi38(int) *string
552func fb38() *bool
553
554func f38(b bool) {
555 // we don't care what temps are printed on the lines with output.
556 // we care that the println lines have no live variables
557 // and therefore no output.
558 if b {
559 select { // ERROR "live at call"
560 case <-fc38(): // ERROR "live at call"
561 println()
562 case fc38() <- *fi38(1): // ERROR "live at call"
563 println()
564 case *fi38(2) = <-fc38(): // ERROR "live at call"
565 println()
566 case *fi38(3), *fb38() = <-fc38(): // ERROR "live at call"
567 println()
568 }
569 println()
570 }
571 println()
572}
Russ Cox89d46fe2014-05-29 13:47:31 -0400573
574// issue 8097: mishandling of x = x during return.
575
576func f39() (x []int) {
577 x = []int{1}
578 println() // ERROR "live at call to printnl: x"
579 return x
580}
581
582func f39a() (x []int) {
583 x = []int{1}
584 println() // ERROR "live at call to printnl: x"
585 return
586}
587
588func f39b() (x [10]*int) {
Russ Cox454d1b02014-09-30 12:48:47 -0400589 x = [10]*int{}
590 x[0] = new(int) // ERROR "live at call to newobject: x"
591 println() // ERROR "live at call to printnl: x"
Russ Cox89d46fe2014-05-29 13:47:31 -0400592 return x
593}
594
595func f39c() (x [10]*int) {
Russ Cox454d1b02014-09-30 12:48:47 -0400596 x = [10]*int{}
597 x[0] = new(int) // ERROR "live at call to newobject: x"
598 println() // ERROR "live at call to printnl: x"
Russ Cox89d46fe2014-05-29 13:47:31 -0400599 return
600}
Russ Coxeb540792014-06-02 21:26:32 -0400601
602// issue 8142: lost 'addrtaken' bit on inlined variables.
603// no inlining in this test, so just checking that non-inlined works.
604
605type T40 struct {
606 m map[int]int
607}
608
609func newT40() *T40 {
Russ Cox454d1b02014-09-30 12:48:47 -0400610 ret := T40{}
611 ret.m = make(map[int]int) // ERROR "live at call to makemap: &ret"
Russ Coxeb540792014-06-02 21:26:32 -0400612 return &ret
613}
614
615func bad40() {
616 t := newT40()
617 println()
618 _ = t
619}
620
621func good40() {
Russ Cox454d1b02014-09-30 12:48:47 -0400622 ret := T40{}
623 ret.m = make(map[int]int) // ERROR "live at call to makemap: ret"
Russ Coxeb540792014-06-02 21:26:32 -0400624 t := &ret
625 println() // ERROR "live at call to printnl: ret"
626 _ = t
627}