$ ./update-xtools.sh
Copied /Users/rsc/src/golang.org/x/tools@
aa829657 to .
$ cd ~/src/golang.org/x/tools
$ git log -n1
aa829657
commit
aa82965741a9fecd12b026fbb3d3c6ed3231b8f8 (HEAD -> release-branch.go1.12, origin/release-branch.go1.12)
Author: Daniel Martí <mvdan@mvdan.cc>
AuthorDate: Fri Mar 1 11:00:19 2019 +0000
Commit: Brad Fitzpatrick <bradfitz@golang.org>
CommitDate: Wed Mar 13 21:06:03 2019 +0000
...
$
Picks up cmd/vet fixes that have been inadvertently missed in point releases so far.
Fixes #30399.
Fixes #30465.
Change-Id: Ibcfaac51d134205b986b32f857d54006b19c896a
Reviewed-on: https://go-review.googlesource.com/c/go/+/174519
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
OtherFiles []string // names of non-Go files of this package
Pkg *types.Package // type information about the package
TypesInfo *types.Info // type information about the syntax trees
+ TypesSizes types.Sizes // function for computing sizes of types
// Report reports a Diagnostic, a finding about a specific location
// in the analyzed source code such as a potential mistake.
var Analyzer = &analysis.Analyzer{
Name: "printf",
- FactTypes: []reflect.Type{reflect.TypeOf(new(isWrapper))},
+ FactTypes: []analysis.Fact{new(isWrapper)},
...
}
// library we cannot assume types.SizesFor is consistent with arches.
// For now, assume 64-bit norms and print a warning.
// But this warning should really be deferred until we attempt to use
- // arch, which is very unlikely.
+ // arch, which is very unlikely. Better would be
+ // to defer size computation until we have Pass.TypesSizes.
arch.sizes = types.SizesFor("gc", "amd64")
log.Printf("unknown architecture %s", arch.name)
}
import (
"fmt"
"go/ast"
- "go/build"
"go/format"
"go/parser"
"go/token"
return nil, nil // doesn't use cgo
}
- cgofiles, info, err := typeCheckCgoSourceFiles(pass.Fset, pass.Pkg, pass.Files, pass.TypesInfo)
+ cgofiles, info, err := typeCheckCgoSourceFiles(pass.Fset, pass.Pkg, pass.Files, pass.TypesInfo, pass.TypesSizes)
if err != nil {
return nil, err
}
// limited ourselves here to preserving function bodies and initializer
// expressions since that is all that the cgocall analyzer needs.
//
-func typeCheckCgoSourceFiles(fset *token.FileSet, pkg *types.Package, files []*ast.File, info *types.Info) ([]*ast.File, *types.Info, error) {
+func typeCheckCgoSourceFiles(fset *token.FileSet, pkg *types.Package, files []*ast.File, info *types.Info, sizes types.Sizes) ([]*ast.File, *types.Info, error) {
const thispkg = "·this·"
// Which files are cgo files?
Importer: importerFunc(func(path string) (*types.Package, error) {
return importMap[path], nil
}),
- // TODO(adonovan): Sizes should probably be provided by analysis.Pass.
- Sizes: types.SizesFor("gc", build.Default.GOARCH),
+ Sizes: sizes,
Error: func(error) {}, // ignore errors (e.g. unused import)
}
This analyzer reports a diagnostic for composite literals of struct
types imported from another package that do not use the field-keyed
syntax. Such literals are fragile because the addition of a new field
-(even if unexported) to the struct will cause compilation to fail.`
+(even if unexported) to the struct will cause compilation to fail.
+
+As an example,
+
+ err = &net.DNSConfigError{err}
+
+should be replaced by:
+
+ err = &net.DNSConfigError{Err: err}
+`
var Analyzer = &analysis.Analyzer{
Name: "composites",
//
// Example of use in another analysis:
//
-// import "golang.org/x/tools/go/analysis/passes/inspect"
+// import (
+// "golang.org/x/tools/go/analysis"
+// "golang.org/x/tools/go/analysis/passes/inspect"
+// "golang.org/x/tools/go/ast/inspector"
+// )
//
// var Analyzer = &analysis.Analyzer{
// ...
}
// isFormatter reports whether t satisfies fmt.Formatter.
-// Unlike fmt.Stringer, it's impossible to satisfy fmt.Formatter without importing fmt.
-func isFormatter(pass *analysis.Pass, t types.Type) bool {
- for _, imp := range pass.Pkg.Imports() {
- if imp.Path() == "fmt" {
- formatter := imp.Scope().Lookup("Formatter").Type().Underlying().(*types.Interface)
- return types.Implements(t, formatter)
- }
+// The only interface method to look for is "Format(State, rune)".
+func isFormatter(typ types.Type) bool {
+ obj, _, _ := types.LookupFieldOrMethod(typ, false, nil, "Format")
+ fn, ok := obj.(*types.Func)
+ if !ok {
+ return false
}
- return false
+ sig := fn.Type().(*types.Signature)
+ return sig.Params().Len() == 2 &&
+ sig.Results().Len() == 0 &&
+ isNamed(sig.Params().At(0).Type(), "fmt", "State") &&
+ types.Identical(sig.Params().At(1).Type(), types.Typ[types.Rune])
+}
+
+func isNamed(T types.Type, pkgpath, name string) bool {
+ named, ok := T.(*types.Named)
+ return ok && named.Obj().Pkg().Path() == pkgpath && named.Obj().Name() == name
}
// formatState holds the parsed representation of a printf directive such as "%3.*[4]d".
formatter := false
if state.argNum < len(call.Args) {
if tv, ok := pass.TypesInfo.Types[call.Args[state.argNum]]; ok {
- formatter = isFormatter(pass, tv.Type)
+ formatter = isFormatter(tv.Type)
}
}
typ := pass.TypesInfo.Types[e].Type
// It's unlikely to be a recursive stringer if it has a Format method.
- if isFormatter(pass, typ) {
+ if isFormatter(typ) {
return false
}
import (
"go/ast"
- "go/build"
"go/types"
"golang.org/x/tools/go/analysis"
}
}
// If the type implements fmt.Formatter, we have nothing to check.
- if isFormatter(pass, typ) {
+ if isFormatter(typ) {
return true
}
// If we can use a string, might arg (dynamically) implement the Stringer or Error interface?
}
return true
}
-
-var archSizes = types.SizesFor("gc", build.Default.GOARCH)
import (
"go/ast"
- "go/build"
"go/constant"
"go/token"
- "go/types"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/passes/inspect"
if t == nil {
return
}
- b, ok := t.Underlying().(*types.Basic)
- if !ok {
- return
- }
- var size int64
- switch b.Kind() {
- case types.Uint8, types.Int8:
- size = 8
- case types.Uint16, types.Int16:
- size = 16
- case types.Uint32, types.Int32:
- size = 32
- case types.Uint64, types.Int64:
- size = 64
- case types.Int, types.Uint:
- size = uintBitSize
- case types.Uintptr:
- size = uintptrBitSize
- default:
- return
- }
+ size := 8 * pass.TypesSizes.Sizeof(t)
if amt >= size {
ident := analysisutil.Format(pass.Fset, x)
pass.Reportf(node.Pos(), "%s (%d bits) too small for shift of %d", ident, size, amt)
}
}
-
-var (
- uintBitSize = 8 * archSizes.Sizeof(types.Typ[types.Uint])
- uintptrBitSize = 8 * archSizes.Sizeof(types.Typ[types.Uintptr])
-)
-
-var archSizes = types.SizesFor("gc", build.Default.GOARCH)
}
if val == "" || val[0] == ',' {
if field.Anonymous() {
+ // Disable this check enhancement in Go 1.12.1; some
+ // false positives were spotted in the initial 1.12
+ // release. See https://golang.org/issues/30465.
+ return
+
typ, ok := field.Type().Underlying().(*types.Struct)
if !ok {
return
OtherFiles: cfg.NonGoFiles,
Pkg: pkg,
TypesInfo: info,
+ TypesSizes: tc.Sizes,
ResultOf: inputs,
Report: func(d analysis.Diagnostic) { act.diagnostics = append(act.diagnostics, d) },
ImportObjectFact: facts.ImportObjectFact,
// Experiments suggest the inspector's traversals are about 2.5x faster
// than ast.Inspect, but it may take around 5 traversals for this
// benefit to amortize the inspector's construction cost.
-// If efficiency is the primary concern, do not use use Inspector for
+// If efficiency is the primary concern, do not use Inspector for
// one-off traversals.
package inspector