From: Dan Kortschak Date: Sun, 1 Jul 2018 00:03:55 +0000 (+0930) Subject: cmd/vet,sync: check lock values more precisely X-Git-Tag: go1.11beta2~104 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=c2eba53e7f80df21d51285879d51ab81bcfbf6bc;p=gostls13.git cmd/vet,sync: check lock values more precisely Fixes #26165 Change-Id: I1f3bd193af9b6f8461c736330952b6e50d3e00d9 Reviewed-on: https://go-review.googlesource.com/121876 Reviewed-by: Alan Donovan Run-TryBot: Rob Pike TryBot-Result: Gobot Gobot --- diff --git a/src/cmd/vet/copylock.go b/src/cmd/vet/copylock.go index ce14e1af34..ed88ca8960 100644 --- a/src/cmd/vet/copylock.go +++ b/src/cmd/vet/copylock.go @@ -234,13 +234,11 @@ func lockPath(tpkg *types.Package, typ types.Type) typePath { return nil } - // We're looking for cases in which a reference to this type - // can be locked, but a value cannot. This differentiates + // We're looking for cases in which a pointer to this type + // is a sync.Locker, but a value is not. This differentiates // embedded interfaces from embedded values. - if plock := types.NewMethodSet(types.NewPointer(typ)).Lookup(tpkg, "Lock"); plock != nil { - if lock := types.NewMethodSet(typ).Lookup(tpkg, "Lock"); lock == nil { - return []types.Type{typ} - } + if types.Implements(types.NewPointer(typ), lockerType) && !types.Implements(typ, lockerType) { + return []types.Type{typ} } nfields := styp.NumFields() @@ -254,3 +252,15 @@ func lockPath(tpkg *types.Package, typ types.Type) typePath { 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() +} diff --git a/src/sync/cond.go b/src/sync/cond.go index 3dcbf1c351..b254c9360a 100644 --- a/src/sync/cond.go +++ b/src/sync/cond.go @@ -94,4 +94,5 @@ func (c *copyChecker) check() { type noCopy struct{} // Lock is a no-op used by -copylocks checker from `go vet`. -func (*noCopy) Lock() {} +func (*noCopy) Lock() {} +func (*noCopy) Unlock() {}