Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201105173854-bc9fc8d8c4bc / go / analysis / passes / copylock / testdata / src / a / copylock_func.go
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 a
9
10 import "sync"
11
12 func OkFunc(*sync.Mutex) {}
13 func BadFunc(sync.Mutex) {} // want "BadFunc passes lock by value: sync.Mutex"
14 func BadFunc2(sync.Map)  {} // want "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
17
18 var (
19         OkClosure   = func(*sync.Mutex) {}
20         BadClosure  = func(sync.Mutex) {} // want "func passes lock by value: sync.Mutex"
21         BadClosure2 = func(sync.Map) {}   // want "func passes lock by value: sync.Map contains sync.Mutex"
22 )
23
24 type EmbeddedRWMutex struct {
25         sync.RWMutex
26 }
27
28 func (*EmbeddedRWMutex) OkMeth() {}
29 func (EmbeddedRWMutex) BadMeth() {} // want "BadMeth passes lock by value: a.EmbeddedRWMutex"
30 func OkFunc(e *EmbeddedRWMutex)  {}
31 func BadFunc(EmbeddedRWMutex)    {} // want "BadFunc passes lock by value: a.EmbeddedRWMutex"
32 func OkRet() *EmbeddedRWMutex    {}
33 func BadRet() EmbeddedRWMutex    {} // Don't warn about results
34
35 type FieldMutex struct {
36         s sync.Mutex
37 }
38
39 func (*FieldMutex) OkMeth()   {}
40 func (FieldMutex) BadMeth()   {} // want "BadMeth passes lock by value: a.FieldMutex contains sync.Mutex"
41 func OkFunc(*FieldMutex)      {}
42 func BadFunc(FieldMutex, int) {} // want "BadFunc passes lock by value: a.FieldMutex contains sync.Mutex"
43
44 type L0 struct {
45         L1
46 }
47
48 type L1 struct {
49         l L2
50 }
51
52 type L2 struct {
53         sync.Mutex
54 }
55
56 func (*L0) Ok() {}
57 func (L0) Bad() {} // want "Bad passes lock by value: a.L0 contains a.L1 contains a.L2"
58
59 type EmbeddedMutexPointer struct {
60         s *sync.Mutex // safe to copy this pointer
61 }
62
63 func (*EmbeddedMutexPointer) Ok()      {}
64 func (EmbeddedMutexPointer) AlsoOk()   {}
65 func StillOk(EmbeddedMutexPointer)     {}
66 func LookinGood() EmbeddedMutexPointer {}
67
68 type EmbeddedLocker struct {
69         sync.Locker // safe to copy interface values
70 }
71
72 func (*EmbeddedLocker) Ok()    {}
73 func (EmbeddedLocker) AlsoOk() {}
74
75 type CustomLock struct{}
76
77 func (*CustomLock) Lock()   {}
78 func (*CustomLock) Unlock() {}
79
80 func Ok(*CustomLock) {}
81 func Bad(CustomLock) {} // want "Bad passes lock by value: a.CustomLock"
82
83 // Passing lock values into interface function arguments
84 func FuncCallInterfaceArg(f func(a int, b interface{})) {
85         var m sync.Mutex
86         var t struct{ lock sync.Mutex }
87
88         f(1, "foo")
89         f(2, &t)
90         f(3, &sync.Mutex{})
91         f(4, m) // want "call of f copies lock value: sync.Mutex"
92         f(5, t) // want "call of f copies lock value: struct.lock sync.Mutex. contains sync.Mutex"
93         var fntab []func(t)
94         fntab[0](t) // want "call of fntab.0. copies lock value: struct.lock sync.Mutex. contains sync.Mutex"
95 }
96
97 // Returning lock via interface value
98 func ReturnViaInterface(x int) (int, interface{}) {
99         var m sync.Mutex
100         var t struct{ lock sync.Mutex }
101
102         switch x % 4 {
103         case 0:
104                 return 0, "qwe"
105         case 1:
106                 return 1, &sync.Mutex{}
107         case 2:
108                 return 2, m // want "return copies lock value: sync.Mutex"
109         default:
110                 return 3, t // want "return copies lock value: struct.lock sync.Mutex. contains sync.Mutex"
111         }
112 }
113
114 // Some cases that we don't warn about.
115
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)
120 }
121
122 // TODO: Unfortunate cases
123
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
128
129 func (LocalOnce) Bad() {} // want "Bad passes lock by value: a.LocalOnce contains sync.Mutex"
130
131 // False negative:
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
135
136 func (LocalMutex) Bad() {} // WANTED: An error here :(