mirror of
https://github.com/golang/go
synced 2024-11-12 05:30:21 -07:00
cmd/gc: more race instrumentation.
Handle interface comparison correctly, add a few more tests, mark more nodes as impossible. R=dvyukov, golang-dev CC=golang-dev https://golang.org/cl/7942045
This commit is contained in:
parent
ce99bb2caf
commit
eb7c51c148
@ -312,6 +312,10 @@ racewalknode(Node **np, NodeList **init, int wr, int skip)
|
||||
racewalknode(&n->right, init, 0, 0);
|
||||
goto ret;
|
||||
|
||||
case OITAB:
|
||||
racewalknode(&n->left, init, 0, 0);
|
||||
goto ret;
|
||||
|
||||
// should not appear in AST by now
|
||||
case OSEND:
|
||||
case ORECV:
|
||||
@ -323,6 +327,7 @@ racewalknode(Node **np, NodeList **init, int wr, int skip)
|
||||
case OPANIC:
|
||||
case ORECOVER:
|
||||
case OCONVIFACE:
|
||||
case OCMPIFACE:
|
||||
case OMAKECHAN:
|
||||
case OMAKEMAP:
|
||||
case OMAKESLICE:
|
||||
@ -338,6 +343,12 @@ racewalknode(Node **np, NodeList **init, int wr, int skip)
|
||||
case OADDSTR:
|
||||
case ODOTTYPE:
|
||||
case ODOTTYPE2:
|
||||
case OCALLPART: // lowered to PTRLIT
|
||||
case OCLOSURE: // lowered to PTRLIT
|
||||
case ORANGE: // lowered to ordinary for loop
|
||||
case OARRAYLIT: // lowered to assignments
|
||||
case OMAPLIT:
|
||||
case OSTRUCTLIT:
|
||||
yyerror("racewalk: %O must be lowered by now", n->op);
|
||||
goto ret;
|
||||
|
||||
@ -364,30 +375,23 @@ racewalknode(Node **np, NodeList **init, int wr, int skip)
|
||||
// does not require instrumentation
|
||||
case OPRINT: // don't bother instrumenting it
|
||||
case OPRINTN: // don't bother instrumenting it
|
||||
case OCHECKNOTNIL: // always followed by a read.
|
||||
case OPARAM: // it appears only in fn->exit to copy heap params back
|
||||
case OCLOSUREVAR:// immutable pointer to captured variable
|
||||
case ODOTMETH: // either part of CALLMETH or CALLPART (lowered to PTRLIT)
|
||||
goto ret;
|
||||
|
||||
// unimplemented
|
||||
case OSLICESTR:
|
||||
case OAPPEND:
|
||||
case OCMPIFACE:
|
||||
case OARRAYLIT:
|
||||
case OMAPLIT:
|
||||
case OSTRUCTLIT:
|
||||
case OCLOSURE:
|
||||
case ODCL:
|
||||
case ODCLCONST:
|
||||
case ODCLTYPE:
|
||||
case OLITERAL:
|
||||
case ORANGE:
|
||||
case OTYPE:
|
||||
case ONONAME:
|
||||
case OINDREG:
|
||||
case ODOTMETH:
|
||||
case OITAB:
|
||||
case OHMUL:
|
||||
case OCHECKNOTNIL:
|
||||
case OCLOSUREVAR:
|
||||
goto ret;
|
||||
}
|
||||
|
||||
|
92
src/pkg/runtime/race/testdata/mop_test.go
vendored
92
src/pkg/runtime/race/testdata/mop_test.go
vendored
@ -576,6 +576,30 @@ func TestRaceIfaceWW(t *testing.T) {
|
||||
a = b
|
||||
}
|
||||
|
||||
func TestRaceIfaceCmp(t *testing.T) {
|
||||
var a, b Writer
|
||||
a = DummyWriter{1}
|
||||
ch := make(chan bool, 1)
|
||||
go func() {
|
||||
a = DummyWriter{1}
|
||||
ch <- true
|
||||
}()
|
||||
_ = a == b
|
||||
<-ch
|
||||
}
|
||||
|
||||
func TestRaceIfaceCmpNil(t *testing.T) {
|
||||
var a Writer
|
||||
a = DummyWriter{1}
|
||||
ch := make(chan bool, 1)
|
||||
go func() {
|
||||
a = DummyWriter{1}
|
||||
ch <- true
|
||||
}()
|
||||
_ = a == nil
|
||||
<-ch
|
||||
}
|
||||
|
||||
func TestRaceEfaceConv(t *testing.T) {
|
||||
c := make(chan bool)
|
||||
v := 0
|
||||
@ -1151,6 +1175,15 @@ func (p InterImpl) Foo(x int) {
|
||||
_, _, _ = x, y, z
|
||||
}
|
||||
|
||||
type InterImpl2 InterImpl
|
||||
|
||||
func (p *InterImpl2) Foo(x int) {
|
||||
if p == nil {
|
||||
InterImpl{}.Foo(x)
|
||||
}
|
||||
InterImpl(*p).Foo(x)
|
||||
}
|
||||
|
||||
func TestRaceInterCall(t *testing.T) {
|
||||
c := make(chan bool, 1)
|
||||
p := InterImpl{}
|
||||
@ -1212,6 +1245,54 @@ func TestRaceMethodCall2(t *testing.T) {
|
||||
<-c
|
||||
}
|
||||
|
||||
// Method value with concrete value receiver.
|
||||
func TestRaceMethodValue(t *testing.T) {
|
||||
c := make(chan bool, 1)
|
||||
i := InterImpl{}
|
||||
go func() {
|
||||
i = InterImpl{}
|
||||
c <- true
|
||||
}()
|
||||
_ = i.Foo
|
||||
<-c
|
||||
}
|
||||
|
||||
// Method value with interface receiver.
|
||||
func TestRaceMethodValue2(t *testing.T) {
|
||||
c := make(chan bool, 1)
|
||||
var i Inter = InterImpl{}
|
||||
go func() {
|
||||
i = InterImpl{}
|
||||
c <- true
|
||||
}()
|
||||
_ = i.Foo
|
||||
<-c
|
||||
}
|
||||
|
||||
// Method value with implicit dereference.
|
||||
func TestRaceMethodValue3(t *testing.T) {
|
||||
c := make(chan bool, 1)
|
||||
i := &InterImpl{}
|
||||
go func() {
|
||||
*i = InterImpl{}
|
||||
c <- true
|
||||
}()
|
||||
_ = i.Foo // dereferences i.
|
||||
<-c
|
||||
}
|
||||
|
||||
// Method value implicitly taking receiver address.
|
||||
func TestNoRaceMethodValue(t *testing.T) {
|
||||
c := make(chan bool, 1)
|
||||
i := InterImpl2{}
|
||||
go func() {
|
||||
i = InterImpl2{}
|
||||
c <- true
|
||||
}()
|
||||
_ = i.Foo // takes the address of i only.
|
||||
<-c
|
||||
}
|
||||
|
||||
func TestRacePanicArg(t *testing.T) {
|
||||
c := make(chan bool, 1)
|
||||
err := errors.New("err")
|
||||
@ -1338,6 +1419,17 @@ func TestRaceSliceSlice2(t *testing.T) {
|
||||
<-c
|
||||
}
|
||||
|
||||
func TestRaceSliceString(t *testing.T) {
|
||||
c := make(chan bool, 1)
|
||||
x := "hello"
|
||||
go func() {
|
||||
x = "world"
|
||||
c <- true
|
||||
}()
|
||||
_ = x[2:3]
|
||||
<-c
|
||||
}
|
||||
|
||||
// http://golang.org/issue/4453
|
||||
func TestRaceFailingSliceStruct(t *testing.T) {
|
||||
type X struct {
|
||||
|
Loading…
Reference in New Issue
Block a user