summaryrefslogtreecommitdiff
path: root/src/cmd/gc/dcl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/gc/dcl.c')
-rw-r--r--src/cmd/gc/dcl.c41
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;
}