Commit 9172a1b5 authored by Dmitry Vyukov's avatar Dmitry Vyukov

runtime: race instrument read of convT2E/I arg

Sometimes this read is instrumented by compiler when it creates
a temp to take address, but sometimes it is not (e.g. for global vars
compiler takes address of the global directly).

Instrument convT2E/I similarly to chansend and mapaccess.

Fixes #12664

Change-Id: Ia7807f15d735483996426c5f3aed60a33b279579
Reviewed-on: https://go-review.googlesource.com/14752Reviewed-by: default avatarKeith Randall <khr@golang.org>
Run-TryBot: Dmitry Vyukov <dvyukov@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent e31114da
...@@ -129,6 +129,9 @@ func typ2Itab(t *_type, inter *interfacetype, cache **itab) *itab { ...@@ -129,6 +129,9 @@ func typ2Itab(t *_type, inter *interfacetype, cache **itab) *itab {
} }
func convT2E(t *_type, elem unsafe.Pointer, x unsafe.Pointer) (e interface{}) { func convT2E(t *_type, elem unsafe.Pointer, x unsafe.Pointer) (e interface{}) {
if raceenabled {
raceReadObjectPC(t, elem, getcallerpc(unsafe.Pointer(&t)), funcPC(convT2E))
}
ep := (*eface)(unsafe.Pointer(&e)) ep := (*eface)(unsafe.Pointer(&e))
if isDirectIface(t) { if isDirectIface(t) {
ep._type = t ep._type = t
...@@ -147,6 +150,9 @@ func convT2E(t *_type, elem unsafe.Pointer, x unsafe.Pointer) (e interface{}) { ...@@ -147,6 +150,9 @@ func convT2E(t *_type, elem unsafe.Pointer, x unsafe.Pointer) (e interface{}) {
} }
func convT2I(t *_type, inter *interfacetype, cache **itab, elem unsafe.Pointer, x unsafe.Pointer) (i fInterface) { func convT2I(t *_type, inter *interfacetype, cache **itab, elem unsafe.Pointer, x unsafe.Pointer) (i fInterface) {
if raceenabled {
raceReadObjectPC(t, elem, getcallerpc(unsafe.Pointer(&t)), funcPC(convT2I))
}
tab := (*itab)(atomicloadp(unsafe.Pointer(cache))) tab := (*itab)(atomicloadp(unsafe.Pointer(cache)))
if tab == nil { if tab == nil {
tab = getitab(inter, t, false) tab = getitab(inter, t, false)
......
// Copyright 2015 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.
package race_test
import (
"fmt"
"testing"
)
var issue12664 = "hi"
func TestRaceIssue12664(t *testing.T) {
c := make(chan struct{})
go func() {
issue12664 = "bye"
close(c)
}()
fmt.Println(issue12664)
<-c
}
type MyI interface {
foo()
}
type MyT int
func (MyT) foo() {
}
var issue12664_2 MyT = 0
func TestRaceIssue12664_2(t *testing.T) {
c := make(chan struct{})
go func() {
issue12664_2 = 1
close(c)
}()
func(x MyI) {
// Never true, but prevents inlining.
if x.(MyT) == -1 {
close(c)
}
}(issue12664_2)
<-c
}
var issue12664_3 MyT = 0
func TestRaceIssue12664_3(t *testing.T) {
c := make(chan struct{})
go func() {
issue12664_3 = 1
close(c)
}()
var r MyT
var i interface{} = r
issue12664_3 = i.(MyT)
<-c
}
var issue12664_4 MyT = 0
func TestRaceIssue12664_4(t *testing.T) {
c := make(chan struct{})
go func() {
issue12664_4 = 1
close(c)
}()
var r MyT
var i MyI = r
issue12664_4 = i.(MyT)
<-c
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment