mirror of
https://github.com/golang/go
synced 2024-11-12 04:00:23 -07:00
cmd/vet: extend copylocks to anonymous functions
Running -copylocks over a large corpus generates 1507 warnings. Of those, only 3 are from the new anonymous function check, but they are all bugs. Fixes #10927. Change-Id: I2672f6871036bed711beec5f88bc39aa8b3b6a94 Reviewed-on: https://go-review.googlesource.com/11051 Reviewed-by: Rob Pike <r@golang.org>
This commit is contained in:
parent
cb2d02c803
commit
ff8f3f0fa1
@ -18,7 +18,7 @@ func init() {
|
||||
register("copylocks",
|
||||
"check that locks are not passed by value",
|
||||
checkCopyLocks,
|
||||
funcDecl, rangeStmt)
|
||||
funcDecl, rangeStmt, funcLit)
|
||||
}
|
||||
|
||||
// checkCopyLocks checks whether node might
|
||||
@ -28,7 +28,9 @@ func checkCopyLocks(f *File, node ast.Node) {
|
||||
case *ast.RangeStmt:
|
||||
checkCopyLocksRange(f, node)
|
||||
case *ast.FuncDecl:
|
||||
checkCopyLocksFunc(f, node)
|
||||
checkCopyLocksFunc(f, node.Name.Name, node.Recv, node.Type)
|
||||
case *ast.FuncLit:
|
||||
checkCopyLocksFunc(f, "func", nil, node.Type)
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,28 +38,28 @@ func checkCopyLocks(f *File, node ast.Node) {
|
||||
// inadvertently copy a lock, by checking whether
|
||||
// its receiver, parameters, or return values
|
||||
// are locks.
|
||||
func checkCopyLocksFunc(f *File, d *ast.FuncDecl) {
|
||||
if d.Recv != nil && len(d.Recv.List) > 0 {
|
||||
expr := d.Recv.List[0].Type
|
||||
func checkCopyLocksFunc(f *File, name string, recv *ast.FieldList, typ *ast.FuncType) {
|
||||
if recv != nil && len(recv.List) > 0 {
|
||||
expr := recv.List[0].Type
|
||||
if path := lockPath(f.pkg.typesPkg, f.pkg.types[expr].Type); path != nil {
|
||||
f.Badf(expr.Pos(), "%s passes Lock by value: %v", d.Name.Name, path)
|
||||
f.Badf(expr.Pos(), "%s passes Lock by value: %v", name, path)
|
||||
}
|
||||
}
|
||||
|
||||
if d.Type.Params != nil {
|
||||
for _, field := range d.Type.Params.List {
|
||||
if typ.Params != nil {
|
||||
for _, field := range typ.Params.List {
|
||||
expr := field.Type
|
||||
if path := lockPath(f.pkg.typesPkg, f.pkg.types[expr].Type); path != nil {
|
||||
f.Badf(expr.Pos(), "%s passes Lock by value: %v", d.Name.Name, path)
|
||||
f.Badf(expr.Pos(), "%s passes Lock by value: %v", name, path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if d.Type.Results != nil {
|
||||
for _, field := range d.Type.Results.List {
|
||||
if typ.Results != nil {
|
||||
for _, field := range typ.Results.List {
|
||||
expr := field.Type
|
||||
if path := lockPath(f.pkg.typesPkg, f.pkg.types[expr].Type); path != nil {
|
||||
f.Badf(expr.Pos(), "%s returns Lock by value: %v", d.Name.Name, path)
|
||||
f.Badf(expr.Pos(), "%s returns Lock by value: %v", name, path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
5
src/cmd/vet/testdata/copylock_func.go
vendored
5
src/cmd/vet/testdata/copylock_func.go
vendored
@ -14,6 +14,11 @@ func BadFunc(sync.Mutex) {} // ERROR "BadFunc passes Lock by value: sync.Mutex"
|
||||
func OkRet() *sync.Mutex {}
|
||||
func BadRet() sync.Mutex {} // ERROR "BadRet returns Lock by value: sync.Mutex"
|
||||
|
||||
var (
|
||||
OkClosure = func(*sync.Mutex) {}
|
||||
BadClosure = func(sync.Mutex) {} // ERROR "func passes Lock by value: sync.Mutex"
|
||||
)
|
||||
|
||||
type EmbeddedRWMutex struct {
|
||||
sync.RWMutex
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user