]> Cypherpunks repositories - gostls13.git/commitdiff
bug with interaction of variables
authorKen Thompson <ken@golang.org>
Tue, 10 Mar 2009 23:49:34 +0000 (16:49 -0700)
committerKen Thompson <ken@golang.org>
Tue, 10 Mar 2009 23:49:34 +0000 (16:49 -0700)
declared in cases and heap allocation

R=r
OCL=26064
CL=26064

src/cmd/6g/reg.c
src/cmd/gc/swt.c

index 5b56138b3446dbb818c573c219066e8202af2895..a2c64fa9fab2829727e60ed637351731e4b7f38a 100644 (file)
@@ -787,7 +787,9 @@ mkvar(Reg *r, Adr *a)
        s = a->sym;
        if(s == S)
                goto none;
-       if(s->name[0] == '!' || s->name[0] == '.')
+//     if(s->name[0] == '!')
+//             goto none;
+       if(s->name[0] == '.')
                goto none;
        et = a->etype;
        o = a->offset;
index 5f014e9a9f5f51ef0c3e35fb130e56edcfb6be04..0c5e5eed871b579e225dad8c273bfeb75e5b9eb1 100644 (file)
@@ -189,7 +189,6 @@ casebody(Node *sw)
        br = nod(OBREAK, N, N);
 
 loop:
-
        if(t == N) {
                if(oc == N && os != N)
                        yyerror("first switch statement must be a case");
@@ -259,12 +258,12 @@ loop:
  * rebulid case statements into if .. goto
  */
 void
-prepsw(Node *sw, int arg)
+exprswitch(Node *sw, int arg)
 {
        Iter save;
        Node *name, *bool, *cas;
        Node *t, *a;
-//dump("prepsw before", sw->nbody->left);
+//dump("exprswitch before", sw->nbody->left);
 
        cas = N;
        name = N;
@@ -281,7 +280,7 @@ prepsw(Node *sw, int arg)
 loop:
        if(t == N) {
                sw->nbody->left = rev(cas);
-//dump("prepsw after", sw->nbody->left);
+//dump("exprswitch after", sw->nbody->left);
                return;
        }
 
@@ -291,6 +290,16 @@ loop:
                goto loop;
        }
 
+       // pull out the dcl in case this
+       // variable is allocated on the heap.
+       // this should be done better to prevent
+       // multiple (unused) heap allocations per switch.
+       if(t->ninit != N && t->ninit->op == ODCL) {
+//dump("exprswitch case init", t->ninit);
+               cas = list(cas, t->ninit);
+               t->ninit = N;
+       }
+
        if(t->left->op == OAS) {
                if(bool == N) {
                        bool = nod(OXXX, N, N);
@@ -394,6 +403,18 @@ loop:
                goto loop;
        }
 
+       // pull out the dcl in case this
+       // variable is allocated on the heap.
+       // this should be done better to prevent
+       // multiple (unused) heap allocations per switch.
+       // not worth doing now -- make a binary search
+       // on contents of signature instead.
+       if(t->ninit != N && t->ninit->op == ODCL) {
+//dump("typeswitch case init", t->ninit);
+               cas = list(cas, t->ninit);
+               t->ninit = N;
+       }
+
        a = t->left->left;              // var
        a = nod(OLIST, a, bool);        // var,bool
 
@@ -476,7 +497,7 @@ walkswitch(Node *sw)
        /*
         * convert the switch into OIF statements
         */
-       prepsw(sw, arg);
+       exprswitch(sw, arg);
        walkstate(sw->nbody);
 //print("normal done\n");
 }