]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/gc: instrument blocks for race detection.
authorRémy Oudompheng <oudomphe@phare.normalesup.org>
Fri, 2 Nov 2012 23:11:06 +0000 (00:11 +0100)
committerRémy Oudompheng <oudomphe@phare.normalesup.org>
Fri, 2 Nov 2012 23:11:06 +0000 (00:11 +0100)
It happens that blocks are used for function calls in a
quite low-level way so they cannot be instrumented as
usual.

Blocks are also used for inlined functions.

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

src/cmd/gc/racewalk.c

index 9e942498ba102200e339a786806f2dcb457bdc0f..647b54b713632ffdf2efc2ac7e804571f3aa3148 100644 (file)
@@ -88,6 +88,7 @@ static void
 racewalknode(Node **np, NodeList **init, int wr, int skip)
 {
        Node *n, *n1;
+       NodeList *fini;
 
        n = *np;
 
@@ -116,8 +117,28 @@ racewalknode(Node **np, NodeList **init, int wr, int skip)
                goto ret;
 
        case OBLOCK:
-               // leads to crashes.
-               //racewalklist(n->list, nil);
+               if(n->list == nil)
+                       goto ret;
+
+               switch(n->list->n->op) {
+               case OCALLFUNC:
+               case OCALLMETH:
+               case OCALLINTER:
+                       // Blocks are used for multiple return function calls.
+                       // x, y := f() becomes BLOCK{CALL f, AS x [SP+0], AS y [SP+n]}
+                       // We don't want to instrument between the statements because it will
+                       // smash the results.
+                       racewalknode(&n->list->n, &n->ninit, 0, 0);
+                       fini = nil;
+                       racewalklist(n->list->next, &fini);
+                       n->list = concat(n->list, fini);
+                       break;
+
+               default:
+                       // Ordinary block, for loop initialization or inlined bodies.
+                       racewalklist(n->list, nil);
+                       break;
+               }
                goto ret;
 
        case ODEFER: