// Copyright 2012 The Go Authors. All rights reserved.
|
// Use of this source code is governed by a BSD-style
|
// license that can be found in the LICENSE file.
|
|
package race_test
|
|
import (
|
"testing"
|
)
|
|
func TestRaceMapRW(t *testing.T) {
|
m := make(map[int]int)
|
ch := make(chan bool, 1)
|
go func() {
|
_ = m[1]
|
ch <- true
|
}()
|
m[1] = 1
|
<-ch
|
}
|
|
func TestRaceMapRW2(t *testing.T) {
|
m := make(map[int]int)
|
ch := make(chan bool, 1)
|
go func() {
|
_, _ = m[1]
|
ch <- true
|
}()
|
m[1] = 1
|
<-ch
|
}
|
|
func TestRaceMapRWArray(t *testing.T) {
|
// Check instrumentation of unaddressable arrays (issue 4578).
|
m := make(map[int][2]int)
|
ch := make(chan bool, 1)
|
go func() {
|
_ = m[1][1]
|
ch <- true
|
}()
|
m[2] = [2]int{1, 2}
|
<-ch
|
}
|
|
func TestNoRaceMapRR(t *testing.T) {
|
m := make(map[int]int)
|
ch := make(chan bool, 1)
|
go func() {
|
_, _ = m[1]
|
ch <- true
|
}()
|
_ = m[1]
|
<-ch
|
}
|
|
func TestRaceMapRange(t *testing.T) {
|
m := make(map[int]int)
|
ch := make(chan bool, 1)
|
go func() {
|
for range m {
|
}
|
ch <- true
|
}()
|
m[1] = 1
|
<-ch
|
}
|
|
func TestRaceMapRange2(t *testing.T) {
|
m := make(map[int]int)
|
ch := make(chan bool, 1)
|
go func() {
|
for range m {
|
}
|
ch <- true
|
}()
|
m[1] = 1
|
<-ch
|
}
|
|
func TestNoRaceMapRangeRange(t *testing.T) {
|
m := make(map[int]int)
|
// now the map is not empty and range triggers an event
|
// should work without this (as in other tests)
|
// so it is suspicious if this test passes and others don't
|
m[0] = 0
|
ch := make(chan bool, 1)
|
go func() {
|
for range m {
|
}
|
ch <- true
|
}()
|
for range m {
|
}
|
<-ch
|
}
|
|
func TestRaceMapLen(t *testing.T) {
|
m := make(map[string]bool)
|
ch := make(chan bool, 1)
|
go func() {
|
_ = len(m)
|
ch <- true
|
}()
|
m[""] = true
|
<-ch
|
}
|
|
func TestRaceMapDelete(t *testing.T) {
|
m := make(map[string]bool)
|
ch := make(chan bool, 1)
|
go func() {
|
delete(m, "")
|
ch <- true
|
}()
|
m[""] = true
|
<-ch
|
}
|
|
func TestRaceMapLenDelete(t *testing.T) {
|
m := make(map[string]bool)
|
ch := make(chan bool, 1)
|
go func() {
|
delete(m, "a")
|
ch <- true
|
}()
|
_ = len(m)
|
<-ch
|
}
|
|
func TestRaceMapVariable(t *testing.T) {
|
ch := make(chan bool, 1)
|
m := make(map[int]int)
|
_ = m
|
go func() {
|
m = make(map[int]int)
|
ch <- true
|
}()
|
m = make(map[int]int)
|
<-ch
|
}
|
|
func TestRaceMapVariable2(t *testing.T) {
|
ch := make(chan bool, 1)
|
m := make(map[int]int)
|
go func() {
|
m[1] = 1
|
ch <- true
|
}()
|
m = make(map[int]int)
|
<-ch
|
}
|
|
func TestRaceMapVariable3(t *testing.T) {
|
ch := make(chan bool, 1)
|
m := make(map[int]int)
|
go func() {
|
_ = m[1]
|
ch <- true
|
}()
|
m = make(map[int]int)
|
<-ch
|
}
|
|
type Big struct {
|
x [17]int32
|
}
|
|
func TestRaceMapLookupPartKey(t *testing.T) {
|
k := &Big{}
|
m := make(map[Big]bool)
|
ch := make(chan bool, 1)
|
go func() {
|
k.x[8] = 1
|
ch <- true
|
}()
|
_ = m[*k]
|
<-ch
|
}
|
|
func TestRaceMapLookupPartKey2(t *testing.T) {
|
k := &Big{}
|
m := make(map[Big]bool)
|
ch := make(chan bool, 1)
|
go func() {
|
k.x[8] = 1
|
ch <- true
|
}()
|
_, _ = m[*k]
|
<-ch
|
}
|
func TestRaceMapDeletePartKey(t *testing.T) {
|
k := &Big{}
|
m := make(map[Big]bool)
|
ch := make(chan bool, 1)
|
go func() {
|
k.x[8] = 1
|
ch <- true
|
}()
|
delete(m, *k)
|
<-ch
|
}
|
|
func TestRaceMapInsertPartKey(t *testing.T) {
|
k := &Big{}
|
m := make(map[Big]bool)
|
ch := make(chan bool, 1)
|
go func() {
|
k.x[8] = 1
|
ch <- true
|
}()
|
m[*k] = true
|
<-ch
|
}
|
|
func TestRaceMapInsertPartVal(t *testing.T) {
|
v := &Big{}
|
m := make(map[int]Big)
|
ch := make(chan bool, 1)
|
go func() {
|
v.x[8] = 1
|
ch <- true
|
}()
|
m[1] = *v
|
<-ch
|
}
|
|
// Test for issue 7561.
|
func TestRaceMapAssignMultipleReturn(t *testing.T) {
|
connect := func() (int, error) { return 42, nil }
|
conns := make(map[int][]int)
|
conns[1] = []int{0}
|
ch := make(chan bool, 1)
|
var err error
|
_ = err
|
go func() {
|
conns[1][0], err = connect()
|
ch <- true
|
}()
|
x := conns[1][0]
|
_ = x
|
<-ch
|
}
|
|
// BigKey and BigVal must be larger than 256 bytes,
|
// so that compiler sets KindGCProg for them.
|
type BigKey [1000]*int
|
|
type BigVal struct {
|
x int
|
y [1000]*int
|
}
|
|
func TestRaceMapBigKeyAccess1(t *testing.T) {
|
m := make(map[BigKey]int)
|
var k BigKey
|
ch := make(chan bool, 1)
|
go func() {
|
_ = m[k]
|
ch <- true
|
}()
|
k[30] = new(int)
|
<-ch
|
}
|
|
func TestRaceMapBigKeyAccess2(t *testing.T) {
|
m := make(map[BigKey]int)
|
var k BigKey
|
ch := make(chan bool, 1)
|
go func() {
|
_, _ = m[k]
|
ch <- true
|
}()
|
k[30] = new(int)
|
<-ch
|
}
|
|
func TestRaceMapBigKeyInsert(t *testing.T) {
|
m := make(map[BigKey]int)
|
var k BigKey
|
ch := make(chan bool, 1)
|
go func() {
|
m[k] = 1
|
ch <- true
|
}()
|
k[30] = new(int)
|
<-ch
|
}
|
|
func TestRaceMapBigKeyDelete(t *testing.T) {
|
m := make(map[BigKey]int)
|
var k BigKey
|
ch := make(chan bool, 1)
|
go func() {
|
delete(m, k)
|
ch <- true
|
}()
|
k[30] = new(int)
|
<-ch
|
}
|
|
func TestRaceMapBigValInsert(t *testing.T) {
|
m := make(map[int]BigVal)
|
var v BigVal
|
ch := make(chan bool, 1)
|
go func() {
|
m[1] = v
|
ch <- true
|
}()
|
v.y[30] = new(int)
|
<-ch
|
}
|
|
func TestRaceMapBigValAccess1(t *testing.T) {
|
m := make(map[int]BigVal)
|
var v BigVal
|
ch := make(chan bool, 1)
|
go func() {
|
v = m[1]
|
ch <- true
|
}()
|
v.y[30] = new(int)
|
<-ch
|
}
|
|
func TestRaceMapBigValAccess2(t *testing.T) {
|
m := make(map[int]BigVal)
|
var v BigVal
|
ch := make(chan bool, 1)
|
go func() {
|
v, _ = m[1]
|
ch <- true
|
}()
|
v.y[30] = new(int)
|
<-ch
|
}
|