github.com/likebike/go--@v0.0.0-20190911215757-0bd925d16e96/go/src/runtime/race/testdata/regression_test.go (about) 1 // Copyright 2012 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 // Code patterns that caused problems in the past. 6 7 package race_test 8 9 import ( 10 "testing" 11 ) 12 13 type LogImpl struct { 14 x int 15 } 16 17 func NewLog() (l LogImpl) { 18 c := make(chan bool) 19 go func() { 20 _ = l 21 c <- true 22 }() 23 l = LogImpl{} 24 <-c 25 return 26 } 27 28 var _ LogImpl = NewLog() 29 30 func MakeMap() map[int]int { 31 return make(map[int]int) 32 } 33 34 func InstrumentMapLen() { 35 _ = len(MakeMap()) 36 } 37 38 func InstrumentMapLen2() { 39 m := make(map[int]map[int]int) 40 _ = len(m[0]) 41 } 42 43 func InstrumentMapLen3() { 44 m := make(map[int]*map[int]int) 45 _ = len(*m[0]) 46 } 47 48 func TestRaceUnaddressableMapLen(t *testing.T) { 49 m := make(map[int]map[int]int) 50 ch := make(chan int, 1) 51 m[0] = make(map[int]int) 52 go func() { 53 _ = len(m[0]) 54 ch <- 0 55 }() 56 m[0][0] = 1 57 <-ch 58 } 59 60 type Rect struct { 61 x, y int 62 } 63 64 type Image struct { 65 min, max Rect 66 } 67 68 //go:noinline 69 func NewImage() Image { 70 return Image{} 71 } 72 73 func AddrOfTemp() { 74 _ = NewImage().min 75 } 76 77 type TypeID int 78 79 func (t *TypeID) encodeType(x int) (tt TypeID, err error) { 80 switch x { 81 case 0: 82 return t.encodeType(x * x) 83 } 84 return 0, nil 85 } 86 87 type stack []int 88 89 func (s *stack) push(x int) { 90 *s = append(*s, x) 91 } 92 93 func (s *stack) pop() int { 94 i := len(*s) 95 n := (*s)[i-1] 96 *s = (*s)[:i-1] 97 return n 98 } 99 100 func TestNoRaceStackPushPop(t *testing.T) { 101 var s stack 102 go func(s *stack) {}(&s) 103 s.push(1) 104 x := s.pop() 105 _ = x 106 } 107 108 type RpcChan struct { 109 c chan bool 110 } 111 112 var makeChanCalls int 113 114 //go:noinline 115 func makeChan() *RpcChan { 116 makeChanCalls++ 117 c := &RpcChan{make(chan bool, 1)} 118 c.c <- true 119 return c 120 } 121 122 func call() bool { 123 x := <-makeChan().c 124 return x 125 } 126 127 func TestNoRaceRpcChan(t *testing.T) { 128 makeChanCalls = 0 129 _ = call() 130 if makeChanCalls != 1 { 131 t.Fatalf("makeChanCalls %d, expected 1\n", makeChanCalls) 132 } 133 } 134 135 func divInSlice() { 136 v := make([]int64, 10) 137 i := 1 138 _ = v[(i*4)/3] 139 } 140 141 func TestNoRaceReturn(t *testing.T) { 142 c := make(chan int) 143 noRaceReturn(c) 144 <-c 145 } 146 147 // Return used to do an implicit a = a, causing a read/write race 148 // with the goroutine. Compiler has an optimization to avoid that now. 149 // See issue 4014. 150 func noRaceReturn(c chan int) (a, b int) { 151 a = 42 152 go func() { 153 _ = a 154 c <- 1 155 }() 156 return a, 10 157 } 158 159 func issue5431() { 160 var p **inltype 161 if inlinetest(p).x && inlinetest(p).y { 162 } else if inlinetest(p).x || inlinetest(p).y { 163 } 164 } 165 166 type inltype struct { 167 x, y bool 168 } 169 170 func inlinetest(p **inltype) *inltype { 171 return *p 172 } 173 174 type iface interface { 175 Foo() *struct{ b bool } 176 } 177 178 type Int int 179 180 func (i Int) Foo() *struct{ b bool } { 181 return &struct{ b bool }{false} 182 } 183 184 func TestNoRaceForInfiniteLoop(t *testing.T) { 185 var x Int 186 // interface conversion causes nodes to be put on init list 187 for iface(x).Foo().b { 188 } 189 }