]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/gc: fix race instrumentation of append and type switches.
authorRémy Oudompheng <oudomphe@phare.normalesup.org>
Wed, 27 Mar 2013 19:33:17 +0000 (20:33 +0100)
committerRémy Oudompheng <oudomphe@phare.normalesup.org>
Wed, 27 Mar 2013 19:33:17 +0000 (20:33 +0100)
The remaining issues are about runtime and sync package
instrumentation.

Update #4228

R=dvyukov, bradfitz
CC=golang-dev
https://golang.org/cl/8041043

src/cmd/gc/racewalk.c
src/pkg/runtime/race/testdata/mop_test.go
src/pkg/runtime/race/testdata/slice_test.go

index fee5cf42264c6865f874a195e24a7ccb9f3b8c29..5d4f62e761c2f63d414a3a1d52030038e6ab4a93 100644 (file)
@@ -133,7 +133,6 @@ racewalknode(Node **np, NodeList **init, int wr, int skip)
        case OASOP:
        case OAS:
        case OAS2:
-       case OAS2DOTTYPE:
        case OAS2RECV:
        case OAS2FUNC:
        case OAS2MAPR:
@@ -186,12 +185,6 @@ racewalknode(Node **np, NodeList **init, int wr, int skip)
                racewalknode(&n->left, init, 0, 0);
                goto ret;
 
-       case OSWITCH:
-               if(n->ntest->op == OTYPESW)
-                       // TODO(dvyukov): the expression can contain calls or reads.
-                       return;
-               goto ret;
-
        case ONOT:
        case OMINUS:
        case OPLUS:
@@ -317,6 +310,10 @@ racewalknode(Node **np, NodeList **init, int wr, int skip)
                racewalknode(&n->left, init, 0, 0);
                goto ret;
 
+       case OTYPESW:
+               racewalknode(&n->right, init, 0, 0);
+               goto ret;
+
        // should not appear in AST by now
        case OSEND:
        case ORECV:
@@ -334,6 +331,7 @@ racewalknode(Node **np, NodeList **init, int wr, int skip)
        case OMAKESLICE:
        case OCALL:
        case OCOPY:
+       case OAPPEND:
        case ORUNESTR:
        case OARRAYBYTESTR:
        case OARRAYRUNESTR:
@@ -344,6 +342,7 @@ racewalknode(Node **np, NodeList **init, int wr, int skip)
        case OADDSTR:
        case ODOTTYPE:
        case ODOTTYPE2:
+       case OAS2DOTTYPE:
        case OCALLPART: // lowered to PTRLIT
        case OCLOSURE:  // lowered to PTRLIT
        case ORANGE:    // lowered to ordinary for loop
@@ -364,6 +363,7 @@ racewalknode(Node **np, NodeList **init, int wr, int skip)
        case OIF:
        case OCALLMETH:
        case ORETURN:
+       case OSWITCH:
        case OSELECT:
        case OEMPTY:
        case OBREAK:
@@ -389,10 +389,6 @@ racewalknode(Node **np, NodeList **init, int wr, int skip)
        case OLITERAL:
        case OSLICESTR:  // always preceded by bounds checking, avoid double instrumentation.
                goto ret;
-
-       // unimplemented
-       case OAPPEND:
-               goto ret;
        }
 
 ret:
@@ -448,6 +444,7 @@ callinstr(Node **np, NodeList **init, int wr, int skip)
        if(isartificial(n))
                return 0;
        if(t->etype == TSTRUCT) {
+               // TODO: instrument arrays similarly.
                // PARAMs w/o PHEAP are not interesting.
                if(n->class == PPARAM || n->class == PPARAMOUT)
                        return 0;
@@ -484,7 +481,7 @@ callinstr(Node **np, NodeList **init, int wr, int skip)
        // that has got a pointer inside. Whether it points to
        // the heap or not is impossible to know at compile time
        if((class&PHEAP) || class == PPARAMREF || class == PEXTERN
-               || b->type->etype == TARRAY || b->op == ODOTPTR || b->op == OIND || b->op == OXDOT) {
+               || b->op == OINDEX || b->op == ODOTPTR || b->op == OIND || b->op == OXDOT) {
                hascalls = 0;
                foreach(n, hascallspred, &hascalls);
                if(hascalls) {
@@ -510,6 +507,8 @@ uintptraddr(Node *n)
        return r;
 }
 
+// basenod returns the simplest child node of n pointing to the same
+// memory area.
 static Node*
 basenod(Node *n)
 {
@@ -518,7 +517,7 @@ basenod(Node *n)
                        n = n->left;
                        continue;
                }
-               if(n->op == OINDEX) {
+               if(n->op == OINDEX && isfixedarray(n->type)) {
                        n = n->left;
                        continue;
                }
index 1a7ed96249d5f202a4907563e5f3495156ae496d..ae70cbb5f8d253fb28096785e5f5ee585f731c91 100644 (file)
@@ -227,6 +227,37 @@ func TestRaceCaseFallthrough(t *testing.T) {
        <-ch
 }
 
+func TestRaceCaseType(t *testing.T) {
+       var x, y int
+       var i interface{} = x
+       c := make(chan int, 1)
+       go func() {
+               switch i.(type) {
+               case nil:
+               case int:
+               }
+               c <- 1
+       }()
+       i = y
+       <-c
+}
+
+func TestRaceCaseTypeBody(t *testing.T) {
+       var x, y int
+       var i interface{} = &x
+       c := make(chan int, 1)
+       go func() {
+               switch i := i.(type) {
+               case nil:
+               case *int:
+                       *i = y
+               }
+               c <- 1
+       }()
+       x = y
+       <-c
+}
+
 func TestNoRaceRange(t *testing.T) {
        ch := make(chan int, 3)
        a := [...]int{1, 2, 3}
@@ -1446,6 +1477,21 @@ func TestRaceFailingSliceStruct(t *testing.T) {
        <-c
 }
 
+func TestRaceAppendSliceStruct(t *testing.T) {
+       type X struct {
+               x, y int
+       }
+       c := make(chan bool, 1)
+       x := make([]X, 10)
+       go func() {
+               y := make([]X, 0, 10)
+               y = append(y, x...)
+               c <- true
+       }()
+       x[1].y = 42
+       <-c
+}
+
 func TestRaceStructInd(t *testing.T) {
        c := make(chan bool, 1)
        type Item struct {
index 1fe051b1215cb8907c876687c15bb7de44e33e93..c85df5e3d637375eedf6b9284174ba9561d0e069 100644 (file)
@@ -338,8 +338,7 @@ func TestRaceSliceVarCopy2(t *testing.T) {
        <-c
 }
 
-// Not implemented.
-func TestRaceFailingSliceAppend(t *testing.T) {
+func TestRaceSliceAppend(t *testing.T) {
        c := make(chan bool, 1)
        s := make([]int, 10, 20)
        go func() {