]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/gc: implement more cases in racewalk.
authorRémy Oudompheng <oudomphe@phare.normalesup.org>
Thu, 21 Mar 2013 07:53:52 +0000 (08:53 +0100)
committerRémy Oudompheng <oudomphe@phare.normalesup.org>
Thu, 21 Mar 2013 07:53:52 +0000 (08:53 +0100)
Add missing CLOSUREVAR in switch.
Mark MAKE, string conversion nodes as impossible.
Control statements do not need instrumentation.
Instrument COM and LROT nodes.
Instrument map length.

Update #4228

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

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

index 269c0b26526b4d37859043662a7364efedcdeac9..3e5e592ca0a08514808a051189a1bfae05b65685 100644 (file)
@@ -196,6 +196,7 @@ racewalknode(Node **np, NodeList **init, int wr, int skip)
        case OPLUS:
        case OREAL:
        case OIMAG:
+       case OCOM:
                racewalknode(&n->left, init, wr, 0);
                goto ret;
 
@@ -222,23 +223,17 @@ racewalknode(Node **np, NodeList **init, int wr, int skip)
        case OCAP:
                racewalknode(&n->left, init, 0, 0);
                if(istype(n->left->type, TMAP)) {
-                       // crashes on len(m[0]) or len(f())
-                       SET(n1);
-                       USED(n1);
-                       /*
-                       n1 = nod(OADDR, n->left, N);
-                       n1 = conv(n1, types[TUNSAFEPTR]);
-                       n1 = conv(n1, ptrto(ptrto(types[TINT8])));
-                       n1 = nod(OIND, n1, N);
+                       n1 = nod(OCONVNOP, n->left, N);
+                       n1->type = ptrto(types[TUINT8]);
                        n1 = nod(OIND, n1, N);
                        typecheck(&n1, Erv);
                        callinstr(&n1, init, 0, skip);
-                       */
                }
                goto ret;
 
        case OLSH:
        case ORSH:
+       case OLROT:
        case OAND:
        case OANDNOT:
        case OOR:
@@ -279,7 +274,6 @@ racewalknode(Node **np, NodeList **init, int wr, int skip)
 
        case ODIV:
        case OMOD:
-               // TODO(dvyukov): add a test for this
                racewalknode(&n->left, init, wr, 0);
                racewalknode(&n->right, init, wr, 0);
                goto ret;
@@ -324,9 +318,30 @@ racewalknode(Node **np, NodeList **init, int wr, int skip)
        case OPANIC:
        case ORECOVER:
        case OCONVIFACE:
+       case OMAKECHAN:
+       case OMAKEMAP:
+       case OMAKESLICE:
+       case OCALL:
+       case OCOPY:
+       case ORUNESTR:
+       case OARRAYBYTESTR:
+       case OARRAYRUNESTR:
+       case OSTRARRAYBYTE:
+       case OSTRARRAYRUNE:
+       case OINDEXMAP:  // lowered to call
+       case OCMPSTR:
+       case OADDSTR:
+       case ODOTTYPE:
+       case ODOTTYPE2:
                yyerror("racewalk: %O must be lowered by now", n->op);
                goto ret;
 
+       // impossible nodes: only appear in backend.
+       case ORROTC:
+       case OEXTEND:
+               yyerror("racewalk: %O cannot exist now", n->op);
+               goto ret;
+
        // just do generic traversal
        case OFOR:
        case OIF:
@@ -334,43 +349,28 @@ racewalknode(Node **np, NodeList **init, int wr, int skip)
        case ORETURN:
        case OSELECT:
        case OEMPTY:
+       case OBREAK:
+       case OCONTINUE:
+       case OFALL:
+       case OGOTO:
+       case OLABEL:
                goto ret;
 
        // does not require instrumentation
-       case OINDEXMAP:  // implemented in runtime
        case OPRINT:     // don't bother instrumenting it
        case OPRINTN:    // don't bother instrumenting it
        case OPARAM:     // it appears only in fn->exit to copy heap params back
                goto ret;
 
        // unimplemented
-       case OCMPSTR:
-       case OADDSTR:
        case OSLICESTR:
        case OAPPEND:
-       case OCOPY:
-       case OMAKECHAN:
-       case OMAKEMAP:
-       case OMAKESLICE:
-       case ORUNESTR:
-       case OARRAYBYTESTR:
-       case OARRAYRUNESTR:
-       case OSTRARRAYBYTE:
-       case OSTRARRAYRUNE:
        case OCMPIFACE:
        case OARRAYLIT:
        case OMAPLIT:
        case OSTRUCTLIT:
        case OCLOSURE:
-       case ODOTTYPE:
-       case ODOTTYPE2:
-       case OCALL:
-       case OBREAK:
        case ODCL:
-       case OCONTINUE:
-       case OFALL:
-       case OGOTO:
-       case OLABEL:
        case ODCLCONST:
        case ODCLTYPE:
        case OLITERAL:
@@ -378,14 +378,11 @@ racewalknode(Node **np, NodeList **init, int wr, int skip)
        case OTYPE:
        case ONONAME:
        case OINDREG:
-       case OCOM:
        case ODOTMETH:
        case OITAB:
-       case OEXTEND:
        case OHMUL:
-       case OLROT:
-       case ORROTC:
        case OCHECKNOTNIL:
+       case OCLOSUREVAR:
                goto ret;
        }
 
index 6f86a50b70c4d0841f9983f5c80a868420437812..35db8db69b4c33c97dc4eb4174c3488c0743ac9e 100644 (file)
@@ -94,8 +94,7 @@ func TestNoRaceMapRangeRange(t *testing.T) {
        <-ch
 }
 
-// Map len is not instrumented.
-func TestRaceFailingMapLen(t *testing.T) {
+func TestRaceMapLen(t *testing.T) {
        m := make(map[string]bool)
        ch := make(chan bool, 1)
        go func() {
@@ -117,8 +116,7 @@ func TestRaceMapDelete(t *testing.T) {
        <-ch
 }
 
-// Map len is not instrumented.
-func TestRaceFailingMapLenDelete(t *testing.T) {
+func TestRaceMapLenDelete(t *testing.T) {
        m := make(map[string]bool)
        ch := make(chan bool, 1)
        go func() {
index f2daa3730197784fcbbd83fa96be687ca1c49f26..26cd3a4e41140ccb2389e4242d4b609453f995d8 100644 (file)
@@ -306,6 +306,102 @@ func TestNoRacePlus(t *testing.T) {
        <-ch
 }
 
+func TestRaceComplement(t *testing.T) {
+       var x, y, z int
+       ch := make(chan int, 2)
+
+       go func() {
+               x = ^y
+               ch <- 1
+       }()
+       go func() {
+               y = ^z
+               ch <- 1
+       }()
+       <-ch
+       <-ch
+}
+
+func TestRaceDiv(t *testing.T) {
+       var x, y, z int
+       ch := make(chan int, 2)
+
+       go func() {
+               x = y / (z + 1)
+               ch <- 1
+       }()
+       go func() {
+               y = z
+               ch <- 1
+       }()
+       <-ch
+       <-ch
+}
+
+func TestRaceDivConst(t *testing.T) {
+       var x, y, z int
+       ch := make(chan int, 2)
+
+       go func() {
+               x = y / 3
+               ch <- 1
+       }()
+       go func() {
+               y = z
+               ch <- 1
+       }()
+       <-ch
+       <-ch
+}
+
+func TestRaceMod(t *testing.T) {
+       var x, y, z int
+       ch := make(chan int, 2)
+
+       go func() {
+               x = y % (z + 1)
+               ch <- 1
+       }()
+       go func() {
+               y = z
+               ch <- 1
+       }()
+       <-ch
+       <-ch
+}
+
+func TestRaceModConst(t *testing.T) {
+       var x, y, z int
+       ch := make(chan int, 2)
+
+       go func() {
+               x = y % 3
+               ch <- 1
+       }()
+       go func() {
+               y = z
+               ch <- 1
+       }()
+       <-ch
+       <-ch
+}
+
+func TestRaceRotate(t *testing.T) {
+       var x, y, z uint32
+       ch := make(chan int, 2)
+
+       go func() {
+               x = y<<12 | y>>20
+               ch <- 1
+       }()
+       go func() {
+               y = z
+               ch <- 1
+       }()
+       <-ch
+       <-ch
+}
+
 // May crash if the instrumentation is reckless.
 func TestNoRaceEnoughRegisters(t *testing.T) {
        // from erf.go
index afe8cc5ec250cd3f5f0e5a3fa3fccac43e585d75..f08ee3ed31df7f1f886c6f664aeebeedf8aeb160 100644 (file)
@@ -45,6 +45,18 @@ func InstrumentMapLen3() {
        _ = len(*m[0])
 }
 
+func TestRaceUnaddressableMapLen(t *testing.T) {
+       m := make(map[int]map[int]int)
+       ch := make(chan int, 1)
+       m[0] = make(map[int]int)
+       go func() {
+               _ = len(m[0])
+               ch <- 0
+       }()
+       m[0][0] = 1
+       <-ch
+}
+
 type Rect struct {
        x, y int
 }
index 773463662b2eee9654a56ada52438be308508863..1fe051b1215cb8907c876687c15bb7de44e33e93 100644 (file)
@@ -463,3 +463,24 @@ func TestRaceSliceRuneToString(t *testing.T) {
        s[9] = 42
        <-c
 }
+
+func TestRaceConcatString(t *testing.T) {
+       s := "hello"
+       c := make(chan string, 1)
+       go func() {
+               c <- s + " world"
+       }()
+       s = "world"
+       <-c
+}
+
+func TestRaceCompareString(t *testing.T) {
+       s1 := "hello"
+       s2 := "world"
+       c := make(chan bool, 1)
+       go func() {
+               c <- s1 == s2
+       }()
+       s1 = s2
+       <-c
+}