go: cmd/go/internal/test: -vet accepts bad input

What version of Go are you using (go version)?

$ go version
go version go1.16.6 linux/amd64

Does this issue reproduce with the latest release?

yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/user/.cache/go-build"
GOENV="/home/user/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/user/go/pkg/mod"
GOOS="linux"
GOPATH="/home/user/go"
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/lib/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.16.6"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/dev/null"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build2105906029=/tmp/go-build -gno-record-gcc-switches"

What did you do?

https://play.golang.org/p/t6Q8DJU3ON6

go test .
go test -vet=all .

What did you expect to see?

ok  	trash/five	(cached) [no tests to run]
deprecated flag provided: -all

What did you see instead?

ok  	trash/five	(cached) [no tests to run]
# trash/five
./main.go:7:8: using r before checking for errors
FAIL	trash/five [build failed]
FAIL

What would you like done?

This came out of development on #45963 [CL 334873]. It was discovered that go test -vet=all, actually works today. This is because unlike what the docs say -vet simply passes the list of “checks”, with - prefixes, to go vet as flag arguments.

-vet list Configure the invocation of “go vet” during “go test” to use the comma-separated list of vet checks. If list is empty, “go test” runs “go vet” with a curated list of checks believed to be always worth addressing. If list is “off”, “go test” does not run “go vet” at all.

This was is an intended feature and seems quite brittle. As such, we should pin -vet to the documented interface, or define what “flags” we accept and update the the documentation. If we are not expanding the definition, we should ignore or error on all the deprecated and non-check name flags: -V, -source, -c, -printfuncs, and -printf.funcs(anything with a dot). (This is very much a blocklist, since we want to allow new checks to be added over time.)

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 17 (11 by maintainers)

Commits related to this issue

Most upvoted comments

If we are committing to allowing full configuration of vet

I don’t think we should allow configuration of flags like -c and -v in go test -vet. If users want that much control, they can run go vet separately from go test.

Ok, so the plan forward is to rely on go tool vet -flags to get the list of supported analysis flags.

https://github.com/golang/go/issues/35487 suggests having an exported list of analyzers available somewhere. This would be robust (but it does mean initializing all of the vet packages just to get their names).

One is to write a go:generate script that updates a map or function, and then verify that that map or function is up to date in a unit test. (That’s the approach I used for #18682.)

This is then probably the most robust way going forward.

@zpavlinovic, we currently propagate -vet=a,b,c as -a -b -c, yes. What I think we should do instead is not filtering, but validation: go test should fail outright if any of the -vet parameters does not name a valid (or, perhaps, a once-valid) analyzer flag.