github.com/4ad/go@v0.0.0-20161219182952-69a12818b605/test/live_ssa.go (about)

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