github.com/sean-/go@v0.0.0-20151219100004-97f854cd7bb6/src/cmd/vet/testdata/copylock_func.go (about) 1 // Copyright 2013 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // This file contains tests for the copylock checker's 6 // function declaration analysis. 7 8 package testdata 9 10 import "sync" 11 12 func OkFunc(*sync.Mutex) {} 13 func BadFunc(sync.Mutex) {} // ERROR "BadFunc passes lock by value: sync.Mutex" 14 func OkRet() *sync.Mutex {} 15 func BadRet() sync.Mutex {} // ERROR "BadRet returns lock by value: sync.Mutex" 16 17 var ( 18 OkClosure = func(*sync.Mutex) {} 19 BadClosure = func(sync.Mutex) {} // ERROR "func passes lock by value: sync.Mutex" 20 ) 21 22 type EmbeddedRWMutex struct { 23 sync.RWMutex 24 } 25 26 func (*EmbeddedRWMutex) OkMeth() {} 27 func (EmbeddedRWMutex) BadMeth() {} // ERROR "BadMeth passes lock by value: testdata.EmbeddedRWMutex" 28 func OkFunc(e *EmbeddedRWMutex) {} 29 func BadFunc(EmbeddedRWMutex) {} // ERROR "BadFunc passes lock by value: testdata.EmbeddedRWMutex" 30 func OkRet() *EmbeddedRWMutex {} 31 func BadRet() EmbeddedRWMutex {} // ERROR "BadRet returns lock by value: testdata.EmbeddedRWMutex" 32 33 type FieldMutex struct { 34 s sync.Mutex 35 } 36 37 func (*FieldMutex) OkMeth() {} 38 func (FieldMutex) BadMeth() {} // ERROR "BadMeth passes lock by value: testdata.FieldMutex contains sync.Mutex" 39 func OkFunc(*FieldMutex) {} 40 func BadFunc(FieldMutex, int) {} // ERROR "BadFunc passes lock by value: testdata.FieldMutex contains sync.Mutex" 41 42 type L0 struct { 43 L1 44 } 45 46 type L1 struct { 47 l L2 48 } 49 50 type L2 struct { 51 sync.Mutex 52 } 53 54 func (*L0) Ok() {} 55 func (L0) Bad() {} // ERROR "Bad passes lock by value: testdata.L0 contains testdata.L1 contains testdata.L2" 56 57 type EmbeddedMutexPointer struct { 58 s *sync.Mutex // safe to copy this pointer 59 } 60 61 func (*EmbeddedMutexPointer) Ok() {} 62 func (EmbeddedMutexPointer) AlsoOk() {} 63 func StillOk(EmbeddedMutexPointer) {} 64 func LookinGood() EmbeddedMutexPointer {} 65 66 type EmbeddedLocker struct { 67 sync.Locker // safe to copy interface values 68 } 69 70 func (*EmbeddedLocker) Ok() {} 71 func (EmbeddedLocker) AlsoOk() {} 72 73 type CustomLock struct{} 74 75 func (*CustomLock) Lock() {} 76 func (*CustomLock) Unlock() {} 77 78 func Ok(*CustomLock) {} 79 func Bad(CustomLock) {} // ERROR "Bad passes lock by value: testdata.CustomLock" 80 81 // TODO: Unfortunate cases 82 83 // Non-ideal error message: 84 // Since we're looking for Lock methods, sync.Once's underlying 85 // sync.Mutex gets called out, but without any reference to the sync.Once. 86 type LocalOnce sync.Once 87 88 func (LocalOnce) Bad() {} // ERROR "Bad passes lock by value: testdata.LocalOnce contains sync.Mutex" 89 90 // False negative: 91 // LocalMutex doesn't have a Lock method. 92 // Nevertheless, it is probably a bad idea to pass it by value. 93 type LocalMutex sync.Mutex 94 95 func (LocalMutex) Bad() {} // WANTED: An error here :(