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 7package race_test 8 9import ( 10 "testing" 11) 12 13type LogImpl struct { 14 x int 15} 16 17func 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 28var _ LogImpl = NewLog() 29 30func MakeMap() map[int]int { 31 return make(map[int]int) 32} 33 34func InstrumentMapLen() { 35 _ = len(MakeMap()) 36} 37 38func InstrumentMapLen2() { 39 m := make(map[int]map[int]int) 40 _ = len(m[0]) 41} 42 43func InstrumentMapLen3() { 44 m := make(map[int]*map[int]int) 45 _ = len(*m[0]) 46} 47 48func 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 60type Rect struct { 61 x, y int 62} 63 64type Image struct { 65 min, max Rect 66} 67 68//go:noinline 69func NewImage() Image { 70 return Image{} 71} 72 73func AddrOfTemp() { 74 _ = NewImage().min 75} 76 77type TypeID int 78 79func (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 87type stack []int 88 89func (s *stack) push(x int) { 90 *s = append(*s, x) 91} 92 93func (s *stack) pop() int { 94 i := len(*s) 95 n := (*s)[i-1] 96 *s = (*s)[:i-1] 97 return n 98} 99 100func 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 108type RpcChan struct { 109 c chan bool 110} 111 112var makeChanCalls int 113 114//go:noinline 115func makeChan() *RpcChan { 116 makeChanCalls++ 117 c := &RpcChan{make(chan bool, 1)} 118 c.c <- true 119 return c 120} 121 122func call() bool { 123 x := <-makeChan().c 124 return x 125} 126 127func 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 135func divInSlice() { 136 v := make([]int64, 10) 137 i := 1 138 _ = v[(i*4)/3] 139} 140 141func 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. 150func 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 159func 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 166type inltype struct { 167 x, y bool 168} 169 170func inlinetest(p **inltype) *inltype { 171 return *p 172} 173 174type iface interface { 175 Foo() *struct{ b bool } 176} 177 178type Int int 179 180func (i Int) Foo() *struct{ b bool } { 181 return &struct{ b bool }{false} 182} 183 184func 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} 190