1
0
mirror of https://github.com/golang/go synced 2024-09-24 17:20:12 -06: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:
Josh Bleecher Snyder 2015-06-12 19:49:45 -07:00
parent cb2d02c803
commit ff8f3f0fa1
2 changed files with 19 additions and 12 deletions

View File

@ -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)
}
}
}

View File

@ -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
}