diff options
Diffstat (limited to 'src/pkg/runtime/race/testdata/mop_test.go')
-rw-r--r-- | src/pkg/runtime/race/testdata/mop_test.go | 1957 |
1 files changed, 0 insertions, 1957 deletions
diff --git a/src/pkg/runtime/race/testdata/mop_test.go b/src/pkg/runtime/race/testdata/mop_test.go deleted file mode 100644 index cb17a27d3..000000000 --- a/src/pkg/runtime/race/testdata/mop_test.go +++ /dev/null @@ -1,1957 +0,0 @@ -// Copyright 2011 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 ( - "bytes" - "crypto/sha1" - "errors" - "fmt" - "io" - "os" - "runtime" - "sync" - "testing" - "time" - "unsafe" -) - -type Point struct { - x, y int -} - -type NamedPoint struct { - name string - p Point -} - -type DummyWriter struct { - state int -} -type Writer interface { - Write(p []byte) (n int) -} - -func (d DummyWriter) Write(p []byte) (n int) { - return 0 -} - -var GlobalX, GlobalY int = 0, 0 -var GlobalCh chan int = make(chan int, 2) - -func GlobalFunc1() { - GlobalY = GlobalX - GlobalCh <- 1 -} - -func GlobalFunc2() { - GlobalX = 1 - GlobalCh <- 1 -} - -func TestRaceIntRWGlobalFuncs(t *testing.T) { - go GlobalFunc1() - go GlobalFunc2() - <-GlobalCh - <-GlobalCh -} - -func TestRaceIntRWClosures(t *testing.T) { - var x, y int - ch := make(chan int, 2) - - go func() { - y = x - ch <- 1 - }() - go func() { - x = 1 - ch <- 1 - }() - <-ch - <-ch -} - -func TestNoRaceIntRWClosures(t *testing.T) { - var x, y int - ch := make(chan int, 1) - - go func() { - y = x - ch <- 1 - }() - <-ch - go func() { - x = 1 - ch <- 1 - }() - <-ch - -} - -func TestRaceInt32RWClosures(t *testing.T) { - var x, y int32 - ch := make(chan bool, 2) - - go func() { - y = x - ch <- true - }() - go func() { - x = 1 - ch <- true - }() - <-ch - <-ch -} - -func TestNoRaceCase(t *testing.T) { - var y int - for x := -1; x <= 1; x++ { - switch { - case x < 0: - y = -1 - case x == 0: - y = 0 - case x > 0: - y = 1 - } - } - y++ -} - -func TestRaceCaseCondition(t *testing.T) { - var x int = 0 - ch := make(chan int, 2) - - go func() { - x = 2 - ch <- 1 - }() - go func() { - switch x < 2 { - case true: - x = 1 - //case false: - // x = 5 - } - ch <- 1 - }() - <-ch - <-ch -} - -func TestRaceCaseCondition2(t *testing.T) { - // switch body is rearranged by the compiler so the tests - // passes even if we don't instrument '<' - var x int = 0 - ch := make(chan int, 2) - - go func() { - x = 2 - ch <- 1 - }() - go func() { - switch x < 2 { - case true: - x = 1 - case false: - x = 5 - } - ch <- 1 - }() - <-ch - <-ch -} - -func TestRaceCaseBody(t *testing.T) { - var x, y int - ch := make(chan int, 2) - - go func() { - y = x - ch <- 1 - }() - go func() { - switch { - default: - x = 1 - case x == 100: - x = -x - } - ch <- 1 - }() - <-ch - <-ch -} - -func TestNoRaceCaseFallthrough(t *testing.T) { - var x, y, z int - ch := make(chan int, 2) - z = 1 - - go func() { - y = x - ch <- 1 - }() - go func() { - switch { - case z == 1: - case z == 2: - x = 2 - } - ch <- 1 - }() - <-ch - <-ch -} - -func TestRaceCaseFallthrough(t *testing.T) { - var x, y, z int - ch := make(chan int, 2) - z = 1 - - go func() { - y = x - ch <- 1 - }() - go func() { - switch { - case z == 1: - fallthrough - case z == 2: - x = 2 - } - ch <- 1 - }() - - <-ch - <-ch -} - -func TestRaceCaseIssue6418(t *testing.T) { - m := map[string]map[string]string{ - "a": { - "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 - c := make(chan int, 1) - go func() { - switch i.(type) { - case nil: - case int: - } - c <- 1 - }() - i = y - <-c -} - -func TestRaceCaseTypeBody(t *testing.T) { - var x, y int - var i interface{} = &x - c := make(chan int, 1) - go func() { - switch i := i.(type) { - case nil: - case *int: - *i = y - } - c <- 1 - }() - x = y - <-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} - for _, v := range a { - ch <- v - } - 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 - var x, y int - done := make(chan bool, N) - for i, v := range a { - go func(i int) { - // we don't want a write-vs-write race - // so there is no array b here - if i == 0 { - x = v - } else { - y = v - } - done <- true - }(i) - } - for i := 0; i < N; i++ { - <-done - } -} - -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) - - go func() { - y = x + z - ch <- 1 - }() - go func() { - y = x + z + z - ch <- 1 - }() - <-ch - <-ch -} - -func TestRacePlus2(t *testing.T) { - var x, y, z int - ch := make(chan int, 2) - - go func() { - x = 1 - ch <- 1 - }() - go func() { - y = +x + z - ch <- 1 - }() - <-ch - <-ch -} - -func TestNoRacePlus(t *testing.T) { - var x, y, z, f int - ch := make(chan int, 2) - - go func() { - y = x + z - ch <- 1 - }() - go func() { - f = z + x - ch <- 1 - }() - <-ch - <-ch -} - -func TestRaceComplement(t *testing.T) { - var x, y, z int - ch := make(chan int, 2) - - go func() { - x = ^y - ch <- 1 - }() - go func() { - y = ^z - ch <- 1 - }() - <-ch - <-ch -} - -func TestRaceDiv(t *testing.T) { - var x, y, z int - ch := make(chan int, 2) - - go func() { - x = y / (z + 1) - ch <- 1 - }() - go func() { - y = z - ch <- 1 - }() - <-ch - <-ch -} - -func TestRaceDivConst(t *testing.T) { - var x, y, z uint32 - ch := make(chan int, 2) - - go func() { - x = y / 3 // involves only a HMUL node - ch <- 1 - }() - go func() { - y = z - ch <- 1 - }() - <-ch - <-ch -} - -func TestRaceMod(t *testing.T) { - var x, y, z int - ch := make(chan int, 2) - - go func() { - x = y % (z + 1) - ch <- 1 - }() - go func() { - y = z - ch <- 1 - }() - <-ch - <-ch -} - -func TestRaceModConst(t *testing.T) { - var x, y, z int - ch := make(chan int, 2) - - go func() { - x = y % 3 - ch <- 1 - }() - go func() { - y = z - ch <- 1 - }() - <-ch - <-ch -} - -func TestRaceRotate(t *testing.T) { - var x, y, z uint32 - ch := make(chan int, 2) - - go func() { - x = y<<12 | y>>20 - ch <- 1 - }() - go func() { - y = z - ch <- 1 - }() - <-ch - <-ch -} - -// May crash if the instrumentation is reckless. -func TestNoRaceEnoughRegisters(t *testing.T) { - // from erf.go - const ( - sa1 = 1 - sa2 = 2 - sa3 = 3 - sa4 = 4 - sa5 = 5 - sa6 = 6 - sa7 = 7 - sa8 = 8 - ) - var s, S float64 - s = 3.1415 - S = 1 + s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(sa5+s*(sa6+s*(sa7+s*sa8))))))) - s = S -} - -// emptyFunc should not be inlined. -func emptyFunc(x int) { - if false { - fmt.Println(x) - } -} - -func TestRaceFuncArgument(t *testing.T) { - var x int - ch := make(chan bool, 1) - go func() { - emptyFunc(x) - ch <- true - }() - x = 1 - <-ch -} - -func TestRaceFuncArgument2(t *testing.T) { - var x int - ch := make(chan bool, 2) - go func() { - x = 42 - ch <- true - }() - go func(y int) { - ch <- true - }(x) - <-ch - <-ch -} - -func TestRaceSprint(t *testing.T) { - var x int - ch := make(chan bool, 1) - go func() { - fmt.Sprint(x) - ch <- true - }() - x = 1 - <-ch -} - -func TestRaceArrayCopy(t *testing.T) { - ch := make(chan bool, 1) - var a [5]int - go func() { - a[3] = 1 - ch <- true - }() - a = [5]int{1, 2, 3, 4, 5} - <-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) - go func() { - p = Point{1, 1} - ch <- true - }() - q := p - <-ch - p = q -} - -func TestRaceStructFieldRW1(t *testing.T) { - p := Point{0, 0} - ch := make(chan bool, 1) - go func() { - p.x = 1 - ch <- true - }() - _ = p.x - <-ch -} - -func TestNoRaceStructFieldRW1(t *testing.T) { - // Same struct, different variables, no - // pointers. The layout is known (at compile time?) -> - // no read on p - // writes on x and y - p := Point{0, 0} - ch := make(chan bool, 1) - go func() { - p.x = 1 - ch <- true - }() - p.y = 1 - <-ch - _ = p -} - -func TestNoRaceStructFieldRW2(t *testing.T) { - // Same as NoRaceStructFieldRW1 - // but p is a pointer, so there is a read on p - p := Point{0, 0} - ch := make(chan bool, 1) - go func() { - p.x = 1 - ch <- true - }() - p.y = 1 - <-ch - _ = p -} - -func TestRaceStructFieldRW2(t *testing.T) { - p := &Point{0, 0} - ch := make(chan bool, 1) - go func() { - p.x = 1 - ch <- true - }() - _ = p.x - <-ch -} - -func TestRaceStructFieldRW3(t *testing.T) { - p := NamedPoint{name: "a", p: Point{0, 0}} - ch := make(chan bool, 1) - go func() { - p.p.x = 1 - ch <- true - }() - _ = p.p.x - <-ch -} - -func TestRaceEfaceWW(t *testing.T) { - var a, b interface{} - ch := make(chan bool, 1) - go func() { - a = 1 - ch <- true - }() - a = 2 - <-ch - _, _ = a, b -} - -func TestRaceIfaceWW(t *testing.T) { - var a, b Writer - ch := make(chan bool, 1) - go func() { - a = DummyWriter{1} - ch <- true - }() - a = DummyWriter{2} - <-ch - b = a - a = b -} - -func TestRaceIfaceCmp(t *testing.T) { - var a, b Writer - a = DummyWriter{1} - ch := make(chan bool, 1) - go func() { - a = DummyWriter{1} - ch <- true - }() - _ = a == b - <-ch -} - -func TestRaceIfaceCmpNil(t *testing.T) { - var a Writer - a = DummyWriter{1} - ch := make(chan bool, 1) - go func() { - a = DummyWriter{1} - ch <- true - }() - _ = a == nil - <-ch -} - -func TestRaceEfaceConv(t *testing.T) { - c := make(chan bool) - v := 0 - go func() { - go func(x interface{}) { - }(v) - c <- true - }() - v = 42 - <-c -} - -type OsFile struct{} - -func (*OsFile) Read() { -} - -type IoReader interface { - Read() -} - -func TestRaceIfaceConv(t *testing.T) { - c := make(chan bool) - f := &OsFile{} - go func() { - go func(x IoReader) { - }(f) - c <- true - }() - f = &OsFile{} - <-c -} - -func TestRaceError(t *testing.T) { - ch := make(chan bool, 1) - var err error - go func() { - err = nil - ch <- true - }() - _ = err - <-ch -} - -func TestRaceIntptrRW(t *testing.T) { - var x, y int - var p *int = &x - ch := make(chan bool, 1) - go func() { - *p = 5 - ch <- true - }() - y = *p - x = y - <-ch -} - -func TestRaceStringRW(t *testing.T) { - ch := make(chan bool, 1) - s := "" - go func() { - s = "abacaba" - ch <- true - }() - _ = s - <-ch -} - -func TestRaceStringPtrRW(t *testing.T) { - ch := make(chan bool, 1) - var x string - p := &x - go func() { - *p = "a" - ch <- true - }() - _ = *p - <-ch -} - -func TestRaceFloat64WW(t *testing.T) { - var x, y float64 - ch := make(chan bool, 1) - go func() { - x = 1.0 - ch <- true - }() - x = 2.0 - <-ch - - y = x - x = y -} - -func TestRaceComplex128WW(t *testing.T) { - var x, y complex128 - ch := make(chan bool, 1) - go func() { - x = 2 + 2i - ch <- true - }() - x = 4 + 4i - <-ch - - y = x - x = y -} - -func TestRaceUnsafePtrRW(t *testing.T) { - var x, y, z int - x, y, z = 1, 2, 3 - var p unsafe.Pointer = unsafe.Pointer(&x) - ch := make(chan bool, 1) - go func() { - p = (unsafe.Pointer)(&z) - ch <- true - }() - y = *(*int)(p) - x = y - <-ch -} - -func TestRaceFuncVariableRW(t *testing.T) { - var f func(x int) int - f = func(x int) int { - return x * x - } - ch := make(chan bool, 1) - go func() { - f = func(x int) int { - return x - } - ch <- true - }() - y := f(1) - <-ch - x := y - y = x -} - -func TestRaceFuncVariableWW(t *testing.T) { - var f func(x int) int - ch := make(chan bool, 1) - go func() { - f = func(x int) int { - return x - } - ch <- true - }() - f = func(x int) int { - return x * x - } - <-ch -} - -// This one should not belong to mop_test -func TestRacePanic(t *testing.T) { - var x int - var zero int = 0 - ch := make(chan bool, 2) - go func() { - defer func() { - err := recover() - if err == nil { - panic("should be panicking") - } - x = 1 - ch <- true - }() - var y int = 1 / zero - zero = y - }() - go func() { - defer func() { - err := recover() - if err == nil { - panic("should be panicking") - } - x = 2 - ch <- true - }() - var y int = 1 / zero - zero = y - }() - - <-ch - <-ch - if zero != 0 { - panic("zero has changed") - } -} - -func TestNoRaceBlank(t *testing.T) { - var a [5]int - ch := make(chan bool, 1) - go func() { - _, _ = a[0], a[1] - ch <- true - }() - _, _ = a[2], a[3] - <-ch - a[1] = a[0] -} - -func TestRaceAppendRW(t *testing.T) { - a := make([]int, 10) - ch := make(chan bool) - go func() { - _ = append(a, 1) - ch <- true - }() - a[0] = 1 - <-ch -} - -func TestRaceAppendLenRW(t *testing.T) { - a := make([]int, 0) - ch := make(chan bool) - go func() { - a = append(a, 1) - ch <- true - }() - _ = len(a) - <-ch -} - -func TestRaceAppendCapRW(t *testing.T) { - a := make([]int, 0) - ch := make(chan string) - go func() { - a = append(a, 1) - ch <- "" - }() - _ = cap(a) - <-ch -} - -func TestNoRaceFuncArgsRW(t *testing.T) { - ch := make(chan byte, 1) - var x byte - go func(y byte) { - _ = y - ch <- 0 - }(x) - x = 1 - <-ch -} - -func TestRaceFuncArgsRW(t *testing.T) { - ch := make(chan byte, 1) - var x byte - go func(y *byte) { - _ = *y - ch <- 0 - }(&x) - x = 1 - <-ch -} - -// from the mailing list, slightly modified -// unprotected concurrent access to seen[] -func TestRaceCrawl(t *testing.T) { - url := "dummyurl" - depth := 3 - seen := make(map[string]bool) - ch := make(chan int, 100) - var wg sync.WaitGroup - var crawl func(string, int) - crawl = func(u string, d int) { - nurl := 0 - defer func() { - ch <- nurl - }() - seen[u] = true - if d <= 0 { - return - } - urls := [...]string{"a", "b", "c"} - for _, uu := range urls { - if _, ok := seen[uu]; !ok { - wg.Add(1) - go crawl(uu, d-1) - nurl++ - } - } - wg.Done() - } - wg.Add(1) - go crawl(url, depth) - wg.Wait() -} - -func TestRaceIndirection(t *testing.T) { - ch := make(chan struct{}, 1) - var y int - var x *int = &y - go func() { - *x = 1 - ch <- struct{}{} - }() - *x = 2 - <-ch - _ = *x -} - -func TestRaceRune(t *testing.T) { - c := make(chan bool) - var x rune - go func() { - x = 1 - c <- true - }() - _ = x - <-c -} - -func TestRaceEmptyInterface1(t *testing.T) { - c := make(chan bool) - var x interface{} - go func() { - x = nil - c <- true - }() - _ = x - <-c -} - -func TestRaceEmptyInterface2(t *testing.T) { - c := make(chan bool) - var x interface{} - go func() { - x = &Point{} - c <- true - }() - _ = x - <-c -} - -func TestRaceTLS(t *testing.T) { - comm := make(chan *int) - done := make(chan bool, 2) - go func() { - var x int - comm <- &x - x = 1 - x = *(<-comm) - done <- true - }() - go func() { - p := <-comm - *p = 2 - comm <- p - done <- true - }() - <-done - <-done -} - -func TestNoRaceHeapReallocation(t *testing.T) { - // It is possible that a future implementation - // of memory allocation will ruin this test. - // Increasing n might help in this case, so - // this test is a bit more generic than most of the - // others. - const n = 2 - done := make(chan bool, n) - empty := func(p *int) {} - for i := 0; i < n; i++ { - ms := i - go func() { - <-time.After(time.Duration(ms) * time.Millisecond) - runtime.GC() - var x int - empty(&x) // x goes to the heap - done <- true - }() - } - for i := 0; i < n; i++ { - <-done - } -} - -func TestRaceAnd(t *testing.T) { - c := make(chan bool) - x, y := 0, 0 - go func() { - x = 1 - c <- true - }() - if x == 1 && y == 1 { - } - <-c -} - -func TestRaceAnd2(t *testing.T) { - c := make(chan bool) - x, y := 0, 0 - go func() { - x = 1 - c <- true - }() - if y == 0 && x == 1 { - } - <-c -} - -func TestNoRaceAnd(t *testing.T) { - c := make(chan bool) - x, y := 0, 0 - go func() { - x = 1 - c <- true - }() - if y == 1 && x == 1 { - } - <-c -} - -func TestRaceOr(t *testing.T) { - c := make(chan bool) - x, y := 0, 0 - go func() { - x = 1 - c <- true - }() - if x == 1 || y == 1 { - } - <-c -} - -func TestRaceOr2(t *testing.T) { - c := make(chan bool) - x, y := 0, 0 - go func() { - x = 1 - c <- true - }() - if y == 1 || x == 1 { - } - <-c -} - -func TestNoRaceOr(t *testing.T) { - c := make(chan bool) - x, y := 0, 0 - go func() { - x = 1 - c <- true - }() - if y == 0 || x == 1 { - } - <-c -} - -func TestNoRaceShortCalc(t *testing.T) { - c := make(chan bool) - x, y := 0, 0 - go func() { - y = 1 - c <- true - }() - if x == 0 || y == 0 { - } - <-c -} - -func TestNoRaceShortCalc2(t *testing.T) { - c := make(chan bool) - x, y := 0, 0 - go func() { - y = 1 - c <- true - }() - if x == 1 && y == 0 { - } - <-c -} - -func TestRaceFuncItself(t *testing.T) { - c := make(chan bool) - f := func() {} - go func() { - f() - c <- true - }() - f = func() {} - <-c -} - -func TestNoRaceFuncUnlock(t *testing.T) { - ch := make(chan bool, 1) - var mu sync.Mutex - x := 0 - go func() { - mu.Lock() - x = 42 - mu.Unlock() - ch <- true - }() - x = func(mu *sync.Mutex) int { - mu.Lock() - return 43 - }(&mu) - mu.Unlock() - <-ch -} - -func TestRaceStructInit(t *testing.T) { - type X struct { - x, y int - } - c := make(chan bool, 1) - y := 0 - go func() { - y = 42 - c <- true - }() - x := X{x: y} - _ = x - <-c -} - -func TestRaceArrayInit(t *testing.T) { - c := make(chan bool, 1) - y := 0 - go func() { - y = 42 - c <- true - }() - x := []int{0, y, 42} - _ = x - <-c -} - -func TestRaceMapInit(t *testing.T) { - c := make(chan bool, 1) - y := 0 - go func() { - y = 42 - c <- true - }() - x := map[int]int{0: 42, y: 42} - _ = x - <-c -} - -func TestRaceMapInit2(t *testing.T) { - c := make(chan bool, 1) - y := 0 - go func() { - y = 42 - c <- true - }() - x := map[int]int{0: 42, 42: y} - _ = x - <-c -} - -type Inter interface { - Foo(x int) -} -type InterImpl struct { - x, y int -} - -func (p InterImpl) Foo(x int) { - // prevent inlining - z := 42 - x = 85 - y := x / z - z = y * z - x = z * y - _, _, _ = x, y, z -} - -type InterImpl2 InterImpl - -func (p *InterImpl2) Foo(x int) { - if p == nil { - InterImpl{}.Foo(x) - } - InterImpl(*p).Foo(x) -} - -func TestRaceInterCall(t *testing.T) { - c := make(chan bool, 1) - p := InterImpl{} - var x Inter = p - go func() { - p2 := InterImpl{} - x = p2 - c <- true - }() - x.Foo(0) - <-c -} - -func TestRaceInterCall2(t *testing.T) { - c := make(chan bool, 1) - p := InterImpl{} - var x Inter = p - z := 0 - go func() { - z = 42 - c <- true - }() - x.Foo(z) - <-c -} - -func TestRaceFuncCall(t *testing.T) { - c := make(chan bool, 1) - f := func(x, y int) {} - x, y := 0, 0 - go func() { - y = 42 - c <- true - }() - f(x, y) - <-c -} - -func TestRaceMethodCall(t *testing.T) { - c := make(chan bool, 1) - i := InterImpl{} - x := 0 - go func() { - x = 42 - c <- true - }() - i.Foo(x) - <-c -} - -func TestRaceMethodCall2(t *testing.T) { - c := make(chan bool, 1) - i := &InterImpl{} - go func() { - i = &InterImpl{} - c <- true - }() - i.Foo(0) - <-c -} - -// Method value with concrete value receiver. -func TestRaceMethodValue(t *testing.T) { - c := make(chan bool, 1) - i := InterImpl{} - go func() { - i = InterImpl{} - c <- true - }() - _ = i.Foo - <-c -} - -// Method value with interface receiver. -func TestRaceMethodValue2(t *testing.T) { - c := make(chan bool, 1) - var i Inter = InterImpl{} - go func() { - i = InterImpl{} - c <- true - }() - _ = i.Foo - <-c -} - -// Method value with implicit dereference. -func TestRaceMethodValue3(t *testing.T) { - c := make(chan bool, 1) - i := &InterImpl{} - go func() { - *i = InterImpl{} - c <- true - }() - _ = i.Foo // dereferences i. - <-c -} - -// Method value implicitly taking receiver address. -func TestNoRaceMethodValue(t *testing.T) { - c := make(chan bool, 1) - i := InterImpl2{} - go func() { - i = InterImpl2{} - c <- true - }() - _ = i.Foo // takes the address of i only. - <-c -} - -func TestRacePanicArg(t *testing.T) { - c := make(chan bool, 1) - err := errors.New("err") - go func() { - err = errors.New("err2") - c <- true - }() - defer func() { - recover() - <-c - }() - panic(err) -} - -func TestRaceDeferArg(t *testing.T) { - c := make(chan bool, 1) - x := 0 - go func() { - x = 42 - c <- true - }() - func() { - defer func(x int) { - }(x) - }() - <-c -} - -type DeferT int - -func (d DeferT) Foo() { -} - -func TestRaceDeferArg2(t *testing.T) { - c := make(chan bool, 1) - var x DeferT - go func() { - var y DeferT - x = y - c <- true - }() - func() { - defer x.Foo() - }() - <-c -} - -func TestNoRaceAddrExpr(t *testing.T) { - c := make(chan bool, 1) - x := 0 - go func() { - x = 42 - c <- true - }() - _ = &x - <-c -} - -type AddrT struct { - _ [256]byte - x int -} - -type AddrT2 struct { - _ [512]byte - p *AddrT -} - -func TestRaceAddrExpr(t *testing.T) { - c := make(chan bool, 1) - a := AddrT2{p: &AddrT{x: 42}} - go func() { - a.p = &AddrT{x: 43} - c <- true - }() - _ = &a.p.x - <-c -} - -func TestRaceTypeAssert(t *testing.T) { - c := make(chan bool, 1) - x := 0 - var i interface{} = x - go func() { - y := 0 - i = y - c <- true - }() - _ = i.(int) - <-c -} - -func TestRaceBlockAs(t *testing.T) { - c := make(chan bool, 1) - var x, y int - go func() { - x = 42 - c <- true - }() - x, y = y, x - <-c -} - -func TestRaceSliceSlice(t *testing.T) { - c := make(chan bool, 1) - x := make([]int, 10) - go func() { - x = make([]int, 20) - c <- true - }() - _ = x[2:3] - <-c -} - -func TestRaceSliceSlice2(t *testing.T) { - c := make(chan bool, 1) - x := make([]int, 10) - i := 2 - go func() { - i = 3 - c <- true - }() - _ = x[i:4] - <-c -} - -func TestRaceSliceString(t *testing.T) { - c := make(chan bool, 1) - x := "hello" - go func() { - x = "world" - c <- true - }() - _ = x[2:3] - <-c -} - -func TestRaceSliceStruct(t *testing.T) { - type X struct { - x, y int - } - c := make(chan bool, 1) - x := make([]X, 10) - go func() { - y := make([]X, 10) - copy(y, x) - c <- true - }() - x[1].y = 42 - <-c -} - -func TestRaceAppendSliceStruct(t *testing.T) { - type X struct { - x, y int - } - c := make(chan bool, 1) - x := make([]X, 10) - go func() { - y := make([]X, 0, 10) - y = append(y, x...) - c <- true - }() - x[1].y = 42 - <-c -} - -func TestRaceStructInd(t *testing.T) { - c := make(chan bool, 1) - type Item struct { - x, y int - } - i := Item{} - go func(p *Item) { - *p = Item{} - c <- true - }(&i) - i.y = 42 - <-c -} - -func TestRaceAsFunc1(t *testing.T) { - var s []byte - c := make(chan bool, 1) - go func() { - var err error - s, err = func() ([]byte, error) { - t := []byte("hello world") - return t, nil - }() - c <- true - _ = err - }() - _ = string(s) - <-c -} - -func TestRaceAsFunc2(t *testing.T) { - c := make(chan bool, 1) - x := 0 - go func() { - func(x int) { - }(x) - c <- true - }() - x = 42 - <-c -} - -func TestRaceAsFunc3(t *testing.T) { - c := make(chan bool, 1) - var mu sync.Mutex - x := 0 - go func() { - func(x int) { - mu.Lock() - }(x) // Read of x must be outside of the mutex. - mu.Unlock() - c <- true - }() - mu.Lock() - x = 42 - mu.Unlock() - <-c -} - -func TestNoRaceAsFunc4(t *testing.T) { - c := make(chan bool, 1) - var mu sync.Mutex - x := 0 - go func() { - x = func() int { // Write of x must be under the mutex. - mu.Lock() - return 42 - }() - mu.Unlock() - c <- true - }() - mu.Lock() - x = 42 - mu.Unlock() - <-c -} - -func TestRaceHeapParam(t *testing.T) { - x := func() (x int) { - go func() { - x = 42 - }() - return - }() - _ = x -} - -func TestNoRaceEmptyStruct(t *testing.T) { - type Empty struct{} - type X struct { - y int64 - Empty - } - type Y struct { - x X - y int64 - } - c := make(chan X) - var y Y - go func() { - x := y.x - c <- x - }() - y.y = 42 - <-c -} - -func TestRaceNestedStruct(t *testing.T) { - type X struct { - x, y int - } - type Y struct { - x X - } - c := make(chan Y) - var y Y - go func() { - c <- y - }() - 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 -} - -func TestNoRaceTinyAlloc(t *testing.T) { - const P = 4 - const N = 1e6 - var tinySink *byte - done := make(chan bool) - for p := 0; p < P; p++ { - go func() { - for i := 0; i < N; i++ { - var b byte - if b != 0 { - tinySink = &b // make it heap allocated - } - b = 42 - } - done <- true - }() - } - for p := 0; p < P; p++ { - <-done - } -} |