Skip to content

Commit 4f76871

Browse files
committed
cmd/go: run full 'go vet' during 'go test' for packages in GOROOT
Now that the main tree complies with 'go vet', enable all vet checks during 'go test' in the main tree. This helps surface helpful errors while developing, instead of having to wait for the misc-vet-vetall builder. During 'go test', the additional vet checks are essentially free: the vet invocations themselves take only 8 seconds total for the entire tree. Also update buildall.bash (used by the misc-compile builders) to run 'go vet std cmd' for each GOOS/GOARCH pair. This is not as free, since in general it can require recompiling packages with their tests included before invoking vet. (That compilation was going on anyway in the 'go test' case.) On my Mac laptop, ./buildall.bash freebsd used to take 68+16+17+18 = 119 seconds for make.bash and then the builds of the three freebsd architectures. Now it takes 68+16+23+17+23+18+24 = 189 seconds, 60% longer. Some of this is spent doing unnecessary cgo work. Still, this lets us shard the vet checks and match all.bash. Fixes #20119. For #31916. Change-Id: I6b0c40bac47708a688463c7fca12c0fc23ab2751 Reviewed-on: https://go-review.googlesource.com/c/go/+/176439 Run-TryBot: Russ Cox <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Brad Fitzpatrick <[email protected]>
1 parent 639ac76 commit 4f76871

File tree

5 files changed

+47
-24
lines changed

5 files changed

+47
-24
lines changed

src/buildall.bash

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,11 @@ do
7373
export GOARCH=386
7474
export GO386=387
7575
fi
76-
if ! "$GOROOT/bin/go" build -a std cmd; then
76+
77+
# Build and vet everything.
78+
# cmd/go/internal/work/exec.go enables the same vet flags during go test of std cmd
79+
# and should be kept in sync with any vet flag changes here.
80+
if ! "$GOROOT/bin/go" build std cmd || ! "$GOROOT/bin/go" vet -unsafeptr=false std cmd; then
7781
failed=true
7882
if $sete; then
7983
exit 1

src/cmd/go/internal/load/test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ func TestPackagesAndErrors(p *Package, cover *TestCover) (pmain, ptest, pxtest *
192192
ImportPath: p.ImportPath + "_test",
193193
Root: p.Root,
194194
Dir: p.Dir,
195+
Goroot: p.Goroot,
195196
GoFiles: p.XTestGoFiles,
196197
Imports: p.XTestImports,
197198
ForTest: p.ImportPath,

src/cmd/go/internal/test/test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,9 @@ var (
492492
testCacheExpire time.Time // ignore cached test results before this time
493493
)
494494

495+
// testVetExplicit records whether testVetFlags were set by an explicit -vet.
496+
var testVetExplicit = false
497+
495498
// testVetFlags is the list of flags to pass to vet when invoked automatically during go test.
496499
var testVetFlags = []string{
497500
// TODO(rsc): Decide which tests are enabled by default.
@@ -533,6 +536,7 @@ func runTest(cmd *base.Command, args []string) {
533536

534537
work.BuildInit()
535538
work.VetFlags = testVetFlags
539+
work.VetExplicit = testVetExplicit
536540

537541
pkgs = load.PackagesForBuild(pkgArgs)
538542
if len(pkgs) == 0 {

src/cmd/go/internal/test/testflag.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ func testFlags(usage func(), args []string) (packageNames, passToTest []string)
202202
}
203203
}
204204

205+
testVetExplicit = testVetList != ""
205206
if testVetList != "" && testVetList != "off" {
206207
if strings.Contains(testVetList, "=") {
207208
base.Fatalf("-vet argument cannot contain equal signs")

src/cmd/go/internal/work/exec.go

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -968,10 +968,13 @@ func buildVetConfig(a *Action, srcfiles []string) {
968968
// The caller is expected to set it (if needed) before executing any vet actions.
969969
var VetTool string
970970

971-
// VetFlags are the flags to pass to vet.
971+
// VetFlags are the default flags to pass to vet.
972972
// The caller is expected to set them before executing any vet actions.
973973
var VetFlags []string
974974

975+
// VetExplicit records whether the vet flags were set explicitly on the command line.
976+
var VetExplicit bool
977+
975978
func (b *Builder) vet(a *Action) error {
976979
// a.Deps[0] is the build of the package being vetted.
977980
// a.Deps[1] is the build of the "fmt" package.
@@ -998,12 +1001,42 @@ func (b *Builder) vet(a *Action) error {
9981001
h := cache.NewHash("vet " + a.Package.ImportPath)
9991002
fmt.Fprintf(h, "vet %q\n", b.toolID("vet"))
10001003

1004+
vetFlags := VetFlags
1005+
1006+
// In GOROOT, we enable all the vet tests during 'go test',
1007+
// not just the high-confidence subset. This gets us extra
1008+
// checking for the standard library (at some compliance cost)
1009+
// and helps us gain experience about how well the checks
1010+
// work, to help decide which should be turned on by default.
1011+
// The command-line still wins.
1012+
//
1013+
// Note that this flag change applies even when running vet as
1014+
// a dependency of vetting a package outside std.
1015+
// (Otherwise we'd have to introduce a whole separate
1016+
// space of "vet fmt as a dependency of a std top-level vet"
1017+
// versus "vet fmt as a dependency of a non-std top-level vet".)
1018+
// This is OK as long as the packages that are farther down the
1019+
// dependency tree turn on *more* analysis, as here.
1020+
// (The unsafeptr check does not write any facts for use by
1021+
// later vet runs.)
1022+
if a.Package.Goroot && !VetExplicit {
1023+
// Note that $GOROOT/src/buildall.bash
1024+
// does the same for the misc-compile trybots
1025+
// and should be updated if these flags are
1026+
// changed here.
1027+
//
1028+
// There's too much unsafe.Pointer code
1029+
// that vet doesn't like in low-level packages
1030+
// like runtime, sync, and reflect.
1031+
vetFlags = []string{"-unsafeptr=false"}
1032+
}
1033+
10011034
// Note: We could decide that vet should compute export data for
10021035
// all analyses, in which case we don't need to include the flags here.
10031036
// But that would mean that if an analysis causes problems like
10041037
// unexpected crashes there would be no way to turn it off.
10051038
// It seems better to let the flags disable export analysis too.
1006-
fmt.Fprintf(h, "vetflags %q\n", VetFlags)
1039+
fmt.Fprintf(h, "vetflags %q\n", vetFlags)
10071040

10081041
fmt.Fprintf(h, "pkg %q\n", a.Deps[0].actionID)
10091042
for _, a1 := range a.Deps {
@@ -1023,26 +1056,6 @@ func (b *Builder) vet(a *Action) error {
10231056
}
10241057
}
10251058

1026-
// TODO(adonovan): delete this when we use the new vet printf checker.
1027-
// https://github.com/golang/go/issues/28756
1028-
if vcfg.ImportMap["fmt"] == "" {
1029-
a1 := a.Deps[1]
1030-
vcfg.ImportMap["fmt"] = "fmt"
1031-
if a1.built != "" {
1032-
vcfg.PackageFile["fmt"] = a1.built
1033-
}
1034-
vcfg.Standard["fmt"] = true
1035-
}
1036-
1037-
// During go test, ignore type-checking failures during vet.
1038-
// We only run vet if the compilation has succeeded,
1039-
// so at least for now assume the bug is in vet.
1040-
// We know of at least #18395.
1041-
// TODO(rsc,gri): Try to remove this for Go 1.11.
1042-
//
1043-
// Disabled 2018-04-20. Let's see if we can do without it.
1044-
// vcfg.SucceedOnTypecheckFailure = cfg.CmdName == "test"
1045-
10461059
js, err := json.MarshalIndent(vcfg, "", "\t")
10471060
if err != nil {
10481061
return fmt.Errorf("internal error marshaling vet config: %v", err)
@@ -1062,7 +1075,7 @@ func (b *Builder) vet(a *Action) error {
10621075
if tool == "" {
10631076
tool = base.Tool("vet")
10641077
}
1065-
runErr := b.run(a, p.Dir, p.ImportPath, env, cfg.BuildToolexec, tool, VetFlags, a.Objdir+"vet.cfg")
1078+
runErr := b.run(a, p.Dir, p.ImportPath, env, cfg.BuildToolexec, tool, vetFlags, a.Objdir+"vet.cfg")
10661079

10671080
// If vet wrote export data, save it for input to future vets.
10681081
if f, err := os.Open(vcfg.VetxOutput); err == nil {

0 commit comments

Comments
 (0)