Commit c2eba53e authored by Dan Kortschak's avatar Dan Kortschak Committed by Rob Pike

cmd/vet,sync: check lock values more precisely

Fixes #26165

Change-Id: I1f3bd193af9b6f8461c736330952b6e50d3e00d9
Reviewed-on: https://go-review.googlesource.com/121876Reviewed-by: default avatarAlan Donovan <adonovan@google.com>
Run-TryBot: Rob Pike <r@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 00ebfcde
...@@ -234,13 +234,11 @@ func lockPath(tpkg *types.Package, typ types.Type) typePath { ...@@ -234,13 +234,11 @@ func lockPath(tpkg *types.Package, typ types.Type) typePath {
return nil return nil
} }
// We're looking for cases in which a reference to this type // We're looking for cases in which a pointer to this type
// can be locked, but a value cannot. This differentiates // is a sync.Locker, but a value is not. This differentiates
// embedded interfaces from embedded values. // embedded interfaces from embedded values.
if plock := types.NewMethodSet(types.NewPointer(typ)).Lookup(tpkg, "Lock"); plock != nil { if types.Implements(types.NewPointer(typ), lockerType) && !types.Implements(typ, lockerType) {
if lock := types.NewMethodSet(typ).Lookup(tpkg, "Lock"); lock == nil { return []types.Type{typ}
return []types.Type{typ}
}
} }
nfields := styp.NumFields() nfields := styp.NumFields()
...@@ -254,3 +252,15 @@ func lockPath(tpkg *types.Package, typ types.Type) typePath { ...@@ -254,3 +252,15 @@ func lockPath(tpkg *types.Package, typ types.Type) typePath {
return nil return nil
} }
var lockerType *types.Interface
// Construct a sync.Locker interface type.
func init() {
nullary := types.NewSignature(nil, nil, nil, false) // func()
methods := []*types.Func{
types.NewFunc(token.NoPos, nil, "Lock", nullary),
types.NewFunc(token.NoPos, nil, "Unlock", nullary),
}
lockerType = types.NewInterface(methods, nil).Complete()
}
...@@ -94,4 +94,5 @@ func (c *copyChecker) check() { ...@@ -94,4 +94,5 @@ func (c *copyChecker) check() {
type noCopy struct{} type noCopy struct{}
// Lock is a no-op used by -copylocks checker from `go vet`. // Lock is a no-op used by -copylocks checker from `go vet`.
func (*noCopy) Lock() {} func (*noCopy) Lock() {}
func (*noCopy) Unlock() {}
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