golang.org/x/tools@v0.21.0/go/analysis/passes/nilness/testdata/src/a/a.go (about)

     1  package a
     2  
     3  type X struct{ f, g int }
     4  
     5  func f(x, y *X) {
     6  	if x == nil {
     7  		print(x.f) // want "nil dereference in field selection"
     8  	} else {
     9  		print(x.f)
    10  	}
    11  
    12  	if x == nil {
    13  		if nil != y {
    14  			print(1)
    15  			panic(0)
    16  		}
    17  		x.f = 1 // want "nil dereference in field selection"
    18  		y.f = 1 // want "nil dereference in field selection"
    19  	}
    20  
    21  	var f func()
    22  	if f == nil { // want "tautological condition: nil == nil"
    23  		go f() // want "nil dereference in dynamic function call"
    24  	} else {
    25  		// This block is unreachable,
    26  		// so we don't report an error for the
    27  		// nil dereference in the call.
    28  		defer f()
    29  	}
    30  }
    31  
    32  func f2(ptr *[3]int, i interface{}) {
    33  	if ptr != nil {
    34  		print(ptr[:])
    35  		*ptr = [3]int{}
    36  		print(*ptr)
    37  	} else {
    38  		print(ptr[:])   // want "nil dereference in slice operation"
    39  		*ptr = [3]int{} // want "nil dereference in store"
    40  		print(*ptr)     // want "nil dereference in load"
    41  
    42  		if ptr != nil { // want "impossible condition: nil != nil"
    43  			// Dominated by ptr==nil and ptr!=nil,
    44  			// this block is unreachable.
    45  			// We do not report errors within it.
    46  			print(*ptr)
    47  		}
    48  	}
    49  
    50  	if i != nil {
    51  		print(i.(interface{ f() }))
    52  	} else {
    53  		print(i.(interface{ f() })) // want "nil dereference in type assertion"
    54  	}
    55  }
    56  
    57  func g() error { return nil }
    58  
    59  func f3() error {
    60  	err := g()
    61  	if err != nil {
    62  		return err
    63  	}
    64  	if err != nil && err.Error() == "foo" { // want "impossible condition: nil != nil"
    65  		print(0)
    66  	}
    67  	ch := make(chan int)
    68  	if ch == nil { // want "impossible condition: non-nil == nil"
    69  		print(0)
    70  	}
    71  	if ch != nil { // want "tautological condition: non-nil != nil"
    72  		print(0)
    73  	}
    74  	return nil
    75  }
    76  
    77  func h(err error, b bool) {
    78  	if err != nil && b {
    79  		return
    80  	} else if err != nil {
    81  		panic(err)
    82  	}
    83  }
    84  
    85  func i(*int) error {
    86  	for {
    87  		if err := g(); err != nil {
    88  			return err
    89  		}
    90  	}
    91  }
    92  
    93  func f4(x *X) {
    94  	if x == nil {
    95  		panic(x)
    96  	}
    97  }
    98  
    99  func f5(x *X) {
   100  	panic(nil) // want "panic with nil value"
   101  }
   102  
   103  func f6(x *X) {
   104  	var err error
   105  	panic(err) // want "panic with nil value"
   106  }
   107  
   108  func f7() {
   109  	x, err := bad()
   110  	if err != nil {
   111  		panic(0)
   112  	}
   113  	if x == nil {
   114  		panic(err) // want "panic with nil value"
   115  	}
   116  }
   117  
   118  func bad() (*X, error) {
   119  	return nil, nil
   120  }
   121  
   122  func f8() {
   123  	var e error
   124  	v, _ := e.(interface{})
   125  	print(v)
   126  }
   127  
   128  func f9(x interface {
   129  	a()
   130  	b()
   131  	c()
   132  }) {
   133  	x.b() // we don't catch this panic because we don't have any facts yet
   134  	xx := interface {
   135  		a()
   136  		b()
   137  	}(x)
   138  	if xx != nil {
   139  		return
   140  	}
   141  	x.c()  // want "nil dereference in dynamic method call"
   142  	xx.b() // want "nil dereference in dynamic method call"
   143  	xxx := interface{ a() }(xx)
   144  	xxx.a() // want "nil dereference in dynamic method call"
   145  
   146  	if unknown() {
   147  		panic(x) // want "panic with nil value"
   148  	}
   149  	if unknown() {
   150  		panic(xx) // want "panic with nil value"
   151  	}
   152  	if unknown() {
   153  		panic(xxx) // want "panic with nil value"
   154  	}
   155  }
   156  
   157  func f10() {
   158  	s0 := make([]string, 0)
   159  	if s0 == nil { // want "impossible condition: non-nil == nil"
   160  		print(0)
   161  	}
   162  
   163  	var s1 []string
   164  	if s1 == nil { // want "tautological condition: nil == nil"
   165  		print(0)
   166  	}
   167  	s2 := s1[:][:]
   168  	if s2 == nil { // want "tautological condition: nil == nil"
   169  		print(0)
   170  	}
   171  }
   172  
   173  func unknown() bool {
   174  	return false
   175  }
   176  
   177  func f11(a interface{}) {
   178  	switch a.(type) {
   179  	case nil:
   180  		return
   181  	}
   182  	switch a.(type) {
   183  	case nil: // want "impossible condition: non-nil == nil"
   184  		return
   185  	}
   186  }
   187  
   188  func f12(a interface{}) {
   189  	switch a {
   190  	case nil:
   191  		return
   192  	}
   193  	switch a {
   194  	case 5,
   195  		nil: // want "impossible condition: non-nil == nil"
   196  		return
   197  	}
   198  }
   199  
   200  type Y struct {
   201  	innerY
   202  }
   203  
   204  type innerY struct {
   205  	value int
   206  }
   207  
   208  func f13() {
   209  	var d *Y
   210  	print(d.value) // want "nil dereference in field selection"
   211  }
   212  
   213  func f14() {
   214  	var x struct{ f string }
   215  	if x == struct{ f string }{} { // we don't catch this tautology as we restrict to reference types
   216  		print(x)
   217  	}
   218  }
   219  
   220  func f15(x any) {
   221  	ptr, ok := x.(*int)
   222  	if ok {
   223  		return
   224  	}
   225  	println(*ptr) // want "nil dereference in load"
   226  }
   227  
   228  func f16(x any) {
   229  	ptr, ok := x.(*int)
   230  	if !ok {
   231  		println(*ptr) // want "nil dereference in load"
   232  		return
   233  	}
   234  	println(*ptr)
   235  }
   236  
   237  func f18(x any) {
   238  	ptr, ok := x.(*int)
   239  	if ok {
   240  		println(ptr)
   241  		// falls through
   242  	}
   243  	println(*ptr)
   244  }
   245  
   246  // Regression test for https://github.com/golang/go/issues/65674:
   247  // spurious "nil deference in slice index operation" when the
   248  // index was subject to a range loop.
   249  func f19(slice []int, array *[2]int, m map[string]int, ch chan int) {
   250  	if slice == nil {
   251  		// A range over a nil slice is dynamically benign,
   252  		// but still signifies a programmer mistake.
   253  		//
   254  		// Since SSA has melted down the control structure,
   255  		// so we can only report a diagnostic about the
   256  		// index operation, with heuristics for "range".
   257  
   258  		for range slice { // nothing to report here
   259  		}
   260  		for _, v := range slice { // want "range of nil slice"
   261  			_ = v
   262  		}
   263  		for i := range slice {
   264  			_ = slice[i] // want "range of nil slice"
   265  		}
   266  		{
   267  			var i int
   268  			for i = range slice {
   269  			}
   270  			_ = slice[i] // want "index of nil slice"
   271  		}
   272  		for i := range slice {
   273  			if i < len(slice) {
   274  				_ = slice[i] // want "range of nil slice"
   275  			}
   276  		}
   277  		if len(slice) > 3 {
   278  			_ = slice[2] // want "index of nil slice"
   279  		}
   280  		for i := 0; i < len(slice); i++ {
   281  			_ = slice[i] // want "index of nil slice"
   282  		}
   283  	}
   284  
   285  	if array == nil {
   286  		// (The v var is necessary, otherwise the SSA
   287  		// code doesn't dereference the pointer.)
   288  		for _, v := range array { // want "nil dereference in array index operation"
   289  			_ = v
   290  		}
   291  	}
   292  
   293  	if m == nil {
   294  		for range m { // want "range over nil map"
   295  		}
   296  		m["one"] = 1 // want "nil dereference in map update"
   297  	}
   298  
   299  	if ch == nil {
   300  		for range ch { // want "receive from nil channel"
   301  		}
   302  		<-ch    // want "receive from nil channel"
   303  		ch <- 0 // want "send to nil channel"
   304  	}
   305  }