github.com/hongwozai/go-src-1.4.3@v0.0.0-20191127132709-dc3fce3dbccb/test/live.go (about)

     1  // errorcheck -0 -l -live -wb=0
     2  
     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  
     7  // liveness tests with inlining disabled.
     8  // see also live2.go.
     9  
    10  package main
    11  
    12  func 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  
    18  func 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  
    28  func f3(b bool) {
    29  	// 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$"
    34  	if b == false {
    35  		print(0) // ERROR "live at call to printint: x y$"
    36  		return
    37  	}
    38  
    39  	if b {
    40  		var x *int
    41  		print(&x) // ERROR "live at call to printpointer: x y$"
    42  		print(&x) // ERROR "live at call to printpointer: x y$"
    43  	} else {
    44  		var y *int
    45  		print(&y) // ERROR "live at call to printpointer: x y$"
    46  		print(&y) // ERROR "live at call to printpointer: x y$"
    47  	}
    48  	print(0) // ERROR "live at call to printint: x y$" "x \(type \*int\) is ambiguously live" "y \(type \*int\) is ambiguously live"
    49  }
    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  
    57  func 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  
    76  func 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  	}
    87  	print(**z) // ERROR "live at call to printint: x y$" "x \(type \*int\) is ambiguously live" "y \(type \*int\) is ambiguously live"
    88  }
    89  
    90  // confusion about the _ result used to cause spurious "live at entry to f6: _".
    91  
    92  func f6() (_, y string) {
    93  	y = "hello"
    94  	return
    95  }
    96  
    97  // confusion about addressed results used to cause "live at entry to f7: x".
    98  
    99  func f7() (x string) {
   100  	_ = &x
   101  	x = "hello"
   102  	return
   103  }
   104  
   105  // ignoring block returns used to cause "live at entry to f8: x, y".
   106  
   107  func f8() (x, y string) {
   108  	return g8()
   109  }
   110  
   111  func g8() (string, string)
   112  
   113  // ignoring block assignments used to cause "live at entry to f9: x"
   114  // issue 7205
   115  
   116  var i9 interface{}
   117  
   118  func f9() bool {
   119  	g8()
   120  	x := i9
   121  	// 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"
   125  }
   126  
   127  // liveness formerly confused by UNDEF followed by RET,
   128  // leading to "live at entry to f10: ~r1" (unnamed result).
   129  
   130  func f10() string {
   131  	panic(1)
   132  }
   133  
   134  // 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  
   139  var c chan *int
   140  var b bool
   141  
   142  // this used to have a spurious "live at entry to f11a: ~r0"
   143  func f11a() *int {
   144  	select { // ERROR "live at call to newselect: autotmp" "live at call to selectgo: autotmp"
   145  	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  
   152  func 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!
   159  		select { // ERROR "live at call to newselect: autotmp" "live at call to selectgo: autotmp"
   160  		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  
   170  func 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"
   176  		select { // ERROR "live at call to newselect: autotmp.* p" "live at call to selectgo: autotmp.* p"
   177  		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  
   188  func f12() *int {
   189  	if b {
   190  		select {}
   191  	} else {
   192  		return nil
   193  	}
   194  }
   195  
   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  
   200  func f13() {
   201  	s := "hello"
   202  	s = h13(s, g13(s)) // ERROR "live at call to g13: s"
   203  }
   204  
   205  func g13(string) string
   206  func h13(string, string) string
   207  
   208  // more incorrectly placed VARDEF.
   209  
   210  func f14() {
   211  	x := g14()
   212  	print(&x) // ERROR "live at call to printpointer: x"
   213  }
   214  
   215  func g14() string
   216  
   217  func f15() {
   218  	var x string
   219  	_ = &x
   220  	x = g15() // ERROR "live at call to g15: x"
   221  	print(x)  // ERROR "live at call to printstring: x"
   222  }
   223  
   224  func g15() string
   225  
   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  
   232  var m map[string]int
   233  
   234  func 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  
   242  var m2s map[string]*byte
   243  var m2 map[[2]string]*byte
   244  var x2 [2]string
   245  var bp *byte
   246  
   247  func 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  
   256  func 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  
   265  func 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  
   274  func g18() [2]string
   275  
   276  func 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  
   288  var ch chan *byte
   289  
   290  func f19() {
   291  	// dest temporary for channel receive.
   292  	var z *byte
   293  
   294  	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  
   302  func 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  
   311  func 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  
   322  func 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  
   334  func 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  }
   343  
   344  // defer should not cause spurious ambiguously live variables
   345  
   346  func 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"
   354  	print(x)  // ERROR "live at call to printstring: x"
   355  } // ERROR "live at call to deferreturn: x"
   356  
   357  func g25()
   358  
   359  // 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  
   363  func f26(b bool) {
   364  	if b {
   365  		print26((*int)(nil), (*int)(nil), (*int)(nil)) // ERROR "live at call to print26: autotmp_[0-9]+$"
   366  	}
   367  	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]+$"
   369  	println()
   370  }
   371  
   372  //go:noescape
   373  func print26(...interface{})
   374  
   375  // non-escaping closures passed to function call should die on return
   376  
   377  func f27(b bool) {
   378  	x := 0
   379  	if b {
   380  		call27(func() { x++ }) // ERROR "live at call to call27: autotmp_[0-9]+$"
   381  	}
   382  	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]+$"
   384  	println()
   385  }
   386  
   387  // but defer does escape to later execution in the function
   388  
   389  func f27defer(b bool) {
   390  	x := 0
   391  	if b {
   392  		defer call27(func() { x++ }) // ERROR "live at call to deferproc: autotmp_[0-9]+$" "live at call to deferreturn: autotmp_[0-9]+$"
   393  	}
   394  	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]+$"
   396  } // ERROR "live at call to deferreturn: autotmp_[0-9]+ autotmp_[0-9]+$"
   397  
   398  // and newproc (go) escapes to the heap
   399  
   400  func f27go(b bool) {
   401  	x := 0
   402  	if b {
   403  		go call27(func() { x++ }) // ERROR "live at call to newobject: &x" "live at call to newproc: &x$"
   404  	}
   405  	go call27(func() { x++ }) // ERROR "live at call to newobject: &x"
   406  	println()
   407  }
   408  
   409  //go:noescape
   410  func call27(func())
   411  
   412  // concatstring slice should die on return
   413  
   414  var s1, s2, s3, s4, s5, s6, s7, s8, s9, s10 string
   415  
   416  func f28(b bool) {
   417  	if b {
   418  		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]+$"
   419  	}
   420  	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  }
   423  
   424  // map iterator should die on end of range loop
   425  
   426  func 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  
   442  var ptrarr [10]*int
   443  
   444  func 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  }
   459  
   460  // conversion to interface should not leave temporary behind
   461  
   462  func 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 {
   467  		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]+$"
   468  	}
   469  	if b3 {
   470  		panic("asdf") // ERROR "live at call to convT2E: autotmp_[0-9]+$" "live at call to gopanic: autotmp_[0-9]+$"
   471  	}
   472  	print(b3)
   473  }
   474  
   475  func g31(interface{})
   476  func h31(...interface{})
   477  
   478  // non-escaping partial functions passed to function call should die on return
   479  
   480  type T32 int
   481  
   482  func (t *T32) Inc() { // ERROR "live at entry"
   483  	*t++
   484  }
   485  
   486  var t32 T32
   487  
   488  func 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
   497  func call32(func())
   498  
   499  // temporaries introduced during if conditions and && || expressions
   500  // should die once the condition has been acted upon.
   501  
   502  var m33 map[interface{}]int
   503  
   504  func 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  
   514  func f34() {
   515  	if m33[nil] == 0 { // ERROR "live at call to mapaccess1: autotmp_[0-9]+$"
   516  		println()
   517  		return
   518  	}
   519  	println()
   520  }
   521  
   522  func 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  
   530  func 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  
   538  func 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  
   548  var c38 chan string
   549  
   550  func fc38() chan string
   551  func fi38(int) *string
   552  func fb38() *bool
   553  
   554  func 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  }
   573  
   574  // issue 8097: mishandling of x = x during return.
   575  
   576  func f39() (x []int) {
   577  	x = []int{1}
   578  	println() // ERROR "live at call to printnl: x"
   579  	return x
   580  }
   581  
   582  func f39a() (x []int) {
   583  	x = []int{1}
   584  	println() // ERROR "live at call to printnl: x"
   585  	return
   586  }
   587  
   588  func f39b() (x [10]*int) {
   589  	x = [10]*int{}
   590  	x[0] = new(int) // ERROR "live at call to newobject: x"
   591  	println()       // ERROR "live at call to printnl: x"
   592  	return x
   593  }
   594  
   595  func f39c() (x [10]*int) {
   596  	x = [10]*int{}
   597  	x[0] = new(int) // ERROR "live at call to newobject: x"
   598  	println()       // ERROR "live at call to printnl: x"
   599  	return
   600  }
   601  
   602  // issue 8142: lost 'addrtaken' bit on inlined variables.
   603  // no inlining in this test, so just checking that non-inlined works.
   604  
   605  type T40 struct {
   606  	m map[int]int
   607  }
   608  
   609  func newT40() *T40 {
   610  	ret := T40{}
   611  	ret.m = make(map[int]int) // ERROR "live at call to makemap: &ret"
   612  	return &ret
   613  }
   614  
   615  func bad40() {
   616  	t := newT40()
   617  	println()
   618  	_ = t
   619  }
   620  
   621  func good40() {
   622  	ret := T40{}
   623  	ret.m = make(map[int]int) // ERROR "live at call to makemap: ret"
   624  	t := &ret
   625  	println() // ERROR "live at call to printnl: ret"
   626  	_ = t
   627  }