From f3761a684f14e1051b67a926faa7bfbc3d6f802d Mon Sep 17 00:00:00 2001 From: Dominik Honnef Date: Thu, 15 Jul 2021 06:45:18 +0200 Subject: [PATCH] SA5011: don't flag indexing of possibly nil slice Indexing a nil slice doesn't cause a nil pointer dereference, "only" an out of bounds. This fix also acts as a workaround for gh-1051 and gh-1053. Closes gh-1051 Updates gh-1053 (cherry picked from commit 4e580ec70dec9aa41a9bb59d244ef178a1a3ed06) --- staticcheck/lint.go | 7 ++++ .../src/CheckMaybeNil/CheckMaybeNil.go | 33 +++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/staticcheck/lint.go b/staticcheck/lint.go index 2795488d5..40ca2c131 100644 --- a/staticcheck/lint.go +++ b/staticcheck/lint.go @@ -4099,6 +4099,13 @@ func CheckMaybeNil(pass *analysis.Pass) (interface{}, error) { ptr = instr.Addr case *ir.IndexAddr: ptr = instr.X + if _, ok := ptr.Type().Underlying().(*types.Slice); ok { + // indexing a nil slice does not cause a nil pointer panic + // + // Note: This also works around the bad lowering of range loops over slices + // (https://github.com/dominikh/go-tools/issues/1053) + continue + } case *ir.FieldAddr: ptr = instr.X } diff --git a/staticcheck/testdata/src/CheckMaybeNil/CheckMaybeNil.go b/staticcheck/testdata/src/CheckMaybeNil/CheckMaybeNil.go index cc93a6115..db3c45e26 100644 --- a/staticcheck/testdata/src/CheckMaybeNil/CheckMaybeNil.go +++ b/staticcheck/testdata/src/CheckMaybeNil/CheckMaybeNil.go @@ -151,3 +151,36 @@ func fn15(x *int) { assert(x != nil) _ = *x } + +func fn16() { + var xs []int + if xs == nil { + println() + } + + for _, x := range xs { + _ = x + } + + var xs2 *[1]int + if xs2 == nil { + println() + } + for _, x := range xs2 { // want `possible nil pointer dereference` + _ = x + } + + var xs3 *[]int + if xs3 == nil { + println() + } + for _, x := range *xs3 { // want `possible nil pointer dereference` + _ = x + } + + var xs4 []int + if xs4 == nil { + println() + } + _ = xs4[0] +}