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{}(str()) // ERROR "live at call to convT2Estring: .autotmp_[0-9]+ x.data x.type$" "live at call to str: 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 // Checking that various temporaries do not persist or cause
    243 // ambiguously live values that must be zeroed.
    244 // The exact temporary names are inconsequential but we are
    245 // trying to check that there is only one at any given site,
    246 // and also that none show up in "ambiguously live" messages.
    247 
    248 var m map[string]int
    249 var mi map[interface{}]int
    250 
    251 // str and iface are used to ensure that a temp is required for runtime calls below.
    252 func str() string
    253 func iface() interface{}
    254 
    255 func f16() {
    256 	if b {
    257 		delete(mi, iface()) // ERROR "live at call to mapdelete: .autotmp_[0-9]+$"
    258 	}
    259 	delete(mi, iface()) // ERROR "live at call to mapdelete: .autotmp_[0-9]+$"
    260 	delete(mi, iface()) // ERROR "live at call to mapdelete: .autotmp_[0-9]+$"
    261 }
    262 
    263 var m2s map[string]*byte
    264 var m2 map[[2]string]*byte
    265 var x2 [2]string
    266 var bp *byte
    267 
    268 func f17a(p *byte) { // ERROR "live at entry to f17a: p$"
    269 	if b {
    270 		m2[x2] = p // ERROR "live at call to mapassign: p$"
    271 	}
    272 	m2[x2] = p // ERROR "live at call to mapassign: p$"
    273 	m2[x2] = p // ERROR "live at call to mapassign: p$"
    274 }
    275 
    276 func f17b(p *byte) { // ERROR "live at entry to f17b: p$"
    277 	// key temporary
    278 	if b {
    279 		m2s[str()] = p // ERROR "live at call to mapassign_faststr: p$" "live at call to str: p$"
    280 	}
    281 	m2s[str()] = p // ERROR "live at call to mapassign_faststr: p$" "live at call to str: p$"
    282 	m2s[str()] = p // ERROR "live at call to mapassign_faststr: p$" "live at call to str: p$"
    283 }
    284 
    285 func f17c() {
    286 	// key and value temporaries
    287 	if b {
    288 		m2s[str()] = f17d() // ERROR "live at call to f17d: .autotmp_[0-9]+$" "live at call to mapassign_faststr: .autotmp_[0-9]+$"
    289 	}
    290 	m2s[str()] = f17d() // ERROR "live at call to f17d: .autotmp_[0-9]+$" "live at call to mapassign_faststr: .autotmp_[0-9]+$"
    291 	m2s[str()] = f17d() // ERROR "live at call to f17d: .autotmp_[0-9]+$" "live at call to mapassign_faststr: .autotmp_[0-9]+$"
    292 }
    293 
    294 func f17d() *byte
    295 
    296 func g18() [2]string
    297 
    298 func f18() {
    299 	// key temporary for mapaccess.
    300 	// temporary introduced by orderexpr.
    301 	var z *byte
    302 	if b {
    303 		z = m2[g18()] // ERROR "live at call to mapaccess1: .autotmp_[0-9]+$"
    304 	}
    305 	z = m2[g18()] // ERROR "live at call to mapaccess1: .autotmp_[0-9]+$"
    306 	z = m2[g18()] // ERROR "live at call to mapaccess1: .autotmp_[0-9]+$"
    307 	printbytepointer(z)
    308 }
    309 
    310 var ch chan *byte
    311 
    312 // byteptr is used to ensure that a temp is required for runtime calls below.
    313 func byteptr() *byte
    314 
    315 func f19() {
    316 	// dest temporary for channel receive.
    317 	var z *byte
    318 
    319 	if b {
    320 		z = <-ch // ERROR "live at call to chanrecv1: .autotmp_[0-9]+$"
    321 	}
    322 	z = <-ch // ERROR "live at call to chanrecv1: .autotmp_[0-9]+$"
    323 	z = <-ch // ERROR "live at call to chanrecv1: .autotmp_[0-9]+$"
    324 	printbytepointer(z)
    325 }
    326 
    327 func f20() {
    328 	// src temporary for channel send
    329 	if b {
    330 		ch <- byteptr() // ERROR "live at call to chansend1: .autotmp_[0-9]+$"
    331 	}
    332 	ch <- byteptr() // ERROR "live at call to chansend1: .autotmp_[0-9]+$"
    333 	ch <- byteptr() // ERROR "live at call to chansend1: .autotmp_[0-9]+$"
    334 }
    335 
    336 func f21() {
    337 	// key temporary for mapaccess using array literal key.
    338 	var z *byte
    339 	if b {
    340 		z = m2[[2]string{"x", "y"}] // ERROR "live at call to mapaccess1: .autotmp_[0-9]+$"
    341 	}
    342 	z = m2[[2]string{"x", "y"}] // ERROR "live at call to mapaccess1: .autotmp_[0-9]+$"
    343 	z = m2[[2]string{"x", "y"}] // ERROR "live at call to mapaccess1: .autotmp_[0-9]+$"
    344 	printbytepointer(z)
    345 }
    346 
    347 func f23() {
    348 	// key temporary for two-result map access using array literal key.
    349 	var z *byte
    350 	var ok bool
    351 	if b {
    352 		z, ok = m2[[2]string{"x", "y"}] // ERROR "live at call to mapaccess2: .autotmp_[0-9]+$"
    353 	}
    354 	z, ok = m2[[2]string{"x", "y"}] // ERROR "live at call to mapaccess2: .autotmp_[0-9]+$"
    355 	z, ok = m2[[2]string{"x", "y"}] // ERROR "live at call to mapaccess2: .autotmp_[0-9]+$"
    356 	printbytepointer(z)
    357 	print(ok)
    358 }
    359 
    360 func f24() {
    361 	// key temporary for map access using array literal key.
    362 	// value temporary too.
    363 	if b {
    364 		m2[[2]string{"x", "y"}] = nil // ERROR "live at call to mapassign: .autotmp_[0-9]+$"
    365 	}
    366 	m2[[2]string{"x", "y"}] = nil // ERROR "live at call to mapassign: .autotmp_[0-9]+$"
    367 	m2[[2]string{"x", "y"}] = nil // ERROR "live at call to mapassign: .autotmp_[0-9]+$"
    368 }
    369 
    370 // defer should not cause spurious ambiguously live variables
    371 
    372 func f25(b bool) {
    373 	defer g25()
    374 	if b {
    375 		return
    376 	}
    377 	var x string
    378 	x = g14()
    379 	printstring(x)
    380 }
    381 
    382 func g25()
    383 
    384 // non-escaping ... slices passed to function call should die on return,
    385 // so that the temporaries do not stack and do not cause ambiguously
    386 // live variables.
    387 
    388 func f26(b bool) {
    389 	if b {
    390 		print26((*int)(nil), (*int)(nil), (*int)(nil)) // ERROR "live at call to print26: .autotmp_[0-9]+$"
    391 	}
    392 	print26((*int)(nil), (*int)(nil), (*int)(nil)) // ERROR "live at call to print26: .autotmp_[0-9]+$"
    393 	print26((*int)(nil), (*int)(nil), (*int)(nil)) // ERROR "live at call to print26: .autotmp_[0-9]+$"
    394 	printnl()
    395 }
    396 
    397 //go:noescape
    398 func print26(...interface{})
    399 
    400 // non-escaping closures passed to function call should die on return
    401 
    402 func f27(b bool) {
    403 	x := 0
    404 	if b {
    405 		call27(func() { x++ }) // ERROR "live at call to call27: .autotmp_[0-9]+$"
    406 	}
    407 	call27(func() { x++ }) // ERROR "live at call to call27: .autotmp_[0-9]+$"
    408 	call27(func() { x++ }) // ERROR "live at call to call27: .autotmp_[0-9]+$"
    409 	printnl()
    410 }
    411 
    412 // but defer does escape to later execution in the function
    413 
    414 func f27defer(b bool) {
    415 	x := 0
    416 	if b {
    417 		defer call27(func() { x++ }) // ERROR "live at call to deferproc: .autotmp_[0-9]+$" "live at call to deferreturn: .autotmp_[0-9]+$"
    418 	}
    419 	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]+$"
    420 	printnl()                    // ERROR "live at call to printnl: .autotmp_[0-9]+ .autotmp_[0-9]+$"
    421 } // ERROR "live at call to deferreturn: .autotmp_[0-9]+ .autotmp_[0-9]+$"
    422 
    423 // and newproc (go) escapes to the heap
    424 
    425 func f27go(b bool) {
    426 	x := 0
    427 	if b {
    428 		go call27(func() { x++ }) // ERROR "live at call to newobject: &x$" "live at call to newproc: &x$"
    429 	}
    430 	go call27(func() { x++ }) // ERROR "live at call to newobject: &x$"
    431 	printnl()
    432 }
    433 
    434 //go:noescape
    435 func call27(func())
    436 
    437 // concatstring slice should die on return
    438 
    439 var s1, s2, s3, s4, s5, s6, s7, s8, s9, s10 string
    440 
    441 func f28(b bool) {
    442 	if b {
    443 		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]+$"
    444 	}
    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 	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]+$"
    447 }
    448 
    449 // map iterator should die on end of range loop
    450 
    451 func f29(b bool) {
    452 	if b {
    453 		for k := range m { // ERROR "live at call to mapiterinit: .autotmp_[0-9]+$" "live at call to mapiternext: .autotmp_[0-9]+$"
    454 			printstring(k) // ERROR "live at call to printstring: .autotmp_[0-9]+$"
    455 		}
    456 	}
    457 	for k := range m { // ERROR "live at call to mapiterinit: .autotmp_[0-9]+$" "live at call to mapiternext: .autotmp_[0-9]+$"
    458 		printstring(k) // ERROR "live at call to printstring: .autotmp_[0-9]+$"
    459 	}
    460 	for k := range m { // ERROR "live at call to mapiterinit: .autotmp_[0-9]+$" "live at call to mapiternext: .autotmp_[0-9]+$"
    461 		printstring(k) // ERROR "live at call to printstring: .autotmp_[0-9]+$"
    462 	}
    463 }
    464 
    465 // copy of array of pointers should die at end of range loop
    466 var pstructarr [10]pstruct
    467 
    468 // Struct size choosen to make pointer to element in pstructarr
    469 // not computable by strength reduction.
    470 type pstruct struct {
    471 	intp *int
    472 	_    [8]byte
    473 }
    474 
    475 func f30(b bool) {
    476 	// two live temps during printintpointer(p):
    477 	// in the copy of p.intp and
    478 	// the internal iterator pointer if a pointer to pstruct in pstructarr
    479 	// can not be easily computed by strength reduction.
    480 	if b {
    481 		for _, p := range pstructarr {
    482 			printintpointer(p.intp) // ERROR "live at call to printintpointer: .autotmp_[0-9]+ .autotmp_[0-9]+$"
    483 		}
    484 	}
    485 	for _, p := range pstructarr {
    486 		printintpointer(p.intp) // ERROR "live at call to printintpointer: .autotmp_[0-9]+ .autotmp_[0-9]+$"
    487 	}
    488 	for _, p := range pstructarr {
    489 		printintpointer(p.intp) // ERROR "live at call to printintpointer: .autotmp_[0-9]+ .autotmp_[0-9]+$"
    490 	}
    491 }
    492 
    493 // conversion to interface should not leave temporary behind
    494 
    495 func f31(b1, b2, b3 bool) {
    496 	if b1 {
    497 		g31(str()) // ERROR "live at call to convT2Estring: .autotmp_[0-9]+$" "live at call to g31: .autotmp_[0-9]+$"
    498 	}
    499 	if b2 {
    500 		h31(str()) // ERROR "live at call to convT2Estring: .autotmp_[0-9]+ .autotmp_[0-9]+$" "live at call to h31: .autotmp_[0-9]+$" "live at call to newobject: .autotmp_[0-9]+$"
    501 	}
    502 	if b3 {
    503 		panic(str()) // ERROR "live at call to convT2Estring: .autotmp_[0-9]+$" "live at call to gopanic: .autotmp_[0-9]+$"
    504 	}
    505 	print(b3)
    506 }
    507 
    508 func g31(interface{})
    509 func h31(...interface{})
    510 
    511 // non-escaping partial functions passed to function call should die on return
    512 
    513 type T32 int
    514 
    515 func (t *T32) Inc() { // ERROR "live at entry to \(\*T32\).Inc: t$"
    516 	*t++
    517 }
    518 
    519 var t32 T32
    520 
    521 func f32(b bool) {
    522 	if b {
    523 		call32(t32.Inc) // ERROR "live at call to call32: .autotmp_[0-9]+$"
    524 	}
    525 	call32(t32.Inc) // ERROR "live at call to call32: .autotmp_[0-9]+$"
    526 	call32(t32.Inc) // ERROR "live at call to call32: .autotmp_[0-9]+$"
    527 }
    528 
    529 //go:noescape
    530 func call32(func())
    531 
    532 // temporaries introduced during if conditions and && || expressions
    533 // should die once the condition has been acted upon.
    534 
    535 var m33 map[interface{}]int
    536 
    537 func f33() {
    538 	if m33[byteptr()] == 0 { // ERROR "live at call to mapaccess1: .autotmp_[0-9]+$"
    539 		printnl()
    540 		return
    541 	} else {
    542 		printnl()
    543 	}
    544 	printnl()
    545 }
    546 
    547 func f34() {
    548 	if m33[byteptr()] == 0 { // ERROR "live at call to mapaccess1: .autotmp_[0-9]+$"
    549 		printnl()
    550 		return
    551 	}
    552 	printnl()
    553 }
    554 
    555 func f35() {
    556 	if m33[byteptr()] == 0 && m33[byteptr()] == 0 { // ERROR "live at call to mapaccess1: .autotmp_[0-9]+$"
    557 		printnl()
    558 		return
    559 	}
    560 	printnl()
    561 }
    562 
    563 func f36() {
    564 	if m33[byteptr()] == 0 || m33[byteptr()] == 0 { // ERROR "live at call to mapaccess1: .autotmp_[0-9]+$"
    565 		printnl()
    566 		return
    567 	}
    568 	printnl()
    569 }
    570 
    571 func f37() {
    572 	if (m33[byteptr()] == 0 || m33[byteptr()] == 0) && m33[byteptr()] == 0 { // ERROR "live at call to mapaccess1: .autotmp_[0-9]+$"
    573 		printnl()
    574 		return
    575 	}
    576 	printnl()
    577 }
    578 
    579 // select temps should disappear in the case bodies
    580 
    581 var c38 chan string
    582 
    583 func fc38() chan string
    584 func fi38(int) *string
    585 func fb38() *bool
    586 
    587 func f38(b bool) {
    588 	// we don't care what temps are printed on the lines with output.
    589 	// we care that the println lines have no live variables
    590 	// and therefore no output.
    591 	if b {
    592 		select { // ERROR "live at call to newselect:( .autotmp_[0-9]+)+$" "live at call to selectgo:( .autotmp_[0-9]+)+$"
    593 		case <-fc38(): // ERROR "live at call to selectrecv:( .autotmp_[0-9]+)+$"
    594 			printnl()
    595 		case fc38() <- *fi38(1): // ERROR "live at call to fc38:( .autotmp_[0-9]+)+$" "live at call to fi38:( .autotmp_[0-9]+)+$" "live at call to selectsend:( .autotmp_[0-9]+)+$"
    596 			printnl()
    597 		case *fi38(2) = <-fc38(): // ERROR "live at call to fc38:( .autotmp_[0-9]+)+$" "live at call to fi38:( .autotmp_[0-9]+)+$" "live at call to selectrecv:( .autotmp_[0-9]+)+$"
    598 			printnl()
    599 		case *fi38(3), *fb38() = <-fc38(): // ERROR "live at call to fb38:( .autotmp_[0-9]+)+$" "live at call to fc38:( .autotmp_[0-9]+)+$" "live at call to fi38:( .autotmp_[0-9]+)+$" "live at call to selectrecv:( .autotmp_[0-9]+)+$"
    600 			printnl()
    601 		}
    602 		printnl()
    603 	}
    604 	printnl()
    605 }
    606 
    607 // issue 8097: mishandling of x = x during return.
    608 
    609 func f39() (x []int) {
    610 	x = []int{1}
    611 	printnl() // ERROR "live at call to printnl: .autotmp_[0-9]+$"
    612 	return x
    613 }
    614 
    615 func f39a() (x []int) {
    616 	x = []int{1}
    617 	printnl() // ERROR "live at call to printnl: .autotmp_[0-9]+$"
    618 	return
    619 }
    620 
    621 func f39b() (x [10]*int) {
    622 	x = [10]*int{}
    623 	x[0] = new(int) // ERROR "live at call to newobject: x$"
    624 	printnl()       // ERROR "live at call to printnl: x$"
    625 	return x
    626 }
    627 
    628 func f39c() (x [10]*int) {
    629 	x = [10]*int{}
    630 	x[0] = new(int) // ERROR "live at call to newobject: x$"
    631 	printnl()       // ERROR "live at call to printnl: x$"
    632 	return
    633 }
    634 
    635 // issue 8142: lost 'addrtaken' bit on inlined variables.
    636 // no inlining in this test, so just checking that non-inlined works.
    637 
    638 type T40 struct {
    639 	m map[int]int
    640 }
    641 
    642 //go:noescape
    643 func useT40(*T40)
    644 
    645 func newT40() *T40 {
    646 	ret := T40{}
    647 	ret.m = make(map[int]int, 42) // ERROR "live at call to makemap: &ret$"
    648 	return &ret
    649 }
    650 
    651 func bad40() {
    652 	t := newT40()
    653 	_ = t
    654 	printnl()
    655 }
    656 
    657 func good40() {
    658 	ret := T40{}
    659 	ret.m = make(map[int]int) // ERROR "live at call to fastrand: .autotmp_[0-9]+ ret$"
    660 	t := &ret
    661 	printnl() // ERROR "live at call to printnl: .autotmp_[0-9]+ ret$"
    662 	useT40(t) // ERROR "live at call to useT40: .autotmp_[0-9]+ ret$"
    663 }
    664 
    665 func ddd1(x, y *int) { // ERROR "live at entry to ddd1: x y$"
    666 	ddd2(x, y) // ERROR "live at call to ddd2: .autotmp_[0-9]+$"
    667 	printnl()
    668 	// Note: no .?autotmp live at printnl.  See issue 16996.
    669 }
    670 func ddd2(a ...*int) { // ERROR "live at entry to ddd2: a$"
    671 	sink = a[0]
    672 }
    673 
    674 // issue 16016: autogenerated wrapper should have arguments live
    675 type T struct{}
    676 
    677 func (*T) Foo(ptr *int) {}
    678 
    679 type R struct{ *T } // ERRORAUTO "live at entry to \(\*R\)\.Foo: \.this ptr" "live at entry to R\.Foo: \.this ptr"
    680 
    681 // issue 18860: output arguments must be live all the time if there is a defer.
    682 // In particular, at printint r must be live.
    683 func f41(p, q *int) (r *int) { // ERROR "live at entry to f41: p q$"
    684 	r = p
    685 	defer func() { // ERROR "live at call to deferproc: q r$" "live at call to deferreturn: r$"
    686 		recover()
    687 	}()
    688 	printint(0) // ERROR "live at call to printint: q r$"
    689 	r = q
    690 	return // ERROR "live at call to deferreturn: r$"
    691 }
    692