]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/vet: fix copylocks false positive on unsafe.Sizeof(mutex)
authorWei Congrui <crvv.mail@gmail.com>
Tue, 26 Sep 2017 10:20:36 +0000 (18:20 +0800)
committerRobert Griesemer <gri@golang.org>
Wed, 18 Oct 2017 19:57:28 +0000 (19:57 +0000)
Fixes #21800

Change-Id: I6c61d3543f28e9951b2a219b3c7298077b38f29e
Reviewed-on: https://go-review.googlesource.com/66210
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
src/cmd/vet/copylock.go
src/cmd/vet/testdata/copylock.go

index 27eb5d465174dd7a75a477d4386fdd7bf6156176..ce14e1af3439b0a0107371ba0792c5ce40d42287 100644 (file)
@@ -93,9 +93,16 @@ func checkCopyLocksReturnStmt(f *File, rs *ast.ReturnStmt) {
 
 // checkCopyLocksCallExpr detects lock copy in the arguments to a function call
 func checkCopyLocksCallExpr(f *File, ce *ast.CallExpr) {
-       if id, ok := ce.Fun.(*ast.Ident); ok && f.pkg.types[id].IsBuiltin() {
-               switch id.Name {
-               case "new", "len", "cap":
+       var id *ast.Ident
+       switch fun := ce.Fun.(type) {
+       case *ast.Ident:
+               id = fun
+       case *ast.SelectorExpr:
+               id = fun.Sel
+       }
+       if fun, ok := f.pkg.uses[id].(*types.Builtin); ok {
+               switch fun.Name() {
+               case "new", "len", "cap", "Sizeof":
                        return
                }
        }
index 6fabbc337a0d6ac5865ca7fc8684551ac0ab4a7f..d733488e6218b55778458d7ff37125c3e5a16787 100644 (file)
@@ -3,6 +3,9 @@ package testdata
 import (
        "sync"
        "sync/atomic"
+       "unsafe"
+       . "unsafe"
+       unsafe1 "unsafe"
 )
 
 func OkFunc() {
@@ -102,6 +105,17 @@ func LenAndCapOnLockArrays() {
        cap(a) // ERROR "call of cap copies lock value: sync.Mutex"
 }
 
+func SizeofMutex() {
+       var mu sync.Mutex
+       unsafe.Sizeof(mu)  // OK
+       unsafe1.Sizeof(mu) // OK
+       Sizeof(mu)         // OK
+       unsafe := struct{ Sizeof func(interface{}) }{}
+       unsafe.Sizeof(mu) // ERROR "call of unsafe.Sizeof copies lock value: sync.Mutex"
+       Sizeof := func(interface{}) {}
+       Sizeof(mu) // ERROR "call of Sizeof copies lock value: sync.Mutex"
+}
+
 // SyncTypesCheck checks copying of sync.* types except sync.Mutex
 func SyncTypesCheck() {
        // sync.RWMutex copying