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 :(