diff options
Diffstat (limited to 'src/pkg/runtime/race/testdata/mop_test.go')
-rw-r--r-- | src/pkg/runtime/race/testdata/mop_test.go | 329 |
1 files changed, 324 insertions, 5 deletions
diff --git a/src/pkg/runtime/race/testdata/mop_test.go b/src/pkg/runtime/race/testdata/mop_test.go index fa7abe0ef..b0b66562c 100644 --- a/src/pkg/runtime/race/testdata/mop_test.go +++ b/src/pkg/runtime/race/testdata/mop_test.go @@ -5,8 +5,12 @@ package race_test import ( + "bytes" + "crypto/sha1" "errors" "fmt" + "io" + "os" "runtime" "sync" "testing" @@ -227,6 +231,22 @@ func TestRaceCaseFallthrough(t *testing.T) { <-ch } +func TestRaceCaseIssue6418(t *testing.T) { + m := map[string]map[string]string{ + "a": map[string]string{ + "b": "c", + }, + } + ch := make(chan int) + go func() { + m["a"]["x"] = "y" + ch <- 1 + }() + switch m["a"]["b"] { + } + <-ch +} + func TestRaceCaseType(t *testing.T) { var x, y int var i interface{} = x @@ -258,6 +278,25 @@ func TestRaceCaseTypeBody(t *testing.T) { <-c } +func TestRaceCaseTypeIssue5890(t *testing.T) { + // spurious extra instrumentation of the initial interface + // value. + var x, y int + m := make(map[int]map[int]interface{}) + m[0] = make(map[int]interface{}) + c := make(chan int, 1) + go func() { + switch i := m[0][1].(type) { + case nil: + case *int: + *i = x + } + c <- 1 + }() + m[0][1] = y + <-c +} + func TestNoRaceRange(t *testing.T) { ch := make(chan int, 3) a := [...]int{1, 2, 3} @@ -267,6 +306,19 @@ func TestNoRaceRange(t *testing.T) { close(ch) } +func TestNoRaceRangeIssue5446(t *testing.T) { + ch := make(chan int, 3) + a := []int{1, 2, 3} + b := []int{4} + // used to insert a spurious instrumentation of a[i] + // and crash. + i := 1 + for i, a[i] = range b { + ch <- i + } + close(ch) +} + func TestRaceRange(t *testing.T) { const N = 2 var a [N]int @@ -289,6 +341,94 @@ func TestRaceRange(t *testing.T) { } } +func TestRaceForInit(t *testing.T) { + c := make(chan int) + x := 0 + go func() { + c <- x + }() + for x = 42; false; { + } + <-c +} + +func TestNoRaceForInit(t *testing.T) { + done := make(chan bool) + c := make(chan bool) + x := 0 + go func() { + for { + _, ok := <-c + if !ok { + done <- true + return + } + x++ + } + }() + i := 0 + for x = 42; i < 10; i++ { + c <- true + } + close(c) + <-done +} + +func TestRaceForTest(t *testing.T) { + done := make(chan bool) + c := make(chan bool) + stop := false + go func() { + for { + _, ok := <-c + if !ok { + done <- true + return + } + stop = true + } + }() + for !stop { + c <- true + } + close(c) + <-done +} + +func TestRaceForIncr(t *testing.T) { + done := make(chan bool) + c := make(chan bool) + x := 0 + go func() { + for { + _, ok := <-c + if !ok { + done <- true + return + } + x++ + } + }() + for i := 0; i < 10; x++ { + i++ + c <- true + } + close(c) + <-done +} + +func TestNoRaceForIncr(t *testing.T) { + done := make(chan bool) + x := 0 + go func() { + x++ + done <- true + }() + for i := 0; i < 0; x++ { + } + <-done +} + func TestRacePlus(t *testing.T) { var x, y, z int ch := make(chan int, 2) @@ -495,8 +635,7 @@ func TestRaceSprint(t *testing.T) { <-ch } -// Not implemented. -func TestRaceFailingArrayCopy(t *testing.T) { +func TestRaceArrayCopy(t *testing.T) { ch := make(chan bool, 1) var a [5]int go func() { @@ -507,6 +646,24 @@ func TestRaceFailingArrayCopy(t *testing.T) { <-ch } +// Blows up a naive compiler. +func TestRaceNestedArrayCopy(t *testing.T) { + ch := make(chan bool, 1) + type ( + Point32 [2][2][2][2][2]Point + Point1024 [2][2][2][2][2]Point32 + Point32k [2][2][2][2][2]Point1024 + Point1M [2][2][2][2][2]Point32k + ) + var a, b Point1M + go func() { + a[0][1][0][1][0][1][0][1][0][1][0][1][0][1][0][1][0][1][0][1].y = 1 + ch <- true + }() + a = b + <-ch +} + func TestRaceStructRW(t *testing.T) { p := Point{0, 0} ch := make(chan bool, 1) @@ -1461,8 +1618,7 @@ func TestRaceSliceString(t *testing.T) { <-c } -// http://golang.org/issue/4453 -func TestRaceFailingSliceStruct(t *testing.T) { +func TestRaceSliceStruct(t *testing.T) { type X struct { x, y int } @@ -1477,7 +1633,7 @@ func TestRaceFailingSliceStruct(t *testing.T) { <-c } -func TestRaceFailingAppendSliceStruct(t *testing.T) { +func TestRaceAppendSliceStruct(t *testing.T) { type X struct { x, y int } @@ -1614,3 +1770,166 @@ func TestRaceNestedStruct(t *testing.T) { y.x.y = 42 <-c } + +func TestRaceIssue5567(t *testing.T) { + defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4)) + in := make(chan []byte) + res := make(chan error) + go func() { + var err error + defer func() { + close(in) + res <- err + }() + path := "mop_test.go" + f, err := os.Open(path) + if err != nil { + return + } + defer f.Close() + var n, total int + b := make([]byte, 17) // the race is on b buffer + for err == nil { + n, err = f.Read(b) + total += n + if n > 0 { + in <- b[:n] + } + } + if err == io.EOF { + err = nil + } + }() + h := sha1.New() + for b := range in { + h.Write(b) + } + _ = h.Sum(nil) + err := <-res + if err != nil { + t.Fatal(err) + } +} + +func TestRaceIssue5654(t *testing.T) { + text := `Friends, Romans, countrymen, lend me your ears; +I come to bury Caesar, not to praise him. +The evil that men do lives after them; +The good is oft interred with their bones; +So let it be with Caesar. The noble Brutus +Hath told you Caesar was ambitious: +If it were so, it was a grievous fault, +And grievously hath Caesar answer'd it. +Here, under leave of Brutus and the rest - +For Brutus is an honourable man; +So are they all, all honourable men - +Come I to speak in Caesar's funeral. +He was my friend, faithful and just to me: +But Brutus says he was ambitious; +And Brutus is an honourable man.` + + data := bytes.NewBufferString(text) + in := make(chan []byte) + + go func() { + buf := make([]byte, 16) + var n int + var err error + for ; err == nil; n, err = data.Read(buf) { + in <- buf[:n] + } + close(in) + }() + res := "" + for s := range in { + res += string(s) + } + _ = res +} + +type Base int + +func (b *Base) Foo() int { + return 42 +} + +func (b Base) Bar() int { + return int(b) +} + +func TestNoRaceMethodThunk(t *testing.T) { + type Derived struct { + pad int + Base + } + var d Derived + done := make(chan bool) + go func() { + _ = d.Foo() + done <- true + }() + d = Derived{} + <-done +} + +func TestRaceMethodThunk(t *testing.T) { + type Derived struct { + pad int + *Base + } + var d Derived + done := make(chan bool) + go func() { + _ = d.Foo() + done <- true + }() + d = Derived{} + <-done +} + +func TestRaceMethodThunk2(t *testing.T) { + type Derived struct { + pad int + Base + } + var d Derived + done := make(chan bool) + go func() { + _ = d.Bar() + done <- true + }() + d = Derived{} + <-done +} + +func TestRaceMethodThunk3(t *testing.T) { + type Derived struct { + pad int + *Base + } + var d Derived + d.Base = new(Base) + done := make(chan bool) + go func() { + _ = d.Bar() + done <- true + }() + d.Base = new(Base) + <-done +} + +func TestRaceMethodThunk4(t *testing.T) { + type Derived struct { + pad int + *Base + } + var d Derived + d.Base = new(Base) + done := make(chan bool) + go func() { + _ = d.Bar() + done <- true + }() + *(*int)(d.Base) = 42 + <-done +} |