Commit 4af639a5 authored by Keith Randall's avatar Keith Randall Committed by Keith Randall

cmd: vendor in new version of x/tools

Fixes #35264

Change-Id: Id540a48f593d8ac1b414551255c5eff24666aa0b
Reviewed-on: https://go-review.googlesource.com/c/go/+/205240
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent ea0b4e7c
......@@ -9,5 +9,5 @@ require (
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550
golang.org/x/mod v0.1.1-0.20191029194233-18c3998b6452
golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82 // indirect
golang.org/x/tools v0.0.0-20191018203202-04252eccb9d5
golang.org/x/tools v0.0.0-20191104222624-6b7b8b79ae80
)
......@@ -18,8 +18,8 @@ golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82 h1:vsphBvatvfbhlb4PO1BYSr9dz
golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20191018203202-04252eccb9d5 h1:TFUhCYbgGMOGnRxJv+j0iAcxCjk8oGjXXWNejQBhUUs=
golang.org/x/tools v0.0.0-20191018203202-04252eccb9d5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191104222624-6b7b8b79ae80 h1:6CcDC1SXj4DrJP955osT9RJmKsH3LQBZJ59D5v4Rw0s=
golang.org/x/tools v0.0.0-20191104222624-6b7b8b79ae80/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
......
......@@ -163,13 +163,19 @@ func (pass *Pass) Reportf(pos token.Pos, format string, args ...interface{}) {
pass.Report(Diagnostic{Pos: pos, Message: msg})
}
// reportNodef is a helper function that reports a Diagnostic using the
// range denoted by the AST node.
//
// WARNING: This is an experimental API and may change in the future.
func (pass *Pass) reportNodef(node ast.Node, format string, args ...interface{}) {
// The Range interface provides a range. It's equivalent to and satisfied by
// ast.Node.
type Range interface {
Pos() token.Pos // position of first character belonging to the node
End() token.Pos // position of first character immediately after the node
}
// ReportRangef is a helper function that reports a Diagnostic using the
// range provided. ast.Node values can be passed in as the range because
// they satisfy the Range interface.
func (pass *Pass) ReportRangef(rng Range, format string, args ...interface{}) {
msg := fmt.Sprintf(format, args...)
pass.Report(Diagnostic{Pos: node.Pos(), End: node.End(), Message: msg})
pass.Report(Diagnostic{Pos: rng.Pos(), End: rng.End(), Message: msg})
}
func (pass *Pass) String() string {
......
......@@ -22,6 +22,19 @@ type Diagnostic struct {
// Diagnostics should not contain SuggestedFixes that overlap.
// Experimental: This API is experimental and may change in the future.
SuggestedFixes []SuggestedFix // optional
// Experimental: This API is experimental and may change in the future.
Related []RelatedInformation // optional
}
// RelatedInformation contains information related to a diagnostic.
// For example, a diagnostic that flags duplicated declarations of a
// variable may include one RelatedInformation per existing
// declaration.
type RelatedInformation struct {
Pos token.Pos
End token.Pos
Message string
}
// A SuggestedFix is a code change associated with a Diagnostic that a user can choose
......
......@@ -101,11 +101,13 @@ func (s *Set) ExportObjectFact(obj types.Object, fact analysis.Fact) {
func (s *Set) AllObjectFacts(filter map[reflect.Type]bool) []analysis.ObjectFact {
var facts []analysis.ObjectFact
s.mu.Lock()
for k, v := range s.m {
if k.obj != nil && filter[k.t] {
facts = append(facts, analysis.ObjectFact{Object: k.obj, Fact: v})
}
}
s.mu.Unlock()
return facts
}
......@@ -134,11 +136,13 @@ func (s *Set) ExportPackageFact(fact analysis.Fact) {
func (s *Set) AllPackageFacts(filter map[reflect.Type]bool) []analysis.PackageFact {
var facts []analysis.PackageFact
s.mu.Lock()
for k, v := range s.m {
if k.obj == nil && filter[k.t] {
facts = append(facts, analysis.PackageFact{Package: k.pkg, Fact: v})
}
}
s.mu.Unlock()
return facts
}
......@@ -227,7 +231,6 @@ func Decode(pkg *types.Package, read func(packagePath string) ([]byte, error)) (
// It may fail if one of the Facts could not be gob-encoded, but this is
// a sign of a bug in an Analyzer.
func (s *Set) Encode() []byte {
// TODO(adonovan): opt: use a more efficient encoding
// that avoids repeating PkgPath for each fact.
......
......@@ -661,6 +661,10 @@ func asmCheckVar(badf func(string, ...interface{}), fn *asmFunc, line, expr stri
src = 4
break
}
if op == "MOVO" || op == "MOVOU" {
src = 16
break
}
if strings.HasPrefix(op, "SET") {
// SETEQ, etc
src = 1
......@@ -736,6 +740,11 @@ func asmCheckVar(badf func(string, ...interface{}), fn *asmFunc, line, expr stri
vk = v.inner[0].kind
vs = v.inner[0].size
vt = v.inner[0].typ
case asmComplex:
// Allow a single instruction to load both parts of a complex.
if int(kind) == vs {
kind = asmComplex
}
}
if addr {
vk = asmKind(archDef.ptrSize)
......
......@@ -91,6 +91,6 @@ func checkAtomicAddAssignment(pass *analysis.Pass, left ast.Expr, call *ast.Call
}
if broken {
pass.Reportf(left.Pos(), "direct assignment to atomic value")
pass.ReportRangef(left, "direct assignment to atomic value")
}
}
......@@ -100,7 +100,7 @@ func (op boolOp) checkRedundant(pass *analysis.Pass, exprs []ast.Expr) {
for _, e := range exprs {
efmt := analysisutil.Format(pass.Fset, e)
if seen[efmt] {
pass.Reportf(e.Pos(), "redundant %s: %s %s %s", op.name, efmt, op.tok, efmt)
pass.ReportRangef(e, "redundant %s: %s %s %s", op.name, efmt, op.tok, efmt)
} else {
seen[efmt] = true
}
......@@ -147,7 +147,7 @@ func (op boolOp) checkSuspect(pass *analysis.Pass, exprs []ast.Expr) {
if prev, found := seen[xfmt]; found {
// checkRedundant handles the case in which efmt == prev.
if efmt != prev {
pass.Reportf(e.Pos(), "suspect %s: %s %s %s", op.name, efmt, op.tok, prev)
pass.ReportRangef(e, "suspect %s: %s %s %s", op.name, efmt, op.tok, prev)
}
} else {
seen[xfmt] = efmt
......
......@@ -97,7 +97,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
return
}
pass.Reportf(cl.Pos(), "%s composite literal uses unkeyed fields", typeName)
pass.ReportRangef(cl, "%s composite literal uses unkeyed fields", typeName)
})
return nil, nil
}
......
......@@ -74,7 +74,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
func checkCopyLocksAssign(pass *analysis.Pass, as *ast.AssignStmt) {
for i, x := range as.Rhs {
if path := lockPathRhs(pass, x); path != nil {
pass.Reportf(x.Pos(), "assignment copies lock value to %v: %v", analysisutil.Format(pass.Fset, as.Lhs[i]), path)
pass.ReportRangef(x, "assignment copies lock value to %v: %v", analysisutil.Format(pass.Fset, as.Lhs[i]), path)
}
}
}
......@@ -89,7 +89,7 @@ func checkCopyLocksGenDecl(pass *analysis.Pass, gd *ast.GenDecl) {
valueSpec := spec.(*ast.ValueSpec)
for i, x := range valueSpec.Values {
if path := lockPathRhs(pass, x); path != nil {
pass.Reportf(x.Pos(), "variable declaration copies lock value to %v: %v", valueSpec.Names[i].Name, path)
pass.ReportRangef(x, "variable declaration copies lock value to %v: %v", valueSpec.Names[i].Name, path)
}
}
}
......@@ -102,7 +102,7 @@ func checkCopyLocksCompositeLit(pass *analysis.Pass, cl *ast.CompositeLit) {
x = node.Value
}
if path := lockPathRhs(pass, x); path != nil {
pass.Reportf(x.Pos(), "literal copies lock value from %v: %v", analysisutil.Format(pass.Fset, x), path)
pass.ReportRangef(x, "literal copies lock value from %v: %v", analysisutil.Format(pass.Fset, x), path)
}
}
}
......@@ -111,7 +111,7 @@ func checkCopyLocksCompositeLit(pass *analysis.Pass, cl *ast.CompositeLit) {
func checkCopyLocksReturnStmt(pass *analysis.Pass, rs *ast.ReturnStmt) {
for _, x := range rs.Results {
if path := lockPathRhs(pass, x); path != nil {
pass.Reportf(x.Pos(), "return copies lock value: %v", path)
pass.ReportRangef(x, "return copies lock value: %v", path)
}
}
}
......@@ -133,7 +133,7 @@ func checkCopyLocksCallExpr(pass *analysis.Pass, ce *ast.CallExpr) {
}
for _, x := range ce.Args {
if path := lockPathRhs(pass, x); path != nil {
pass.Reportf(x.Pos(), "call of %s copies lock value: %v", analysisutil.Format(pass.Fset, ce.Fun), path)
pass.ReportRangef(x, "call of %s copies lock value: %v", analysisutil.Format(pass.Fset, ce.Fun), path)
}
}
}
......@@ -146,7 +146,7 @@ func checkCopyLocksFunc(pass *analysis.Pass, name string, recv *ast.FieldList, t
if recv != nil && len(recv.List) > 0 {
expr := recv.List[0].Type
if path := lockPath(pass.Pkg, pass.TypesInfo.Types[expr].Type); path != nil {
pass.Reportf(expr.Pos(), "%s passes lock by value: %v", name, path)
pass.ReportRangef(expr, "%s passes lock by value: %v", name, path)
}
}
......@@ -154,7 +154,7 @@ func checkCopyLocksFunc(pass *analysis.Pass, name string, recv *ast.FieldList, t
for _, field := range typ.Params.List {
expr := field.Type
if path := lockPath(pass.Pkg, pass.TypesInfo.Types[expr].Type); path != nil {
pass.Reportf(expr.Pos(), "%s passes lock by value: %v", name, path)
pass.ReportRangef(expr, "%s passes lock by value: %v", name, path)
}
}
}
......
......@@ -51,7 +51,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
return // not enough arguments, e.g. called with return values of another function
}
if fn.FullName() == "errors.As" && !pointerToInterfaceOrError(pass, call.Args[1]) {
pass.Reportf(call.Pos(), "second argument to errors.As must be a pointer to an interface or a type implementing error")
pass.ReportRangef(call, "second argument to errors.As must be a pointer to an interface or a type implementing error")
}
})
return nil, nil
......
......@@ -85,7 +85,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
}
if resp.Obj == root.Obj {
pass.Reportf(root.Pos(), "using %s before checking for errors", resp.Name)
pass.ReportRangef(root, "using %s before checking for errors", resp.Name)
}
return true
})
......
......@@ -16,7 +16,7 @@
//
// var Analyzer = &analysis.Analyzer{
// ...
// Requires: reflect.TypeOf(new(inspect.Analyzer)),
// Requires: []*analysis.Analyzer{inspect.Analyzer},
// }
//
// func run(pass *analysis.Pass) (interface{}, error) {
......
......@@ -119,7 +119,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
}
for _, v := range vars {
if v.Obj == id.Obj {
pass.Reportf(id.Pos(), "loop variable %s captured by func literal",
pass.ReportRangef(id, "loop variable %s captured by func literal",
id.Name)
}
}
......
......@@ -121,7 +121,7 @@ func runFunc(pass *analysis.Pass, node ast.Node) {
}
if id != nil {
if id.Name == "_" {
pass.Reportf(id.Pos(),
pass.ReportRangef(id,
"the cancel function returned by context.%s should be called, not discarded, to avoid a context leak",
n.(*ast.SelectorExpr).Sel.Name)
} else if v, ok := pass.TypesInfo.Uses[id].(*types.Var); ok {
......@@ -174,8 +174,8 @@ func runFunc(pass *analysis.Pass, node ast.Node) {
for v, stmt := range cancelvars {
if ret := lostCancelPath(pass, g, v, stmt, sig); ret != nil {
lineno := pass.Fset.Position(stmt.Pos()).Line
pass.Reportf(stmt.Pos(), "the %s function is not used on all paths (possible context leak)", v.Name())
pass.Reportf(ret.Pos(), "this return statement may be reached without using the %s var defined on line %d", v.Name(), lineno)
pass.ReportRangef(stmt, "the %s function is not used on all paths (possible context leak)", v.Name())
pass.ReportRangef(ret, "this return statement may be reached without using the %s var defined on line %d", v.Name(), lineno)
}
}
}
......
......@@ -68,7 +68,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
return
}
pass.Reportf(e.Pos(), "comparison of function %v %v nil is always %v", obj.Name(), e.Op, e.Op == token.NEQ)
pass.ReportRangef(e, "comparison of function %v %v nil is always %v", obj.Name(), e.Op, e.Op == token.NEQ)
})
return nil, nil
}
......@@ -94,6 +94,6 @@ func checkLongShift(pass *analysis.Pass, node ast.Node, x, y ast.Expr) {
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)
pass.ReportRangef(node, "%s (%d bits) too small for shift of %d", ident, size, amt)
}
}
......@@ -141,7 +141,7 @@ func canonicalMethod(pass *analysis.Pass, id *ast.Ident) {
actual = strings.TrimPrefix(actual, "func")
actual = id.Name + actual
pass.Reportf(id.Pos(), "method %s should have signature %s", actual, expectFmt)
pass.ReportRangef(id, "method %s should have signature %s", actual, expectFmt)
}
}
......
......@@ -189,7 +189,7 @@ func (d *deadState) findDead(stmt ast.Stmt) {
case *ast.EmptyStmt:
// do not warn about unreachable empty statements
default:
d.pass.Reportf(stmt.Pos(), "unreachable code")
d.pass.ReportRangef(stmt, "unreachable code")
d.reachable = true // silence error about next statement
}
}
......
......@@ -45,7 +45,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
if hasBasicType(pass.TypesInfo, x.Fun, types.UnsafePointer) &&
hasBasicType(pass.TypesInfo, x.Args[0], types.Uintptr) &&
!isSafeUintptr(pass.TypesInfo, x.Args[0]) {
pass.Reportf(x.Pos(), "possible misuse of unsafe.Pointer")
pass.ReportRangef(x, "possible misuse of unsafe.Pointer")
}
})
return nil, nil
......
......@@ -43,7 +43,7 @@ golang.org/x/mod/sumdb/tlog
## explicit
golang.org/x/sys/unix
golang.org/x/sys/windows
# golang.org/x/tools v0.0.0-20191018203202-04252eccb9d5
# golang.org/x/tools v0.0.0-20191104222624-6b7b8b79ae80
## explicit
golang.org/x/tools/go/analysis
golang.org/x/tools/go/analysis/internal/analysisflags
......
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