]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: race instrument read of convT2E/I arg
authorDmitry Vyukov <dvyukov@google.com>
Fri, 18 Sep 2015 09:40:36 +0000 (11:40 +0200)
committerDmitry Vyukov <dvyukov@google.com>
Sat, 19 Sep 2015 10:26:36 +0000 (10:26 +0000)
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/14752
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: Dmitry Vyukov <dvyukov@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/runtime/iface.go
src/runtime/race/testdata/issue12664_test.go [new file with mode: 0644]

index 332b7d50ab33aa110ff5dd0686524f741f827206..646f8789ebb172e37a7557b111049e6047bb64ea 100644 (file)
@@ -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{}) {
+       if raceenabled {
+               raceReadObjectPC(t, elem, getcallerpc(unsafe.Pointer(&t)), funcPC(convT2E))
+       }
        ep := (*eface)(unsafe.Pointer(&e))
        if isDirectIface(t) {
                ep._type = t
@@ -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) {
+       if raceenabled {
+               raceReadObjectPC(t, elem, getcallerpc(unsafe.Pointer(&t)), funcPC(convT2I))
+       }
        tab := (*itab)(atomicloadp(unsafe.Pointer(cache)))
        if tab == nil {
                tab = getitab(inter, t, false)
diff --git a/src/runtime/race/testdata/issue12664_test.go b/src/runtime/race/testdata/issue12664_test.go
new file mode 100644 (file)
index 0000000..c9f790e
--- /dev/null
@@ -0,0 +1,76 @@
+// 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
+}