]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/vet,sync: check lock values more precisely
authorDan Kortschak <dan@kortschak.io>
Sun, 1 Jul 2018 00:03:55 +0000 (09:33 +0930)
committerRob Pike <r@golang.org>
Sat, 14 Jul 2018 06:48:21 +0000 (06:48 +0000)
Fixes #26165

Change-Id: I1f3bd193af9b6f8461c736330952b6e50d3e00d9
Reviewed-on: https://go-review.googlesource.com/121876
Reviewed-by: Alan Donovan <adonovan@google.com>
Run-TryBot: Rob Pike <r@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/vet/copylock.go
src/sync/cond.go

index ce14e1af3439b0a0107371ba0792c5ce40d42287..ed88ca89603a43ff34961f2ebf8c4a7a82ac440f 100644 (file)
@@ -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()
+}
index 3dcbf1c3512f30d48c8e4758398cc81d3f04a3cc..b254c9360ac8b34f5e72ba10d7fc6d6d3d2a95cd 100644 (file)
@@ -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() {}