Home | History | Annotate | Download | only in test
      1 // errorcheckwithauto -0 -l -live -wb=0 -d=ssa/insert_resched_checks/off
      2 // +build !ppc64,!ppc64le
      3 // ppc64 needs a better tighten pass to make f18 pass
      4 // rescheduling checks need to be turned off because there are some live variables across the inserted check call
      5 
      6 // Copyright 2014 The Go Authors. All rights reserved.
      7 // Use of this source code is governed by a BSD-style
      8 // license that can be found in the LICENSE file.
      9 
     10 // liveness tests with inlining disabled.
     11 // see also live2.go.
     12 
     13 package main
     14 
     15 func printnl()
     16 
     17 //go:noescape
     18 func printpointer(**int)
     19 
     20 //go:noescape
     21 func printintpointer(*int)
     22 
     23 //go:noescape
     24 func printstringpointer(*string)
     25 
     26 //go:noescape
     27 func printstring(string)
     28 
     29 //go:noescape
     30 func printbytepointer(*byte)
     31 
     32 func printint(int)
     33 
     34 func f1() {
     35 	var x *int
     36 	printpointer(&x) // ERROR "live at call to printpointer: x$"
     37 	printpointer(&x) // ERROR "live at call to printpointer: x$"
     38 }
     39 
     40 func f2(b bool) {
     41 	if b {
     42 		printint(0) // nothing live here
     43 		return
     44 	}
     45 	var x *int
     46 	printpointer(&x) // ERROR "live at call to printpointer: x$"
     47 	printpointer(&x) // ERROR "live at call to printpointer: x$"
     48 }
     49 
     50 func f3(b1, b2 bool) {
     51 	// Here x and y are ambiguously live. In previous go versions they
     52 	// were marked as live throughout the function to avoid being
     53 	// poisoned in GODEBUG=gcdead=1 mode; this is now no longer the
     54 	// case.
     55 
     56 	printint(0)
     57 	if b1 == false {
     58 		printint(0)
     59 		return
     60 	}
     61 
     62 	if b2 {
     63 		var x *int
     64 		printpointer(&x) // ERROR "live at call to printpointer: x$"
     65 		printpointer(&x) // ERROR "live at call to printpointer: x$"
     66 	} else {
     67 		var y *int
     68 		printpointer(&y) // ERROR "live at call to printpointer: y$"
     69 		printpointer(&y) // ERROR "live at call to printpointer: y$"
     70 	}
     71 	printint(0) // ERROR "f3: x \(type \*int\) is ambiguously live$" "f3: y \(type \*int\) is ambiguously live$" "live at call to printint: x y$"
     72 }
     73 
     74 // The old algorithm treated x as live on all code that
     75 // could flow to a return statement, so it included the
     76 // function entry and code above the declaration of x
     77 // but would not include an indirect use of x in an infinite loop.
     78 // Check that these cases are handled correctly.
     79 
     80 func f4(b1, b2 bool) { // x not live here
     81 	if b2 {
     82 		printint(0) // x not live here
     83 		return
     84 	}
     85 	var z **int
     86 	x := new(int)
     87 	*x = 42
     88 	z = &x
     89 	printint(**z) // ERROR "live at call to printint: x$"
     90 	if b2 {
     91 		printint(1) // x not live here
     92 		return
     93 	}
     94 	for {
     95 		printint(**z) // ERROR "live at call to printint: x$"
     96 	}
     97 }
     98 
     99 func f5(b1 bool) {
    100 	var z **int
    101 	if b1 {
    102 		x := new(int)
    103 		*x = 42
    104 		z = &x
    105 	} else {
    106 		y := new(int)
    107 		*y = 54
    108 		z = &y
    109 	}
    110 	printint(**z) // ERROR "f5: x \(type \*int\) is ambiguously live$" "f5: y \(type \*int\) is ambiguously live$" "live at call to printint: x y$"
    111 }
    112 
    113 // confusion about the _ result used to cause spurious "live at entry to f6: _".
    114 
    115 func f6() (_, y string) {
    116 	y = "hello"
    117 	return
    118 }
    119 
    120 // confusion about addressed results used to cause "live at entry to f7: x".
    121 
    122 func f7() (x string) {
    123 	_ = &x
    124 	x = "hello"
    125 	return
    126 }
    127 
    128 // ignoring block returns used to cause "live at entry to f8: x, y".
    129 
    130 func f8() (x, y string) {
    131 	return g8()
    132 }
    133 
    134 func g8() (string, string)
    135 
    136 // ignoring block assignments used to cause "live at entry to f9: x"
    137 // issue 7205
    138 
    139 var i9 interface{}
    140 
    141 func f9() bool {
    142 	g8()
    143 	x := i9
    144 	y := interface{}(99.0i) // ERROR "live at call to convT2E: x.data x.type$"
    145 	i9 = y                  // make y escape so the line above has to call convT2E
    146 	return x != y
    147 }
    148 
    149 // liveness formerly confused by UNDEF followed by RET,
    150 // leading to "live at entry to f10: ~r1" (unnamed result).
    151 
    152 func f10() string {
    153 	panic(1)
    154 }
    155 
    156 // liveness formerly confused by select, thinking runtime.selectgo
    157 // can return to next instruction; it always jumps elsewhere.
    158 // note that you have to use at least two cases in the select
    159 // to get a true select; smaller selects compile to optimized helper functions.
    160 
    161 var c chan *int
    162 var b bool
    163 
    164 // this used to have a spurious "live at entry to f11a: ~r0"
    165 func f11a() *int {
    166 	select { // ERROR "live at call to newselect: .autotmp_[0-9]+$" "live at call to selectgo: .autotmp_[0-9]+$"
    167 	case <-c: // ERROR "live at call to selectrecv: .autotmp_[0-9]+$"
    168 		return nil
    169 	case <-c: // ERROR "live at call to selectrecv: .autotmp_[0-9]+$"
    170 		return nil
    171 	}
    172 }
    173 
    174 func f11b() *int {
    175 	p := new(int)
    176 	if b {
    177 		// At this point p is dead: the code here cannot
    178 		// get to the bottom of the function.
    179 		// This used to have a spurious "live at call to printint: p".
    180 		printint(1) // nothing live here!
    181 		select {    // ERROR "live at call to newselect: .autotmp_[0-9]+$" "live at call to selectgo: .autotmp_[0-9]+$"
    182 		case <-c: // ERROR "live at call to selectrecv: .autotmp_[0-9]+$"
    183 			return nil
    184 		case <-c: // ERROR "live at call to selectrecv: .autotmp_[0-9]+$"
    185 			return nil
    186 		}
    187 	}
    188 	println(*p)
    189 	return nil
    190 }
    191 
    192 var sink *int
    193 
    194 func f11c() *int {
    195 	p := new(int)
    196 	sink = p // prevent stack allocation, otherwise p is rematerializeable
    197 	if b {
    198 		// Unlike previous, the cases in this select fall through,
    199 		// so we can get to the println, so p is not dead.
    200 		printint(1) // ERROR "live at call to printint: p$"
    201 		select {    // ERROR "live at call to newselect: .autotmp_[0-9]+ p$" "live at call to selectgo: .autotmp_[0-9]+ p$"
    202 		case <-c: // ERROR "live at call to selectrecv: .autotmp_[0-9]+ p$"
    203 		case <-c: // ERROR "live at call to selectrecv: .autotmp_[0-9]+ p$"
    204 		}
    205 	}
    206 	println(*p)
    207 	return nil
    208 }
    209 
    210 // similarly, select{} does not fall through.
    211 // this used to have a spurious "live at entry to f12: ~r0".
    212 
    213 func f12() *int {
    214 	if b {
    215 		select {}
    216 	} else {
    217 		return nil
    218 	}
    219 }
    220 
    221 // incorrectly placed VARDEF annotations can cause missing liveness annotations.
    222 // this used to be missing the fact that s is live during the call to g13 (because it is
    223 // needed for the call to h13).
    224 
    225 func f13() {
    226 	s := g14()
    227 	s = h13(s, g13(s)) // ERROR "live at call to g13: s.ptr$"
    228 }
    229 
    230 func g13(string) string
    231 func h13(string, string) string
    232 
    233 // more incorrectly placed VARDEF.
    234 
    235 func f14() {
    236 	x := g14()
    237 	printstringpointer(&x) // ERROR "live at call to printstringpointer: x$"
    238 }
    239 
    240 func g14() string
    241 
    242 func f15() {
    243 	var x string
    244 	_ = &x
    245 	x = g15()      // ERROR "live at call to g15: x$"
    246 	printstring(x) // ERROR "live at call to printstring: x$"
    247 }
    248 
    249 func g15() string
    250 
    251 // Checking that various temporaries do not persist or cause
    252 // ambiguously live values that must be zeroed.
    253 // The exact temporary names are inconsequential but we are
    254 // trying to check that there is only one at any given site,
    255 // and also that none show up in "ambiguously live" messages.
    256 
    257 var m map[string]int
    258 
    259 func f16() {
    260 	if b {
    261 		delete(m, "hi") // ERROR "live at call to mapdelete: .autotmp_[0-9]+$"
    262 	}
    263 	delete(m, "hi") // ERROR "live at call to mapdelete: .autotmp_[0-9]+$"
    264 	delete(m, "hi") // ERROR "live at call to mapdelete: .autotmp_[0-9]+$"
    265 }
    266 
    267 var m2s map[string]*byte
    268 var m2 map[[2]string]*byte
    269 var x2 [2]string
    270 var bp *byte
    271 
    272 func f17a(p *byte) { // ERROR "live at entry to f17a: p$"
    273 	if b {
    274 		m2[x2] = p // ERROR "live at call to mapassign: p$"
    275 	}
    276 	m2[x2] = p // ERROR "live at call to mapassign: p$"
    277 	m2[x2] = p // ERROR "live at call to mapassign: p$"
    278 }
    279 
    280 func f17b(p *byte) { // ERROR "live at entry to f17b: p$"
    281 	// key temporary
    282 	if b {
    283 		m2s["x"] = p // ERROR "live at call to mapassign: p .autotmp_[0-9]+$"
    284 	}
    285 	m2s["x"] = p // ERROR "live at call to mapassign: p .autotmp_[0-9]+$"
    286 	m2s["x"] = p // ERROR "live at call to mapassign: p .autotmp_[0-9]+$"
    287 }
    288 
    289 func f17c() {
    290 	// key and value temporaries
    291 	if b {
    292 		m2s["x"] = f17d() // ERROR "live at call to f17d: .autotmp_[0-9]+$" "live at call to mapassign: .autotmp_[0-9]+ .autotmp_[0-9]+$"
    293 	}
    294 	m2s["x"] = f17d() // ERROR "live at call to f17d: .autotmp_[0-9]+$" "live at call to mapassign: .autotmp_[0-9]+ .autotmp_[0-9]+$"
    295 	m2s["x"] = f17d() // ERROR "live at call to f17d: .autotmp_[0-9]+$" "live at call to mapassign: .autotmp_[0-9]+ .autotmp_[0-9]+$"
    296 }
    297 
    298 func f17d() *byte
    299 
    300 func g18() [2]string
    301 
    302 func f18() {
    303 	// key temporary for mapaccess.
    304 	// temporary introduced by orderexpr.
    305 	var z *byte
    306 	if b {
    307 		z = m2[g18()] // ERROR "live at call to mapaccess1: .autotmp_[0-9]+$"
    308 	}
    309 	z = m2[g18()] // ERROR "live at call to mapaccess1: .autotmp_[0-9]+$"
    310 	z = m2[g18()] // ERROR "live at call to mapaccess1: .autotmp_[0-9]+$"
    311 	printbytepointer(z)
    312 }
    313 
    314 var ch chan *byte
    315 
    316 func f19() {
    317 	// dest temporary for channel receive.
    318 	var z *byte
    319 
    320 	if b {
    321 		z = <-ch // ERROR "live at call to chanrecv1: .autotmp_[0-9]+$"
    322 	}
    323 	z = <-ch // ERROR "live at call to chanrecv1: .autotmp_[0-9]+$"
    324 	z = <-ch // ERROR "live at call to chanrecv1: .autotmp_[0-9]+$"
    325 	printbytepointer(z)
    326 }
    327 
    328 func f20() {
    329 	// src temporary for channel send
    330 	if b {
    331 		ch <- nil // ERROR "live at call to chansend1: .autotmp_[0-9]+$"
    332 	}
    333 	ch <- nil // ERROR "live at call to chansend1: .autotmp_[0-9]+$"
    334 	ch <- nil // ERROR "live at call to chansend1: .autotmp_[0-9]+$"
    335 }
    336 
    337 func f21() {
    338 	// key temporary for mapaccess using array literal key.
    339 	var z *byte
    340 	if b {
    341 		z = m2[[2]string{"x", "y"}] // ERROR "live at call to mapaccess1: .autotmp_[0-9]+$"
    342 	}
    343 	z = m2[[2]string{"x", "y"}] // ERROR "live at call to mapaccess1: .autotmp_[0-9]+$"
    344 	z = m2[[2]string{"x", "y"}] // ERROR "live at call to mapaccess1: .autotmp_[0-9]+$"
    345 	printbytepointer(z)
    346 }
    347 
    348 func f23() {
    349 	// key temporary for two-result map access using array literal key.
    350 	var z *byte
    351 	var ok bool
    352 	if b {
    353 		z, ok = m2[[2]string{"x", "y"}] // ERROR "live at call to mapaccess2: .autotmp_[0-9]+$"
    354 	}
    355 	z, ok = m2[[2]string{"x", "y"}] // ERROR "live at call to mapaccess2: .autotmp_[0-9]+$"
    356 	z, ok = m2[[2]string{"x", "y"}] // ERROR "live at call to mapaccess2: .autotmp_[0-9]+$"
    357 	printbytepointer(z)
    358 	print(ok)
    359 }
    360 
    361 func f24() {
    362 	// key temporary for map access using array literal key.
    363 	// value temporary too.
    364 	if b {
    365 		m2[[2]string{"x", "y"}] = nil // ERROR "live at call to mapassign: .autotmp_[0-9]+$"
    366 	}
    367 	m2[[2]string{"x", "y"}] = nil // ERROR "live at call to mapassign: .autotmp_[0-9]+$"
    368 	m2[[2]string{"x", "y"}] = nil // ERROR "live at call to mapassign: .autotmp_[0-9]+$"
    369 }
    370 
    371 // defer should not cause spurious ambiguously live variables
    372 
    373 func f25(b bool) {
    374 	defer g25()
    375 	if b {
    376 		return
    377 	}
    378 	var x string
    379 	_ = &x
    380 	x = g15()      // ERROR "live at call to g15: x$"
    381 	printstring(x) // ERROR "live at call to printstring: x$"
    382 } // ERROR "live at call to deferreturn: x$"
    383 
    384 func g25()
    385 
    386 // non-escaping ... slices passed to function call should die on return,
    387 // so that the temporaries do not stack and do not cause ambiguously
    388 // live variables.
    389 
    390 func f26(b bool) {
    391 	if b {
    392 		print26((*int)(nil), (*int)(nil), (*int)(nil)) // ERROR "live at call to print26: .autotmp_[0-9]+$"
    393 	}
    394 	print26((*int)(nil), (*int)(nil), (*int)(nil)) // ERROR "live at call to print26: .autotmp_[0-9]+$"
    395 	print26((*int)(nil), (*int)(nil), (*int)(nil)) // ERROR "live at call to print26: .autotmp_[0-9]+$"
    396 	printnl()
    397 }
    398 
    399 //go:noescape
    400 func print26(...interface{})
    401 
    402 // non-escaping closures passed to function call should die on return
    403 
    404 func f27(b bool) {
    405 	x := 0
    406 	if b {
    407 		call27(func() { x++ }) // ERROR "live at call to call27: .autotmp_[0-9]+$"
    408 	}
    409 	call27(func() { x++ }) // ERROR "live at call to call27: .autotmp_[0-9]+$"
    410 	call27(func() { x++ }) // ERROR "live at call to call27: .autotmp_[0-9]+$"
    411 	printnl()
    412 }
    413 
    414 // but defer does escape to later execution in the function
    415 
    416 func f27defer(b bool) {
    417 	x := 0
    418 	if b {
    419 		defer call27(func() { x++ }) // ERROR "live at call to deferproc: .autotmp_[0-9]+$" "live at call to deferreturn: .autotmp_[0-9]+$"
    420 	}
    421 	defer call27(func() { x++ }) // ERROR "f27defer: .autotmp_[0-9]+ \(type struct { F uintptr; x \*int }\) is ambiguously live$" "live at call to deferproc: .autotmp_[0-9]+ .autotmp_[0-9]+$" "live at call to deferreturn: .autotmp_[0-9]+ .autotmp_[0-9]+$"
    422 	printnl()                    // ERROR "live at call to printnl: .autotmp_[0-9]+ .autotmp_[0-9]+$"
    423 } // ERROR "live at call to deferreturn: .autotmp_[0-9]+ .autotmp_[0-9]+$"
    424 
    425 // and newproc (go) escapes to the heap
    426 
    427 func f27go(b bool) {
    428 	x := 0
    429 	if b {
    430 		go call27(func() { x++ }) // ERROR "live at call to newobject: &x$" "live at call to newproc: &x$"
    431 	}
    432 	go call27(func() { x++ }) // ERROR "live at call to newobject: &x$"
    433 	printnl()
    434 }
    435 
    436 //go:noescape
    437 func call27(func())
    438 
    439 // concatstring slice should die on return
    440 
    441 var s1, s2, s3, s4, s5, s6, s7, s8, s9, s10 string
    442 
    443 func f28(b bool) {
    444 	if b {
    445 		printstring(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]+$"
    446 	}
    447 	printstring(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]+$"
    448 	printstring(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]+$"
    449 }
    450 
    451 // map iterator should die on end of range loop
    452 
    453 func f29(b bool) {
    454 	if b {
    455 		for k := range m { // ERROR "live at call to mapiterinit: .autotmp_[0-9]+$" "live at call to mapiternext: .autotmp_[0-9]+$"
    456 			printstring(k) // ERROR "live at call to printstring: .autotmp_[0-9]+$"
    457 		}
    458 	}
    459 	for k := range m { // ERROR "live at call to mapiterinit: .autotmp_[0-9]+$" "live at call to mapiternext: .autotmp_[0-9]+$"
    460 		printstring(k) // ERROR "live at call to printstring: .autotmp_[0-9]+$"
    461 	}
    462 	for k := range m { // ERROR "live at call to mapiterinit: .autotmp_[0-9]+$" "live at call to mapiternext: .autotmp_[0-9]+$"
    463 		printstring(k) // ERROR "live at call to printstring: .autotmp_[0-9]+$"
    464 	}
    465 }
    466 
    467 // copy of array of pointers should die at end of range loop
    468 
    469 var ptrarr [10]*int
    470 
    471 func f30(b bool) {
    472 	// two live temps during print(p):
    473 	// the copy of ptrarr and the internal iterator pointer.
    474 	if b {
    475 		for _, p := range ptrarr {
    476 			printintpointer(p) // ERROR "live at call to printintpointer: .autotmp_[0-9]+ .autotmp_[0-9]+$"
    477 		}
    478 	}
    479 	for _, p := range ptrarr {
    480 		printintpointer(p) // ERROR "live at call to printintpointer: .autotmp_[0-9]+ .autotmp_[0-9]+$"
    481 	}
    482 	for _, p := range ptrarr {
    483 		printintpointer(p) // ERROR "live at call to printintpointer: .autotmp_[0-9]+ .autotmp_[0-9]+$"
    484 	}
    485 }
    486 
    487 // conversion to interface should not leave temporary behind
    488 
    489 func f31(b1, b2, b3 bool) {
    490 	if b1 {
    491 		g31("a") // ERROR "live at call to convT2E: .autotmp_[0-9]+$" "live at call to g31: .autotmp_[0-9]+$"
    492 	}
    493 	if b2 {
    494 		h31("b") // ERROR "live at call to convT2E: .autotmp_[0-9]+ .autotmp_[0-9]+$" "live at call to h31: .autotmp_[0-9]+$" "live at call to newobject: .autotmp_[0-9]+$"
    495 	}
    496 	if b3 {
    497 		panic("asdf") // ERROR "live at call to convT2E: .autotmp_[0-9]+$" "live at call to gopanic: .autotmp_[0-9]+$"
    498 	}
    499 	print(b3)
    500 }
    501 
    502 func g31(interface{})
    503 func h31(...interface{})
    504 
    505 // non-escaping partial functions passed to function call should die on return
    506 
    507 type T32 int
    508 
    509 func (t *T32) Inc() { // ERROR "live at entry to \(\*T32\).Inc: t$"
    510 	*t++
    511 }
    512 
    513 var t32 T32
    514 
    515 func f32(b bool) {
    516 	if b {
    517 		call32(t32.Inc) // ERROR "live at call to call32: .autotmp_[0-9]+$"
    518 	}
    519 	call32(t32.Inc) // ERROR "live at call to call32: .autotmp_[0-9]+$"
    520 	call32(t32.Inc) // ERROR "live at call to call32: .autotmp_[0-9]+$"
    521 }
    522 
    523 //go:noescape
    524 func call32(func())
    525 
    526 // temporaries introduced during if conditions and && || expressions
    527 // should die once the condition has been acted upon.
    528 
    529 var m33 map[interface{}]int
    530 
    531 func f33() {
    532 	if m33[nil] == 0 { // ERROR "live at call to mapaccess1: .autotmp_[0-9]+$"
    533 		printnl()
    534 		return
    535 	} else {
    536 		printnl()
    537 	}
    538 	printnl()
    539 }
    540 
    541 func f34() {
    542 	if m33[nil] == 0 { // ERROR "live at call to mapaccess1: .autotmp_[0-9]+$"
    543 		printnl()
    544 		return
    545 	}
    546 	printnl()
    547 }
    548 
    549 func f35() {
    550 	if m33[nil] == 0 && m33[nil] == 0 { // ERROR "live at call to mapaccess1: .autotmp_[0-9]+$"
    551 		printnl()
    552 		return
    553 	}
    554 	printnl()
    555 }
    556 
    557 func f36() {
    558 	if m33[nil] == 0 || m33[nil] == 0 { // ERROR "live at call to mapaccess1: .autotmp_[0-9]+$"
    559 		printnl()
    560 		return
    561 	}
    562 	printnl()
    563 }
    564 
    565 func f37() {
    566 	if (m33[nil] == 0 || m33[nil] == 0) && m33[nil] == 0 { // ERROR "live at call to mapaccess1: .autotmp_[0-9]+$"
    567 		printnl()
    568 		return
    569 	}
    570 	printnl()
    571 }
    572 
    573 // select temps should disappear in the case bodies
    574 
    575 var c38 chan string
    576 
    577 func fc38() chan string
    578 func fi38(int) *string
    579 func fb38() *bool
    580 
    581 func f38(b bool) {
    582 	// we don't care what temps are printed on the lines with output.
    583 	// we care that the println lines have no live variables
    584 	// and therefore no output.
    585 	if b {
    586 		select { // ERROR "live at call to newselect: .autotmp_[0-9]+ .autotmp_[0-9]+ .autotmp_[0-9]+ .autotmp_[0-9]+ .autotmp_[0-9]+ .autotmp_[0-9]+ .autotmp_[0-9]+ .autotmp_[0-9]+$" "live at call to selectgo: .autotmp_[0-9]+ .autotmp_[0-9]+ .autotmp_[0-9]+ .autotmp_[0-9]+ .autotmp_[0-9]+ .autotmp_[0-9]+ .autotmp_[0-9]+$"
    587 		case <-fc38(): // ERROR "live at call to selectrecv: .autotmp_[0-9]+ .autotmp_[0-9]+ .autotmp_[0-9]+ .autotmp_[0-9]+ .autotmp_[0-9]+ .autotmp_[0-9]+ .autotmp_[0-9]+$"
    588 			printnl()
    589 		case fc38() <- *fi38(1): // ERROR "live at call to fc38: .autotmp_[0-9]+$" "live at call to fi38: .autotmp_[0-9]+ .autotmp_[0-9]+$" "live at call to selectsend: .autotmp_[0-9]+ .autotmp_[0-9]+ .autotmp_[0-9]+ .autotmp_[0-9]+ .autotmp_[0-9]+ .autotmp_[0-9]+ .autotmp_[0-9]+$"
    590 			printnl()
    591 		case *fi38(2) = <-fc38(): // ERROR "live at call to fc38: .autotmp_[0-9]+ .autotmp_[0-9]+ .autotmp_[0-9]+$" "live at call to fi38: .autotmp_[0-9]+ .autotmp_[0-9]+ .autotmp_[0-9]+$" "live at call to selectrecv: .autotmp_[0-9]+ .autotmp_[0-9]+ .autotmp_[0-9]+ .autotmp_[0-9]+ .autotmp_[0-9]+ .autotmp_[0-9]+ .autotmp_[0-9]+$"
    592 			printnl()
    593 		case *fi38(3), *fb38() = <-fc38(): // ERROR "live at call to fb38: .autotmp_[0-9]+ .autotmp_[0-9]+ .autotmp_[0-9]+$" "live at call to fc38: .autotmp_[0-9]+ .autotmp_[0-9]+ .autotmp_[0-9]+ .autotmp_[0-9]+ .autotmp_[0-9]+$" "live at call to fi38: .autotmp_[0-9]+ .autotmp_[0-9]+ .autotmp_[0-9]+$" "live at call to selectrecv2: .autotmp_[0-9]+ .autotmp_[0-9]+ .autotmp_[0-9]+ .autotmp_[0-9]+ .autotmp_[0-9]+ .autotmp_[0-9]+ .autotmp_[0-9]+$"
    594 			printnl()
    595 		}
    596 		printnl()
    597 	}
    598 	printnl()
    599 }
    600 
    601 // issue 8097: mishandling of x = x during return.
    602 
    603 func f39() (x []int) {
    604 	x = []int{1}
    605 	printnl() // ERROR "live at call to printnl: .autotmp_[0-9]+$"
    606 	return x
    607 }
    608 
    609 func f39a() (x []int) {
    610 	x = []int{1}
    611 	printnl() // ERROR "live at call to printnl: .autotmp_[0-9]+$"
    612 	return
    613 }
    614 
    615 func f39b() (x [10]*int) {
    616 	x = [10]*int{}
    617 	x[0] = new(int) // ERROR "live at call to newobject: x$"
    618 	printnl()       // ERROR "live at call to printnl: x$"
    619 	return x
    620 }
    621 
    622 func f39c() (x [10]*int) {
    623 	x = [10]*int{}
    624 	x[0] = new(int) // ERROR "live at call to newobject: x$"
    625 	printnl()       // ERROR "live at call to printnl: x$"
    626 	return
    627 }
    628 
    629 // issue 8142: lost 'addrtaken' bit on inlined variables.
    630 // no inlining in this test, so just checking that non-inlined works.
    631 
    632 type T40 struct {
    633 	m map[int]int
    634 }
    635 
    636 func newT40() *T40 {
    637 	ret := T40{}
    638 	ret.m = make(map[int]int) // ERROR "live at call to makemap: &ret$"
    639 	return &ret
    640 }
    641 
    642 func bad40() {
    643 	t := newT40()
    644 	_ = t
    645 	printnl()
    646 }
    647 
    648 func good40() {
    649 	ret := T40{}
    650 	ret.m = make(map[int]int) // ERROR "live at call to makemap: .autotmp_[0-9]+ ret$"
    651 	t := &ret
    652 	printnl() // ERROR "live at call to printnl: .autotmp_[0-9]+ ret$"
    653 	_ = t
    654 }
    655 
    656 func ddd1(x, y *int) { // ERROR "live at entry to ddd1: x y$"
    657 	ddd2(x, y) // ERROR "live at call to ddd2: .autotmp_[0-9]+$"
    658 	printnl()
    659 	// Note: no .?autotmp live at printnl.  See issue 16996.
    660 }
    661 func ddd2(a ...*int) { // ERROR "live at entry to ddd2: a$"
    662 	sink = a[0]
    663 }
    664 
    665 // issue 16016: autogenerated wrapper should have arguments live
    666 type T struct{}
    667 
    668 func (*T) Foo(ptr *int) {}
    669 
    670 type R struct{ *T } // ERRORAUTO "live at entry to \(\*R\)\.Foo: \.this ptr" "live at entry to R\.Foo: \.this ptr"
    671