aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCuong Manh Le <cuong.manhle.vn@gmail.com>2023-08-25 22:10:38 +0700
committerGopher Robot <gobot@golang.org>2024-08-01 14:57:13 +0000
commit09eefb3a4d15bb409ad8a85b505ec9230702a27a (patch)
tree2a043117529e5db11d88a576e73354a9fd1e62a7 /src
parent4c05a23bb63efee928f3c3cbe712ae7d562ba588 (diff)
downloadgo-09eefb3a4d15bb409ad8a85b505ec9230702a27a.tar.xz
cmd/compile: add race instrumentation during walkCompare
So the racy usage could be detected after re-writing "==" to runtime.memequal call. Updates #61204 Change-Id: Idb4ac37e55813cc87f9d16aa656fb447edf69ea1 Reviewed-on: https://go-review.googlesource.com/c/go/+/601117 Reviewed-by: Egon Elbre <egonelbre@gmail.com> Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: Michael Knyszek <mknyszek@google.com> Reviewed-by: Cherry Mui <cherryyz@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Diffstat (limited to 'src')
-rw-r--r--src/cmd/compile/internal/walk/compare.go14
-rw-r--r--src/runtime/race/output_test.go54
2 files changed, 66 insertions, 2 deletions
diff --git a/src/cmd/compile/internal/walk/compare.go b/src/cmd/compile/internal/walk/compare.go
index 625cfecee0..25160008ee 100644
--- a/src/cmd/compile/internal/walk/compare.go
+++ b/src/cmd/compile/internal/walk/compare.go
@@ -192,8 +192,18 @@ func walkCompare(n *ir.BinaryExpr, init *ir.Nodes) ir.Node {
// is handled by walkCompare.
fn, needsLength := reflectdata.EqFor(t)
call := ir.NewCallExpr(base.Pos, ir.OCALL, fn, nil)
- call.Args.Append(typecheck.NodAddr(cmpl))
- call.Args.Append(typecheck.NodAddr(cmpr))
+ addrCmpl := typecheck.NodAddr(cmpl)
+ addrCmpR := typecheck.NodAddr(cmpr)
+ if !types.IsNoRacePkg(types.LocalPkg) && base.Flag.Race {
+ ptrL := typecheck.Conv(typecheck.Conv(addrCmpl, types.Types[types.TUNSAFEPTR]), types.Types[types.TUINTPTR])
+ ptrR := typecheck.Conv(typecheck.Conv(addrCmpR, types.Types[types.TUNSAFEPTR]), types.Types[types.TUINTPTR])
+ raceFn := typecheck.LookupRuntime("racereadrange")
+ size := ir.NewInt(base.Pos, t.Size())
+ call.PtrInit().Append(mkcall1(raceFn, nil, init, ptrL, size))
+ call.PtrInit().Append(mkcall1(raceFn, nil, init, ptrR, size))
+ }
+ call.Args.Append(addrCmpl)
+ call.Args.Append(addrCmpR)
if needsLength {
call.Args.Append(ir.NewInt(base.Pos, t.Size()))
}
diff --git a/src/runtime/race/output_test.go b/src/runtime/race/output_test.go
index 0ee0f41334..0d5c9096f0 100644
--- a/src/runtime/race/output_test.go
+++ b/src/runtime/race/output_test.go
@@ -477,4 +477,58 @@ Previous write at 0x[0-9,a-f]+ by main goroutine:
.*/main.go:10 \+0x[0-9,a-f]+
`}},
+ {"non_inline_array_compare", "run", "", "atexit_sleep_ms=0", `
+package main
+
+import (
+ "math/rand/v2"
+)
+
+var x = [1024]byte{}
+
+var ch = make(chan bool)
+
+func main() {
+ started := make(chan struct{})
+ go func() {
+ close(started)
+ var y = [len(x)]byte{}
+ eq := x == y
+ ch <- eq
+ }()
+ <-started
+ x[rand.IntN(len(x))]++
+ println(<-ch)
+}
+`, []string{`==================
+WARNING: DATA RACE
+`}},
+ {"non_inline_struct_compare", "run", "", "atexit_sleep_ms=0", `
+package main
+
+import "math/rand/v2"
+
+type S struct {
+ a [1024]byte
+}
+
+var x = S{a: [1024]byte{}}
+
+var ch = make(chan bool)
+
+func main() {
+ started := make(chan struct{})
+ go func() {
+ close(started)
+ var y = S{a: [len(x.a)]byte{}}
+ eq := x == y
+ ch <- eq
+ }()
+ <-started
+ x.a[rand.IntN(len(x.a))]++
+ println(<-ch)
+}
+`, []string{`==================
+WARNING: DATA RACE
+`}},
}