Home | History | Annotate | Download | only in testdata
      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 }
    190