8000 No warning when nil cleanup func is deferred before checking error · Issue #1687 · dominikh/go-tools · GitHub
[go: up one dir, main page]

Skip to content

No warning when nil cleanup func is deferred before checking error #1687

Open

Description

@starius
  • staticcheck -version: staticcheck 2025.1.1 (0.6.1)
  • staticcheck -debug.version:
staticcheck 2025.1.1 (0.6.1)

Compiled with Go version: go1.25.2
Main module:
	honnef.co/go/tools@v0.6.1 (sum: h1:R094WgE8K4JirYjBaOpz/AvTyUu/3wbmAoskKN/pxTI=)
Dependencies:
	github.com/BurntSushi/toml@v1.4.1-0.20240526193622-a339e1f7089c (sum: h1:pxW6RcqyfI9/kWtOwnv/G+AzdKuy2ZrqINhenH4HyNs=)
	golang.org/x/exp/typeparams@v0.0.0-20231108232855-2478ac86f678 (sum: h1:1P7xPZEwZMoBoz0Yze5Nx2/4pxj6nw9ZqHWXqP0iRgQ=)
	golang.org/x/mod@v0.23.0 (sum: h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM=)
	golang.org/x/sync@v0.11.0 (sum: h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=)
	golang.org/x/tools@v0.30.0 (sum: h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY=)
  • go version: go version go1.25.2 linux/amd64
  • go env:
AR='ar'
CC='gcc'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='g++'
GCCGO='gccgo'
GO111MODULE=''
GOAMD64='v1'
GOARCH='amd64'
GOAUTH='netrc'
GOBIN=''
GOCACHE='/home/user/.cache/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/home/user/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build3826221701=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='/home/user/nautilus/go.mod'
GOMODCACHE='/home/user/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/user'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/nix/store/k1kn1c59ss7nq6agdppzq3krwmi3xqy4-go-1.25.2/share/go'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/home/user/.config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/nix/store/k1kn1c59ss7nq6agdppzq3krwmi3xqy4-go-1.25.2/share/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.25.2'
GOWORK=''
PKG_CONFIG='pkg-config'
  • Command ran: staticcheck ./... (run inside a module containing the reproducer below)

Code that triggers the bug

Create a module containing this single file (or run go run on it directly):

package main

import "errors"

var errStop = errors.New("stop")

func acquire(flag bool) (func(), error) {
        if flag {
                return nil, errStop
        }

        return func() {}, nil
}

func use(flag bool) error {
        release, err := acquire(flag)
        defer release()
        if err != nil {
                return err
        }

        return nil
}

func main() {
        _ = use(true)
}

Observed behavior

Running this program consistently crashes with panic: runtime error: invalid memory address or nil pointer dereference. When flag is true, acquire reports an error and returns a nil cleanup function. use unconditionally defers release() before inspecting err, so the defer executes with release == nil and the process dies. This pattern occurred in a long-lived production service: a shutdown path hit the nil defer only after years in prod, immediately taking down the whole server.

Expected behavior

Staticcheck (SA5001 or a new check) should warn whenever a func() return value is deferred before verifying that the accompanying error is nil. The tool already flags IO closers that are deferred prior to error handling, but it stays silent for cleanup functions stored in variables. Given that nil func() values panic when called, emitting a diagnostic here would catch a class of severe crashes that are otherwise very hard to spot in code review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      0