Source file test/fixedbugs/issue31419.go

     1  // run
     2  
     3  // Copyright 2019 The Go Authors. All rights reserved.
     4  // Use of this source code is governed by a BSD-style
     5  // license that can be found in the LICENSE file.
     6  
     7  // Issue 31419: race in getitab when two goroutines try
     8  // to do the same failed interface conversion.
     9  
    10  package main
    11  
    12  type T int
    13  
    14  func (t T) M() {}
    15  
    16  type I interface {
    17  	M()
    18  	M2()
    19  }
    20  
    21  var t T
    22  var e interface{} = &t
    23  var ok = false
    24  var ch = make(chan int)
    25  
    26  func main() {
    27  	_, ok = e.(I) // populate itab cache with a false result
    28  
    29  	go f() // get itab in a loop
    30  
    31  	var i I
    32  	for k := 0; k < 10000; k++ {
    33  		i, ok = e.(I) // read the cached itab
    34  		if ok {
    35  			println("iteration", k, "i =", i, "&t =", &t)
    36  			panic("conversion succeeded")
    37  		}
    38  	}
    39  	<-ch
    40  }
    41  
    42  func f() {
    43  	for i := 0; i < 10000; i++ {
    44  		f1()
    45  	}
    46  	ch <- 1
    47  }
    48  
    49  func f1() {
    50  	defer func() {
    51  		err := recover()
    52  		if err == nil {
    53  			panic("did not panic")
    54  		}
    55  	}()
    56  	i := e.(I) // triggers itab.init, for getting the panic string
    57  	_ = i
    58  }
    59  

View as plain text