Commit 9ac70939 authored by Russ Cox's avatar Russ Cox

[release-branch.go1.12] cmd/vendor/golang.org/x/tools/go/analysis: update from...

[release-branch.go1.12] cmd/vendor/golang.org/x/tools/go/analysis: update from release-branch.go1.12

$ ./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: default avatarBrad Fitzpatrick <bradfitz@golang.org>
parent fd367630
...@@ -87,6 +87,7 @@ type Pass struct { ...@@ -87,6 +87,7 @@ type Pass struct {
OtherFiles []string // names of non-Go files of this package OtherFiles []string // names of non-Go files of this package
Pkg *types.Package // type information about the package Pkg *types.Package // type information about the package
TypesInfo *types.Info // type information about the syntax trees 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 // Report reports a Diagnostic, a finding about a specific location
// in the analyzed source code such as a potential mistake. // in the analyzed source code such as a potential mistake.
......
...@@ -246,7 +246,7 @@ An Analyzer that uses facts must declare their types: ...@@ -246,7 +246,7 @@ An Analyzer that uses facts must declare their types:
var Analyzer = &analysis.Analyzer{ var Analyzer = &analysis.Analyzer{
Name: "printf", Name: "printf",
FactTypes: []reflect.Type{reflect.TypeOf(new(isWrapper))}, FactTypes: []analysis.Fact{new(isWrapper)},
... ...
} }
......
...@@ -114,7 +114,8 @@ func init() { ...@@ -114,7 +114,8 @@ func init() {
// library we cannot assume types.SizesFor is consistent with arches. // library we cannot assume types.SizesFor is consistent with arches.
// For now, assume 64-bit norms and print a warning. // For now, assume 64-bit norms and print a warning.
// But this warning should really be deferred until we attempt to use // 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") arch.sizes = types.SizesFor("gc", "amd64")
log.Printf("unknown architecture %s", arch.name) log.Printf("unknown architecture %s", arch.name)
} }
......
...@@ -9,7 +9,6 @@ package cgocall ...@@ -9,7 +9,6 @@ package cgocall
import ( import (
"fmt" "fmt"
"go/ast" "go/ast"
"go/build"
"go/format" "go/format"
"go/parser" "go/parser"
"go/token" "go/token"
...@@ -45,7 +44,7 @@ func run(pass *analysis.Pass) (interface{}, error) { ...@@ -45,7 +44,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
return nil, nil // doesn't use cgo 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 { if err != nil {
return nil, err return nil, err
} }
...@@ -171,7 +170,7 @@ func checkCgo(fset *token.FileSet, f *ast.File, info *types.Info, reportf func(t ...@@ -171,7 +170,7 @@ func checkCgo(fset *token.FileSet, f *ast.File, info *types.Info, reportf func(t
// limited ourselves here to preserving function bodies and initializer // limited ourselves here to preserving function bodies and initializer
// expressions since that is all that the cgocall analyzer needs. // 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·" const thispkg = "·this·"
// Which files are cgo files? // Which files are cgo files?
...@@ -269,8 +268,7 @@ func typeCheckCgoSourceFiles(fset *token.FileSet, pkg *types.Package, files []*a ...@@ -269,8 +268,7 @@ func typeCheckCgoSourceFiles(fset *token.FileSet, pkg *types.Package, files []*a
Importer: importerFunc(func(path string) (*types.Package, error) { Importer: importerFunc(func(path string) (*types.Package, error) {
return importMap[path], nil return importMap[path], nil
}), }),
// TODO(adonovan): Sizes should probably be provided by analysis.Pass. Sizes: sizes,
Sizes: types.SizesFor("gc", build.Default.GOARCH),
Error: func(error) {}, // ignore errors (e.g. unused import) Error: func(error) {}, // ignore errors (e.g. unused import)
} }
......
...@@ -21,7 +21,16 @@ const Doc = `check for unkeyed composite literals ...@@ -21,7 +21,16 @@ const Doc = `check for unkeyed composite literals
This analyzer reports a diagnostic for composite literals of struct This analyzer reports a diagnostic for composite literals of struct
types imported from another package that do not use the field-keyed types imported from another package that do not use the field-keyed
syntax. Such literals are fragile because the addition of a new field 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{ var Analyzer = &analysis.Analyzer{
Name: "composites", Name: "composites",
......
...@@ -8,7 +8,11 @@ ...@@ -8,7 +8,11 @@
// //
// Example of use in another analysis: // 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{ // var Analyzer = &analysis.Analyzer{
// ... // ...
......
...@@ -453,15 +453,23 @@ func printfNameAndKind(pass *analysis.Pass, call *ast.CallExpr) (fn *types.Func, ...@@ -453,15 +453,23 @@ func printfNameAndKind(pass *analysis.Pass, call *ast.CallExpr) (fn *types.Func,
} }
// isFormatter reports whether t satisfies fmt.Formatter. // isFormatter reports whether t satisfies fmt.Formatter.
// Unlike fmt.Stringer, it's impossible to satisfy fmt.Formatter without importing fmt. // The only interface method to look for is "Format(State, rune)".
func isFormatter(pass *analysis.Pass, t types.Type) bool { func isFormatter(typ types.Type) bool {
for _, imp := range pass.Pkg.Imports() { obj, _, _ := types.LookupFieldOrMethod(typ, false, nil, "Format")
if imp.Path() == "fmt" { fn, ok := obj.(*types.Func)
formatter := imp.Scope().Lookup("Formatter").Type().Underlying().(*types.Interface) if !ok {
return types.Implements(t, formatter)
}
}
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". // formatState holds the parsed representation of a printf directive such as "%3.*[4]d".
...@@ -753,7 +761,7 @@ func okPrintfArg(pass *analysis.Pass, call *ast.CallExpr, state *formatState) (o ...@@ -753,7 +761,7 @@ func okPrintfArg(pass *analysis.Pass, call *ast.CallExpr, state *formatState) (o
formatter := false formatter := false
if state.argNum < len(call.Args) { if state.argNum < len(call.Args) {
if tv, ok := pass.TypesInfo.Types[call.Args[state.argNum]]; ok { if tv, ok := pass.TypesInfo.Types[call.Args[state.argNum]]; ok {
formatter = isFormatter(pass, tv.Type) formatter = isFormatter(tv.Type)
} }
} }
...@@ -831,7 +839,7 @@ func recursiveStringer(pass *analysis.Pass, e ast.Expr) bool { ...@@ -831,7 +839,7 @@ func recursiveStringer(pass *analysis.Pass, e ast.Expr) bool {
typ := pass.TypesInfo.Types[e].Type typ := pass.TypesInfo.Types[e].Type
// It's unlikely to be a recursive stringer if it has a Format method. // It's unlikely to be a recursive stringer if it has a Format method.
if isFormatter(pass, typ) { if isFormatter(typ) {
return false return false
} }
......
...@@ -2,7 +2,6 @@ package printf ...@@ -2,7 +2,6 @@ package printf
import ( import (
"go/ast" "go/ast"
"go/build"
"go/types" "go/types"
"golang.org/x/tools/go/analysis" "golang.org/x/tools/go/analysis"
...@@ -39,7 +38,7 @@ func matchArgTypeInternal(pass *analysis.Pass, t printfArgType, typ types.Type, ...@@ -39,7 +38,7 @@ func matchArgTypeInternal(pass *analysis.Pass, t printfArgType, typ types.Type,
} }
} }
// If the type implements fmt.Formatter, we have nothing to check. // If the type implements fmt.Formatter, we have nothing to check.
if isFormatter(pass, typ) { if isFormatter(typ) {
return true return true
} }
// If we can use a string, might arg (dynamically) implement the Stringer or Error interface? // If we can use a string, might arg (dynamically) implement the Stringer or Error interface?
...@@ -235,5 +234,3 @@ func matchStructArgType(pass *analysis.Pass, t printfArgType, typ *types.Struct, ...@@ -235,5 +234,3 @@ func matchStructArgType(pass *analysis.Pass, t printfArgType, typ *types.Struct,
} }
return true return true
} }
var archSizes = types.SizesFor("gc", build.Default.GOARCH)
...@@ -12,10 +12,8 @@ package shift ...@@ -12,10 +12,8 @@ package shift
import ( import (
"go/ast" "go/ast"
"go/build"
"go/constant" "go/constant"
"go/token" "go/token"
"go/types"
"golang.org/x/tools/go/analysis" "golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/passes/inspect" "golang.org/x/tools/go/analysis/passes/inspect"
...@@ -93,36 +91,9 @@ func checkLongShift(pass *analysis.Pass, node ast.Node, x, y ast.Expr) { ...@@ -93,36 +91,9 @@ func checkLongShift(pass *analysis.Pass, node ast.Node, x, y ast.Expr) {
if t == nil { if t == nil {
return return
} }
b, ok := t.Underlying().(*types.Basic) size := 8 * pass.TypesSizes.Sizeof(t)
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
}
if amt >= size { if amt >= size {
ident := analysisutil.Format(pass.Fset, x) ident := analysisutil.Format(pass.Fset, x)
pass.Reportf(node.Pos(), "%s (%d bits) too small for shift of %d", ident, size, amt) 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)
...@@ -96,6 +96,11 @@ func checkTagDuplicates(pass *analysis.Pass, tag, key string, nearest, field *ty ...@@ -96,6 +96,11 @@ func checkTagDuplicates(pass *analysis.Pass, tag, key string, nearest, field *ty
} }
if val == "" || val[0] == ',' { if val == "" || val[0] == ',' {
if field.Anonymous() { 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) typ, ok := field.Type().Underlying().(*types.Struct)
if !ok { if !ok {
return return
......
...@@ -329,6 +329,7 @@ func run(fset *token.FileSet, cfg *Config, analyzers []*analysis.Analyzer) ([]re ...@@ -329,6 +329,7 @@ func run(fset *token.FileSet, cfg *Config, analyzers []*analysis.Analyzer) ([]re
OtherFiles: cfg.NonGoFiles, OtherFiles: cfg.NonGoFiles,
Pkg: pkg, Pkg: pkg,
TypesInfo: info, TypesInfo: info,
TypesSizes: tc.Sizes,
ResultOf: inputs, ResultOf: inputs,
Report: func(d analysis.Diagnostic) { act.diagnostics = append(act.diagnostics, d) }, Report: func(d analysis.Diagnostic) { act.diagnostics = append(act.diagnostics, d) },
ImportObjectFact: facts.ImportObjectFact, ImportObjectFact: facts.ImportObjectFact,
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
// Experiments suggest the inspector's traversals are about 2.5x faster // Experiments suggest the inspector's traversals are about 2.5x faster
// than ast.Inspect, but it may take around 5 traversals for this // than ast.Inspect, but it may take around 5 traversals for this
// benefit to amortize the inspector's construction cost. // 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. // one-off traversals.
package inspector package inspector
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment