]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: add race instrumentation during walkCompare
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Fri, 25 Aug 2023 15:10:38 +0000 (22:10 +0700)
committerGopher Robot <gobot@golang.org>
Thu, 1 Aug 2024 14:57:13 +0000 (14:57 +0000)
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>

src/cmd/compile/internal/walk/compare.go
src/runtime/race/output_test.go

index 625cfecee0c8feadaeec0421fe35ddd82c49af82..25160008ee90ba3c0ed3ee0e3534d88f64bd3780 100644 (file)
@@ -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()))
                }
index 0ee0f41334bea622337762819e9754459675971a..0d5c9096f0ccf17002ed058968e3f27dcd6980f2 100644 (file)
@@ -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
 `}},
 }