Source file src/runtime/race/testdata/regression_test.go

     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  

View as plain text