Go version
go1.24.4
Output of go env
in your module/workspace:
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/apocalypse555/.cache/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/home/apocalypse555/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build1252593989=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='/dev/null'
GOMODCACHE='/home/apocalypse555/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/apocalypse555/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/lib/go'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/home/apocalypse555/.config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/lib/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.24.4'
GOWORK=''
PKG_CONFIG='pkg-config'
What did you do?
I run go vet
on this code :
func ok(a int) bool {
if a < 10 {
//panic(`with that, it's well detected`)
os.Exit(1)
return false
}
return true
}
(https://go.dev/play/p/CHtVr0fs-yw)
What did you see happen?
No warning like with panic()
.
What did you expect to see?
A warning like with panic()
.
It seems odd that an unreachable code is detected after a panic()
but not after an os.Exit()
.
Related issue
https://github.com/golang/go/issues/53968
Comment From: randall77
Adding return false
is required in many cases to adhere to the language spec on terminating statements.
func f(b bool) int {
if b {
return 5
} else {
os.Exit(1)
return 0 // doesn't compile without this line
}
}
The language spec doesn't say that os.Exit
is a terminating statement. I'm not sure it should, as the spec doesn't mention specific packages very often. And changing the definition of terminating statement now would break existing programs.
I suppose vet could find code like the code in your case, where removing it doesn't invalidate the program. That's an extra complication, and I'm not sure how often such a constrained vet rule would trigger.
Comment From: cagedmantis
Comment From: adonovan
I did an experiment a long time ago to make cmd/vet smarter about dead code following calls to "no-return" functions. The ctrlflow analyzer already knows about such functions, so basing unreachable
atop ctrflow
would do most of the heavy lifting. I just shared some old prototype code in https://go.dev/cl/687635, but it needs some care to make it production-worthy.
I think the ideal behavior would be for the analyzer to offer a fix to turn any statement following a noreturn call into panic("unreachable")
.
Comment From: gopherbot
Change https://go.dev/cl/687635 mentions this issue: go/analysis/passes/unreachable: use ctrlflow analyzer
Comment From: TapirLiu
And runtime.Goexit
. I'm surprised that it is not mentioned in Go spec at all. And its doc also doesn't mention the fact that if can cancel panics.
package main
import "runtime"
func main() {
var c = make(chan int)
go func() {
defer func() {
c <- 1
}()
defer func() {
runtime.Goexit() // cancel panic "bye"
}()
panic("bye")
}()
<-c
}
Comment From: seankhliao
seems like there's not a lot of code that has this problem, is this frequent enough for vet? https://github.com/search?q=language%3AGo+%2F%5E%5Cs%2Bos.Exit%5C%28.*%5C%29%5Cn%5Cs%2B%5Bae-os-z%5D%2F&type=code
regex is sort of limited, so search excludes: - [b]reak - [c]ase - [d]efault - [p]anic - [r]eturn - }
Comment From: adonovan
Here's the result of applying https://go.dev/cl/687635 to the Module Mirror corpus. It reported 7241 diagnostics in 24K modules (though many of those had build errors):
A quick inspection of ten at random shows that 7 are valid and 3 are signs of serious bugs in the analyzer: - https://go-mod-viewer.appspot.com/github.com/cznic/cc@v0.0.0-20181122101902-d673e9b70d4d/v2/ast2.go#L3771 - https://go-mod-viewer.appspot.com/github.com/Kucoin/kucoin-go-sdk@v1.2.18/order_test.go#L176 - https://go-mod-viewer.appspot.com/github.com/Augustu/go-micro/v2@v2.9.3/debug/log/kubernetes/kubernetes_test.go#L54
I guess I have more work to do here.
A random 50 are shown below.
https://go-mod-viewer.appspot.com/github.com/cloudwan/edgelq-sdk@v1.15.4/audit/resources/v1alpha2/common/common.pb.fieldpath.go#L2983: unreachable code https://go-mod-viewer.appspot.com/github.com/Kucoin/kucoin-go-sdk@v1.2.18/order_test.go#L176: unreachable code https://go-mod-viewer.appspot.com/github.com/cloudwan/edgelq-sdk@v1.15.4/alerting/resources/v1/common/specs.pb.fieldpath.go#L15077: unreachable code https://go-mod-viewer.appspot.com/github.com/ethereum/go-ethereum@v1.16.1/internal/cmdtest/test_cmd.go#L170: unreachable code https://go-mod-viewer.appspot.com/github.com/pachyderm/pachyderm@v1.13.4/src/server/admin/server/convert1_10.go#L488: unreachable code https://go-mod-viewer.appspot.com/github.com/epsagon/epsagon-go@v1.39.0/example/s3_example/write/main.go#L58: unreachable code https://go-mod-viewer.appspot.com/github.com/snikch/goodman@v0.0.0-20171125024755-10e37e294daa/example/main.go#L23: unreachable code https://go-mod-viewer.appspot.com/github.com/cloudwan/edgelq-sdk@v1.15.4/logging/client/v1alpha2/log_descriptor/log_descriptor_service.pb.descriptors.go#L1351: unreachable code https://go-mod-viewer.appspot.com/github.com/cznic/cc@v0.0.0-20181122101902-d673e9b70d4d/v2/ast2.go#L3771: unreachable code https://go-mod-viewer.appspot.com/github.com/Augustu/go-micro/v2@v2.9.3/debug/log/kubernetes/kubernetes_test.go#L54: unreachable code https://go-mod-viewer.appspot.com/github.com/whiteCcinn/protobuf-go@v1.0.9/internal/testprotos/legacy/proto2_20160225_2fc053c5/test.pb.go#L1826: unreachable code https://go-mod-viewer.appspot.com/github.com/CESSProject/cess-go-sdk@v0.7.2/example/chain/parseblock/parseblock.go#L120: unreachable code https://go-mod-viewer.appspot.com/github.com/aws/aws-encryption-sdk/releases/go/encryption-sdk@v0.2.0/KeyDerivation/KeyDerivation.go#L448: unreachable code https://go-mod-viewer.appspot.com/sourcegraph.com/sourcegraph/go-vcs@v0.0.0-20230717073621-ca41431d1b7d/vcs/git/repo.go#L296: unreachable code https://go-mod-viewer.appspot.com/github.com/cloudwan/edgelq-sdk@v1.15.4/monitoring/resources/v4/alert/alert.pb.fieldpath.go#L3327: unreachable code https://go-mod-viewer.appspot.com/github.com/conbanwa/logs@v0.4.7/compare.go#L176: unreachable code https://go-mod-viewer.appspot.com/github.com/aws/aws-cryptographic-material-providers-library/releases/go/smithy-dafny-standard-library@v0.2.0/Actions/Actions.go#L191: unreachable code https://go-mod-viewer.appspot.com/github.com/Venafi/vcert/v5@v5.10.2/pkg/venafi/tpp/connector_test.go#L577: unreachable code https://go-mod-viewer.appspot.com/github.com/Kucoin/kucoin-go-sdk@v1.2.18/margin_test.go#L294: unreachable code https://go-mod-viewer.appspot.com/github.com/charlesetsmith/saratoga/sarflags@v0.0.0-20240223233549-4e862e6c4217/sarflags.go#L807: unreachable code https://go-mod-viewer.appspot.com/github.com/cockroachdb/pebble@v1.1.5/scan_internal_test.go#L337: unreachable code https://go-mod-viewer.appspot.com/github.com/aws/aws-cryptographic-material-providers-library/releases/go/mpl@v0.2.0/IntermediateKeyWrapping/IntermediateKeyWrapping.go#L526: unreachable code https://go-mod-viewer.appspot.com/github.com/cloudwan/edgelq-sdk@v1.15.4/applications/resources/v1alpha2/pod/pod.pb.fieldpath.go#L3007: unreachable code https://go-mod-viewer.appspot.com/github.com/vishvananda/netlink@v1.3.1/filter_test.go#L1146: unreachable code https://go-mod-viewer.appspot.com/github.com/decred/dcrlnd@v0.7.6/cmd/dcrlncli/cmd_open_channel.go#L587: unreachable code https://go-mod-viewer.appspot.com/github.com/balzaczyy/golucene@v0.0.0-20151210033525-d0be9ee89713/core/index/writer.go#L1399: unreachable code https://go-mod-viewer.appspot.com/github.com/core-coin/go-core@v1.1.7/p2p/discover/ntp_test.go#L25: unreachable code https://go-mod-viewer.appspot.com/github.com/network-quality/goresponsiveness@v0.0.0-20240129151524-343954285090/probe/tracer.go#L113: unreachable code https://go-mod-viewer.appspot.com/github.com/core-coin/go-core@v1.1.7/p2p/discover/ntp_test.go#L31: unreachable code https://go-mod-viewer.appspot.com/github.com/theQRL/go-zond@v0.2.1/trie/stacktrie_test.go#L329: unreachable code https://go-mod-viewer.appspot.com/github.com/TIBCOSoftware/flogo-lib@v0.5.9/core/mapper/exprmapper/expression/expression_test.go#L263: unreachable code https://go-mod-viewer.appspot.com/github.com/xujiajun/gorouter@v1.2.0/router_test.go#L219: unreachable code https://go-mod-viewer.appspot.com/github.com/epsagon/epsagon-go@v1.39.0/example/sts_example/main.go#L41: unreachable code https://go-mod-viewer.appspot.com/github.com/luckypickle/go-ethereum-vet@v1.14.2/signer/rules/rules_test.go#L521: unreachable code https://go-mod-viewer.appspot.com/github.com/cznic/fileutil@v0.0.0-20181122101858-4d67cfea8c87/storage/probe_test.go#L44: unreachable code https://go-mod-viewer.appspot.com/github.com/symfony-cli/console@v1.2.1/flag_test.go#L1229: unreachable code https://go-mod-viewer.appspot.com/github.com/whiteCcinn/protobuf-go@v1.0.9/internal/testprotos/legacy/proto3_20160225_2fc053c5/test.pb.go#L758: unreachable code https://go-mod-viewer.appspot.com/github.com/btnguyen2k/consu/semita@v0.1.5/Semita_test.go#L2543: unreachable code https://go-mod-viewer.appspot.com/github.com/uber-go/tally/v4@v4.1.17/thirdparty/github.com/apache/thrift/lib/go/thrift/protocol_test.go#L109: unreachable code https://go-mod-viewer.appspot.com/github.com/cohesity/app-sdk-go@v0.0.0-20190722230114-5dbb9337cc19/unirest-go/Request.go#L131: unreachable code https://go-mod-viewer.appspot.com/github.com/nicocha30/gvisor-ligolo@v0.0.0-20250509122847-3be646365354/pkg/abi/linux/linux_abi_autogen_unsafe.go#L5436: unreachable code https://go-mod-viewer.appspot.com/github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/service/debug/log/kubernetes/kubernetes_test.go#L44: unreachable code https://go-mod-viewer.appspot.com/modernc.org/cc@v1.0.1/v2/ast2.go#L3894: unreachable code https://go-mod-viewer.appspot.com/github.com/gogf/gf@v1.16.9/database/gdb/gdb_z_mysql_transaction_test.go#L1069: unreachable code https://go-mod-viewer.appspot.com/github.com/btnguyen2k/consu/semita@v0.1.5/Semita_test.go#L2087: unreachable code https://go-mod-viewer.appspot.com/github.com/cloudwan/edgelq-sdk@v1.15.4/monitoring/client/v4/project/project_service.pb.descriptors.go#L1448: unreachable code https://go-mod-viewer.appspot.com/github.com/terraform-linters/tflint-plugin-sdk@v0.22.0/plugin/internal/plugin2host/plugin2host_test.go#L749: unreachable code https://go-mod-viewer.appspot.com/github.com/glycerine/goconvey@v0.0.0-20190410193231-58a59202ab31/convey/assertions/ignorespaces.go#L330: unreachable code https://go-mod-viewer.appspot.com/github.com/cloudwan/edgelq-sdk@v1.15.4/devices/resources/v1/device/device.pb.fieldpath.go#L18980: unreachable code https://go-mod-viewer.appspot.com/github.com/hashicorp/terraform-plugin-sdk@v1.17.2/terraform/upgrade_state_v1_test.go#L68: unreachable code ecosystem$