Commit 3c92bdc7 authored by Daniel Martí's avatar Daniel Martí

cmd/vendor: update to golang.org/x/tools@139d099f

Mainly to pull the fix for the regression in #28792.

Change-Id: If71ae783fd9a9e3935186b49fdf501ba098235a2
Reviewed-on: https://go-review.googlesource.com/c/150161
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarAlan Donovan <adonovan@google.com>
parent bc438895
...@@ -16,7 +16,7 @@ import ( ...@@ -16,7 +16,7 @@ import (
"golang.org/x/tools/go/ast/inspector" "golang.org/x/tools/go/ast/inspector"
) )
const Doc = `checked for unkeyed composite literals 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
......
...@@ -93,32 +93,32 @@ func runFunc(pass *analysis.Pass, node ast.Node) { ...@@ -93,32 +93,32 @@ func runFunc(pass *analysis.Pass, node ast.Node) {
// ctx, cancel = context.WithCancel(...) // ctx, cancel = context.WithCancel(...)
// var ctx, cancel = context.WithCancel(...) // var ctx, cancel = context.WithCancel(...)
// //
if isContextWithCancel(pass.TypesInfo, n) && isCall(stack[len(stack)-2]) { if !isContextWithCancel(pass.TypesInfo, n) || !isCall(stack[len(stack)-2]) {
var id *ast.Ident // id of cancel var return true
stmt := stack[len(stack)-3] }
switch stmt := stmt.(type) { var id *ast.Ident // id of cancel var
case *ast.ValueSpec: stmt := stack[len(stack)-3]
if len(stmt.Names) > 1 { switch stmt := stmt.(type) {
id = stmt.Names[1] case *ast.ValueSpec:
} if len(stmt.Names) > 1 {
case *ast.AssignStmt: id = stmt.Names[1]
if len(stmt.Lhs) > 1 {
id, _ = stmt.Lhs[1].(*ast.Ident)
}
} }
if id != nil { case *ast.AssignStmt:
if id.Name == "_" { if len(stmt.Lhs) > 1 {
pass.Reportf(id.Pos(), id, _ = stmt.Lhs[1].(*ast.Ident)
"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 { if id != nil {
cancelvars[v] = stmt if id.Name == "_" {
} else if v, ok := pass.TypesInfo.Defs[id].(*types.Var); ok { pass.Reportf(id.Pos(),
cancelvars[v] = stmt "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 {
cancelvars[v] = stmt
} else if v, ok := pass.TypesInfo.Defs[id].(*types.Var); ok {
cancelvars[v] = stmt
} }
} }
return true return true
}) })
...@@ -179,18 +179,22 @@ func hasImport(pkg *types.Package, path string) bool { ...@@ -179,18 +179,22 @@ func hasImport(pkg *types.Package, path string) bool {
// isContextWithCancel reports whether n is one of the qualified identifiers // isContextWithCancel reports whether n is one of the qualified identifiers
// context.With{Cancel,Timeout,Deadline}. // context.With{Cancel,Timeout,Deadline}.
func isContextWithCancel(info *types.Info, n ast.Node) bool { func isContextWithCancel(info *types.Info, n ast.Node) bool {
if sel, ok := n.(*ast.SelectorExpr); ok { sel, ok := n.(*ast.SelectorExpr)
switch sel.Sel.Name { if !ok {
case "WithCancel", "WithTimeout", "WithDeadline": return false
if x, ok := sel.X.(*ast.Ident); ok { }
if pkgname, ok := info.Uses[x].(*types.PkgName); ok { switch sel.Sel.Name {
return pkgname.Imported().Path() == contextPackage case "WithCancel", "WithTimeout", "WithDeadline":
} default:
// Import failed, so we can't check package path. return false
// Just check the local package name (heuristic). }
return x.Name == "context" if x, ok := sel.X.(*ast.Ident); ok {
} if pkgname, ok := info.Uses[x].(*types.PkgName); ok {
return pkgname.Imported().Path() == contextPackage
} }
// Import failed, so we can't check package path.
// Just check the local package name (heuristic).
return x.Name == "context"
} }
return false return false
} }
...@@ -270,29 +274,30 @@ outer: ...@@ -270,29 +274,30 @@ outer:
var search func(blocks []*cfg.Block) *ast.ReturnStmt var search func(blocks []*cfg.Block) *ast.ReturnStmt
search = func(blocks []*cfg.Block) *ast.ReturnStmt { search = func(blocks []*cfg.Block) *ast.ReturnStmt {
for _, b := range blocks { for _, b := range blocks {
if !seen[b] { if seen[b] {
seen[b] = true continue
}
seen[b] = true
// Prune the search if the block uses v. // Prune the search if the block uses v.
if blockUses(pass, v, b) { if blockUses(pass, v, b) {
continue continue
} }
// Found path to return statement? // Found path to return statement?
if ret := b.Return(); ret != nil { if ret := b.Return(); ret != nil {
if debug { if debug {
fmt.Printf("found path to return in block %s\n", b) fmt.Printf("found path to return in block %s\n", b)
}
return ret // found
} }
return ret // found
}
// Recur // Recur
if ret := search(b.Succs); ret != nil { if ret := search(b.Succs); ret != nil {
if debug { if debug {
fmt.Printf(" from block %s\n", b) fmt.Printf(" from block %s\n", b)
}
return ret
} }
return ret
} }
} }
return nil return nil
......
...@@ -131,7 +131,7 @@ func canonicalMethod(pass *analysis.Pass, id *ast.Ident) { ...@@ -131,7 +131,7 @@ func canonicalMethod(pass *analysis.Pass, id *ast.Ident) {
expectFmt += " (" + argjoin(expect.results) + ")" expectFmt += " (" + argjoin(expect.results) + ")"
} }
actual := types.TypeString(sign, (*types.Package).Name) actual := typeString(sign)
actual = strings.TrimPrefix(actual, "func") actual = strings.TrimPrefix(actual, "func")
actual = id.Name + actual actual = id.Name + actual
...@@ -139,6 +139,10 @@ func canonicalMethod(pass *analysis.Pass, id *ast.Ident) { ...@@ -139,6 +139,10 @@ func canonicalMethod(pass *analysis.Pass, id *ast.Ident) {
} }
} }
func typeString(typ types.Type) string {
return types.TypeString(typ, (*types.Package).Name)
}
func argjoin(x []string) string { func argjoin(x []string) string {
y := make([]string, len(x)) y := make([]string, len(x))
for i, s := range x { for i, s := range x {
...@@ -178,5 +182,5 @@ func matchParamType(fset *token.FileSet, pkg *types.Package, expect string, actu ...@@ -178,5 +182,5 @@ func matchParamType(fset *token.FileSet, pkg *types.Package, expect string, actu
} }
// Overkill but easy. // Overkill but easy.
return actual.String() == expect return typeString(actual) == expect
} }
...@@ -62,28 +62,28 @@ func isSafeUintptr(info *types.Info, x ast.Expr) bool { ...@@ -62,28 +62,28 @@ func isSafeUintptr(info *types.Info, x ast.Expr) bool {
return isSafeUintptr(info, x.X) return isSafeUintptr(info, x.X)
case *ast.SelectorExpr: case *ast.SelectorExpr:
switch x.Sel.Name { if x.Sel.Name != "Data" {
case "Data": break
// reflect.SliceHeader and reflect.StringHeader are okay, }
// but only if they are pointing at a real slice or string. // reflect.SliceHeader and reflect.StringHeader are okay,
// It's not okay to do: // but only if they are pointing at a real slice or string.
// var x SliceHeader // It's not okay to do:
// x.Data = uintptr(unsafe.Pointer(...)) // var x SliceHeader
// ... use x ... // x.Data = uintptr(unsafe.Pointer(...))
// p := unsafe.Pointer(x.Data) // ... use x ...
// because in the middle the garbage collector doesn't // p := unsafe.Pointer(x.Data)
// see x.Data as a pointer and so x.Data may be dangling // because in the middle the garbage collector doesn't
// by the time we get to the conversion at the end. // see x.Data as a pointer and so x.Data may be dangling
// For now approximate by saying that *Header is okay // by the time we get to the conversion at the end.
// but Header is not. // For now approximate by saying that *Header is okay
pt, ok := info.Types[x.X].Type.(*types.Pointer) // but Header is not.
if ok { pt, ok := info.Types[x.X].Type.(*types.Pointer)
t, ok := pt.Elem().(*types.Named) if ok {
if ok && t.Obj().Pkg().Path() == "reflect" { t, ok := pt.Elem().(*types.Named)
switch t.Obj().Name() { if ok && t.Obj().Pkg().Path() == "reflect" {
case "StringHeader", "SliceHeader": switch t.Obj().Name() {
return true case "StringHeader", "SliceHeader":
} return true
} }
} }
} }
......
...@@ -95,7 +95,7 @@ func Main(analyzers ...*analysis.Analyzer) { ...@@ -95,7 +95,7 @@ func Main(analyzers ...*analysis.Analyzer) {
Usage of %[1]s: Usage of %[1]s:
%.16[1]s unit.cfg # execute analysis specified by config file %.16[1]s unit.cfg # execute analysis specified by config file
%.16[1]s help # general help %.16[1]s help # general help
%.16[1]s help name # help on specific analyzer and its flags %.16[1]s help name # help on specific analyzer and its flags
`, progname) `, progname)
os.Exit(1) os.Exit(1)
......
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