]> Cypherpunks repositories - gostls13.git/commitdiff
bug 150
authorKen Thompson <ken@golang.org>
Tue, 26 May 2009 22:56:37 +0000 (15:56 -0700)
committerKen Thompson <ken@golang.org>
Tue, 26 May 2009 22:56:37 +0000 (15:56 -0700)
R=r
OCL=29405
CL=29405

src/cmd/gc/go.h
src/cmd/gc/walk.c

index 373b5140b9b35a32fb293855972c2053ed088946..eb253d778d2a6afae5301e2a4c4b114c10c17a0f 100644 (file)
@@ -928,7 +928,6 @@ void        arrayconv(Type*, Node*);
 Node*  colas(Node*, Node*);
 Node*  dorange(Node*);
 Node*  reorder1(Node*);
-Node*  reorder2(Node*);
 Node*  reorder3(Node*);
 Node*  reorder4(Node*);
 Node*  structlit(Node*, Node*);
index 974a7e62d26b0ae6e76c410dea094c26f5112ad2..0323624a8d45dd3ff1de12698953d93704298109 100644 (file)
@@ -473,7 +473,7 @@ loop:
                                        break;
                                l = ascompatet(n->op, &n->left, &r->type, 0);
                                if(l != N)
-                                       indir(n, list(r, reorder2(l)));
+                                       indir(n, list(r, l));
                                goto ret;
                        }
                        break;
@@ -543,7 +543,7 @@ loop:
                                r = ifacecvt(r->type, r->left, et);
                                l = ascompatet(n->op, &n->left, &r->type, 0);
                                if(l != N)
-                                       indir(n, list(r, reorder2(l)));
+                                       indir(n, list(r, l));
                                goto ret;
                        }
                        break;
@@ -1774,12 +1774,29 @@ loop:
        goto loop;
 }
 
+/*
+ * n is an lv and t is the type of an rv
+ * return 1 if this implies a function call
+ * evaluating the lv or a function call
+ * in the conversion of the types
+ */
+int
+fncall(Node *l, Type *rt)
+{
+       if(l->ullman >= UINF)
+               return 1;
+       if(eqtype(l->type, rt))
+               return 0;
+       return 1;
+}
+
 Node*
 ascompatet(int op, Node **nl, Type **nr, int fp)
 {
-       Node *l, *nn, *a;
+       Node *l, *nn, *mm, *tmp, *a;
        Type *r;
        Iter savel, saver;
+       int ucount;
 
        /*
         * check assign type list to
@@ -1789,13 +1806,21 @@ ascompatet(int op, Node **nl, Type **nr, int fp)
        l = listfirst(&savel, nl);
        r = structfirst(&saver, nr);
        nn = N;
+       mm = N;
+       ucount = 0;
 
 loop:
        if(l == N || r == T) {
                if(l != N || r != T)
                        yyerror("assignment count mismatch: %d = %d",
                                listcount(*nl), structcount(*nr));
-
+               if(ucount)
+                       yyerror("reorder2: too many function calls evaluating parameters");
+               if(mm != N) {
+                       mm = rev(mm);
+                       for(l=listfirst(&savel, &mm); l!=N; l=listnext(&savel))
+                               nn = list(nn, l);
+               }
                return rev(nn);
        }
 
@@ -1804,9 +1829,24 @@ loop:
                return N;
        }
 
+       // any lv that causes a fn call must be
+       // deferred until all the return arguments
+       // have been pulled from the output arguments
+       if(fncall(l, r->type)) {
+               tmp = nod(OXXX, N, N);
+               tempname(tmp, r->type);
+               a = nod(OAS, l, tmp);
+               a = convas(a);
+               mm = list(mm, a);
+               l = tmp;
+       }
+
        a = nod(OAS, l, nodarg(r, fp));
        a = convas(a);
-       nn = list(a, nn);
+       ullmancalc(a);
+       if(a->ullman >= UINF)
+               ucount++;
+       nn = list(nn, a);
 
        l = listnext(&savel);
        r = structnext(&saver);
@@ -3828,39 +3868,6 @@ more:
        goto loop2;
 }
 
-/*
- * from ascompat[et]
- *     a,b = f()
- * return of a multi.
- * there can be no function calls at all,
- * or they will over-write the return values.
- */
-Node*
-reorder2(Node *n)
-{
-       Iter save;
-       Node *l;
-       int c;
-
-       l = listfirst(&save, &n);
-       c = 0;
-
-loop1:
-       if(l == N) {
-               if(c > 0)
-                       yyerror("reorder2: too many function calls evaluating parameters");
-               return n;
-       }
-       if(l->op == OLIST)
-               fatal("reorder2 OLIST");
-
-       ullmancalc(l);
-       if(l->ullman >= UINF)
-               c++;
-       l = listnext(&save);
-       goto loop1;
-}
-
 /*
  * from ascompat[ee]
  *     a,b = c,d