package a type X struct{ f, g int } func f(x, y *X) { if x == nil { print(x.f) // want "nil dereference in field selection" } else { print(x.f) } if x == nil { if nil != y { print(1) panic(0) } x.f = 1 // want "nil dereference in field selection" y.f = 1 // want "nil dereference in field selection" } var f func() if f == nil { // want "tautological condition: nil == nil" go f() // want "nil dereference in dynamic function call" } else { // This block is unreachable, // so we don't report an error for the // nil dereference in the call. defer f() } } func f2(ptr *[3]int, i interface{}) { if ptr != nil { print(ptr[:]) *ptr = [3]int{} print(*ptr) } else { print(ptr[:]) // want "nil dereference in slice operation" *ptr = [3]int{} // want "nil dereference in store" print(*ptr) // want "nil dereference in load" if ptr != nil { // want "impossible condition: nil != nil" // Dominated by ptr==nil and ptr!=nil, // this block is unreachable. // We do not report errors within it. print(*ptr) } } if i != nil { print(i.(interface{ f() })) } else { print(i.(interface{ f() })) // want "nil dereference in type assertion" } } func g() error func f3() error { err := g() if err != nil { return err } if err != nil && err.Error() == "foo" { // want "impossible condition: nil != nil" print(0) } ch := make(chan int) if ch == nil { // want "impossible condition: non-nil == nil" print(0) } if ch != nil { // want "tautological condition: non-nil != nil" print(0) } return nil } func h(err error, b bool) { if err != nil && b { return } else if err != nil { panic(err) } } func i(*int) error { for { if err := g(); err != nil { return err } } } func f4(x *X) { if x == nil { panic(x) } } func f5(x *X) { panic(nil) // want "panic with nil value" } func f6(x *X) { var err error panic(err) // want "panic with nil value" } func f7() { x, err := bad() if err != nil { panic(0) } if x == nil { panic(err) // want "panic with nil value" } } func bad() (*X, error) { return nil, nil } func f8() { var e error v, _ := e.(interface{}) print(v) } func f9(x interface { a() b() c() }) { x.b() // we don't catch this panic because we don't have any facts yet xx := interface { a() b() }(x) if xx != nil { return } x.c() // want "nil dereference in dynamic method call" xx.b() // want "nil dereference in dynamic method call" xxx := interface{ a() }(xx) xxx.a() // want "nil dereference in dynamic method call" if unknown() { panic(x) // want "panic with nil value" } if unknown() { panic(xx) // want "panic with nil value" } if unknown() { panic(xxx) // want "panic with nil value" } } func unknown() bool { return false }