diff options
Diffstat (limited to 'src/cmd/gc/dcl.c')
-rw-r--r-- | src/cmd/gc/dcl.c | 41 |
1 files changed, 36 insertions, 5 deletions
diff --git a/src/cmd/gc/dcl.c b/src/cmd/gc/dcl.c index 3089a23b0..99af18d9f 100644 --- a/src/cmd/gc/dcl.c +++ b/src/cmd/gc/dcl.c @@ -560,6 +560,7 @@ funcargs(Node *nt) { Node *n; NodeList *l; + int gen; if(nt->op != OTFUNC) fatal("funcargs %O", nt->op); @@ -589,6 +590,7 @@ funcargs(Node *nt) } // declare the out arguments. + gen = 0; for(l=nt->rlist; l; l=l->next) { n = l->n; if(n->op != ODCLFIELD) @@ -596,6 +598,11 @@ funcargs(Node *nt) if(n->left != N) { n->left->op = ONAME; n->left->ntype = n->right; + if(isblank(n->left)) { + // Give it a name so we can assign to it during return. + snprint(namebuf, sizeof(namebuf), ".anon%d", gen++); + n->left->sym = lookup(namebuf); + } declare(n->left, PPARAMOUT); } } @@ -672,10 +679,10 @@ typedcl2(Type *pt, Type *t) ok: n = pt->nod; - *pt = *t; - pt->method = nil; + copytype(pt->nod, t); + // unzero nod pt->nod = n; - pt->sym = n->sym; + pt->sym->lastlineno = parserline(); declare(n, PEXTERN); @@ -697,12 +704,10 @@ stotype(NodeList *l, int et, Type **t, int funarg) Type *f, *t1, *t2, **t0; Strlit *note; int lno; - NodeList *init; Node *n, *left; char *what; t0 = t; - init = nil; lno = lineno; what = "field"; if(et == TINTER) @@ -1130,6 +1135,32 @@ addmethod(Sym *sf, Type *t, int local) pa = pa->type; f = methtype(pa); if(f == T) { + t = pa; + if(t != T) { + if(isptr[t->etype]) { + if(t->sym != S) { + yyerror("invalid receiver type %T (%T is a pointer type)", pa, t); + return; + } + t = t->type; + } + } + if(t != T) { + if(t->sym == S) { + yyerror("invalid receiver type %T (%T is an unnamed type)", pa, t); + return; + } + if(isptr[t->etype]) { + yyerror("invalid receiver type %T (%T is a pointer type)", pa, t); + return; + } + if(t->etype == TINTER) { + yyerror("invalid receiver type %T (%T is an interface type)", pa, t); + return; + } + } + // Should have picked off all the reasons above, + // but just in case, fall back to generic error. yyerror("invalid receiver type %T", pa); return; } |