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 10package main 11 12type T int 13 14func (t T) M() {} 15 16type I interface { 17 M() 18 M2() 19} 20 21var t T 22var e interface{} = &t 23var ok = false 24var ch = make(chan int) 25 26func 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 42func f() { 43 for i := 0; i < 10000; i++ { 44 f1() 45 } 46 ch <- 1 47} 48 49func 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