1 | package a |
---|---|
2 | |
3 | import ( |
4 | "sync" |
5 | "sync/atomic" |
6 | "unsafe" |
7 | . "unsafe" |
8 | unsafe1 "unsafe" |
9 | ) |
10 | |
11 | func OkFunc() { |
12 | var x *sync.Mutex |
13 | p := x |
14 | var y sync.Mutex |
15 | p = &y |
16 | |
17 | var z = sync.Mutex{} |
18 | w := sync.Mutex{} |
19 | |
20 | w = sync.Mutex{} |
21 | q := struct{ L sync.Mutex }{ |
22 | L: sync.Mutex{}, |
23 | } |
24 | |
25 | yy := []Tlock{ |
26 | Tlock{}, |
27 | Tlock{ |
28 | once: sync.Once{}, |
29 | }, |
30 | } |
31 | |
32 | nl := new(sync.Mutex) |
33 | mx := make([]sync.Mutex, 10) |
34 | xx := struct{ L *sync.Mutex }{ |
35 | L: new(sync.Mutex), |
36 | } |
37 | } |
38 | |
39 | type Tlock struct { |
40 | once sync.Once |
41 | } |
42 | |
43 | func BadFunc() { |
44 | var x *sync.Mutex |
45 | p := x |
46 | var y sync.Mutex |
47 | p = &y |
48 | *p = *x // want `assignment copies lock value to \*p: sync.Mutex` |
49 | |
50 | var t Tlock |
51 | var tp *Tlock |
52 | tp = &t |
53 | *tp = t // want `assignment copies lock value to \*tp: a.Tlock contains sync.Once contains sync\b.*` |
54 | t = *tp // want `assignment copies lock value to t: a.Tlock contains sync.Once contains sync\b.*` |
55 | |
56 | y := *x // want "assignment copies lock value to y: sync.Mutex" |
57 | var z = t // want `variable declaration copies lock value to z: a.Tlock contains sync.Once contains sync\b.*` |
58 | |
59 | w := struct{ L sync.Mutex }{ |
60 | L: *x, // want `literal copies lock value from \*x: sync.Mutex` |
61 | } |
62 | var q = map[int]Tlock{ |
63 | 1: t, // want `literal copies lock value from t: a.Tlock contains sync.Once contains sync\b.*` |
64 | 2: *tp, // want `literal copies lock value from \*tp: a.Tlock contains sync.Once contains sync\b.*` |
65 | } |
66 | yy := []Tlock{ |
67 | t, // want `literal copies lock value from t: a.Tlock contains sync.Once contains sync\b.*` |
68 | *tp, // want `literal copies lock value from \*tp: a.Tlock contains sync.Once contains sync\b.*` |
69 | } |
70 | |
71 | // override 'new' keyword |
72 | new := func(interface{}) {} |
73 | new(t) // want `call of new copies lock value: a.Tlock contains sync.Once contains sync\b.*` |
74 | |
75 | // copy of array of locks |
76 | var muA [5]sync.Mutex |
77 | muB := muA // want "assignment copies lock value to muB: sync.Mutex" |
78 | muA = muB // want "assignment copies lock value to muA: sync.Mutex" |
79 | muSlice := muA[:] // OK |
80 | |
81 | // multidimensional array |
82 | var mmuA [5][5]sync.Mutex |
83 | mmuB := mmuA // want "assignment copies lock value to mmuB: sync.Mutex" |
84 | mmuA = mmuB // want "assignment copies lock value to mmuA: sync.Mutex" |
85 | mmuSlice := mmuA[:] // OK |
86 | |
87 | // slice copy is ok |
88 | var fmuA [5][][5]sync.Mutex |
89 | fmuB := fmuA // OK |
90 | fmuA = fmuB // OK |
91 | fmuSlice := fmuA[:] // OK |
92 | |
93 | // map access by single and tuple copies prohibited |
94 | type mut struct{ mu sync.Mutex } |
95 | muM := map[string]mut{ |
96 | "a": mut{}, |
97 | } |
98 | mumA := muM["a"] // want "assignment copies lock value to mumA: a.mut contains sync.Mutex" |
99 | mumB, _ := muM["a"] // want "assignment copies lock value to mumB: \\(a.mut, bool\\) contains a.mut contains sync.Mutex" |
100 | } |
101 | |
102 | func LenAndCapOnLockArrays() { |
103 | var a [5]sync.Mutex |
104 | aLen := len(a) // OK |
105 | aCap := cap(a) // OK |
106 | |
107 | // override 'len' and 'cap' keywords |
108 | |
109 | len := func(interface{}) {} |
110 | len(a) // want "call of len copies lock value: sync.Mutex" |
111 | |
112 | cap := func(interface{}) {} |
113 | cap(a) // want "call of cap copies lock value: sync.Mutex" |
114 | } |
115 | |
116 | func SizeofMutex() { |
117 | var mu sync.Mutex |
118 | unsafe.Sizeof(mu) // OK |
119 | unsafe1.Sizeof(mu) // OK |
120 | Sizeof(mu) // OK |
121 | unsafe := struct{ Sizeof func(interface{}) }{} |
122 | unsafe.Sizeof(mu) // want "call of unsafe.Sizeof copies lock value: sync.Mutex" |
123 | Sizeof := func(interface{}) {} |
124 | Sizeof(mu) // want "call of Sizeof copies lock value: sync.Mutex" |
125 | } |
126 | |
127 | func OffsetofMutex() { |
128 | type T struct { |
129 | f int |
130 | mu sync.Mutex |
131 | } |
132 | unsafe.Offsetof(T{}.mu) // OK |
133 | unsafe := struct{ Offsetof func(interface{}) }{} |
134 | unsafe.Offsetof(T{}.mu) // want "call of unsafe.Offsetof copies lock value: sync.Mutex" |
135 | } |
136 | |
137 | func AlignofMutex() { |
138 | type T struct { |
139 | f int |
140 | mu sync.Mutex |
141 | } |
142 | unsafe.Alignof(T{}.mu) // OK |
143 | unsafe := struct{ Alignof func(interface{}) }{} |
144 | unsafe.Alignof(T{}.mu) // want "call of unsafe.Alignof copies lock value: sync.Mutex" |
145 | } |
146 | |
147 | // SyncTypesCheck checks copying of sync.* types except sync.Mutex |
148 | func SyncTypesCheck() { |
149 | // sync.RWMutex copying |
150 | var rwmuX sync.RWMutex |
151 | var rwmuXX = sync.RWMutex{} |
152 | rwmuX1 := new(sync.RWMutex) |
153 | rwmuY := rwmuX // want "assignment copies lock value to rwmuY: sync.RWMutex" |
154 | rwmuY = rwmuX // want "assignment copies lock value to rwmuY: sync.RWMutex" |
155 | var rwmuYY = rwmuX // want "variable declaration copies lock value to rwmuYY: sync.RWMutex" |
156 | rwmuP := &rwmuX |
157 | rwmuZ := &sync.RWMutex{} |
158 | |
159 | // sync.Cond copying |
160 | var condX sync.Cond |
161 | var condXX = sync.Cond{} |
162 | condX1 := new(sync.Cond) |
163 | condY := condX // want "assignment copies lock value to condY: sync.Cond contains sync.noCopy" |
164 | condY = condX // want "assignment copies lock value to condY: sync.Cond contains sync.noCopy" |
165 | var condYY = condX // want "variable declaration copies lock value to condYY: sync.Cond contains sync.noCopy" |
166 | condP := &condX |
167 | condZ := &sync.Cond{ |
168 | L: &sync.Mutex{}, |
169 | } |
170 | condZ = sync.NewCond(&sync.Mutex{}) |
171 | |
172 | // sync.WaitGroup copying |
173 | var wgX sync.WaitGroup |
174 | var wgXX = sync.WaitGroup{} |
175 | wgX1 := new(sync.WaitGroup) |
176 | wgY := wgX // want "assignment copies lock value to wgY: sync.WaitGroup contains sync.noCopy" |
177 | wgY = wgX // want "assignment copies lock value to wgY: sync.WaitGroup contains sync.noCopy" |
178 | var wgYY = wgX // want "variable declaration copies lock value to wgYY: sync.WaitGroup contains sync.noCopy" |
179 | wgP := &wgX |
180 | wgZ := &sync.WaitGroup{} |
181 | |
182 | // sync.Pool copying |
183 | var poolX sync.Pool |
184 | var poolXX = sync.Pool{} |
185 | poolX1 := new(sync.Pool) |
186 | poolY := poolX // want "assignment copies lock value to poolY: sync.Pool contains sync.noCopy" |
187 | poolY = poolX // want "assignment copies lock value to poolY: sync.Pool contains sync.noCopy" |
188 | var poolYY = poolX // want "variable declaration copies lock value to poolYY: sync.Pool contains sync.noCopy" |
189 | poolP := &poolX |
190 | poolZ := &sync.Pool{} |
191 | |
192 | // sync.Once copying |
193 | var onceX sync.Once |
194 | var onceXX = sync.Once{} |
195 | onceX1 := new(sync.Once) |
196 | onceY := onceX // want `assignment copies lock value to onceY: sync.Once contains sync\b.*` |
197 | onceY = onceX // want `assignment copies lock value to onceY: sync.Once contains sync\b.*` |
198 | var onceYY = onceX // want `variable declaration copies lock value to onceYY: sync.Once contains sync\b.*` |
199 | onceP := &onceX |
200 | onceZ := &sync.Once{} |
201 | } |
202 | |
203 | // AtomicTypesCheck checks copying of sync/atomic types |
204 | func AtomicTypesCheck() { |
205 | // atomic.Value copying |
206 | var vX atomic.Value |
207 | var vXX = atomic.Value{} |
208 | vX1 := new(atomic.Value) |
209 | // These are OK because the value has not been used yet. |
210 | // (And vet can't tell whether it has been used, so they're always OK.) |
211 | vY := vX |
212 | vY = vX |
213 | var vYY = vX |
214 | vP := &vX |
215 | vZ := &atomic.Value{} |
216 | } |
217 |
Members