From 850cd6a2fe73360d17c5187ce2af1e0115f02e55 Mon Sep 17 00:00:00 2001 From: Ken Thompson Date: Tue, 26 May 2009 15:56:37 -0700 Subject: [PATCH] bug 150 R=r OCL=29405 CL=29405 --- src/cmd/gc/go.h | 1 - src/cmd/gc/walk.c | 83 +++++++++++++++++++++++++---------------------- 2 files changed, 45 insertions(+), 39 deletions(-) diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h index 373b5140b9..eb253d778d 100644 --- a/src/cmd/gc/go.h +++ b/src/cmd/gc/go.h @@ -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*); diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c index 974a7e62d2..0323624a8d 100644 --- a/src/cmd/gc/walk.c +++ b/src/cmd/gc/walk.c @@ -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 -- 2.48.1