github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/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 "bytes" 9 "errors" 10 "fmt" 11 "hash/crc32" 12 "io" 13 "os" 14 "runtime" 15 "sync" 16 "testing" 17 "time" 18 "unsafe" 19 ) 20 21 type Point struct { 22 x, y int 23 } 24 25 type NamedPoint struct { 26 name string 27 p Point 28 } 29 30 type DummyWriter struct { 31 state int 32 } 33 type Writer interface { 34 Write(p []byte) (n int) 35 } 36 37 func (d DummyWriter) Write(p []byte) (n int) { 38 return 0 39 } 40 41 var GlobalX, GlobalY int = 0, 0 42 var GlobalCh chan int = make(chan int, 2) 43 44 func GlobalFunc1() { 45 GlobalY = GlobalX 46 GlobalCh <- 1 47 } 48 49 func GlobalFunc2() { 50 GlobalX = 1 51 GlobalCh <- 1 52 } 53 54 func TestRaceIntRWGlobalFuncs(t *testing.T) { 55 go GlobalFunc1() 56 go GlobalFunc2() 57 <-GlobalCh 58 <-GlobalCh 59 } 60 61 func TestRaceIntRWClosures(t *testing.T) { 62 var x, y int 63 _ = y 64 ch := make(chan int, 2) 65 66 go func() { 67 y = x 68 ch <- 1 69 }() 70 go func() { 71 x = 1 72 ch <- 1 73 }() 74 <-ch 75 <-ch 76 } 77 78 func TestNoRaceIntRWClosures(t *testing.T) { 79 var x, y int 80 _ = y 81 ch := make(chan int, 1) 82 83 go func() { 84 y = x 85 ch <- 1 86 }() 87 <-ch 88 go func() { 89 x = 1 90 ch <- 1 91 }() 92 <-ch 93 94 } 95 96 func TestRaceInt32RWClosures(t *testing.T) { 97 var x, y int32 98 _ = y 99 ch := make(chan bool, 2) 100 101 go func() { 102 y = x 103 ch <- true 104 }() 105 go func() { 106 x = 1 107 ch <- true 108 }() 109 <-ch 110 <-ch 111 } 112 113 func TestNoRaceCase(t *testing.T) { 114 var y int 115 for x := -1; x <= 1; x++ { 116 switch { 117 case x < 0: 118 y = -1 119 case x == 0: 120 y = 0 121 case x > 0: 122 y = 1 123 } 124 } 125 y++ 126 } 127 128 func TestRaceCaseCondition(t *testing.T) { 129 var x int = 0 130 ch := make(chan int, 2) 131 132 go func() { 133 x = 2 134 ch <- 1 135 }() 136 go func() { 137 switch x < 2 { 138 case true: 139 x = 1 140 //case false: 141 // x = 5 142 } 143 ch <- 1 144 }() 145 <-ch 146 <-ch 147 } 148 149 func TestRaceCaseCondition2(t *testing.T) { 150 // switch body is rearranged by the compiler so the tests 151 // passes even if we don't instrument '<' 152 var x int = 0 153 ch := make(chan int, 2) 154 155 go func() { 156 x = 2 157 ch <- 1 158 }() 159 go func() { 160 switch x < 2 { 161 case true: 162 x = 1 163 case false: 164 x = 5 165 } 166 ch <- 1 167 }() 168 <-ch 169 <-ch 170 } 171 172 func TestRaceCaseBody(t *testing.T) { 173 var x, y int 174 _ = y 175 ch := make(chan int, 2) 176 177 go func() { 178 y = x 179 ch <- 1 180 }() 181 go func() { 182 switch { 183 default: 184 x = 1 185 case x == 100: 186 x = -x 187 } 188 ch <- 1 189 }() 190 <-ch 191 <-ch 192 } 193 194 func TestNoRaceCaseFallthrough(t *testing.T) { 195 var x, y, z int 196 _ = y 197 ch := make(chan int, 2) 198 z = 1 199 200 go func() { 201 y = x 202 ch <- 1 203 }() 204 go func() { 205 switch { 206 case z == 1: 207 case z == 2: 208 x = 2 209 } 210 ch <- 1 211 }() 212 <-ch 213 <-ch 214 } 215 216 func TestRaceCaseFallthrough(t *testing.T) { 217 var x, y, z int 218 _ = y 219 ch := make(chan int, 2) 220 z = 1 221 222 go func() { 223 y = x 224 ch <- 1 225 }() 226 go func() { 227 switch { 228 case z == 1: 229 fallthrough 230 case z == 2: 231 x = 2 232 } 233 ch <- 1 234 }() 235 236 <-ch 237 <-ch 238 } 239 240 func TestRaceCaseIssue6418(t *testing.T) { 241 m := map[string]map[string]string{ 242 "a": { 243 "b": "c", 244 }, 245 } 246 ch := make(chan int) 247 go func() { 248 m["a"]["x"] = "y" 249 ch <- 1 250 }() 251 switch m["a"]["b"] { 252 } 253 <-ch 254 } 255 256 func TestRaceCaseType(t *testing.T) { 257 var x, y int 258 var i any = x 259 c := make(chan int, 1) 260 go func() { 261 switch i.(type) { 262 case nil: 263 case int: 264 } 265 c <- 1 266 }() 267 i = y 268 <-c 269 } 270 271 func TestRaceCaseTypeBody(t *testing.T) { 272 var x, y int 273 var i any = &x 274 c := make(chan int, 1) 275 go func() { 276 switch i := i.(type) { 277 case nil: 278 case *int: 279 *i = y 280 } 281 c <- 1 282 }() 283 x = y 284 <-c 285 } 286 287 func TestRaceCaseTypeIssue5890(t *testing.T) { 288 // spurious extra instrumentation of the initial interface 289 // value. 290 var x, y int 291 m := make(map[int]map[int]any) 292 m[0] = make(map[int]any) 293 c := make(chan int, 1) 294 go func() { 295 switch i := m[0][1].(type) { 296 case nil: 297 case *int: 298 *i = x 299 } 300 c <- 1 301 }() 302 m[0][1] = y 303 <-c 304 } 305 306 func TestNoRaceRange(t *testing.T) { 307 ch := make(chan int, 3) 308 a := [...]int{1, 2, 3} 309 for _, v := range a { 310 ch <- v 311 } 312 close(ch) 313 } 314 315 func TestNoRaceRangeIssue5446(t *testing.T) { 316 ch := make(chan int, 3) 317 a := []int{1, 2, 3} 318 b := []int{4} 319 // used to insert a spurious instrumentation of a[i] 320 // and crash. 321 i := 1 322 for i, a[i] = range b { 323 ch <- i 324 } 325 close(ch) 326 } 327 328 func TestRaceRange(t *testing.T) { 329 const N = 2 330 var a [N]int 331 var x, y int 332 _ = x + y 333 done := make(chan bool, N) 334 var i, v int // declare here (not in for stmt) so that i and v are shared w/ or w/o loop variable sharing change 335 for i, v = range a { 336 go func(i int) { 337 // we don't want a write-vs-write race 338 // so there is no array b here 339 if i == 0 { 340 x = v 341 } else { 342 y = v 343 } 344 done <- true 345 }(i) 346 // Ensure the goroutine runs before we continue the loop. 347 runtime.Gosched() 348 } 349 for i := 0; i < N; i++ { 350 <-done 351 } 352 } 353 354 func TestRaceForInit(t *testing.T) { 355 c := make(chan int) 356 x := 0 357 go func() { 358 c <- x 359 }() 360 for x = 42; false; { 361 } 362 <-c 363 } 364 365 func TestNoRaceForInit(t *testing.T) { 366 done := make(chan bool) 367 c := make(chan bool) 368 x := 0 369 go func() { 370 for { 371 _, ok := <-c 372 if !ok { 373 done <- true 374 return 375 } 376 x++ 377 } 378 }() 379 i := 0 380 for x = 42; i < 10; i++ { 381 c <- true 382 } 383 close(c) 384 <-done 385 } 386 387 func TestRaceForTest(t *testing.T) { 388 done := make(chan bool) 389 c := make(chan bool) 390 stop := false 391 go func() { 392 for { 393 _, ok := <-c 394 if !ok { 395 done <- true 396 return 397 } 398 stop = true 399 } 400 }() 401 for !stop { 402 c <- true 403 } 404 close(c) 405 <-done 406 } 407 408 func TestRaceForIncr(t *testing.T) { 409 done := make(chan bool) 410 c := make(chan bool) 411 x := 0 412 go func() { 413 for { 414 _, ok := <-c 415 if !ok { 416 done <- true 417 return 418 } 419 x++ 420 } 421 }() 422 for i := 0; i < 10; x++ { 423 i++ 424 c <- true 425 } 426 close(c) 427 <-done 428 } 429 430 func TestNoRaceForIncr(t *testing.T) { 431 done := make(chan bool) 432 x := 0 433 go func() { 434 x++ 435 done <- true 436 }() 437 for i := 0; i < 0; x++ { 438 } 439 <-done 440 } 441 442 func TestRacePlus(t *testing.T) { 443 var x, y, z int 444 _ = y 445 ch := make(chan int, 2) 446 447 go func() { 448 y = x + z 449 ch <- 1 450 }() 451 go func() { 452 y = x + z + z 453 ch <- 1 454 }() 455 <-ch 456 <-ch 457 } 458 459 func TestRacePlus2(t *testing.T) { 460 var x, y, z int 461 _ = y 462 ch := make(chan int, 2) 463 464 go func() { 465 x = 1 466 ch <- 1 467 }() 468 go func() { 469 y = +x + z 470 ch <- 1 471 }() 472 <-ch 473 <-ch 474 } 475 476 func TestNoRacePlus(t *testing.T) { 477 var x, y, z, f int 478 _ = x + y + f 479 ch := make(chan int, 2) 480 481 go func() { 482 y = x + z 483 ch <- 1 484 }() 485 go func() { 486 f = z + x 487 ch <- 1 488 }() 489 <-ch 490 <-ch 491 } 492 493 func TestRaceComplement(t *testing.T) { 494 var x, y, z int 495 _ = x 496 ch := make(chan int, 2) 497 498 go func() { 499 x = ^y 500 ch <- 1 501 }() 502 go func() { 503 y = ^z 504 ch <- 1 505 }() 506 <-ch 507 <-ch 508 } 509 510 func TestRaceDiv(t *testing.T) { 511 var x, y, z int 512 _ = x 513 ch := make(chan int, 2) 514 515 go func() { 516 x = y / (z + 1) 517 ch <- 1 518 }() 519 go func() { 520 y = z 521 ch <- 1 522 }() 523 <-ch 524 <-ch 525 } 526 527 func TestRaceDivConst(t *testing.T) { 528 var x, y, z uint32 529 _ = x 530 ch := make(chan int, 2) 531 532 go func() { 533 x = y / 3 // involves only a HMUL node 534 ch <- 1 535 }() 536 go func() { 537 y = z 538 ch <- 1 539 }() 540 <-ch 541 <-ch 542 } 543 544 func TestRaceMod(t *testing.T) { 545 var x, y, z int 546 _ = x 547 ch := make(chan int, 2) 548 549 go func() { 550 x = y % (z + 1) 551 ch <- 1 552 }() 553 go func() { 554 y = z 555 ch <- 1 556 }() 557 <-ch 558 <-ch 559 } 560 561 func TestRaceModConst(t *testing.T) { 562 var x, y, z int 563 _ = x 564 ch := make(chan int, 2) 565 566 go func() { 567 x = y % 3 568 ch <- 1 569 }() 570 go func() { 571 y = z 572 ch <- 1 573 }() 574 <-ch 575 <-ch 576 } 577 578 func TestRaceRotate(t *testing.T) { 579 var x, y, z uint32 580 _ = x 581 ch := make(chan int, 2) 582 583 go func() { 584 x = y<<12 | y>>20 585 ch <- 1 586 }() 587 go func() { 588 y = z 589 ch <- 1 590 }() 591 <-ch 592 <-ch 593 } 594 595 // May crash if the instrumentation is reckless. 596 func TestNoRaceEnoughRegisters(t *testing.T) { 597 // from erf.go 598 const ( 599 sa1 = 1 600 sa2 = 2 601 sa3 = 3 602 sa4 = 4 603 sa5 = 5 604 sa6 = 6 605 sa7 = 7 606 sa8 = 8 607 ) 608 var s, S float64 609 s = 3.1415 610 S = 1 + s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(sa5+s*(sa6+s*(sa7+s*sa8))))))) 611 s = S 612 } 613 614 // emptyFunc should not be inlined. 615 func emptyFunc(x int) { 616 if false { 617 fmt.Println(x) 618 } 619 } 620 621 func TestRaceFuncArgument(t *testing.T) { 622 var x int 623 ch := make(chan bool, 1) 624 go func() { 625 emptyFunc(x) 626 ch <- true 627 }() 628 x = 1 629 <-ch 630 } 631 632 func TestRaceFuncArgument2(t *testing.T) { 633 var x int 634 ch := make(chan bool, 2) 635 go func() { 636 x = 42 637 ch <- true 638 }() 639 go func(y int) { 640 ch <- true 641 }(x) 642 <-ch 643 <-ch 644 } 645 646 func TestRaceSprint(t *testing.T) { 647 var x int 648 ch := make(chan bool, 1) 649 go func() { 650 fmt.Sprint(x) 651 ch <- true 652 }() 653 x = 1 654 <-ch 655 } 656 657 func TestRaceArrayCopy(t *testing.T) { 658 ch := make(chan bool, 1) 659 var a [5]int 660 go func() { 661 a[3] = 1 662 ch <- true 663 }() 664 a = [5]int{1, 2, 3, 4, 5} 665 <-ch 666 } 667 668 // Blows up a naive compiler. 669 func TestRaceNestedArrayCopy(t *testing.T) { 670 ch := make(chan bool, 1) 671 type ( 672 Point32 [2][2][2][2][2]Point 673 Point1024 [2][2][2][2][2]Point32 674 Point32k [2][2][2][2][2]Point1024 675 Point1M [2][2][2][2][2]Point32k 676 ) 677 var a, b Point1M 678 go func() { 679 a[0][1][0][1][0][1][0][1][0][1][0][1][0][1][0][1][0][1][0][1].y = 1 680 ch <- true 681 }() 682 a = b 683 <-ch 684 } 685 686 func TestRaceStructRW(t *testing.T) { 687 p := Point{0, 0} 688 ch := make(chan bool, 1) 689 go func() { 690 p = Point{1, 1} 691 ch <- true 692 }() 693 q := p 694 <-ch 695 p = q 696 } 697 698 func TestRaceStructFieldRW1(t *testing.T) { 699 p := Point{0, 0} 700 ch := make(chan bool, 1) 701 go func() { 702 p.x = 1 703 ch <- true 704 }() 705 _ = p.x 706 <-ch 707 } 708 709 func TestNoRaceStructFieldRW1(t *testing.T) { 710 // Same struct, different variables, no 711 // pointers. The layout is known (at compile time?) -> 712 // no read on p 713 // writes on x and y 714 p := Point{0, 0} 715 ch := make(chan bool, 1) 716 go func() { 717 p.x = 1 718 ch <- true 719 }() 720 p.y = 1 721 <-ch 722 _ = p 723 } 724 725 func TestNoRaceStructFieldRW2(t *testing.T) { 726 // Same as NoRaceStructFieldRW1 727 // but p is a pointer, so there is a read on p 728 p := Point{0, 0} 729 ch := make(chan bool, 1) 730 go func() { 731 p.x = 1 732 ch <- true 733 }() 734 p.y = 1 735 <-ch 736 _ = p 737 } 738 739 func TestRaceStructFieldRW2(t *testing.T) { 740 p := &Point{0, 0} 741 ch := make(chan bool, 1) 742 go func() { 743 p.x = 1 744 ch <- true 745 }() 746 _ = p.x 747 <-ch 748 } 749 750 func TestRaceStructFieldRW3(t *testing.T) { 751 p := NamedPoint{name: "a", p: Point{0, 0}} 752 ch := make(chan bool, 1) 753 go func() { 754 p.p.x = 1 755 ch <- true 756 }() 757 _ = p.p.x 758 <-ch 759 } 760 761 func TestRaceEfaceWW(t *testing.T) { 762 var a, b any 763 ch := make(chan bool, 1) 764 go func() { 765 a = 1 766 ch <- true 767 }() 768 a = 2 769 <-ch 770 _, _ = a, b 771 } 772 773 func TestRaceIfaceWW(t *testing.T) { 774 var a, b Writer 775 ch := make(chan bool, 1) 776 go func() { 777 a = DummyWriter{1} 778 ch <- true 779 }() 780 a = DummyWriter{2} 781 <-ch 782 b = a 783 a = b 784 } 785 786 func TestRaceIfaceCmp(t *testing.T) { 787 var a, b Writer 788 a = DummyWriter{1} 789 ch := make(chan bool, 1) 790 go func() { 791 a = DummyWriter{1} 792 ch <- true 793 }() 794 _ = a == b 795 <-ch 796 } 797 798 func TestRaceIfaceCmpNil(t *testing.T) { 799 var a Writer 800 a = DummyWriter{1} 801 ch := make(chan bool, 1) 802 go func() { 803 a = DummyWriter{1} 804 ch <- true 805 }() 806 _ = a == nil 807 <-ch 808 } 809 810 func TestRaceEfaceConv(t *testing.T) { 811 c := make(chan bool) 812 v := 0 813 go func() { 814 go func(x any) { 815 }(v) 816 c <- true 817 }() 818 v = 42 819 <-c 820 } 821 822 type OsFile struct{} 823 824 func (*OsFile) Read() { 825 } 826 827 type IoReader interface { 828 Read() 829 } 830 831 func TestRaceIfaceConv(t *testing.T) { 832 c := make(chan bool) 833 f := &OsFile{} 834 go func() { 835 go func(x IoReader) { 836 }(f) 837 c <- true 838 }() 839 f = &OsFile{} 840 <-c 841 } 842 843 func TestRaceError(t *testing.T) { 844 ch := make(chan bool, 1) 845 var err error 846 go func() { 847 err = nil 848 ch <- true 849 }() 850 _ = err 851 <-ch 852 } 853 854 func TestRaceIntptrRW(t *testing.T) { 855 var x, y int 856 var p *int = &x 857 ch := make(chan bool, 1) 858 go func() { 859 *p = 5 860 ch <- true 861 }() 862 y = *p 863 x = y 864 <-ch 865 } 866 867 func TestRaceStringRW(t *testing.T) { 868 ch := make(chan bool, 1) 869 s := "" 870 go func() { 871 s = "abacaba" 872 ch <- true 873 }() 874 _ = s 875 <-ch 876 } 877 878 func TestRaceStringPtrRW(t *testing.T) { 879 ch := make(chan bool, 1) 880 var x string 881 p := &x 882 go func() { 883 *p = "a" 884 ch <- true 885 }() 886 _ = *p 887 <-ch 888 } 889 890 func TestRaceFloat64WW(t *testing.T) { 891 var x, y float64 892 ch := make(chan bool, 1) 893 go func() { 894 x = 1.0 895 ch <- true 896 }() 897 x = 2.0 898 <-ch 899 900 y = x 901 x = y 902 } 903 904 func TestRaceComplex128WW(t *testing.T) { 905 var x, y complex128 906 ch := make(chan bool, 1) 907 go func() { 908 x = 2 + 2i 909 ch <- true 910 }() 911 x = 4 + 4i 912 <-ch 913 914 y = x 915 x = y 916 } 917 918 func TestRaceUnsafePtrRW(t *testing.T) { 919 var x, y, z int 920 x, y, z = 1, 2, 3 921 var p unsafe.Pointer = unsafe.Pointer(&x) 922 ch := make(chan bool, 1) 923 go func() { 924 p = (unsafe.Pointer)(&z) 925 ch <- true 926 }() 927 y = *(*int)(p) 928 x = y 929 <-ch 930 } 931 932 func TestRaceFuncVariableRW(t *testing.T) { 933 var f func(x int) int 934 f = func(x int) int { 935 return x * x 936 } 937 ch := make(chan bool, 1) 938 go func() { 939 f = func(x int) int { 940 return x 941 } 942 ch <- true 943 }() 944 y := f(1) 945 <-ch 946 x := y 947 y = x 948 } 949 950 func TestRaceFuncVariableWW(t *testing.T) { 951 var f func(x int) int 952 _ = f 953 ch := make(chan bool, 1) 954 go func() { 955 f = func(x int) int { 956 return x 957 } 958 ch <- true 959 }() 960 f = func(x int) int { 961 return x * x 962 } 963 <-ch 964 } 965 966 // This one should not belong to mop_test 967 func TestRacePanic(t *testing.T) { 968 var x int 969 _ = x 970 var zero int = 0 971 ch := make(chan bool, 2) 972 go func() { 973 defer func() { 974 err := recover() 975 if err == nil { 976 panic("should be panicking") 977 } 978 x = 1 979 ch <- true 980 }() 981 var y int = 1 / zero 982 zero = y 983 }() 984 go func() { 985 defer func() { 986 err := recover() 987 if err == nil { 988 panic("should be panicking") 989 } 990 x = 2 991 ch <- true 992 }() 993 var y int = 1 / zero 994 zero = y 995 }() 996 997 <-ch 998 <-ch 999 if zero != 0 { 1000 panic("zero has changed") 1001 } 1002 } 1003 1004 func TestNoRaceBlank(t *testing.T) { 1005 var a [5]int 1006 ch := make(chan bool, 1) 1007 go func() { 1008 _, _ = a[0], a[1] 1009 ch <- true 1010 }() 1011 _, _ = a[2], a[3] 1012 <-ch 1013 a[1] = a[0] 1014 } 1015 1016 func TestRaceAppendRW(t *testing.T) { 1017 a := make([]int, 10) 1018 ch := make(chan bool) 1019 go func() { 1020 _ = append(a, 1) 1021 ch <- true 1022 }() 1023 a[0] = 1 1024 <-ch 1025 } 1026 1027 func TestRaceAppendLenRW(t *testing.T) { 1028 a := make([]int, 0) 1029 ch := make(chan bool) 1030 go func() { 1031 a = append(a, 1) 1032 ch <- true 1033 }() 1034 _ = len(a) 1035 <-ch 1036 } 1037 1038 func TestRaceAppendCapRW(t *testing.T) { 1039 a := make([]int, 0) 1040 ch := make(chan string) 1041 go func() { 1042 a = append(a, 1) 1043 ch <- "" 1044 }() 1045 _ = cap(a) 1046 <-ch 1047 } 1048 1049 func TestNoRaceFuncArgsRW(t *testing.T) { 1050 ch := make(chan byte, 1) 1051 var x byte 1052 go func(y byte) { 1053 _ = y 1054 ch <- 0 1055 }(x) 1056 x = 1 1057 <-ch 1058 } 1059 1060 func TestRaceFuncArgsRW(t *testing.T) { 1061 ch := make(chan byte, 1) 1062 var x byte 1063 go func(y *byte) { 1064 _ = *y 1065 ch <- 0 1066 }(&x) 1067 x = 1 1068 <-ch 1069 } 1070 1071 // from the mailing list, slightly modified 1072 // unprotected concurrent access to seen[] 1073 func TestRaceCrawl(t *testing.T) { 1074 url := "dummyurl" 1075 depth := 3 1076 seen := make(map[string]bool) 1077 ch := make(chan int, 100) 1078 var wg sync.WaitGroup 1079 var crawl func(string, int) 1080 crawl = func(u string, d int) { 1081 nurl := 0 1082 defer func() { 1083 ch <- nurl 1084 }() 1085 seen[u] = true 1086 if d <= 0 { 1087 wg.Done() 1088 return 1089 } 1090 urls := [...]string{"a", "b", "c"} 1091 for _, uu := range urls { 1092 if _, ok := seen[uu]; !ok { 1093 wg.Add(1) 1094 go crawl(uu, d-1) 1095 nurl++ 1096 } 1097 } 1098 wg.Done() 1099 } 1100 wg.Add(1) 1101 go crawl(url, depth) 1102 wg.Wait() 1103 } 1104 1105 func TestRaceIndirection(t *testing.T) { 1106 ch := make(chan struct{}, 1) 1107 var y int 1108 var x *int = &y 1109 go func() { 1110 *x = 1 1111 ch <- struct{}{} 1112 }() 1113 *x = 2 1114 <-ch 1115 _ = *x 1116 } 1117 1118 func TestRaceRune(t *testing.T) { 1119 c := make(chan bool) 1120 var x rune 1121 go func() { 1122 x = 1 1123 c <- true 1124 }() 1125 _ = x 1126 <-c 1127 } 1128 1129 func TestRaceEmptyInterface1(t *testing.T) { 1130 c := make(chan bool) 1131 var x any 1132 go func() { 1133 x = nil 1134 c <- true 1135 }() 1136 _ = x 1137 <-c 1138 } 1139 1140 func TestRaceEmptyInterface2(t *testing.T) { 1141 c := make(chan bool) 1142 var x any 1143 go func() { 1144 x = &Point{} 1145 c <- true 1146 }() 1147 _ = x 1148 <-c 1149 } 1150 1151 func TestRaceTLS(t *testing.T) { 1152 comm := make(chan *int) 1153 done := make(chan bool, 2) 1154 go func() { 1155 var x int 1156 comm <- &x 1157 x = 1 1158 x = *(<-comm) 1159 done <- true 1160 }() 1161 go func() { 1162 p := <-comm 1163 *p = 2 1164 comm <- p 1165 done <- true 1166 }() 1167 <-done 1168 <-done 1169 } 1170 1171 func TestNoRaceHeapReallocation(t *testing.T) { 1172 // It is possible that a future implementation 1173 // of memory allocation will ruin this test. 1174 // Increasing n might help in this case, so 1175 // this test is a bit more generic than most of the 1176 // others. 1177 const n = 2 1178 done := make(chan bool, n) 1179 empty := func(p *int) {} 1180 for i := 0; i < n; i++ { 1181 ms := i 1182 go func() { 1183 <-time.After(time.Duration(ms) * time.Millisecond) 1184 runtime.GC() 1185 var x int 1186 empty(&x) // x goes to the heap 1187 done <- true 1188 }() 1189 } 1190 for i := 0; i < n; i++ { 1191 <-done 1192 } 1193 } 1194 1195 func TestRaceAnd(t *testing.T) { 1196 c := make(chan bool) 1197 x, y := 0, 0 1198 go func() { 1199 x = 1 1200 c <- true 1201 }() 1202 if x == 1 && y == 1 { 1203 } 1204 <-c 1205 } 1206 1207 func TestRaceAnd2(t *testing.T) { 1208 c := make(chan bool) 1209 x, y := 0, 0 1210 go func() { 1211 x = 1 1212 c <- true 1213 }() 1214 if y == 0 && x == 1 { 1215 } 1216 <-c 1217 } 1218 1219 func TestNoRaceAnd(t *testing.T) { 1220 c := make(chan bool) 1221 x, y := 0, 0 1222 go func() { 1223 x = 1 1224 c <- true 1225 }() 1226 if y == 1 && x == 1 { 1227 } 1228 <-c 1229 } 1230 1231 func TestRaceOr(t *testing.T) { 1232 c := make(chan bool) 1233 x, y := 0, 0 1234 go func() { 1235 x = 1 1236 c <- true 1237 }() 1238 if x == 1 || y == 1 { 1239 } 1240 <-c 1241 } 1242 1243 func TestRaceOr2(t *testing.T) { 1244 c := make(chan bool) 1245 x, y := 0, 0 1246 go func() { 1247 x = 1 1248 c <- true 1249 }() 1250 if y == 1 || x == 1 { 1251 } 1252 <-c 1253 } 1254 1255 func TestNoRaceOr(t *testing.T) { 1256 c := make(chan bool) 1257 x, y := 0, 0 1258 go func() { 1259 x = 1 1260 c <- true 1261 }() 1262 if y == 0 || x == 1 { 1263 } 1264 <-c 1265 } 1266 1267 func TestNoRaceShortCalc(t *testing.T) { 1268 c := make(chan bool) 1269 x, y := 0, 0 1270 go func() { 1271 y = 1 1272 c <- true 1273 }() 1274 if x == 0 || y == 0 { 1275 } 1276 <-c 1277 } 1278 1279 func TestNoRaceShortCalc2(t *testing.T) { 1280 c := make(chan bool) 1281 x, y := 0, 0 1282 go func() { 1283 y = 1 1284 c <- true 1285 }() 1286 if x == 1 && y == 0 { 1287 } 1288 <-c 1289 } 1290 1291 func TestRaceFuncItself(t *testing.T) { 1292 c := make(chan bool) 1293 f := func() {} 1294 go func() { 1295 f() 1296 c <- true 1297 }() 1298 f = func() {} 1299 <-c 1300 } 1301 1302 func TestNoRaceFuncUnlock(t *testing.T) { 1303 ch := make(chan bool, 1) 1304 var mu sync.Mutex 1305 x := 0 1306 _ = x 1307 go func() { 1308 mu.Lock() 1309 x = 42 1310 mu.Unlock() 1311 ch <- true 1312 }() 1313 x = func(mu *sync.Mutex) int { 1314 mu.Lock() 1315 return 43 1316 }(&mu) 1317 mu.Unlock() 1318 <-ch 1319 } 1320 1321 func TestRaceStructInit(t *testing.T) { 1322 type X struct { 1323 x, y int 1324 } 1325 c := make(chan bool, 1) 1326 y := 0 1327 go func() { 1328 y = 42 1329 c <- true 1330 }() 1331 x := X{x: y} 1332 _ = x 1333 <-c 1334 } 1335 1336 func TestRaceArrayInit(t *testing.T) { 1337 c := make(chan bool, 1) 1338 y := 0 1339 go func() { 1340 y = 42 1341 c <- true 1342 }() 1343 x := []int{0, y, 42} 1344 _ = x 1345 <-c 1346 } 1347 1348 func TestRaceMapInit(t *testing.T) { 1349 c := make(chan bool, 1) 1350 y := 0 1351 go func() { 1352 y = 42 1353 c <- true 1354 }() 1355 x := map[int]int{0: 42, y: 42} 1356 _ = x 1357 <-c 1358 } 1359 1360 func TestRaceMapInit2(t *testing.T) { 1361 c := make(chan bool, 1) 1362 y := 0 1363 go func() { 1364 y = 42 1365 c <- true 1366 }() 1367 x := map[int]int{0: 42, 42: y} 1368 _ = x 1369 <-c 1370 } 1371 1372 type Inter interface { 1373 Foo(x int) 1374 } 1375 type InterImpl struct { 1376 x, y int 1377 } 1378 1379 //go:noinline 1380 func (p InterImpl) Foo(x int) { 1381 } 1382 1383 type InterImpl2 InterImpl 1384 1385 func (p *InterImpl2) Foo(x int) { 1386 if p == nil { 1387 InterImpl{}.Foo(x) 1388 } 1389 InterImpl(*p).Foo(x) 1390 } 1391 1392 func TestRaceInterCall(t *testing.T) { 1393 c := make(chan bool, 1) 1394 p := InterImpl{} 1395 var x Inter = p 1396 go func() { 1397 p2 := InterImpl{} 1398 x = p2 1399 c <- true 1400 }() 1401 x.Foo(0) 1402 <-c 1403 } 1404 1405 func TestRaceInterCall2(t *testing.T) { 1406 c := make(chan bool, 1) 1407 p := InterImpl{} 1408 var x Inter = p 1409 z := 0 1410 go func() { 1411 z = 42 1412 c <- true 1413 }() 1414 x.Foo(z) 1415 <-c 1416 } 1417 1418 func TestRaceFuncCall(t *testing.T) { 1419 c := make(chan bool, 1) 1420 f := func(x, y int) {} 1421 x, y := 0, 0 1422 go func() { 1423 y = 42 1424 c <- true 1425 }() 1426 f(x, y) 1427 <-c 1428 } 1429 1430 func TestRaceMethodCall(t *testing.T) { 1431 c := make(chan bool, 1) 1432 i := InterImpl{} 1433 x := 0 1434 go func() { 1435 x = 42 1436 c <- true 1437 }() 1438 i.Foo(x) 1439 <-c 1440 } 1441 1442 func TestRaceMethodCall2(t *testing.T) { 1443 c := make(chan bool, 1) 1444 i := &InterImpl{} 1445 go func() { 1446 i = &InterImpl{} 1447 c <- true 1448 }() 1449 i.Foo(0) 1450 <-c 1451 } 1452 1453 // Method value with concrete value receiver. 1454 func TestRaceMethodValue(t *testing.T) { 1455 c := make(chan bool, 1) 1456 i := InterImpl{} 1457 go func() { 1458 i = InterImpl{} 1459 c <- true 1460 }() 1461 _ = i.Foo 1462 <-c 1463 } 1464 1465 // Method value with interface receiver. 1466 func TestRaceMethodValue2(t *testing.T) { 1467 c := make(chan bool, 1) 1468 var i Inter = InterImpl{} 1469 go func() { 1470 i = InterImpl{} 1471 c <- true 1472 }() 1473 _ = i.Foo 1474 <-c 1475 } 1476 1477 // Method value with implicit dereference. 1478 func TestRaceMethodValue3(t *testing.T) { 1479 c := make(chan bool, 1) 1480 i := &InterImpl{} 1481 go func() { 1482 *i = InterImpl{} 1483 c <- true 1484 }() 1485 _ = i.Foo // dereferences i. 1486 <-c 1487 } 1488 1489 // Method value implicitly taking receiver address. 1490 func TestNoRaceMethodValue(t *testing.T) { 1491 c := make(chan bool, 1) 1492 i := InterImpl2{} 1493 go func() { 1494 i = InterImpl2{} 1495 c <- true 1496 }() 1497 _ = i.Foo // takes the address of i only. 1498 <-c 1499 } 1500 1501 func TestRacePanicArg(t *testing.T) { 1502 c := make(chan bool, 1) 1503 err := errors.New("err") 1504 go func() { 1505 err = errors.New("err2") 1506 c <- true 1507 }() 1508 defer func() { 1509 recover() 1510 <-c 1511 }() 1512 panic(err) 1513 } 1514 1515 func TestRaceDeferArg(t *testing.T) { 1516 c := make(chan bool, 1) 1517 x := 0 1518 go func() { 1519 x = 42 1520 c <- true 1521 }() 1522 func() { 1523 defer func(x int) { 1524 }(x) 1525 }() 1526 <-c 1527 } 1528 1529 type DeferT int 1530 1531 func (d DeferT) Foo() { 1532 } 1533 1534 func TestRaceDeferArg2(t *testing.T) { 1535 c := make(chan bool, 1) 1536 var x DeferT 1537 go func() { 1538 var y DeferT 1539 x = y 1540 c <- true 1541 }() 1542 func() { 1543 defer x.Foo() 1544 }() 1545 <-c 1546 } 1547 1548 func TestNoRaceAddrExpr(t *testing.T) { 1549 c := make(chan bool, 1) 1550 x := 0 1551 go func() { 1552 x = 42 1553 c <- true 1554 }() 1555 _ = &x 1556 <-c 1557 } 1558 1559 type AddrT struct { 1560 _ [256]byte 1561 x int 1562 } 1563 1564 type AddrT2 struct { 1565 _ [512]byte 1566 p *AddrT 1567 } 1568 1569 func TestRaceAddrExpr(t *testing.T) { 1570 c := make(chan bool, 1) 1571 a := AddrT2{p: &AddrT{x: 42}} 1572 go func() { 1573 a.p = &AddrT{x: 43} 1574 c <- true 1575 }() 1576 _ = &a.p.x 1577 <-c 1578 } 1579 1580 func TestRaceTypeAssert(t *testing.T) { 1581 c := make(chan bool, 1) 1582 x := 0 1583 var i any = x 1584 go func() { 1585 y := 0 1586 i = y 1587 c <- true 1588 }() 1589 _ = i.(int) 1590 <-c 1591 } 1592 1593 func TestRaceBlockAs(t *testing.T) { 1594 c := make(chan bool, 1) 1595 var x, y int 1596 go func() { 1597 x = 42 1598 c <- true 1599 }() 1600 x, y = y, x 1601 <-c 1602 } 1603 1604 func TestRaceBlockCall1(t *testing.T) { 1605 done := make(chan bool) 1606 x, y := 0, 0 1607 go func() { 1608 f := func() (int, int) { 1609 return 42, 43 1610 } 1611 x, y = f() 1612 done <- true 1613 }() 1614 _ = x 1615 <-done 1616 if x != 42 || y != 43 { 1617 panic("corrupted data") 1618 } 1619 } 1620 func TestRaceBlockCall2(t *testing.T) { 1621 done := make(chan bool) 1622 x, y := 0, 0 1623 go func() { 1624 f := func() (int, int) { 1625 return 42, 43 1626 } 1627 x, y = f() 1628 done <- true 1629 }() 1630 _ = y 1631 <-done 1632 if x != 42 || y != 43 { 1633 panic("corrupted data") 1634 } 1635 } 1636 func TestRaceBlockCall3(t *testing.T) { 1637 done := make(chan bool) 1638 var x *int 1639 y := 0 1640 go func() { 1641 f := func() (*int, int) { 1642 i := 42 1643 return &i, 43 1644 } 1645 x, y = f() 1646 done <- true 1647 }() 1648 _ = x 1649 <-done 1650 if *x != 42 || y != 43 { 1651 panic("corrupted data") 1652 } 1653 } 1654 func TestRaceBlockCall4(t *testing.T) { 1655 done := make(chan bool) 1656 x := 0 1657 var y *int 1658 go func() { 1659 f := func() (int, *int) { 1660 i := 43 1661 return 42, &i 1662 } 1663 x, y = f() 1664 done <- true 1665 }() 1666 _ = y 1667 <-done 1668 if x != 42 || *y != 43 { 1669 panic("corrupted data") 1670 } 1671 } 1672 func TestRaceBlockCall5(t *testing.T) { 1673 done := make(chan bool) 1674 var x *int 1675 y := 0 1676 go func() { 1677 f := func() (*int, int) { 1678 i := 42 1679 return &i, 43 1680 } 1681 x, y = f() 1682 done <- true 1683 }() 1684 _ = y 1685 <-done 1686 if *x != 42 || y != 43 { 1687 panic("corrupted data") 1688 } 1689 } 1690 func TestRaceBlockCall6(t *testing.T) { 1691 done := make(chan bool) 1692 x := 0 1693 var y *int 1694 go func() { 1695 f := func() (int, *int) { 1696 i := 43 1697 return 42, &i 1698 } 1699 x, y = f() 1700 done <- true 1701 }() 1702 _ = x 1703 <-done 1704 if x != 42 || *y != 43 { 1705 panic("corrupted data") 1706 } 1707 } 1708 func TestRaceSliceSlice(t *testing.T) { 1709 c := make(chan bool, 1) 1710 x := make([]int, 10) 1711 go func() { 1712 x = make([]int, 20) 1713 c <- true 1714 }() 1715 _ = x[2:3] 1716 <-c 1717 } 1718 1719 func TestRaceSliceSlice2(t *testing.T) { 1720 c := make(chan bool, 1) 1721 x := make([]int, 10) 1722 i := 2 1723 go func() { 1724 i = 3 1725 c <- true 1726 }() 1727 _ = x[i:4] 1728 <-c 1729 } 1730 1731 func TestRaceSliceString(t *testing.T) { 1732 c := make(chan bool, 1) 1733 x := "hello" 1734 go func() { 1735 x = "world" 1736 c <- true 1737 }() 1738 _ = x[2:3] 1739 <-c 1740 } 1741 1742 func TestRaceSliceStruct(t *testing.T) { 1743 type X struct { 1744 x, y int 1745 } 1746 c := make(chan bool, 1) 1747 x := make([]X, 10) 1748 go func() { 1749 y := make([]X, 10) 1750 copy(y, x) 1751 c <- true 1752 }() 1753 x[1].y = 42 1754 <-c 1755 } 1756 1757 func TestRaceAppendSliceStruct(t *testing.T) { 1758 type X struct { 1759 x, y int 1760 } 1761 c := make(chan bool, 1) 1762 x := make([]X, 10) 1763 go func() { 1764 y := make([]X, 0, 10) 1765 y = append(y, x...) 1766 c <- true 1767 }() 1768 x[1].y = 42 1769 <-c 1770 } 1771 1772 func TestRaceStructInd(t *testing.T) { 1773 c := make(chan bool, 1) 1774 type Item struct { 1775 x, y int 1776 } 1777 i := Item{} 1778 go func(p *Item) { 1779 *p = Item{} 1780 c <- true 1781 }(&i) 1782 i.y = 42 1783 <-c 1784 } 1785 1786 func TestRaceAsFunc1(t *testing.T) { 1787 var s []byte 1788 c := make(chan bool, 1) 1789 go func() { 1790 var err error 1791 s, err = func() ([]byte, error) { 1792 t := []byte("hello world") 1793 return t, nil 1794 }() 1795 c <- true 1796 _ = err 1797 }() 1798 _ = string(s) 1799 <-c 1800 } 1801 1802 func TestRaceAsFunc2(t *testing.T) { 1803 c := make(chan bool, 1) 1804 x := 0 1805 go func() { 1806 func(x int) { 1807 }(x) 1808 c <- true 1809 }() 1810 x = 42 1811 <-c 1812 } 1813 1814 func TestRaceAsFunc3(t *testing.T) { 1815 c := make(chan bool, 1) 1816 var mu sync.Mutex 1817 x := 0 1818 go func() { 1819 func(x int) { 1820 mu.Lock() 1821 }(x) // Read of x must be outside of the mutex. 1822 mu.Unlock() 1823 c <- true 1824 }() 1825 mu.Lock() 1826 x = 42 1827 mu.Unlock() 1828 <-c 1829 } 1830 1831 func TestNoRaceAsFunc4(t *testing.T) { 1832 c := make(chan bool, 1) 1833 var mu sync.Mutex 1834 x := 0 1835 _ = x 1836 go func() { 1837 x = func() int { // Write of x must be under the mutex. 1838 mu.Lock() 1839 return 42 1840 }() 1841 mu.Unlock() 1842 c <- true 1843 }() 1844 mu.Lock() 1845 x = 42 1846 mu.Unlock() 1847 <-c 1848 } 1849 1850 func TestRaceHeapParam(t *testing.T) { 1851 done := make(chan bool) 1852 x := func() (x int) { 1853 go func() { 1854 x = 42 1855 done <- true 1856 }() 1857 return 1858 }() 1859 _ = x 1860 <-done 1861 } 1862 1863 func TestNoRaceEmptyStruct(t *testing.T) { 1864 type Empty struct{} 1865 type X struct { 1866 y int64 1867 Empty 1868 } 1869 type Y struct { 1870 x X 1871 y int64 1872 } 1873 c := make(chan X) 1874 var y Y 1875 go func() { 1876 x := y.x 1877 c <- x 1878 }() 1879 y.y = 42 1880 <-c 1881 } 1882 1883 func TestRaceNestedStruct(t *testing.T) { 1884 type X struct { 1885 x, y int 1886 } 1887 type Y struct { 1888 x X 1889 } 1890 c := make(chan Y) 1891 var y Y 1892 go func() { 1893 c <- y 1894 }() 1895 y.x.y = 42 1896 <-c 1897 } 1898 1899 func TestRaceIssue5567(t *testing.T) { 1900 testRaceRead(t, false) 1901 } 1902 1903 func TestRaceIssue51618(t *testing.T) { 1904 testRaceRead(t, true) 1905 } 1906 1907 func testRaceRead(t *testing.T, pread bool) { 1908 defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4)) 1909 in := make(chan []byte) 1910 res := make(chan error) 1911 go func() { 1912 var err error 1913 defer func() { 1914 close(in) 1915 res <- err 1916 }() 1917 path := "mop_test.go" 1918 f, err := os.Open(path) 1919 if err != nil { 1920 return 1921 } 1922 defer f.Close() 1923 var n, total int 1924 b := make([]byte, 17) // the race is on b buffer 1925 for err == nil { 1926 if pread { 1927 n, err = f.ReadAt(b, int64(total)) 1928 } else { 1929 n, err = f.Read(b) 1930 } 1931 total += n 1932 if n > 0 { 1933 in <- b[:n] 1934 } 1935 } 1936 if err == io.EOF { 1937 err = nil 1938 } 1939 }() 1940 h := crc32.New(crc32.MakeTable(0x12345678)) 1941 for b := range in { 1942 h.Write(b) 1943 } 1944 _ = h.Sum(nil) 1945 err := <-res 1946 if err != nil { 1947 t.Fatal(err) 1948 } 1949 } 1950 1951 func TestRaceIssue5654(t *testing.T) { 1952 text := `Friends, Romans, countrymen, lend me your ears; 1953 I come to bury Caesar, not to praise him. 1954 The evil that men do lives after them; 1955 The good is oft interred with their bones; 1956 So let it be with Caesar. The noble Brutus 1957 Hath told you Caesar was ambitious: 1958 If it were so, it was a grievous fault, 1959 And grievously hath Caesar answer'd it. 1960 Here, under leave of Brutus and the rest - 1961 For Brutus is an honourable man; 1962 So are they all, all honourable men - 1963 Come I to speak in Caesar's funeral. 1964 He was my friend, faithful and just to me: 1965 But Brutus says he was ambitious; 1966 And Brutus is an honourable man.` 1967 1968 data := bytes.NewBufferString(text) 1969 in := make(chan []byte) 1970 1971 go func() { 1972 buf := make([]byte, 16) 1973 var n int 1974 var err error 1975 for ; err == nil; n, err = data.Read(buf) { 1976 in <- buf[:n] 1977 } 1978 close(in) 1979 }() 1980 res := "" 1981 for s := range in { 1982 res += string(s) 1983 } 1984 _ = res 1985 } 1986 1987 type Base int 1988 1989 func (b *Base) Foo() int { 1990 return 42 1991 } 1992 1993 func (b Base) Bar() int { 1994 return int(b) 1995 } 1996 1997 func TestNoRaceMethodThunk(t *testing.T) { 1998 type Derived struct { 1999 pad int 2000 Base 2001 } 2002 var d Derived 2003 done := make(chan bool) 2004 go func() { 2005 _ = d.Foo() 2006 done <- true 2007 }() 2008 d = Derived{} 2009 <-done 2010 } 2011 2012 func TestRaceMethodThunk(t *testing.T) { 2013 type Derived struct { 2014 pad int 2015 *Base 2016 } 2017 var d Derived 2018 done := make(chan bool) 2019 go func() { 2020 _ = d.Foo() 2021 done <- true 2022 }() 2023 d = Derived{} 2024 <-done 2025 } 2026 2027 func TestRaceMethodThunk2(t *testing.T) { 2028 type Derived struct { 2029 pad int 2030 Base 2031 } 2032 var d Derived 2033 done := make(chan bool) 2034 go func() { 2035 _ = d.Bar() 2036 done <- true 2037 }() 2038 d = Derived{} 2039 <-done 2040 } 2041 2042 func TestRaceMethodThunk3(t *testing.T) { 2043 type Derived struct { 2044 pad int 2045 *Base 2046 } 2047 var d Derived 2048 d.Base = new(Base) 2049 done := make(chan bool) 2050 go func() { 2051 _ = d.Bar() 2052 done <- true 2053 }() 2054 d.Base = new(Base) 2055 <-done 2056 } 2057 2058 func TestRaceMethodThunk4(t *testing.T) { 2059 type Derived struct { 2060 pad int 2061 *Base 2062 } 2063 var d Derived 2064 d.Base = new(Base) 2065 done := make(chan bool) 2066 go func() { 2067 _ = d.Bar() 2068 done <- true 2069 }() 2070 *(*int)(d.Base) = 42 2071 <-done 2072 } 2073 2074 func TestNoRaceTinyAlloc(t *testing.T) { 2075 const P = 4 2076 const N = 1e6 2077 var tinySink *byte 2078 _ = tinySink 2079 done := make(chan bool) 2080 for p := 0; p < P; p++ { 2081 go func() { 2082 for i := 0; i < N; i++ { 2083 var b byte 2084 if b != 0 { 2085 tinySink = &b // make it heap allocated 2086 } 2087 b = 42 2088 } 2089 done <- true 2090 }() 2091 } 2092 for p := 0; p < P; p++ { 2093 <-done 2094 } 2095 }