mirror of
https://github.com/golang/go
synced 2024-11-13 17:30:24 -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);
|
racewalknode(&n->right, init, 0, 0);
|
||||||
goto ret;
|
goto ret;
|
||||||
|
|
||||||
|
case OITAB:
|
||||||
|
racewalknode(&n->left, init, 0, 0);
|
||||||
|
goto ret;
|
||||||
|
|
||||||
// should not appear in AST by now
|
// should not appear in AST by now
|
||||||
case OSEND:
|
case OSEND:
|
||||||
case ORECV:
|
case ORECV:
|
||||||
@ -323,6 +327,7 @@ racewalknode(Node **np, NodeList **init, int wr, int skip)
|
|||||||
case OPANIC:
|
case OPANIC:
|
||||||
case ORECOVER:
|
case ORECOVER:
|
||||||
case OCONVIFACE:
|
case OCONVIFACE:
|
||||||
|
case OCMPIFACE:
|
||||||
case OMAKECHAN:
|
case OMAKECHAN:
|
||||||
case OMAKEMAP:
|
case OMAKEMAP:
|
||||||
case OMAKESLICE:
|
case OMAKESLICE:
|
||||||
@ -338,6 +343,12 @@ racewalknode(Node **np, NodeList **init, int wr, int skip)
|
|||||||
case OADDSTR:
|
case OADDSTR:
|
||||||
case ODOTTYPE:
|
case ODOTTYPE:
|
||||||
case ODOTTYPE2:
|
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);
|
yyerror("racewalk: %O must be lowered by now", n->op);
|
||||||
goto ret;
|
goto ret;
|
||||||
|
|
||||||
@ -364,30 +375,23 @@ racewalknode(Node **np, NodeList **init, int wr, int skip)
|
|||||||
// does not require instrumentation
|
// does not require instrumentation
|
||||||
case OPRINT: // don't bother instrumenting it
|
case OPRINT: // don't bother instrumenting it
|
||||||
case OPRINTN: // 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 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;
|
goto ret;
|
||||||
|
|
||||||
// unimplemented
|
// unimplemented
|
||||||
case OSLICESTR:
|
case OSLICESTR:
|
||||||
case OAPPEND:
|
case OAPPEND:
|
||||||
case OCMPIFACE:
|
|
||||||
case OARRAYLIT:
|
|
||||||
case OMAPLIT:
|
|
||||||
case OSTRUCTLIT:
|
|
||||||
case OCLOSURE:
|
|
||||||
case ODCL:
|
case ODCL:
|
||||||
case ODCLCONST:
|
case ODCLCONST:
|
||||||
case ODCLTYPE:
|
case ODCLTYPE:
|
||||||
case OLITERAL:
|
case OLITERAL:
|
||||||
case ORANGE:
|
|
||||||
case OTYPE:
|
case OTYPE:
|
||||||
case ONONAME:
|
case ONONAME:
|
||||||
case OINDREG:
|
case OINDREG:
|
||||||
case ODOTMETH:
|
|
||||||
case OITAB:
|
|
||||||
case OHMUL:
|
case OHMUL:
|
||||||
case OCHECKNOTNIL:
|
|
||||||
case OCLOSUREVAR:
|
|
||||||
goto ret;
|
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
|
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) {
|
func TestRaceEfaceConv(t *testing.T) {
|
||||||
c := make(chan bool)
|
c := make(chan bool)
|
||||||
v := 0
|
v := 0
|
||||||
@ -1151,6 +1175,15 @@ func (p InterImpl) Foo(x int) {
|
|||||||
_, _, _ = x, y, z
|
_, _, _ = 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) {
|
func TestRaceInterCall(t *testing.T) {
|
||||||
c := make(chan bool, 1)
|
c := make(chan bool, 1)
|
||||||
p := InterImpl{}
|
p := InterImpl{}
|
||||||
@ -1212,6 +1245,54 @@ func TestRaceMethodCall2(t *testing.T) {
|
|||||||
<-c
|
<-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) {
|
func TestRacePanicArg(t *testing.T) {
|
||||||
c := make(chan bool, 1)
|
c := make(chan bool, 1)
|
||||||
err := errors.New("err")
|
err := errors.New("err")
|
||||||
@ -1338,6 +1419,17 @@ func TestRaceSliceSlice2(t *testing.T) {
|
|||||||
<-c
|
<-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
|
// http://golang.org/issue/4453
|
||||||
func TestRaceFailingSliceStruct(t *testing.T) {
|
func TestRaceFailingSliceStruct(t *testing.T) {
|
||||||
type X struct {
|
type X struct {
|
||||||
|
Loading…
Reference in New Issue
Block a user