if(res == N || res->type == T)
fatal("cgen: res nil");
+ while(n->op == OCONVNOP)
+ n = n->left;
+
// static initializations
if(initflag && gen_as_init(n, res))
goto ret;
goto abop;
case OCONV:
- if(eqtype(n->type, nl->type)) {
- cgen(nl, res);
- break;
- }
regalloc(&n1, nl->type, res);
cgen(nl, &n1);
gmove(&n1, res);
// if(!isptr[res->type->etype])
// fatal("agen: not tptr: %T", res->type);
-
+//
+// while(n->op == OCONVNOP)
+// n = n->left;
+//
// if(n->addable) {
// regalloc(&n1, types[tptr], res);
// gins(ALEAQ, n, &n1);
// fatal("agen: unknown op %N", n);
// break;
-// case OCONV:
-// if(!cvttype(n->type, nl->type))
-// fatal("agen: non-trivial OCONV");
-// agen(nl, res);
-// return;
-
// case OCALLMETH:
// cgen_callmeth(n, 0);
// cgen_aret(n, res);
if(res == N || res->type == T)
fatal("cgen: res nil");
+ while(n->op == OCONVNOP)
+ n = n->left;
+
// static initializations
if(initflag && gen_as_init(n, res))
goto ret;
goto abop;
case OCONV:
- if(eqtype(n->type, nl->type)) {
- cgen(nl, res);
- break;
- }
regalloc(&n1, nl->type, res);
regalloc(&n2, n->type, &n1);
cgen(nl, &n1);
if(!isptr[res->type->etype])
fatal("agen: not tptr: %T", res->type);
+ while(n->op == OCONVNOP)
+ n = n->left;
+
if(n->addable) {
regalloc(&n1, types[tptr], res);
gins(ALEAQ, n, &n1);
fatal("agen: unknown op %N", n);
break;
- case OCONV:
- if(!cvttype(n->type, nl->type))
- fatal("agen: non-trivial OCONV");
- agen(nl, res);
- return;
-
case OCALLMETH:
cgen_callmeth(n, 0);
cgen_aret(n, res);
if(res == N || res->type == T)
fatal("cgen: res nil");
+ while(n->op == OCONVNOP)
+ n = n->left;
+
// static initializations
if(initflag && gen_as_init(n, res))
return;
if(n == N || n->type == T || res == N || res->type == T)
fatal("agen");
+ while(n->op == OCONVNOP)
+ n = n->left;
+
// addressable var is easy
if(n->addable) {
if(n->op == OREGISTER)
default:
fatal("agen %O", n->op);
- case OCONV:
- if(!cvttype(n->type, nl->type))
- fatal("agen: non-trivial OCONV");
- agen(nl, res);
- break;
-
case OCALLMETH:
cgen_callmeth(n, 0);
cgen_aret(n, res);
OREGISTER, OINDREG,
OKEY, OPARAM,
OCOMPOS, OCOMPSLICE, OCOMPMAP,
- OCONV,
+ OCONV, OCONVNOP,
ODOTTYPE, OTYPESW,
OBAD,
EXTERN char* package;
EXTERN Biobuf* bout;
EXTERN int nerrors;
+EXTERN int nsyntaxerrors;
EXTERN char namebuf[NSYMB];
EXTERN char lexbuf[NSYMB];
EXTERN char debug[256];
if(debug['f'])
frame(1);
fninit($4);
- testdclstack();
+ if(nsyntaxerrors == 0)
+ testdclstack();
}
package:
int b;
Node *a;
+ while(n->op == OCONVNOP)
+ n = n->left;
+
// call to newarray - find nel argument
nel = findarg(n, "nel", "newarray");
if(nel == N || !isslice(n->type))
va_start(arg, fmt);
vfprint(1, fmt, arg);
va_end(arg);
- if(strcmp(fmt, "syntax error") == 0)
+ if(strcmp(fmt, "syntax error") == 0) {
+ nsyntaxerrors++;
print(" near %s", lexbuf);
+ }
print("\n");
if(debug['h'])
*(int*)0 = 0;
[OCOM] = "COM",
[OCONTINUE] = "CONTINUE",
[OCONV] = "CONV",
+ [OCONVNOP] = "CONVNOP",
[ODCLARG] = "DCLARG",
[ODCLFIELD] = "DCLFIELD",
[ODCLFUNC] = "DCLFUNC",
goto nottop;
walkconv(n);
goto ret;
+
+ case OCONVNOP:
+ goto ret;
case OCOMPMAP:
case OCOMPSLICE:
if(!isinter(l->type))
yyerror("type assertion requires interface on left, have %T", l->type);
et = ifaceas1(t, l->type, 1);
- if(et == I2Isame || et == E2Esame) {
- n->op = OCONV;
+ if(et == I2Isame || et == E2Esame)
goto nop;
- }
if(et != Inone) {
indir(n, ifacecvt(t, l, et));
return;
// no-op conversion
if(cvttype(t, l->type) == 1) {
nop:
- if(l->op != ONAME) {
+ if(l->op == OLITERAL) {
indir(n, l);
- n->type = t;
+ l->type = t;
+ return;
}
+ // leave OCONV node in place
+ // in case tree gets walked again.
+ // back end will ignore.
+ n->op = OCONVNOP;
return;
}
// finish call - first half above
l = listfirst(&savel, &nl);
t = structfirst(&saver, getoutarg(t));
+ if(t == T)
+ return N;
while(l != N) {
a = mixedoldnew(l, t->type);
n = list(n, a);