github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/pkg/runtime/race/testdata/mop_test.go (about) 1 // Copyright 2011 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 5 package race_test 6 7 import ( 8 "errors" 9 "fmt" 10 "runtime" 11 "sync" 12 "testing" 13 "time" 14 "unsafe" 15 ) 16 17 type Point struct { 18 x, y int 19 } 20 21 type NamedPoint struct { 22 name string 23 p Point 24 } 25 26 type DummyWriter struct { 27 state int 28 } 29 type Writer interface { 30 Write(p []byte) (n int) 31 } 32 33 func (d DummyWriter) Write(p []byte) (n int) { 34 return 0 35 } 36 37 var GlobalX, GlobalY int = 0, 0 38 var GlobalCh chan int = make(chan int, 2) 39 40 func GlobalFunc1() { 41 GlobalY = GlobalX 42 GlobalCh <- 1 43 } 44 45 func GlobalFunc2() { 46 GlobalX = 1 47 GlobalCh <- 1 48 } 49 50 func TestRaceIntRWGlobalFuncs(t *testing.T) { 51 go GlobalFunc1() 52 go GlobalFunc2() 53 <-GlobalCh 54 <-GlobalCh 55 } 56 57 func TestRaceIntRWClosures(t *testing.T) { 58 var x, y int 59 ch := make(chan int, 2) 60 61 go func() { 62 y = x 63 ch <- 1 64 }() 65 go func() { 66 x = 1 67 ch <- 1 68 }() 69 <-ch 70 <-ch 71 } 72 73 func TestNoRaceIntRWClosures(t *testing.T) { 74 var x, y int 75 ch := make(chan int, 1) 76 77 go func() { 78 y = x 79 ch <- 1 80 }() 81 <-ch 82 go func() { 83 x = 1 84 ch <- 1 85 }() 86 <-ch 87 88 } 89 90 func TestRaceInt32RWClosures(t *testing.T) { 91 var x, y int32 92 ch := make(chan bool, 2) 93 94 go func() { 95 y = x 96 ch <- true 97 }() 98 go func() { 99 x = 1 100 ch <- true 101 }() 102 <-ch 103 <-ch 104 } 105 106 func TestNoRaceCase(t *testing.T) { 107 var y int 108 for x := -1; x <= 1; x++ { 109 switch { 110 case x < 0: 111 y = -1 112 case x == 0: 113 y = 0 114 case x > 0: 115 y = 1 116 } 117 } 118 y++ 119 } 120 121 func TestRaceCaseCondition(t *testing.T) { 122 var x int = 0 123 ch := make(chan int, 2) 124 125 go func() { 126 x = 2 127 ch <- 1 128 }() 129 go func() { 130 switch x < 2 { 131 case true: 132 x = 1 133 //case false: 134 // x = 5 135 } 136 ch <- 1 137 }() 138 <-ch 139 <-ch 140 } 141 142 func TestRaceCaseCondition2(t *testing.T) { 143 // switch body is rearranged by the compiler so the tests 144 // passes even if we don't instrument '<' 145 var x int = 0 146 ch := make(chan int, 2) 147 148 go func() { 149 x = 2 150 ch <- 1 151 }() 152 go func() { 153 switch x < 2 { 154 case true: 155 x = 1 156 case false: 157 x = 5 158 } 159 ch <- 1 160 }() 161 <-ch 162 <-ch 163 } 164 165 func TestRaceCaseBody(t *testing.T) { 166 var x, y int 167 ch := make(chan int, 2) 168 169 go func() { 170 y = x 171 ch <- 1 172 }() 173 go func() { 174 switch { 175 default: 176 x = 1 177 case x == 100: 178 x = -x 179 } 180 ch <- 1 181 }() 182 <-ch 183 <-ch 184 } 185 186 func TestNoRaceCaseFallthrough(t *testing.T) { 187 var x, y, z int 188 ch := make(chan int, 2) 189 z = 1 190 191 go func() { 192 y = x 193 ch <- 1 194 }() 195 go func() { 196 switch { 197 case z == 1: 198 case z == 2: 199 x = 2 200 } 201 ch <- 1 202 }() 203 <-ch 204 <-ch 205 } 206 207 func TestRaceCaseFallthrough(t *testing.T) { 208 var x, y, z int 209 ch := make(chan int, 2) 210 z = 1 211 212 go func() { 213 y = x 214 ch <- 1 215 }() 216 go func() { 217 switch { 218 case z == 1: 219 fallthrough 220 case z == 2: 221 x = 2 222 } 223 ch <- 1 224 }() 225 226 <-ch 227 <-ch 228 } 229 230 func TestRaceCaseType(t *testing.T) { 231 var x, y int 232 var i interface{} = x 233 c := make(chan int, 1) 234 go func() { 235 switch i.(type) { 236 case nil: 237 case int: 238 } 239 c <- 1 240 }() 241 i = y 242 <-c 243 } 244 245 func TestRaceCaseTypeBody(t *testing.T) { 246 var x, y int 247 var i interface{} = &x 248 c := make(chan int, 1) 249 go func() { 250 switch i := i.(type) { 251 case nil: 252 case *int: 253 *i = y 254 } 255 c <- 1 256 }() 257 x = y 258 <-c 259 } 260 261 func TestNoRaceRange(t *testing.T) { 262 ch := make(chan int, 3) 263 a := [...]int{1, 2, 3} 264 for _, v := range a { 265 ch <- v 266 } 267 close(ch) 268 } 269 270 func TestRaceRange(t *testing.T) { 271 const N = 2 272 var a [N]int 273 var x, y int 274 done := make(chan bool, N) 275 for i, v := range a { 276 go func(i int) { 277 // we don't want a write-vs-write race 278 // so there is no array b here 279 if i == 0 { 280 x = v 281 } else { 282 y = v 283 } 284 done <- true 285 }(i) 286 } 287 for i := 0; i < N; i++ { 288 <-done 289 } 290 } 291 292 func TestRacePlus(t *testing.T) { 293 var x, y, z int 294 ch := make(chan int, 2) 295 296 go func() { 297 y = x + z 298 ch <- 1 299 }() 300 go func() { 301 y = x + z + z 302 ch <- 1 303 }() 304 <-ch 305 <-ch 306 } 307 308 func TestRacePlus2(t *testing.T) { 309 var x, y, z int 310 ch := make(chan int, 2) 311 312 go func() { 313 x = 1 314 ch <- 1 315 }() 316 go func() { 317 y = +x + z 318 ch <- 1 319 }() 320 <-ch 321 <-ch 322 } 323 324 func TestNoRacePlus(t *testing.T) { 325 var x, y, z, f int 326 ch := make(chan int, 2) 327 328 go func() { 329 y = x + z 330 ch <- 1 331 }() 332 go func() { 333 f = z + x 334 ch <- 1 335 }() 336 <-ch 337 <-ch 338 } 339 340 func TestRaceComplement(t *testing.T) { 341 var x, y, z int 342 ch := make(chan int, 2) 343 344 go func() { 345 x = ^y 346 ch <- 1 347 }() 348 go func() { 349 y = ^z 350 ch <- 1 351 }() 352 <-ch 353 <-ch 354 } 355 356 func TestRaceDiv(t *testing.T) { 357 var x, y, z int 358 ch := make(chan int, 2) 359 360 go func() { 361 x = y / (z + 1) 362 ch <- 1 363 }() 364 go func() { 365 y = z 366 ch <- 1 367 }() 368 <-ch 369 <-ch 370 } 371 372 func TestRaceDivConst(t *testing.T) { 373 var x, y, z uint32 374 ch := make(chan int, 2) 375 376 go func() { 377 x = y / 3 // involves only a HMUL node 378 ch <- 1 379 }() 380 go func() { 381 y = z 382 ch <- 1 383 }() 384 <-ch 385 <-ch 386 } 387 388 func TestRaceMod(t *testing.T) { 389 var x, y, z int 390 ch := make(chan int, 2) 391 392 go func() { 393 x = y % (z + 1) 394 ch <- 1 395 }() 396 go func() { 397 y = z 398 ch <- 1 399 }() 400 <-ch 401 <-ch 402 } 403 404 func TestRaceModConst(t *testing.T) { 405 var x, y, z int 406 ch := make(chan int, 2) 407 408 go func() { 409 x = y % 3 410 ch <- 1 411 }() 412 go func() { 413 y = z 414 ch <- 1 415 }() 416 <-ch 417 <-ch 418 } 419 420 func TestRaceRotate(t *testing.T) { 421 var x, y, z uint32 422 ch := make(chan int, 2) 423 424 go func() { 425 x = y<<12 | y>>20 426 ch <- 1 427 }() 428 go func() { 429 y = z 430 ch <- 1 431 }() 432 <-ch 433 <-ch 434 } 435 436 // May crash if the instrumentation is reckless. 437 func TestNoRaceEnoughRegisters(t *testing.T) { 438 // from erf.go 439 const ( 440 sa1 = 1 441 sa2 = 2 442 sa3 = 3 443 sa4 = 4 444 sa5 = 5 445 sa6 = 6 446 sa7 = 7 447 sa8 = 8 448 ) 449 var s, S float64 450 s = 3.1415 451 S = 1 + s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(sa5+s*(sa6+s*(sa7+s*sa8))))))) 452 s = S 453 } 454 455 // emptyFunc should not be inlined. 456 func emptyFunc(x int) { 457 if false { 458 fmt.Println(x) 459 } 460 } 461 462 func TestRaceFuncArgument(t *testing.T) { 463 var x int 464 ch := make(chan bool, 1) 465 go func() { 466 emptyFunc(x) 467 ch <- true 468 }() 469 x = 1 470 <-ch 471 } 472 473 func TestRaceFuncArgument2(t *testing.T) { 474 var x int 475 ch := make(chan bool, 2) 476 go func() { 477 x = 42 478 ch <- true 479 }() 480 go func(y int) { 481 ch <- true 482 }(x) 483 <-ch 484 <-ch 485 } 486 487 func TestRaceSprint(t *testing.T) { 488 var x int 489 ch := make(chan bool, 1) 490 go func() { 491 fmt.Sprint(x) 492 ch <- true 493 }() 494 x = 1 495 <-ch 496 } 497 498 // Not implemented. 499 func TestRaceFailingArrayCopy(t *testing.T) { 500 ch := make(chan bool, 1) 501 var a [5]int 502 go func() { 503 a[3] = 1 504 ch <- true 505 }() 506 a = [5]int{1, 2, 3, 4, 5} 507 <-ch 508 } 509 510 func TestRaceStructRW(t *testing.T) { 511 p := Point{0, 0} 512 ch := make(chan bool, 1) 513 go func() { 514 p = Point{1, 1} 515 ch <- true 516 }() 517 q := p 518 <-ch 519 p = q 520 } 521 522 func TestRaceStructFieldRW1(t *testing.T) { 523 p := Point{0, 0} 524 ch := make(chan bool, 1) 525 go func() { 526 p.x = 1 527 ch <- true 528 }() 529 _ = p.x 530 <-ch 531 } 532 533 func TestNoRaceStructFieldRW1(t *testing.T) { 534 // Same struct, different variables, no 535 // pointers. The layout is known (at compile time?) -> 536 // no read on p 537 // writes on x and y 538 p := Point{0, 0} 539 ch := make(chan bool, 1) 540 go func() { 541 p.x = 1 542 ch <- true 543 }() 544 p.y = 1 545 <-ch 546 _ = p 547 } 548 549 func TestNoRaceStructFieldRW2(t *testing.T) { 550 // Same as NoRaceStructFieldRW1 551 // but p is a pointer, so there is a read on p 552 p := Point{0, 0} 553 ch := make(chan bool, 1) 554 go func() { 555 p.x = 1 556 ch <- true 557 }() 558 p.y = 1 559 <-ch 560 _ = p 561 } 562 563 func TestRaceStructFieldRW2(t *testing.T) { 564 p := &Point{0, 0} 565 ch := make(chan bool, 1) 566 go func() { 567 p.x = 1 568 ch <- true 569 }() 570 _ = p.x 571 <-ch 572 } 573 574 func TestRaceStructFieldRW3(t *testing.T) { 575 p := NamedPoint{name: "a", p: Point{0, 0}} 576 ch := make(chan bool, 1) 577 go func() { 578 p.p.x = 1 579 ch <- true 580 }() 581 _ = p.p.x 582 <-ch 583 } 584 585 func TestRaceEfaceWW(t *testing.T) { 586 var a, b interface{} 587 ch := make(chan bool, 1) 588 go func() { 589 a = 1 590 ch <- true 591 }() 592 a = 2 593 <-ch 594 _, _ = a, b 595 } 596 597 func TestRaceIfaceWW(t *testing.T) { 598 var a, b Writer 599 ch := make(chan bool, 1) 600 go func() { 601 a = DummyWriter{1} 602 ch <- true 603 }() 604 a = DummyWriter{2} 605 <-ch 606 b = a 607 a = b 608 } 609 610 func TestRaceIfaceCmp(t *testing.T) { 611 var a, b Writer 612 a = DummyWriter{1} 613 ch := make(chan bool, 1) 614 go func() { 615 a = DummyWriter{1} 616 ch <- true 617 }() 618 _ = a == b 619 <-ch 620 } 621 622 func TestRaceIfaceCmpNil(t *testing.T) { 623 var a Writer 624 a = DummyWriter{1} 625 ch := make(chan bool, 1) 626 go func() { 627 a = DummyWriter{1} 628 ch <- true 629 }() 630 _ = a == nil 631 <-ch 632 } 633 634 func TestRaceEfaceConv(t *testing.T) { 635 c := make(chan bool) 636 v := 0 637 go func() { 638 go func(x interface{}) { 639 }(v) 640 c <- true 641 }() 642 v = 42 643 <-c 644 } 645 646 type OsFile struct{} 647 648 func (*OsFile) Read() { 649 } 650 651 type IoReader interface { 652 Read() 653 } 654 655 func TestRaceIfaceConv(t *testing.T) { 656 c := make(chan bool) 657 f := &OsFile{} 658 go func() { 659 go func(x IoReader) { 660 }(f) 661 c <- true 662 }() 663 f = &OsFile{} 664 <-c 665 } 666 667 func TestRaceError(t *testing.T) { 668 ch := make(chan bool, 1) 669 var err error 670 go func() { 671 err = nil 672 ch <- true 673 }() 674 _ = err 675 <-ch 676 } 677 678 func TestRaceIntptrRW(t *testing.T) { 679 var x, y int 680 var p *int = &x 681 ch := make(chan bool, 1) 682 go func() { 683 *p = 5 684 ch <- true 685 }() 686 y = *p 687 x = y 688 <-ch 689 } 690 691 func TestRaceStringRW(t *testing.T) { 692 ch := make(chan bool, 1) 693 s := "" 694 go func() { 695 s = "abacaba" 696 ch <- true 697 }() 698 _ = s 699 <-ch 700 } 701 702 func TestRaceStringPtrRW(t *testing.T) { 703 ch := make(chan bool, 1) 704 var x string 705 p := &x 706 go func() { 707 *p = "a" 708 ch <- true 709 }() 710 _ = *p 711 <-ch 712 } 713 714 func TestRaceFloat64WW(t *testing.T) { 715 var x, y float64 716 ch := make(chan bool, 1) 717 go func() { 718 x = 1.0 719 ch <- true 720 }() 721 x = 2.0 722 <-ch 723 724 y = x 725 x = y 726 } 727 728 func TestRaceComplex128WW(t *testing.T) { 729 var x, y complex128 730 ch := make(chan bool, 1) 731 go func() { 732 x = 2 + 2i 733 ch <- true 734 }() 735 x = 4 + 4i 736 <-ch 737 738 y = x 739 x = y 740 } 741 742 func TestRaceUnsafePtrRW(t *testing.T) { 743 var x, y, z int 744 x, y, z = 1, 2, 3 745 var p unsafe.Pointer = unsafe.Pointer(&x) 746 ch := make(chan bool, 1) 747 go func() { 748 p = (unsafe.Pointer)(&z) 749 ch <- true 750 }() 751 y = *(*int)(p) 752 x = y 753 <-ch 754 } 755 756 func TestRaceFuncVariableRW(t *testing.T) { 757 var f func(x int) int 758 f = func(x int) int { 759 return x * x 760 } 761 ch := make(chan bool, 1) 762 go func() { 763 f = func(x int) int { 764 return x 765 } 766 ch <- true 767 }() 768 y := f(1) 769 <-ch 770 x := y 771 y = x 772 } 773 774 func TestRaceFuncVariableWW(t *testing.T) { 775 var f func(x int) int 776 ch := make(chan bool, 1) 777 go func() { 778 f = func(x int) int { 779 return x 780 } 781 ch <- true 782 }() 783 f = func(x int) int { 784 return x * x 785 } 786 <-ch 787 } 788 789 // This one should not belong to mop_test 790 func TestRacePanic(t *testing.T) { 791 var x int 792 var zero int = 0 793 ch := make(chan bool, 2) 794 go func() { 795 defer func() { 796 err := recover() 797 if err == nil { 798 panic("should be panicking") 799 } 800 x = 1 801 ch <- true 802 }() 803 var y int = 1 / zero 804 zero = y 805 }() 806 go func() { 807 defer func() { 808 err := recover() 809 if err == nil { 810 panic("should be panicking") 811 } 812 x = 2 813 ch <- true 814 }() 815 var y int = 1 / zero 816 zero = y 817 }() 818 819 <-ch 820 <-ch 821 if zero != 0 { 822 panic("zero has changed") 823 } 824 } 825 826 func TestNoRaceBlank(t *testing.T) { 827 var a [5]int 828 ch := make(chan bool, 1) 829 go func() { 830 _, _ = a[0], a[1] 831 ch <- true 832 }() 833 _, _ = a[2], a[3] 834 <-ch 835 a[1] = a[0] 836 } 837 838 func TestRaceAppendRW(t *testing.T) { 839 a := make([]int, 10) 840 ch := make(chan bool) 841 go func() { 842 _ = append(a, 1) 843 ch <- true 844 }() 845 a[0] = 1 846 <-ch 847 } 848 849 func TestRaceAppendLenRW(t *testing.T) { 850 a := make([]int, 0) 851 ch := make(chan bool) 852 go func() { 853 a = append(a, 1) 854 ch <- true 855 }() 856 _ = len(a) 857 <-ch 858 } 859 860 func TestRaceAppendCapRW(t *testing.T) { 861 a := make([]int, 0) 862 ch := make(chan string) 863 go func() { 864 a = append(a, 1) 865 ch <- "" 866 }() 867 _ = cap(a) 868 <-ch 869 } 870 871 func TestNoRaceFuncArgsRW(t *testing.T) { 872 ch := make(chan byte, 1) 873 var x byte 874 go func(y byte) { 875 _ = y 876 ch <- 0 877 }(x) 878 x = 1 879 <-ch 880 } 881 882 func TestRaceFuncArgsRW(t *testing.T) { 883 ch := make(chan byte, 1) 884 var x byte 885 go func(y *byte) { 886 _ = *y 887 ch <- 0 888 }(&x) 889 x = 1 890 <-ch 891 } 892 893 // from the mailing list, slightly modified 894 // unprotected concurrent access to seen[] 895 func TestRaceCrawl(t *testing.T) { 896 url := "dummyurl" 897 depth := 3 898 seen := make(map[string]bool) 899 ch := make(chan int, 100) 900 var wg sync.WaitGroup 901 var crawl func(string, int) 902 crawl = func(u string, d int) { 903 nurl := 0 904 defer func() { 905 ch <- nurl 906 }() 907 seen[u] = true 908 if d <= 0 { 909 return 910 } 911 urls := [...]string{"a", "b", "c"} 912 for _, uu := range urls { 913 if _, ok := seen[uu]; !ok { 914 wg.Add(1) 915 go crawl(uu, d-1) 916 nurl++ 917 } 918 } 919 wg.Done() 920 } 921 wg.Add(1) 922 go crawl(url, depth) 923 wg.Wait() 924 } 925 926 func TestRaceIndirection(t *testing.T) { 927 ch := make(chan struct{}, 1) 928 var y int 929 var x *int = &y 930 go func() { 931 *x = 1 932 ch <- struct{}{} 933 }() 934 *x = 2 935 <-ch 936 _ = *x 937 } 938 939 func TestRaceRune(t *testing.T) { 940 c := make(chan bool) 941 var x rune 942 go func() { 943 x = 1 944 c <- true 945 }() 946 _ = x 947 <-c 948 } 949 950 func TestRaceEmptyInterface1(t *testing.T) { 951 c := make(chan bool) 952 var x interface{} 953 go func() { 954 x = nil 955 c <- true 956 }() 957 _ = x 958 <-c 959 } 960 961 func TestRaceEmptyInterface2(t *testing.T) { 962 c := make(chan bool) 963 var x interface{} 964 go func() { 965 x = &Point{} 966 c <- true 967 }() 968 _ = x 969 <-c 970 } 971 972 func TestRaceTLS(t *testing.T) { 973 comm := make(chan *int) 974 done := make(chan bool, 2) 975 go func() { 976 var x int 977 comm <- &x 978 x = 1 979 x = *(<-comm) 980 done <- true 981 }() 982 go func() { 983 p := <-comm 984 *p = 2 985 comm <- p 986 done <- true 987 }() 988 <-done 989 <-done 990 } 991 992 func TestNoRaceHeapReallocation(t *testing.T) { 993 // It is possible that a future implementation 994 // of memory allocation will ruin this test. 995 // Increasing n might help in this case, so 996 // this test is a bit more generic than most of the 997 // others. 998 const n = 2 999 done := make(chan bool, n) 1000 empty := func(p *int) {} 1001 for i := 0; i < n; i++ { 1002 ms := i 1003 go func() { 1004 <-time.After(time.Duration(ms) * time.Millisecond) 1005 runtime.GC() 1006 var x int 1007 empty(&x) // x goes to the heap 1008 done <- true 1009 }() 1010 } 1011 for i := 0; i < n; i++ { 1012 <-done 1013 } 1014 } 1015 1016 func TestRaceAnd(t *testing.T) { 1017 c := make(chan bool) 1018 x, y := 0, 0 1019 go func() { 1020 x = 1 1021 c <- true 1022 }() 1023 if x == 1 && y == 1 { 1024 } 1025 <-c 1026 } 1027 1028 func TestRaceAnd2(t *testing.T) { 1029 c := make(chan bool) 1030 x, y := 0, 0 1031 go func() { 1032 x = 1 1033 c <- true 1034 }() 1035 if y == 0 && x == 1 { 1036 } 1037 <-c 1038 } 1039 1040 func TestNoRaceAnd(t *testing.T) { 1041 c := make(chan bool) 1042 x, y := 0, 0 1043 go func() { 1044 x = 1 1045 c <- true 1046 }() 1047 if y == 1 && x == 1 { 1048 } 1049 <-c 1050 } 1051 1052 func TestRaceOr(t *testing.T) { 1053 c := make(chan bool) 1054 x, y := 0, 0 1055 go func() { 1056 x = 1 1057 c <- true 1058 }() 1059 if x == 1 || y == 1 { 1060 } 1061 <-c 1062 } 1063 1064 func TestRaceOr2(t *testing.T) { 1065 c := make(chan bool) 1066 x, y := 0, 0 1067 go func() { 1068 x = 1 1069 c <- true 1070 }() 1071 if y == 1 || x == 1 { 1072 } 1073 <-c 1074 } 1075 1076 func TestNoRaceOr(t *testing.T) { 1077 c := make(chan bool) 1078 x, y := 0, 0 1079 go func() { 1080 x = 1 1081 c <- true 1082 }() 1083 if y == 0 || x == 1 { 1084 } 1085 <-c 1086 } 1087 1088 func TestNoRaceShortCalc(t *testing.T) { 1089 c := make(chan bool) 1090 x, y := 0, 0 1091 go func() { 1092 y = 1 1093 c <- true 1094 }() 1095 if x == 0 || y == 0 { 1096 } 1097 <-c 1098 } 1099 1100 func TestNoRaceShortCalc2(t *testing.T) { 1101 c := make(chan bool) 1102 x, y := 0, 0 1103 go func() { 1104 y = 1 1105 c <- true 1106 }() 1107 if x == 1 && y == 0 { 1108 } 1109 <-c 1110 } 1111 1112 func TestRaceFuncItself(t *testing.T) { 1113 c := make(chan bool) 1114 f := func() {} 1115 go func() { 1116 f() 1117 c <- true 1118 }() 1119 f = func() {} 1120 <-c 1121 } 1122 1123 func TestNoRaceFuncUnlock(t *testing.T) { 1124 ch := make(chan bool, 1) 1125 var mu sync.Mutex 1126 x := 0 1127 go func() { 1128 mu.Lock() 1129 x = 42 1130 mu.Unlock() 1131 ch <- true 1132 }() 1133 x = func(mu *sync.Mutex) int { 1134 mu.Lock() 1135 return 43 1136 }(&mu) 1137 mu.Unlock() 1138 <-ch 1139 } 1140 1141 func TestRaceStructInit(t *testing.T) { 1142 type X struct { 1143 x, y int 1144 } 1145 c := make(chan bool, 1) 1146 y := 0 1147 go func() { 1148 y = 42 1149 c <- true 1150 }() 1151 x := X{x: y} 1152 _ = x 1153 <-c 1154 } 1155 1156 func TestRaceArrayInit(t *testing.T) { 1157 c := make(chan bool, 1) 1158 y := 0 1159 go func() { 1160 y = 42 1161 c <- true 1162 }() 1163 x := []int{0, y, 42} 1164 _ = x 1165 <-c 1166 } 1167 1168 func TestRaceMapInit(t *testing.T) { 1169 c := make(chan bool, 1) 1170 y := 0 1171 go func() { 1172 y = 42 1173 c <- true 1174 }() 1175 x := map[int]int{0: 42, y: 42} 1176 _ = x 1177 <-c 1178 } 1179 1180 func TestRaceMapInit2(t *testing.T) { 1181 c := make(chan bool, 1) 1182 y := 0 1183 go func() { 1184 y = 42 1185 c <- true 1186 }() 1187 x := map[int]int{0: 42, 42: y} 1188 _ = x 1189 <-c 1190 } 1191 1192 type Inter interface { 1193 Foo(x int) 1194 } 1195 type InterImpl struct { 1196 x, y int 1197 } 1198 1199 func (p InterImpl) Foo(x int) { 1200 // prevent inlining 1201 z := 42 1202 x = 85 1203 y := x / z 1204 z = y * z 1205 x = z * y 1206 _, _, _ = x, y, z 1207 } 1208 1209 type InterImpl2 InterImpl 1210 1211 func (p *InterImpl2) Foo(x int) { 1212 if p == nil { 1213 InterImpl{}.Foo(x) 1214 } 1215 InterImpl(*p).Foo(x) 1216 } 1217 1218 func TestRaceInterCall(t *testing.T) { 1219 c := make(chan bool, 1) 1220 p := InterImpl{} 1221 var x Inter = p 1222 go func() { 1223 p2 := InterImpl{} 1224 x = p2 1225 c <- true 1226 }() 1227 x.Foo(0) 1228 <-c 1229 } 1230 1231 func TestRaceInterCall2(t *testing.T) { 1232 c := make(chan bool, 1) 1233 p := InterImpl{} 1234 var x Inter = p 1235 z := 0 1236 go func() { 1237 z = 42 1238 c <- true 1239 }() 1240 x.Foo(z) 1241 <-c 1242 } 1243 1244 func TestRaceFuncCall(t *testing.T) { 1245 c := make(chan bool, 1) 1246 f := func(x, y int) {} 1247 x, y := 0, 0 1248 go func() { 1249 y = 42 1250 c <- true 1251 }() 1252 f(x, y) 1253 <-c 1254 } 1255 1256 func TestRaceMethodCall(t *testing.T) { 1257 c := make(chan bool, 1) 1258 i := InterImpl{} 1259 x := 0 1260 go func() { 1261 x = 42 1262 c <- true 1263 }() 1264 i.Foo(x) 1265 <-c 1266 } 1267 1268 func TestRaceMethodCall2(t *testing.T) { 1269 c := make(chan bool, 1) 1270 i := &InterImpl{} 1271 go func() { 1272 i = &InterImpl{} 1273 c <- true 1274 }() 1275 i.Foo(0) 1276 <-c 1277 } 1278 1279 // Method value with concrete value receiver. 1280 func TestRaceMethodValue(t *testing.T) { 1281 c := make(chan bool, 1) 1282 i := InterImpl{} 1283 go func() { 1284 i = InterImpl{} 1285 c <- true 1286 }() 1287 _ = i.Foo 1288 <-c 1289 } 1290 1291 // Method value with interface receiver. 1292 func TestRaceMethodValue2(t *testing.T) { 1293 c := make(chan bool, 1) 1294 var i Inter = InterImpl{} 1295 go func() { 1296 i = InterImpl{} 1297 c <- true 1298 }() 1299 _ = i.Foo 1300 <-c 1301 } 1302 1303 // Method value with implicit dereference. 1304 func TestRaceMethodValue3(t *testing.T) { 1305 c := make(chan bool, 1) 1306 i := &InterImpl{} 1307 go func() { 1308 *i = InterImpl{} 1309 c <- true 1310 }() 1311 _ = i.Foo // dereferences i. 1312 <-c 1313 } 1314 1315 // Method value implicitly taking receiver address. 1316 func TestNoRaceMethodValue(t *testing.T) { 1317 c := make(chan bool, 1) 1318 i := InterImpl2{} 1319 go func() { 1320 i = InterImpl2{} 1321 c <- true 1322 }() 1323 _ = i.Foo // takes the address of i only. 1324 <-c 1325 } 1326 1327 func TestRacePanicArg(t *testing.T) { 1328 c := make(chan bool, 1) 1329 err := errors.New("err") 1330 go func() { 1331 err = errors.New("err2") 1332 c <- true 1333 }() 1334 defer func() { 1335 recover() 1336 <-c 1337 }() 1338 panic(err) 1339 } 1340 1341 func TestRaceDeferArg(t *testing.T) { 1342 c := make(chan bool, 1) 1343 x := 0 1344 go func() { 1345 x = 42 1346 c <- true 1347 }() 1348 func() { 1349 defer func(x int) { 1350 }(x) 1351 }() 1352 <-c 1353 } 1354 1355 type DeferT int 1356 1357 func (d DeferT) Foo() { 1358 } 1359 1360 func TestRaceDeferArg2(t *testing.T) { 1361 c := make(chan bool, 1) 1362 var x DeferT 1363 go func() { 1364 var y DeferT 1365 x = y 1366 c <- true 1367 }() 1368 func() { 1369 defer x.Foo() 1370 }() 1371 <-c 1372 } 1373 1374 func TestNoRaceAddrExpr(t *testing.T) { 1375 c := make(chan bool, 1) 1376 x := 0 1377 go func() { 1378 x = 42 1379 c <- true 1380 }() 1381 _ = &x 1382 <-c 1383 } 1384 1385 type AddrT struct { 1386 _ [256]byte 1387 x int 1388 } 1389 1390 type AddrT2 struct { 1391 _ [512]byte 1392 p *AddrT 1393 } 1394 1395 func TestRaceAddrExpr(t *testing.T) { 1396 c := make(chan bool, 1) 1397 a := AddrT2{p: &AddrT{x: 42}} 1398 go func() { 1399 a.p = &AddrT{x: 43} 1400 c <- true 1401 }() 1402 _ = &a.p.x 1403 <-c 1404 } 1405 1406 func TestRaceTypeAssert(t *testing.T) { 1407 c := make(chan bool, 1) 1408 x := 0 1409 var i interface{} = x 1410 go func() { 1411 y := 0 1412 i = y 1413 c <- true 1414 }() 1415 _ = i.(int) 1416 <-c 1417 } 1418 1419 func TestRaceBlockAs(t *testing.T) { 1420 c := make(chan bool, 1) 1421 var x, y int 1422 go func() { 1423 x = 42 1424 c <- true 1425 }() 1426 x, y = y, x 1427 <-c 1428 } 1429 1430 func TestRaceSliceSlice(t *testing.T) { 1431 c := make(chan bool, 1) 1432 x := make([]int, 10) 1433 go func() { 1434 x = make([]int, 20) 1435 c <- true 1436 }() 1437 _ = x[2:3] 1438 <-c 1439 } 1440 1441 func TestRaceSliceSlice2(t *testing.T) { 1442 c := make(chan bool, 1) 1443 x := make([]int, 10) 1444 i := 2 1445 go func() { 1446 i = 3 1447 c <- true 1448 }() 1449 _ = x[i:4] 1450 <-c 1451 } 1452 1453 func TestRaceSliceString(t *testing.T) { 1454 c := make(chan bool, 1) 1455 x := "hello" 1456 go func() { 1457 x = "world" 1458 c <- true 1459 }() 1460 _ = x[2:3] 1461 <-c 1462 } 1463 1464 // http://golang.org/issue/4453 1465 func TestRaceFailingSliceStruct(t *testing.T) { 1466 type X struct { 1467 x, y int 1468 } 1469 c := make(chan bool, 1) 1470 x := make([]X, 10) 1471 go func() { 1472 y := make([]X, 10) 1473 copy(y, x) 1474 c <- true 1475 }() 1476 x[1].y = 42 1477 <-c 1478 } 1479 1480 func TestRaceFailingAppendSliceStruct(t *testing.T) { 1481 type X struct { 1482 x, y int 1483 } 1484 c := make(chan bool, 1) 1485 x := make([]X, 10) 1486 go func() { 1487 y := make([]X, 0, 10) 1488 y = append(y, x...) 1489 c <- true 1490 }() 1491 x[1].y = 42 1492 <-c 1493 } 1494 1495 func TestRaceStructInd(t *testing.T) { 1496 c := make(chan bool, 1) 1497 type Item struct { 1498 x, y int 1499 } 1500 i := Item{} 1501 go func(p *Item) { 1502 *p = Item{} 1503 c <- true 1504 }(&i) 1505 i.y = 42 1506 <-c 1507 } 1508 1509 func TestRaceAsFunc1(t *testing.T) { 1510 var s []byte 1511 c := make(chan bool, 1) 1512 go func() { 1513 var err error 1514 s, err = func() ([]byte, error) { 1515 t := []byte("hello world") 1516 return t, nil 1517 }() 1518 c <- true 1519 _ = err 1520 }() 1521 _ = string(s) 1522 <-c 1523 } 1524 1525 func TestRaceAsFunc2(t *testing.T) { 1526 c := make(chan bool, 1) 1527 x := 0 1528 go func() { 1529 func(x int) { 1530 }(x) 1531 c <- true 1532 }() 1533 x = 42 1534 <-c 1535 } 1536 1537 func TestRaceAsFunc3(t *testing.T) { 1538 c := make(chan bool, 1) 1539 var mu sync.Mutex 1540 x := 0 1541 go func() { 1542 func(x int) { 1543 mu.Lock() 1544 }(x) // Read of x must be outside of the mutex. 1545 mu.Unlock() 1546 c <- true 1547 }() 1548 mu.Lock() 1549 x = 42 1550 mu.Unlock() 1551 <-c 1552 } 1553 1554 func TestNoRaceAsFunc4(t *testing.T) { 1555 c := make(chan bool, 1) 1556 var mu sync.Mutex 1557 x := 0 1558 go func() { 1559 x = func() int { // Write of x must be under the mutex. 1560 mu.Lock() 1561 return 42 1562 }() 1563 mu.Unlock() 1564 c <- true 1565 }() 1566 mu.Lock() 1567 x = 42 1568 mu.Unlock() 1569 <-c 1570 } 1571 1572 func TestRaceHeapParam(t *testing.T) { 1573 x := func() (x int) { 1574 go func() { 1575 x = 42 1576 }() 1577 return 1578 }() 1579 _ = x 1580 } 1581 1582 func TestNoRaceEmptyStruct(t *testing.T) { 1583 type Empty struct{} 1584 type X struct { 1585 y int64 1586 Empty 1587 } 1588 type Y struct { 1589 x X 1590 y int64 1591 } 1592 c := make(chan X) 1593 var y Y 1594 go func() { 1595 x := y.x 1596 c <- x 1597 }() 1598 y.y = 42 1599 <-c 1600 } 1601 1602 func TestRaceNestedStruct(t *testing.T) { 1603 type X struct { 1604 x, y int 1605 } 1606 type Y struct { 1607 x X 1608 } 1609 c := make(chan Y) 1610 var y Y 1611 go func() { 1612 c <- y 1613 }() 1614 y.x.y = 42 1615 <-c 1616 }