1// Copyright 2012 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
5package race_test
6
7import (
8	"testing"
9)
10
11func TestRaceMapRW(t *testing.T) {
12	m := make(map[int]int)
13	ch := make(chan bool, 1)
14	go func() {
15		_ = m[1]
16		ch <- true
17	}()
18	m[1] = 1
19	<-ch
20}
21
22func TestRaceMapRW2(t *testing.T) {
23	m := make(map[int]int)
24	ch := make(chan bool, 1)
25	go func() {
26		_, _ = m[1]
27		ch <- true
28	}()
29	m[1] = 1
30	<-ch
31}
32
33func TestRaceMapRWArray(t *testing.T) {
34	// Check instrumentation of unaddressable arrays (issue 4578).
35	m := make(map[int][2]int)
36	ch := make(chan bool, 1)
37	go func() {
38		_ = m[1][1]
39		ch <- true
40	}()
41	m[2] = [2]int{1, 2}
42	<-ch
43}
44
45func TestNoRaceMapRR(t *testing.T) {
46	m := make(map[int]int)
47	ch := make(chan bool, 1)
48	go func() {
49		_, _ = m[1]
50		ch <- true
51	}()
52	_ = m[1]
53	<-ch
54}
55
56func TestRaceMapRange(t *testing.T) {
57	m := make(map[int]int)
58	ch := make(chan bool, 1)
59	go func() {
60		for range m {
61		}
62		ch <- true
63	}()
64	m[1] = 1
65	<-ch
66}
67
68func TestRaceMapRange2(t *testing.T) {
69	m := make(map[int]int)
70	ch := make(chan bool, 1)
71	go func() {
72		for range m {
73		}
74		ch <- true
75	}()
76	m[1] = 1
77	<-ch
78}
79
80func TestNoRaceMapRangeRange(t *testing.T) {
81	m := make(map[int]int)
82	// now the map is not empty and range triggers an event
83	// should work without this (as in other tests)
84	// so it is suspicious if this test passes and others don't
85	m[0] = 0
86	ch := make(chan bool, 1)
87	go func() {
88		for range m {
89		}
90		ch <- true
91	}()
92	for range m {
93	}
94	<-ch
95}
96
97func TestRaceMapLen(t *testing.T) {
98	m := make(map[string]bool)
99	ch := make(chan bool, 1)
100	go func() {
101		_ = len(m)
102		ch <- true
103	}()
104	m[""] = true
105	<-ch
106}
107
108func TestRaceMapDelete(t *testing.T) {
109	m := make(map[string]bool)
110	ch := make(chan bool, 1)
111	go func() {
112		delete(m, "")
113		ch <- true
114	}()
115	m[""] = true
116	<-ch
117}
118
119func TestRaceMapLenDelete(t *testing.T) {
120	m := make(map[string]bool)
121	ch := make(chan bool, 1)
122	go func() {
123		delete(m, "a")
124		ch <- true
125	}()
126	_ = len(m)
127	<-ch
128}
129
130func TestRaceMapVariable(t *testing.T) {
131	ch := make(chan bool, 1)
132	m := make(map[int]int)
133	_ = m
134	go func() {
135		m = make(map[int]int)
136		ch <- true
137	}()
138	m = make(map[int]int)
139	<-ch
140}
141
142func TestRaceMapVariable2(t *testing.T) {
143	ch := make(chan bool, 1)
144	m := make(map[int]int)
145	go func() {
146		m[1] = 1
147		ch <- true
148	}()
149	m = make(map[int]int)
150	<-ch
151}
152
153func TestRaceMapVariable3(t *testing.T) {
154	ch := make(chan bool, 1)
155	m := make(map[int]int)
156	go func() {
157		_ = m[1]
158		ch <- true
159	}()
160	m = make(map[int]int)
161	<-ch
162}
163
164type Big struct {
165	x [17]int32
166}
167
168func TestRaceMapLookupPartKey(t *testing.T) {
169	k := &Big{}
170	m := make(map[Big]bool)
171	ch := make(chan bool, 1)
172	go func() {
173		k.x[8] = 1
174		ch <- true
175	}()
176	_ = m[*k]
177	<-ch
178}
179
180func TestRaceMapLookupPartKey2(t *testing.T) {
181	k := &Big{}
182	m := make(map[Big]bool)
183	ch := make(chan bool, 1)
184	go func() {
185		k.x[8] = 1
186		ch <- true
187	}()
188	_, _ = m[*k]
189	<-ch
190}
191func TestRaceMapDeletePartKey(t *testing.T) {
192	k := &Big{}
193	m := make(map[Big]bool)
194	ch := make(chan bool, 1)
195	go func() {
196		k.x[8] = 1
197		ch <- true
198	}()
199	delete(m, *k)
200	<-ch
201}
202
203func TestRaceMapInsertPartKey(t *testing.T) {
204	k := &Big{}
205	m := make(map[Big]bool)
206	ch := make(chan bool, 1)
207	go func() {
208		k.x[8] = 1
209		ch <- true
210	}()
211	m[*k] = true
212	<-ch
213}
214
215func TestRaceMapInsertPartVal(t *testing.T) {
216	v := &Big{}
217	m := make(map[int]Big)
218	ch := make(chan bool, 1)
219	go func() {
220		v.x[8] = 1
221		ch <- true
222	}()
223	m[1] = *v
224	<-ch
225}
226
227// Test for issue 7561.
228func TestRaceMapAssignMultipleReturn(t *testing.T) {
229	connect := func() (int, error) { return 42, nil }
230	conns := make(map[int][]int)
231	conns[1] = []int{0}
232	ch := make(chan bool, 1)
233	var err error
234	_ = err
235	go func() {
236		conns[1][0], err = connect()
237		ch <- true
238	}()
239	x := conns[1][0]
240	_ = x
241	<-ch
242}
243
244// BigKey and BigVal must be larger than 256 bytes,
245// so that compiler sets KindGCProg for them.
246type BigKey [1000]*int
247
248type BigVal struct {
249	x int
250	y [1000]*int
251}
252
253func TestRaceMapBigKeyAccess1(t *testing.T) {
254	m := make(map[BigKey]int)
255	var k BigKey
256	ch := make(chan bool, 1)
257	go func() {
258		_ = m[k]
259		ch <- true
260	}()
261	k[30] = new(int)
262	<-ch
263}
264
265func TestRaceMapBigKeyAccess2(t *testing.T) {
266	m := make(map[BigKey]int)
267	var k BigKey
268	ch := make(chan bool, 1)
269	go func() {
270		_, _ = m[k]
271		ch <- true
272	}()
273	k[30] = new(int)
274	<-ch
275}
276
277func TestRaceMapBigKeyInsert(t *testing.T) {
278	m := make(map[BigKey]int)
279	var k BigKey
280	ch := make(chan bool, 1)
281	go func() {
282		m[k] = 1
283		ch <- true
284	}()
285	k[30] = new(int)
286	<-ch
287}
288
289func TestRaceMapBigKeyDelete(t *testing.T) {
290	m := make(map[BigKey]int)
291	var k BigKey
292	ch := make(chan bool, 1)
293	go func() {
294		delete(m, k)
295		ch <- true
296	}()
297	k[30] = new(int)
298	<-ch
299}
300
301func TestRaceMapBigValInsert(t *testing.T) {
302	m := make(map[int]BigVal)
303	var v BigVal
304	ch := make(chan bool, 1)
305	go func() {
306		m[1] = v
307		ch <- true
308	}()
309	v.y[30] = new(int)
310	<-ch
311}
312
313func TestRaceMapBigValAccess1(t *testing.T) {
314	m := make(map[int]BigVal)
315	var v BigVal
316	ch := make(chan bool, 1)
317	go func() {
318		v = m[1]
319		ch <- true
320	}()
321	v.y[30] = new(int)
322	<-ch
323}
324
325func TestRaceMapBigValAccess2(t *testing.T) {
326	m := make(map[int]BigVal)
327	var v BigVal
328	ch := make(chan bool, 1)
329	go func() {
330		v, _ = m[1]
331		ch <- true
332	}()
333	v.y[30] = new(int)
334	<-ch
335}
336