// 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 {
}
}