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;
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;
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
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);
}
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);
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