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.
5 // This file contains tests for the copylock checker's
6 // function declaration analysis.
12 func OkFunc(*sync
.Mutex
) {}
13 func BadFunc(sync
.Mutex
) {} // ERROR "BadFunc passes lock by value: sync.Mutex"
14 func BadFunc2(sync
.Map
) {} // ERROR "BadFunc2 passes lock by value: sync.Map contains sync.Mutex"
15 func OkRet() *sync
.Mutex
{}
16 func BadRet() sync
.Mutex
{} // Don't warn about results
19 OkClosure
= func(*sync
.Mutex
) {}
20 BadClosure
= func(sync
.Mutex
) {} // ERROR "func passes lock by value: sync.Mutex"
21 BadClosure2
= func(sync
.Map
) {} // ERROR "func passes lock by value: sync.Map contains sync.Mutex"
24 type EmbeddedRWMutex
struct {
28 func (*EmbeddedRWMutex
) OkMeth() {}
29 func (EmbeddedRWMutex
) BadMeth() {} // ERROR "BadMeth passes lock by value: testdata.EmbeddedRWMutex"
30 func OkFunc(e
*EmbeddedRWMutex
) {}
31 func BadFunc(EmbeddedRWMutex
) {} // ERROR "BadFunc passes lock by value: testdata.EmbeddedRWMutex"
32 func OkRet() *EmbeddedRWMutex
{}
33 func BadRet() EmbeddedRWMutex
{} // Don't warn about results
35 type FieldMutex
struct {
39 func (*FieldMutex
) OkMeth() {}
40 func (FieldMutex
) BadMeth() {} // ERROR "BadMeth passes lock by value: testdata.FieldMutex contains sync.Mutex"
41 func OkFunc(*FieldMutex
) {}
42 func BadFunc(FieldMutex
, int) {} // ERROR "BadFunc passes lock by value: testdata.FieldMutex contains sync.Mutex"
57 func (L0
) Bad() {} // ERROR "Bad passes lock by value: testdata.L0 contains testdata.L1 contains testdata.L2"
59 type EmbeddedMutexPointer
struct {
60 s
*sync
.Mutex
// safe to copy this pointer
63 func (*EmbeddedMutexPointer
) Ok() {}
64 func (EmbeddedMutexPointer
) AlsoOk() {}
65 func StillOk(EmbeddedMutexPointer
) {}
66 func LookinGood() EmbeddedMutexPointer
{}
68 type EmbeddedLocker
struct {
69 sync
.Locker
// safe to copy interface values
72 func (*EmbeddedLocker
) Ok() {}
73 func (EmbeddedLocker
) AlsoOk() {}
75 type CustomLock
struct{}
77 func (*CustomLock
) Lock() {}
78 func (*CustomLock
) Unlock() {}
80 func Ok(*CustomLock
) {}
81 func Bad(CustomLock
) {} // ERROR "Bad passes lock by value: testdata.CustomLock"
83 // Passing lock values into interface function arguments
84 func FuncCallInterfaceArg(f
func(a
int, b
interface{})) {
86 var t
struct{ lock sync
.Mutex
}
91 f(4, m
) // ERROR "call of f copies lock value: sync.Mutex"
92 f(5, t
) // ERROR "call of f copies lock value: struct.lock sync.Mutex. contains sync.Mutex"
94 fntab
[0](t
) // ERROR "call of fntab.0. copies lock value: struct.lock sync.Mutex. contains sync.Mutex"
97 // Returning lock via interface value
98 func ReturnViaInterface(x
int) (int, interface{}) {
100 var t
struct{ lock sync
.Mutex
}
106 return 1, &sync
.Mutex
{}
108 return 2, m
// ERROR "return copies lock value: sync.Mutex"
110 return 3, t
// ERROR "return copies lock value: struct.lock sync.Mutex. contains sync.Mutex"
114 // Some cases that we don't warn about.
116 func AcceptedCases() {
117 x
:= EmbeddedRwMutex
{} // composite literal on RHS is OK (#16227)
118 x
= BadRet() // function call on RHS is OK (#16227)
119 x
= *OKRet() // indirection of function call on RHS is OK (#16227)
122 // TODO: Unfortunate cases
124 // Non-ideal error message:
125 // Since we're looking for Lock methods, sync.Once's underlying
126 // sync.Mutex gets called out, but without any reference to the sync.Once.
127 type LocalOnce sync
.Once
129 func (LocalOnce
) Bad() {} // ERROR "Bad passes lock by value: testdata.LocalOnce contains sync.Mutex"
132 // LocalMutex doesn't have a Lock method.
133 // Nevertheless, it is probably a bad idea to pass it by value.
134 type LocalMutex sync
.Mutex
136 func (LocalMutex
) Bad() {} // WANTED: An error here :(