break;
case PAS_SINGLE: // single return val used in expr
- if(nr == N) {
+ if(nr == N || isnil(nr)) {
if(nl->addable) {
gopcodet(PSTOREZ, nl->type, nl);
break;
}
agen(nl);
- gopcodet(PSTOREZIP, nl->type, N);
+ gopcodet(PSTOREZI, nl->type, N);
break;
}
if(nl->addable) {
cgen(nr);
- genconv(nl->type, nr->type);
+ genconv(nl, nr);
gopcodet(PSTORE, nl->type, nl);
break;
}
}
if(!usesptr(nr)) {
cgen(nr);
- genconv(nl->type, nr->type);
+ genconv(nl, nr);
agen(nl);
gopcodet(PSTOREI, nr->type, N);
break;
r = tempname(ptrto(nl->type));
gopcode(PSTORE, PTADDR, r);
cgen(nr);
- genconv(nl->type, nr->type);
+ genconv(nl, nr);
gopcode(PLOAD, PTADDR, r);
gopcodet(PSTOREI, nl->type, N);
break;
gopcodet(PSTOREI, arg->type, arg);
} else {
cgen(arg);
- genconv(f->type, arg->type);
+ genconv(f, arg);
gopcode(PLOAD, PTADDR, a->nname);
gopcode(PADDO, PTADDR, f->nname);
gopcodet(PSTOREI, f->type, N);
gopcodet(PSTOREI, at->type, ae);
} else {
cgen(ae);
- genconv(at->type, ae->type);
+ genconv(at, ae);
gopcode(PADDR, PTADDR, sn);
gopcode(PADDO, PTADDR, at->nname);
gopcodet(PSTOREI, at->type, N);
int
needconvert(Node *tl, Node *tr)
{
- if(isinter(tl))
- if(isptrto(tr, TSTRUCT) || isinter(tr))
+ if(isinter(tl)) {
+ if(isptrto(tr, TSTRUCT))
return 1;
+ if(isinter(tr))
+ return 1;
+ return 0;
+ }
if(isptrto(tl, TSTRUCT))
if(isinter(tr))
return 1;
}
void
-genconv(Node *tl, Node *tr)
+genconv(Node *l, Node *r)
{
+ Node *tl, *tr;
+
+ tl = l->type;
+ tr = r->type;
if(needconvert(tl, tr))
gopcode(PCONV, PTNIL, nod(OCONV, tl, tr));
}
}
break;
+ case PSTOREZI:
+ switch(p->pt) {
+ default:
+ Bprint(bout, "\t*(%Q*)%R = 0;\n", p->pt, PTADDR);
+ break;
+
+ case PTARRAY:
+ case PTSTRUCT:
+ Bprint(bout, "\tmemset((%Q*)%R, 0, sizeof((%Q*)%R));\n", p->pt, PTADDR, p->pt, PTADDR);
+ break;
+
+ case PTINTER:
+ Bprint(bout, "\t((%Q*)%R)->s = 0; ((%Q*)%R)->m = 0;\n", p->pt, PTADDR, p->pt, PTADDR);
+ break;
+
+ case PTSTRING:
+ Bprint(bout, "\t(%Q*)%R = &nilstring;\n", p->pt, PTADDR);
+ break;
+ }
+ break;
+
case PCONV:
doconv(p);
break;