aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/vet/main.go
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2013-03-22 15:14:40 -0400
committerRuss Cox <rsc@golang.org>2013-03-22 15:14:40 -0400
commitb5cfbda21236d273047f6aaec04df29162c26901 (patch)
tree70c523d85aa15836e88d5c22f0e76a9c56da8a4f /src/cmd/vet/main.go
parentd02089101c9d8375d991b679c9a1c8432e415cd8 (diff)
downloadgo-b5cfbda21236d273047f6aaec04df29162c26901.tar.gz
go-b5cfbda21236d273047f6aaec04df29162c26901.zip
cmd/vet: add assembly checker
Fixes #5036. R=golang-dev, r CC=golang-dev https://golang.org/cl/7531045
Diffstat (limited to 'src/cmd/vet/main.go')
-rw-r--r--src/cmd/vet/main.go47
1 files changed, 35 insertions, 12 deletions
diff --git a/src/cmd/vet/main.go b/src/cmd/vet/main.go
index 952b80a95f..8ae829f853 100644
--- a/src/cmd/vet/main.go
+++ b/src/cmd/vet/main.go
@@ -29,6 +29,7 @@ var exitCode = 0
// a flag is set explicitly.
var report = map[string]*bool{
"all": flag.Bool("all", true, "check everything; disabled if any explicit check is requested"),
+ "asmdecl": flag.Bool("asmdecl", false, "check assembly against Go declarations"),
"assign": flag.Bool("assign", false, "check for useless assignments"),
"atomic": flag.Bool("atomic", false, "check for common mistaken usages of the sync/atomic package"),
"buildtags": flag.Bool("buildtags", false, "check that +build tags are valid"),
@@ -64,11 +65,12 @@ func Usage() {
// File is a wrapper for the state of a file used in the parser.
// The parse tree walkers are all methods of this type.
type File struct {
- pkg *Package
- fset *token.FileSet
- name string
- file *ast.File
- b bytes.Buffer // for use by methods
+ pkg *Package
+ fset *token.FileSet
+ name string
+ content []byte
+ file *ast.File
+ b bytes.Buffer // for use by methods
}
func main() {
@@ -163,6 +165,7 @@ func doPackageDir(directory string) {
names = append(names, pkg.GoFiles...)
names = append(names, pkg.CgoFiles...)
names = append(names, pkg.TestGoFiles...) // These are also in the "foo" package.
+ names = append(names, pkg.SFiles...)
prefixDirectory(directory, names)
doPackage(names)
// Is there also a "foo_test" package? If so, do that one as well.
@@ -176,6 +179,7 @@ func doPackageDir(directory string) {
type Package struct {
types map[ast.Expr]Type
values map[ast.Expr]interface{}
+ files []*File
}
// doPackage analyzes the single package constructed from the named files.
@@ -197,15 +201,19 @@ func doPackage(names []string) {
return
}
checkBuildTag(name, data)
- parsedFile, err := parser.ParseFile(fs, name, bytes.NewReader(data), 0)
- if err != nil {
- warnf("%s: %s", name, err)
- return
+ var parsedFile *ast.File
+ if strings.HasSuffix(name, ".go") {
+ parsedFile, err = parser.ParseFile(fs, name, bytes.NewReader(data), 0)
+ if err != nil {
+ warnf("%s: %s", name, err)
+ return
+ }
+ astFiles = append(astFiles, parsedFile)
}
- files = append(files, &File{fset: fs, name: name, file: parsedFile})
- astFiles = append(astFiles, parsedFile)
+ files = append(files, &File{fset: fs, content: data, name: name, file: parsedFile})
}
pkg := new(Package)
+ pkg.files = files
// Type check the package.
err := pkg.check(fs, astFiles)
if err != nil && *verbose {
@@ -213,8 +221,11 @@ func doPackage(names []string) {
}
for _, file := range files {
file.pkg = pkg
- file.walkFile(file.name, file.file)
+ if file.file != nil {
+ file.walkFile(file.name, file.file)
+ }
}
+ asmCheck(pkg)
}
func visit(path string, f os.FileInfo, err error) error {
@@ -230,6 +241,15 @@ func visit(path string, f os.FileInfo, err error) error {
return nil
}
+func (pkg *Package) hasFileWithSuffix(suffix string) bool {
+ for _, f := range pkg.files {
+ if strings.HasSuffix(f.name, suffix) {
+ return true
+ }
+ }
+ return false
+}
+
// walkDir recursively walks the tree looking for Go packages.
func walkDir(root string) {
filepath.Walk(root, visit)
@@ -278,6 +298,9 @@ func (f *File) Badf(pos token.Pos, format string, args ...interface{}) {
}
func (f *File) loc(pos token.Pos) string {
+ if pos == token.NoPos {
+ return ""
+ }
// Do not print columns. Because the pos often points to the start of an
// expression instead of the inner part with the actual error, the
// precision can mislead.