mirror of https://github.com/golang/go.git
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>
This commit is contained in:
parent
4c05a23bb6
commit
09eefb3a4d
|
|
@ -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()))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
`}},
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue