// Copyright 2012 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. // Code patterns that caused problems in the past. package race_test import ( "testing" ) type LogImpl struct { x int } func NewLog() (l LogImpl) { c := make(chan bool) go func() { _ = l c <- true }() l = LogImpl{} <-c return } var _ LogImpl = NewLog() func MakeMap() map[int]int { return make(map[int]int) } func InstrumentMapLen() { _ = len(MakeMap()) } func InstrumentMapLen2() { m := make(map[int]map[int]int) _ = len(m[0]) } func InstrumentMapLen3() { m := make(map[int]*map[int]int) _ = len(*m[0]) } func TestRaceUnaddressableMapLen(t *testing.T) { m := make(map[int]map[int]int) ch := make(chan int, 1) m[0] = make(map[int]int) go func() { _ = len(m[0]) ch <- 0 }() m[0][0] = 1 <-ch } type Rect struct { x, y int } type Image struct { min, max Rect } //go:noinline func NewImage() Image { return Image{} } func AddrOfTemp() { _ = NewImage().min } type TypeID int func (t *TypeID) encodeType(x int) (tt TypeID, err error) { switch x { case 0: return t.encodeType(x * x) } return 0, nil } type stack []int func (s *stack) push(x int) { *s = append(*s, x) } func (s *stack) pop() int { i := len(*s) n := (*s)[i-1] *s = (*s)[:i-1] return n } func TestNoRaceStackPushPop(t *testing.T) { var s stack go func(s *stack) {}(&s) s.push(1) x := s.pop() _ = x } type RpcChan struct { c chan bool } var makeChanCalls int //go:noinline func makeChan() *RpcChan { makeChanCalls++ c := &RpcChan{make(chan bool, 1)} c.c <- true return c } func call() bool { x := <-makeChan().c return x } func TestNoRaceRpcChan(t *testing.T) { makeChanCalls = 0 _ = call() if makeChanCalls != 1 { t.Fatalf("makeChanCalls %d, expected 1\n", makeChanCalls) } } func divInSlice() { v := make([]int64, 10) i := 1 _ = v[(i*4)/3] } func TestNoRaceReturn(t *testing.T) { c := make(chan int) noRaceReturn(c) <-c } // Return used to do an implicit a = a, causing a read/write race // with the goroutine. Compiler has an optimization to avoid that now. // See issue 4014. func noRaceReturn(c chan int) (a, b int) { a = 42 go func() { _ = a c <- 1 }() return a, 10 } func issue5431() { var p **inltype if inlinetest(p).x && inlinetest(p).y { } else if inlinetest(p).x || inlinetest(p).y { } } type inltype struct { x, y bool } func inlinetest(p **inltype) *inltype { return *p } type iface interface { Foo() *struct{ b bool } } type Int int func (i Int) Foo() *struct{ b bool } { return &struct{ b bool }{false} } func TestNoRaceForInfiniteLoop(t *testing.T) { var x Int // interface conversion causes nodes to be put on init list for iface(x).Foo().b { } }