blob: aa7f9a8f8592e4dd0567f535ef5e15d728cb3f6e [file] [log] [blame]
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 f10() {
s0 := make([]string, 0)
if s0 == nil { // want "impossible condition: non-nil == nil"
print(0)
}
var s1 []string
if s1 == nil { // want "tautological condition: nil == nil"
print(0)
}
s2 := s1[:][:]
if s2 == nil { // want "tautological condition: nil == nil"
print(0)
}
}
func unknown() bool {
return false
}
func f11(a interface{}) {
switch a.(type) {
case nil:
return
}
switch a.(type) {
case nil: // want "impossible condition: non-nil == nil"
return
}
}
func f12(a interface{}) {
switch a {
case nil:
return
}
switch a {
case 5,
nil: // want "impossible condition: non-nil == nil"
return
}
}
type Y struct {
innerY
}
type innerY struct {
value int
}
func f13() {
var d *Y
print(d.value) // want "nil dereference in field selection"
}