From 09eefb3a4d15bb409ad8a85b505ec9230702a27a Mon Sep 17 00:00:00 2001 From: Cuong Manh Le Date: Fri, 25 Aug 2023 22:10:38 +0700 Subject: [PATCH] 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 Auto-Submit: Cuong Manh Le Reviewed-by: Michael Knyszek Reviewed-by: Cherry Mui LUCI-TryBot-Result: Go LUCI --- src/cmd/compile/internal/walk/compare.go | 14 +++++- src/runtime/race/output_test.go | 54 ++++++++++++++++++++++++ 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 @@ -476,5 +476,59 @@ Previous write at 0x[0-9,a-f]+ by main goroutine: main\.main\(\) .*/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 `}}, } -- 2.48.1