]> Cypherpunks repositories - gostls13.git/commitdiff
fixed bug in certain
authorKen Thompson <ken@golang.org>
Tue, 9 Sep 2008 22:47:31 +0000 (15:47 -0700)
committerKen Thompson <ken@golang.org>
Tue, 9 Sep 2008 22:47:31 +0000 (15:47 -0700)
evaluation of complex literals

R=r
OCL=15036
CL=15036

src/cmd/6g/gen.c
src/cmd/gc/go.y
src/cmd/gc/walk.c

index d2caaca39c128ed4b8aadb9f2bdf731586dffddf..dbdafd612797a43383787bb82dcaf977a113d05b 100644 (file)
@@ -244,6 +244,9 @@ loop:
                continpc = pc;
                gen(n->nincr, L);                               // contin:      incr
                patch(p1, pc);                          // test:
+               if(n->ntest != N)
+                       if(n->ntest->ninit != N)
+                               gen(n->ntest->ninit, L);
                bgen(n->ntest, 0, breakpc);             //              if(!test) goto break
                if(labloop != L) {
                        labloop->op = OFOR;
@@ -261,6 +264,9 @@ loop:
                p1 = gbranch(AJMP, T);                  //              goto test
                p2 = gbranch(AJMP, T);                  // p2:          goto else
                patch(p1, pc);                          // test:
+               if(n->ntest != N)
+                       if(n->ntest->ninit != N)
+                               gen(n->ntest->ninit, L);
                bgen(n->ntest, 0, p2);                  //              if(!test) goto p2
                gen(n->nbody, L);                       //              then
                p3 = gbranch(AJMP, T);                  //              goto done
@@ -522,6 +528,9 @@ swgen(Node *n)
 
        patch(p1, pc);
 
+       if(n->ntest != N)
+               if(n->ntest->ninit != N)
+                       gen(n->ntest->ninit, L);
        tempname(&tmp, n->ntest->type);
        cgen(n->ntest, &tmp);
 
index be5d0867fc114225054b3b9b52caa0ea50bd1fbd..ac806cc6fffb1e35f6cb7bda8f4139df8008bfc6 100644 (file)
@@ -250,7 +250,7 @@ Bvardcl:
        }
 |      new_name '=' expr
        {
-               walktype($3, Erv);      // this is a little harry
+               gettype($3);
                defaultlit($3);
                dodclvar($1, $3->type);
                $$ = nod(OAS, $1, $3);
@@ -260,7 +260,7 @@ constdcl:
        new_name type '=' expr
        {
                Node *c = treecopy($4);
-               walktype(c, Erv);
+               gettype(c);
                convlit(c, $2);
                dodclconst($1, c);
 
@@ -270,7 +270,7 @@ constdcl:
 |      new_name '=' expr
        {
                Node *c = treecopy($3);
-               walktype(c, Erv);
+               gettype(c);
                dodclconst($1, c);
 
                lastconst = $3;
@@ -282,7 +282,7 @@ constdcl1:
 |      new_name type
        {
                Node *c = treecopy(lastconst);
-               walktype(c, Erv);
+               gettype(c);
                convlit(c, $2);
                dodclconst($1, c);
 
@@ -291,7 +291,7 @@ constdcl1:
 |      new_name
        {
                Node *c = treecopy(lastconst);
-               walktype(c, Erv);
+               gettype(c);
                dodclconst($1, c);
 
                iota += 1;
@@ -346,6 +346,7 @@ noninc_stmt:
 |      expr_list LCOLAS expr_list
        {
                $$ = nod(OAS, colas($1, $3), $3);
+               addtotop($$);
        }
 |      LPRINT '(' oexpr_list ')'
        {
@@ -379,23 +380,17 @@ complex_stmt:
                popdcl();
                $$ = $2;
                $$->op = OSWITCH;
-               //if($$->ninit != N && $$->ntest == N)
-               //      yyerror("switch expression should not be missing");
        }
 |      LIF if_stmt
        {
                popdcl();
                $$ = $2;
-               //if($$->ninit != N && $$->ntest == N)
-               //      yyerror("if conditional should not be missing");
        }
 |      LIF if_stmt LELSE else_stmt1
        {
                popdcl();
                $$ = $2;
                $$->nelse = $4;
-               //if($$->ninit != N && $$->ntest == N)
-               //      yyerror("if conditional should not be missing");
        }
 |      LSELECT select_stmt
        {
@@ -453,8 +448,6 @@ semi_stmt:
                popdcl();
                $$ = $2;
                $$->nelse = $4;
-               //if($$->ninit != N && $$->ntest == N)
-               //      yyerror("if conditional should not be missing");
        }
 
 compound_stmt:
index 37c3ccd7426d051634e306217696bf296146e793..8c26ac932f51df1cc062937eaf22309e9b64bcde 100644 (file)
@@ -13,18 +13,48 @@ static      Node*   addtop;
 void
 walk(Node *fn)
 {
-       if(debug['W'])
-               dump("fn-before", fn->nbody);
+       char s[50];
+
        curfn = fn;
+       if(debug['W']) {
+               snprint(s, sizeof(s), "\nbefore %S", curfn->nname->sym);
+               dump(s, fn->nbody);
+       }
        walkstate(fn->nbody);
+       if(debug['W']) {
+               snprint(s, sizeof(s), "after %S", curfn->nname->sym);
+               dump(s, fn->nbody);
+       }
+}
+
+void
+addtotop(Node *n)
+{
+       Node *l;
+
+       while(addtop != N) {
+               l = addtop;
+               addtop = N;
+               walktype(l, Etop);
+               n->ninit = list(n->ninit, l);
+       }
+}
+
+void
+gettype(Node *n)
+{
        if(debug['W'])
-               dump("fn", fn->nbody);
+               dump("\nbefore gettype", n);
+       walktype(n, Erv);
+       addtotop(n);
+       if(debug['W'])
+               dump("after gettype", n);
 }
 
 void
 walkstate(Node *n)
 {
-       Node *l, *more;
+       Node *more;
 
 loop:
        if(n == N)
@@ -69,12 +99,7 @@ loop:
                break;
        }
 
-       while(addtop != N) {
-               l = addtop;
-               addtop = N;
-               walktype(l, Etop);
-               n->ninit = list(n->ninit, l);
-       }
+       addtotop(n);
 
        if(more != N) {
                n = more;
@@ -227,8 +252,8 @@ loop:
                        goto nottop;
                walkstate(n->ninit);
                walkbool(n->ntest);
-               walkstate(n->nelse);
                walkstate(n->nbody);
+               walkstate(n->nelse);
                goto ret;
 
        case OPROC:
@@ -307,6 +332,9 @@ loop:
                if(top != Etop)
                        goto nottop;
 
+               addtop = list(addtop, n->ninit);
+               n->ninit = N;
+
                l = n->left;
                r = n->right;
                walktype(l, Elv);
@@ -948,6 +976,7 @@ void
 walkbool(Node *n)
 {
        walktype(n, Erv);
+       addtotop(n);
        if(n != N && n->type != T)
                if(!eqtype(n->type, types[TBOOL], 0))
                        yyerror("IF and FOR require a boolean type");
@@ -1545,6 +1574,8 @@ loop:
        w = whatis(l);
        switch(w) {
        default:
+               if(l->type == T)
+                       goto out;
                if(!isptr[l->type->etype]) {
                        badtype(n->op, l->type, T);
                        l = listnext(&save);
@@ -1588,6 +1619,7 @@ loop:
        else
                r = list(r, nod(OCALL, on, l));
 
+out:
        l = listnext(&save);
        goto loop;
 }