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	"sync"
9	"testing"
10)
11
12func TestRaceSliceRW(t *testing.T) {
13	ch := make(chan bool, 1)
14	a := make([]int, 2)
15	go func() {
16		a[1] = 1
17		ch <- true
18	}()
19	_ = a[1]
20	<-ch
21}
22
23func TestNoRaceSliceRW(t *testing.T) {
24	ch := make(chan bool, 1)
25	a := make([]int, 2)
26	go func() {
27		a[0] = 1
28		ch <- true
29	}()
30	_ = a[1]
31	<-ch
32}
33
34func TestRaceSliceWW(t *testing.T) {
35	a := make([]int, 10)
36	ch := make(chan bool, 1)
37	go func() {
38		a[1] = 1
39		ch <- true
40	}()
41	a[1] = 2
42	<-ch
43}
44
45func TestNoRaceArrayWW(t *testing.T) {
46	var a [5]int
47	ch := make(chan bool, 1)
48	go func() {
49		a[0] = 1
50		ch <- true
51	}()
52	a[1] = 2
53	<-ch
54}
55
56func TestRaceArrayWW(t *testing.T) {
57	var a [5]int
58	ch := make(chan bool, 1)
59	go func() {
60		a[1] = 1
61		ch <- true
62	}()
63	a[1] = 2
64	<-ch
65}
66
67func TestNoRaceSliceWriteLen(t *testing.T) {
68	ch := make(chan bool, 1)
69	a := make([]bool, 1)
70	go func() {
71		a[0] = true
72		ch <- true
73	}()
74	_ = len(a)
75	<-ch
76}
77
78func TestNoRaceSliceWriteCap(t *testing.T) {
79	ch := make(chan bool, 1)
80	a := make([]uint64, 100)
81	go func() {
82		a[50] = 123
83		ch <- true
84	}()
85	_ = cap(a)
86	<-ch
87}
88
89func TestRaceSliceCopyRead(t *testing.T) {
90	ch := make(chan bool, 1)
91	a := make([]int, 10)
92	b := make([]int, 10)
93	go func() {
94		_ = a[5]
95		ch <- true
96	}()
97	copy(a, b)
98	<-ch
99}
100
101func TestNoRaceSliceWriteCopy(t *testing.T) {
102	ch := make(chan bool, 1)
103	a := make([]int, 10)
104	b := make([]int, 10)
105	go func() {
106		a[5] = 1
107		ch <- true
108	}()
109	copy(a[:5], b[:5])
110	<-ch
111}
112
113func TestRaceSliceCopyWrite2(t *testing.T) {
114	ch := make(chan bool, 1)
115	a := make([]int, 10)
116	b := make([]int, 10)
117	go func() {
118		b[5] = 1
119		ch <- true
120	}()
121	copy(a, b)
122	<-ch
123}
124
125func TestRaceSliceCopyWrite3(t *testing.T) {
126	ch := make(chan bool, 1)
127	a := make([]byte, 10)
128	go func() {
129		a[7] = 1
130		ch <- true
131	}()
132	copy(a, "qwertyqwerty")
133	<-ch
134}
135
136func TestNoRaceSliceCopyRead(t *testing.T) {
137	ch := make(chan bool, 1)
138	a := make([]int, 10)
139	b := make([]int, 10)
140	go func() {
141		_ = b[5]
142		ch <- true
143	}()
144	copy(a, b)
145	<-ch
146}
147
148func TestRacePointerSliceCopyRead(t *testing.T) {
149	ch := make(chan bool, 1)
150	a := make([]*int, 10)
151	b := make([]*int, 10)
152	go func() {
153		_ = a[5]
154		ch <- true
155	}()
156	copy(a, b)
157	<-ch
158}
159
160func TestNoRacePointerSliceWriteCopy(t *testing.T) {
161	ch := make(chan bool, 1)
162	a := make([]*int, 10)
163	b := make([]*int, 10)
164	go func() {
165		a[5] = new(int)
166		ch <- true
167	}()
168	copy(a[:5], b[:5])
169	<-ch
170}
171
172func TestRacePointerSliceCopyWrite2(t *testing.T) {
173	ch := make(chan bool, 1)
174	a := make([]*int, 10)
175	b := make([]*int, 10)
176	go func() {
177		b[5] = new(int)
178		ch <- true
179	}()
180	copy(a, b)
181	<-ch
182}
183
184func TestNoRacePointerSliceCopyRead(t *testing.T) {
185	ch := make(chan bool, 1)
186	a := make([]*int, 10)
187	b := make([]*int, 10)
188	go func() {
189		_ = b[5]
190		ch <- true
191	}()
192	copy(a, b)
193	<-ch
194}
195
196func TestNoRaceSliceWriteSlice2(t *testing.T) {
197	ch := make(chan bool, 1)
198	a := make([]float64, 10)
199	go func() {
200		a[2] = 1.0
201		ch <- true
202	}()
203	_ = a[0:5]
204	<-ch
205}
206
207func TestRaceSliceWriteSlice(t *testing.T) {
208	ch := make(chan bool, 1)
209	a := make([]float64, 10)
210	go func() {
211		a[2] = 1.0
212		ch <- true
213	}()
214	a = a[5:10]
215	<-ch
216}
217
218func TestNoRaceSliceWriteSlice(t *testing.T) {
219	ch := make(chan bool, 1)
220	a := make([]float64, 10)
221	go func() {
222		a[2] = 1.0
223		ch <- true
224	}()
225	_ = a[5:10]
226	<-ch
227}
228
229func TestNoRaceSliceLenCap(t *testing.T) {
230	ch := make(chan bool, 1)
231	a := make([]struct{}, 10)
232	go func() {
233		_ = len(a)
234		ch <- true
235	}()
236	_ = cap(a)
237	<-ch
238}
239
240func TestNoRaceStructSlicesRangeWrite(t *testing.T) {
241	type Str struct {
242		a []int
243		b []int
244	}
245	ch := make(chan bool, 1)
246	var s Str
247	s.a = make([]int, 10)
248	s.b = make([]int, 10)
249	go func() {
250		for range s.a {
251		}
252		ch <- true
253	}()
254	s.b[5] = 5
255	<-ch
256}
257
258func TestRaceSliceDifferent(t *testing.T) {
259	c := make(chan bool, 1)
260	s := make([]int, 10)
261	s2 := s
262	go func() {
263		s[3] = 3
264		c <- true
265	}()
266	// false negative because s2 is PAUTO w/o PHEAP
267	// so we do not instrument it
268	s2[3] = 3
269	<-c
270}
271
272func TestRaceSliceRangeWrite(t *testing.T) {
273	c := make(chan bool, 1)
274	s := make([]int, 10)
275	go func() {
276		s[3] = 3
277		c <- true
278	}()
279	for _, v := range s {
280		_ = v
281	}
282	<-c
283}
284
285func TestNoRaceSliceRangeWrite(t *testing.T) {
286	c := make(chan bool, 1)
287	s := make([]int, 10)
288	go func() {
289		s[3] = 3
290		c <- true
291	}()
292	for range s {
293	}
294	<-c
295}
296
297func TestRaceSliceRangeAppend(t *testing.T) {
298	c := make(chan bool, 1)
299	s := make([]int, 10)
300	go func() {
301		s = append(s, 3)
302		c <- true
303	}()
304	for range s {
305	}
306	<-c
307}
308
309func TestNoRaceSliceRangeAppend(t *testing.T) {
310	c := make(chan bool, 1)
311	s := make([]int, 10)
312	go func() {
313		_ = append(s, 3)
314		c <- true
315	}()
316	for range s {
317	}
318	<-c
319}
320
321func TestRaceSliceVarWrite(t *testing.T) {
322	c := make(chan bool, 1)
323	s := make([]int, 10)
324	go func() {
325		s[3] = 3
326		c <- true
327	}()
328	s = make([]int, 20)
329	<-c
330}
331
332func TestRaceSliceVarRead(t *testing.T) {
333	c := make(chan bool, 1)
334	s := make([]int, 10)
335	go func() {
336		_ = s[3]
337		c <- true
338	}()
339	s = make([]int, 20)
340	<-c
341}
342
343func TestRaceSliceVarRange(t *testing.T) {
344	c := make(chan bool, 1)
345	s := make([]int, 10)
346	go func() {
347		for range s {
348		}
349		c <- true
350	}()
351	s = make([]int, 20)
352	<-c
353}
354
355func TestRaceSliceVarAppend(t *testing.T) {
356	c := make(chan bool, 1)
357	s := make([]int, 10)
358	go func() {
359		_ = append(s, 10)
360		c <- true
361	}()
362	s = make([]int, 20)
363	<-c
364}
365
366func TestRaceSliceVarCopy(t *testing.T) {
367	c := make(chan bool, 1)
368	s := make([]int, 10)
369	go func() {
370		s2 := make([]int, 10)
371		copy(s, s2)
372		c <- true
373	}()
374	s = make([]int, 20)
375	<-c
376}
377
378func TestRaceSliceVarCopy2(t *testing.T) {
379	c := make(chan bool, 1)
380	s := make([]int, 10)
381	go func() {
382		s2 := make([]int, 10)
383		copy(s2, s)
384		c <- true
385	}()
386	s = make([]int, 20)
387	<-c
388}
389
390func TestRaceSliceAppend(t *testing.T) {
391	c := make(chan bool, 1)
392	s := make([]int, 10, 20)
393	go func() {
394		_ = append(s, 1)
395		c <- true
396	}()
397	_ = append(s, 2)
398	<-c
399}
400
401func TestRaceSliceAppendWrite(t *testing.T) {
402	c := make(chan bool, 1)
403	s := make([]int, 10)
404	go func() {
405		_ = append(s, 1)
406		c <- true
407	}()
408	s[0] = 42
409	<-c
410}
411
412func TestRaceSliceAppendSlice(t *testing.T) {
413	c := make(chan bool, 1)
414	s := make([]int, 10)
415	go func() {
416		s2 := make([]int, 10)
417		_ = append(s, s2...)
418		c <- true
419	}()
420	s[0] = 42
421	<-c
422}
423
424func TestRaceSliceAppendSlice2(t *testing.T) {
425	c := make(chan bool, 1)
426	s := make([]int, 10)
427	s2foobar := make([]int, 10)
428	go func() {
429		_ = append(s, s2foobar...)
430		c <- true
431	}()
432	s2foobar[5] = 42
433	<-c
434}
435
436func TestRaceSliceAppendString(t *testing.T) {
437	c := make(chan bool, 1)
438	s := make([]byte, 10)
439	go func() {
440		_ = append(s, "qwerty"...)
441		c <- true
442	}()
443	s[0] = 42
444	<-c
445}
446
447func TestRacePointerSliceAppend(t *testing.T) {
448	c := make(chan bool, 1)
449	s := make([]*int, 10, 20)
450	go func() {
451		_ = append(s, new(int))
452		c <- true
453	}()
454	_ = append(s, new(int))
455	<-c
456}
457
458func TestRacePointerSliceAppendWrite(t *testing.T) {
459	c := make(chan bool, 1)
460	s := make([]*int, 10)
461	go func() {
462		_ = append(s, new(int))
463		c <- true
464	}()
465	s[0] = new(int)
466	<-c
467}
468
469func TestRacePointerSliceAppendSlice(t *testing.T) {
470	c := make(chan bool, 1)
471	s := make([]*int, 10)
472	go func() {
473		s2 := make([]*int, 10)
474		_ = append(s, s2...)
475		c <- true
476	}()
477	s[0] = new(int)
478	<-c
479}
480
481func TestRacePointerSliceAppendSlice2(t *testing.T) {
482	c := make(chan bool, 1)
483	s := make([]*int, 10)
484	s2foobar := make([]*int, 10)
485	go func() {
486		_ = append(s, s2foobar...)
487		c <- true
488	}()
489	println("WRITE:", &s2foobar[5])
490	s2foobar[5] = nil
491	<-c
492}
493
494func TestNoRaceSliceIndexAccess(t *testing.T) {
495	c := make(chan bool, 1)
496	s := make([]int, 10)
497	v := 0
498	go func() {
499		_ = v
500		c <- true
501	}()
502	s[v] = 1
503	<-c
504}
505
506func TestNoRaceSliceIndexAccess2(t *testing.T) {
507	c := make(chan bool, 1)
508	s := make([]int, 10)
509	v := 0
510	go func() {
511		_ = v
512		c <- true
513	}()
514	_ = s[v]
515	<-c
516}
517
518func TestRaceSliceIndexAccess(t *testing.T) {
519	c := make(chan bool, 1)
520	s := make([]int, 10)
521	v := 0
522	go func() {
523		v = 1
524		c <- true
525	}()
526	s[v] = 1
527	<-c
528}
529
530func TestRaceSliceIndexAccess2(t *testing.T) {
531	c := make(chan bool, 1)
532	s := make([]int, 10)
533	v := 0
534	go func() {
535		v = 1
536		c <- true
537	}()
538	_ = s[v]
539	<-c
540}
541
542func TestRaceSliceByteToString(t *testing.T) {
543	c := make(chan string)
544	s := make([]byte, 10)
545	go func() {
546		c <- string(s)
547	}()
548	s[0] = 42
549	<-c
550}
551
552func TestRaceSliceRuneToString(t *testing.T) {
553	c := make(chan string)
554	s := make([]rune, 10)
555	go func() {
556		c <- string(s)
557	}()
558	s[9] = 42
559	<-c
560}
561
562func TestRaceConcatString(t *testing.T) {
563	s := "hello"
564	c := make(chan string, 1)
565	go func() {
566		c <- s + " world"
567	}()
568	s = "world"
569	<-c
570}
571
572func TestRaceCompareString(t *testing.T) {
573	s1 := "hello"
574	s2 := "world"
575	c := make(chan bool, 1)
576	go func() {
577		c <- s1 == s2
578	}()
579	s1 = s2
580	<-c
581}
582
583func TestRaceSlice3(t *testing.T) {
584	done := make(chan bool)
585	x := make([]int, 10)
586	i := 2
587	go func() {
588		i = 3
589		done <- true
590	}()
591	_ = x[:1:i]
592	<-done
593}
594
595var saved string
596
597func TestRaceSlice4(t *testing.T) {
598	// See issue 36794.
599	data := []byte("hello there")
600	var wg sync.WaitGroup
601	wg.Add(1)
602	go func() {
603		_ = string(data)
604		wg.Done()
605	}()
606	copy(data, data[2:])
607	wg.Wait()
608}
609