1
0
mirror of https://github.com/golang/go synced 2024-09-25 07:30:13 -06:00

cmd/go: vet: pass non-.go files to vet tool

The "gofiles" cache entry has been renamed "srcfiles", and it includes
non-Go files (.s, .c, .cxx) that belong to the package. It does not
include raw cgo files.

Added regression test.

Fixes #27665

Change-Id: I4884fe9b4f823f50705f8c2d357a04a8e567734f
Reviewed-on: https://go-review.googlesource.com/c/148904
Reviewed-by: Bryan C. Mills <bcmills@google.com>
This commit is contained in:
Alan Donovan 2018-11-12 13:42:46 -05:00
parent b075dfba80
commit e787b13328
3 changed files with 58 additions and 16 deletions

View File

@ -377,7 +377,7 @@ func (b *Builder) build(a *Action) (err error) {
if b.NeedExport { if b.NeedExport {
p.Export = a.built p.Export = a.built
} }
if need&needCompiledGoFiles != 0 && b.loadCachedGoFiles(a) { if need&needCompiledGoFiles != 0 && b.loadCachedSrcFiles(a) {
need &^= needCompiledGoFiles need &^= needCompiledGoFiles
} }
// Otherwise, we need to write files to a.Objdir (needVet, needCgoHdr). // Otherwise, we need to write files to a.Objdir (needVet, needCgoHdr).
@ -575,7 +575,13 @@ func (b *Builder) build(a *Action) (err error) {
b.cacheCgoHdr(a) b.cacheCgoHdr(a)
} }
} }
b.cacheGofiles(a, gofiles)
var srcfiles []string // .go and non-.go
srcfiles = append(srcfiles, gofiles...)
srcfiles = append(srcfiles, sfiles...)
srcfiles = append(srcfiles, cfiles...)
srcfiles = append(srcfiles, cxxfiles...)
b.cacheSrcFiles(a, srcfiles)
// Running cgo generated the cgo header. // Running cgo generated the cgo header.
need &^= needCgoHdr need &^= needCgoHdr
@ -587,11 +593,11 @@ func (b *Builder) build(a *Action) (err error) {
// Prepare Go vet config if needed. // Prepare Go vet config if needed.
if need&needVet != 0 { if need&needVet != 0 {
buildVetConfig(a, gofiles) buildVetConfig(a, srcfiles)
need &^= needVet need &^= needVet
} }
if need&needCompiledGoFiles != 0 { if need&needCompiledGoFiles != 0 {
if !b.loadCachedGoFiles(a) { if !b.loadCachedSrcFiles(a) {
return fmt.Errorf("failed to cache compiled Go files") return fmt.Errorf("failed to cache compiled Go files")
} }
need &^= needCompiledGoFiles need &^= needCompiledGoFiles
@ -794,13 +800,13 @@ func (b *Builder) loadCachedCgoHdr(a *Action) bool {
return err == nil return err == nil
} }
func (b *Builder) cacheGofiles(a *Action, gofiles []string) { func (b *Builder) cacheSrcFiles(a *Action, srcfiles []string) {
c := cache.Default() c := cache.Default()
if c == nil { if c == nil {
return return
} }
var buf bytes.Buffer var buf bytes.Buffer
for _, file := range gofiles { for _, file := range srcfiles {
if !strings.HasPrefix(file, a.Objdir) { if !strings.HasPrefix(file, a.Objdir) {
// not generated // not generated
buf.WriteString("./") buf.WriteString("./")
@ -815,7 +821,7 @@ func (b *Builder) cacheGofiles(a *Action, gofiles []string) {
return return
} }
} }
c.PutBytes(cache.Subkey(a.actionID, "gofiles"), buf.Bytes()) c.PutBytes(cache.Subkey(a.actionID, "srcfiles"), buf.Bytes())
} }
func (b *Builder) loadCachedVet(a *Action) bool { func (b *Builder) loadCachedVet(a *Action) bool {
@ -823,34 +829,34 @@ func (b *Builder) loadCachedVet(a *Action) bool {
if c == nil { if c == nil {
return false return false
} }
list, _, err := c.GetBytes(cache.Subkey(a.actionID, "gofiles")) list, _, err := c.GetBytes(cache.Subkey(a.actionID, "srcfiles"))
if err != nil { if err != nil {
return false return false
} }
var gofiles []string var srcfiles []string
for _, name := range strings.Split(string(list), "\n") { for _, name := range strings.Split(string(list), "\n") {
if name == "" { // end of list if name == "" { // end of list
continue continue
} }
if strings.HasPrefix(name, "./") { if strings.HasPrefix(name, "./") {
gofiles = append(gofiles, name[2:]) srcfiles = append(srcfiles, name[2:])
continue continue
} }
if err := b.loadCachedObjdirFile(a, c, name); err != nil { if err := b.loadCachedObjdirFile(a, c, name); err != nil {
return false return false
} }
gofiles = append(gofiles, a.Objdir+name) srcfiles = append(srcfiles, a.Objdir+name)
} }
buildVetConfig(a, gofiles) buildVetConfig(a, srcfiles)
return true return true
} }
func (b *Builder) loadCachedGoFiles(a *Action) bool { func (b *Builder) loadCachedSrcFiles(a *Action) bool {
c := cache.Default() c := cache.Default()
if c == nil { if c == nil {
return false return false
} }
list, _, err := c.GetBytes(cache.Subkey(a.actionID, "gofiles")) list, _, err := c.GetBytes(cache.Subkey(a.actionID, "srcfiles"))
if err != nil { if err != nil {
return false return false
} }
@ -879,6 +885,7 @@ type vetConfig struct {
Dir string // directory containing package Dir string // directory containing package
ImportPath string // canonical import path ("package path") ImportPath string // canonical import path ("package path")
GoFiles []string // absolute paths to package source files GoFiles []string // absolute paths to package source files
NonGoFiles []string // absolute paths to package non-Go files
ImportMap map[string]string // map import path in source code to package path ImportMap map[string]string // map import path in source code to package path
PackageFile map[string]string // map package path to .a file with export data PackageFile map[string]string // map package path to .a file with export data
@ -890,7 +897,18 @@ type vetConfig struct {
SucceedOnTypecheckFailure bool // awful hack; see #18395 and below SucceedOnTypecheckFailure bool // awful hack; see #18395 and below
} }
func buildVetConfig(a *Action, gofiles []string) { func buildVetConfig(a *Action, srcfiles []string) {
// Classify files based on .go extension.
// srcfiles does not include raw cgo files.
var gofiles, nongofiles []string
for _, name := range srcfiles {
if strings.HasSuffix(name, ".go") {
gofiles = append(gofiles, name)
} else {
nongofiles = append(nongofiles, name)
}
}
// Pass list of absolute paths to vet, // Pass list of absolute paths to vet,
// so that vet's error messages will use absolute paths, // so that vet's error messages will use absolute paths,
// so that we can reformat them relative to the directory // so that we can reformat them relative to the directory
@ -899,6 +917,7 @@ func buildVetConfig(a *Action, gofiles []string) {
Compiler: cfg.BuildToolchainName, Compiler: cfg.BuildToolchainName,
Dir: a.Package.Dir, Dir: a.Package.Dir,
GoFiles: mkAbsFiles(a.Package.Dir, gofiles), GoFiles: mkAbsFiles(a.Package.Dir, gofiles),
NonGoFiles: mkAbsFiles(a.Package.Dir, nongofiles),
ImportPath: a.Package.ImportPath, ImportPath: a.Package.ImportPath,
ImportMap: make(map[string]string), ImportMap: make(map[string]string),
PackageFile: make(map[string]string), PackageFile: make(map[string]string),
@ -995,6 +1014,8 @@ func (b *Builder) vet(a *Action) error {
} }
} }
// TODO(adonovan): delete this when we use the new vet printf checker.
// https://github.com/golang/go/issues/28756
if vcfg.ImportMap["fmt"] == "" { if vcfg.ImportMap["fmt"] == "" {
a1 := a.Deps[1] a1 := a.Deps[1]
vcfg.ImportMap["fmt"] = "fmt" vcfg.ImportMap["fmt"] = "fmt"

15
src/cmd/go/testdata/script/vet_asm.txt vendored Normal file
View File

@ -0,0 +1,15 @@
# Issue 27665. Verify that "go vet" analyzes non-Go files.
env GOARCH=amd64
! go vet -asmdecl a
stderr 'f: invalid MOVW of x'
-- a/a.go --
package a
func f(x int8)
-- a/asm.s --
TEXT ·f(SB),0,$0-1
MOVW x+0(FP), AX
RET

View File

@ -365,6 +365,7 @@ type vetConfig struct {
Dir string Dir string
ImportPath string ImportPath string
GoFiles []string GoFiles []string
NonGoFiles []string
ImportMap map[string]string ImportMap map[string]string
PackageFile map[string]string PackageFile map[string]string
Standard map[string]bool Standard map[string]bool
@ -430,7 +431,12 @@ func doPackageCfg(cfgFile string) {
stdImporter = &vcfg stdImporter = &vcfg
inittypes() inittypes()
mustTypecheck = true mustTypecheck = true
doPackage(vcfg.GoFiles, nil)
var allFiles []string
allFiles = append(allFiles, vcfg.GoFiles...)
allFiles = append(allFiles, vcfg.NonGoFiles...)
doPackage(allFiles, nil)
if vcfg.VetxOutput != "" { if vcfg.VetxOutput != "" {
out := make([]vetxExport, 0, len(exporters)) out := make([]vetxExport, 0, len(exporters))
for name, fn := range exporters { for name, fn := range exporters {