Commit ff3a73b4 authored by Russ Cox's avatar Russ Cox

typechecking checkpoint.

started to move typechecking to another file.
can build entire tree still, but lots of work
is duplicated.  much to clean up.

R=ken
OCL=32536
CL=32543
parent 34b277f0
...@@ -281,7 +281,7 @@ cgen(Node *n, Node *res) ...@@ -281,7 +281,7 @@ cgen(Node *n, Node *res)
cgen_callret(n, res); cgen_callret(n, res);
break; break;
case OCALL: case OCALLFUNC:
cgen_call(n, 0); cgen_call(n, 0);
cgen_callret(n, res); cgen_callret(n, res);
break; break;
...@@ -404,7 +404,7 @@ agen(Node *n, Node *res) ...@@ -404,7 +404,7 @@ agen(Node *n, Node *res)
cgen_aret(n, res); cgen_aret(n, res);
break; break;
case OCALL: case OCALLFUNC:
cgen_call(n, 0); cgen_call(n, 0);
cgen_aret(n, res); cgen_aret(n, res);
break; break;
...@@ -811,7 +811,7 @@ stkof(Node *n) ...@@ -811,7 +811,7 @@ stkof(Node *n)
case OCALLMETH: case OCALLMETH:
case OCALLINTER: case OCALLINTER:
case OCALL: case OCALLFUNC:
t = n->left->type; t = n->left->type;
if(isptr[t->etype]) if(isptr[t->etype])
t = t->type; t = t->type;
......
...@@ -300,7 +300,7 @@ cgen(Node *n, Node *res) ...@@ -300,7 +300,7 @@ cgen(Node *n, Node *res)
cgen_callret(n, res); cgen_callret(n, res);
break; break;
case OCALL: case OCALLFUNC:
cgen_call(n, 0); cgen_call(n, 0);
cgen_callret(n, res); cgen_callret(n, res);
break; break;
...@@ -420,7 +420,7 @@ agen(Node *n, Node *res) ...@@ -420,7 +420,7 @@ agen(Node *n, Node *res)
cgen_aret(n, res); cgen_aret(n, res);
break; break;
case OCALL: case OCALLFUNC:
cgen_call(n, 0); cgen_call(n, 0);
cgen_aret(n, res); cgen_aret(n, res);
break; break;
...@@ -827,7 +827,7 @@ stkof(Node *n) ...@@ -827,7 +827,7 @@ stkof(Node *n)
case OCALLMETH: case OCALLMETH:
case OCALLINTER: case OCALLINTER:
case OCALL: case OCALLFUNC:
t = n->left->type; t = n->left->type;
if(isptr[t->etype]) if(isptr[t->etype])
t = t->type; t = t->type;
......
...@@ -306,7 +306,7 @@ cgen(Node *n, Node *res) ...@@ -306,7 +306,7 @@ cgen(Node *n, Node *res)
cgen_callret(n, res); cgen_callret(n, res);
break; break;
case OCALL: case OCALLFUNC:
cgen_call(n, 0); cgen_call(n, 0);
cgen_callret(n, res); cgen_callret(n, res);
break; break;
...@@ -447,7 +447,7 @@ agen(Node *n, Node *res) ...@@ -447,7 +447,7 @@ agen(Node *n, Node *res)
cgen_aret(n, res); cgen_aret(n, res);
break; break;
case OCALL: case OCALLFUNC:
cgen_call(n, 0); cgen_call(n, 0);
cgen_aret(n, res); cgen_aret(n, res);
break; break;
...@@ -922,7 +922,7 @@ stkof(Node *n) ...@@ -922,7 +922,7 @@ stkof(Node *n)
case OCALLMETH: case OCALLMETH:
case OCALLINTER: case OCALLINTER:
case OCALL: case OCALLFUNC:
t = n->left->type; t = n->left->type;
if(isptr[t->etype]) if(isptr[t->etype])
t = t->type; t = t->type;
......
...@@ -35,6 +35,7 @@ OFILES=\ ...@@ -35,6 +35,7 @@ OFILES=\
gen.$O\ gen.$O\
obj.$O\ obj.$O\
print.$O\ print.$O\
typecheck.$O\
$(LIB): $(OFILES) $(LIB): $(OFILES)
ar rsc $(LIB) $(OFILES) ar rsc $(LIB) $(OFILES)
......
...@@ -339,6 +339,14 @@ typeinit(void) ...@@ -339,6 +339,14 @@ typeinit(void)
okfor[OCAP] = okforcap; okfor[OCAP] = okforcap;
okfor[OLEN] = okforlen; okfor[OLEN] = okforlen;
// comparison
iscmp[OLT] = 1;
iscmp[OGT] = 1;
iscmp[OGE] = 1;
iscmp[OLE] = 1;
iscmp[OEQ] = 1;
iscmp[ONE] = 1;
mpatofix(maxintval[TINT8], "0x7f"); mpatofix(maxintval[TINT8], "0x7f");
mpatofix(minintval[TINT8], "-0x80"); mpatofix(minintval[TINT8], "-0x80");
mpatofix(maxintval[TINT16], "0x7fff"); mpatofix(maxintval[TINT16], "0x7fff");
......
...@@ -89,12 +89,17 @@ convlit1(Node **np, Type *t, int explicit) ...@@ -89,12 +89,17 @@ convlit1(Node **np, Type *t, int explicit)
switch(n->op) { switch(n->op) {
default: default:
if(n->type->etype == TIDEAL) {
convlit(&n->left, t);
convlit(&n->right, t);
n->type = t;
}
return; return;
case OLITERAL: case OLITERAL:
break; break;
case OLSH: case OLSH:
case ORSH: case ORSH:
convlit1(&n->left, t, explicit); convlit(&n->left, t);
n->type = n->left->type; n->type = n->left->type;
return; return;
} }
...@@ -259,11 +264,15 @@ overflow(Val v, Type *t) ...@@ -259,11 +264,15 @@ overflow(Val v, Type *t)
return; return;
switch(v.ctype) { switch(v.ctype) {
case CTINT: case CTINT:
if(!isint[t->etype])
fatal("overflow: %T integer constant", t);
if(mpcmpfixfix(v.u.xval, minintval[t->etype]) < 0 if(mpcmpfixfix(v.u.xval, minintval[t->etype]) < 0
|| mpcmpfixfix(v.u.xval, maxintval[t->etype]) > 0) || mpcmpfixfix(v.u.xval, maxintval[t->etype]) > 0)
yyerror("constant %B overflows %T", v.u.xval, t); yyerror("constant %B overflows %T", v.u.xval, t);
break; break;
case CTFLT: case CTFLT:
if(!isfloat[t->etype])
fatal("overflow: %T floating-point constant", t);
if(mpcmpfltflt(v.u.fval, minfltval[t->etype]) < 0 if(mpcmpfltflt(v.u.fval, minfltval[t->etype]) < 0
|| mpcmpfltflt(v.u.fval, maxfltval[t->etype]) > 0) || mpcmpfltflt(v.u.fval, maxfltval[t->etype]) > 0)
yyerror("constant %#F overflows %T", v.u.fval, t); yyerror("constant %#F overflows %T", v.u.fval, t);
...@@ -325,6 +334,11 @@ evconst(Node *n) ...@@ -325,6 +334,11 @@ evconst(Node *n)
Val v; Val v;
Mpint b; Mpint b;
switch(n->op) {
case OMAKE:
return;
}
nl = n->left; nl = n->left;
if(nl == N || nl->type == T) if(nl == N || nl->type == T)
return; return;
...@@ -590,6 +604,7 @@ unary: ...@@ -590,6 +604,7 @@ unary:
case TUP(OCONV, CTINT): case TUP(OCONV, CTINT):
case TUP(OCONV, CTFLT): case TUP(OCONV, CTFLT):
case TUP(OCONV, CTSTR): case TUP(OCONV, CTSTR):
case TUP(OCONV, CTNIL):
convlit1(&nl, n->type, 1); convlit1(&nl, n->type, 1);
break; break;
...@@ -711,6 +726,11 @@ defaultlit(Node **np, Type *t) ...@@ -711,6 +726,11 @@ defaultlit(Node **np, Type *t)
defaultlit(&n->left, t); defaultlit(&n->left, t);
n->type = n->left->type; n->type = n->left->type;
return; return;
default:
defaultlit(&n->left, t);
defaultlit(&n->right, t);
n->type = n->left->type;
return;
} }
lno = lineno; lno = lineno;
...@@ -753,7 +773,7 @@ defaultlit(Node **np, Type *t) ...@@ -753,7 +773,7 @@ defaultlit(Node **np, Type *t)
* get the same type going out. * get the same type going out.
*/ */
void void
defaultlit2(Node **lp, Node **rp) defaultlit2(Node **lp, Node **rp, int force)
{ {
Node *l, *r; Node *l, *r;
...@@ -769,6 +789,8 @@ defaultlit2(Node **lp, Node **rp) ...@@ -769,6 +789,8 @@ defaultlit2(Node **lp, Node **rp)
convlit(lp, r->type); convlit(lp, r->type);
return; return;
} }
if(!force)
return;
if(isconst(l, CTFLT) || isconst(r, CTFLT)) { if(isconst(l, CTFLT) || isconst(r, CTFLT)) {
convlit(lp, types[TFLOAT]); convlit(lp, types[TFLOAT]);
convlit(rp, types[TFLOAT]); convlit(rp, types[TFLOAT]);
......
...@@ -528,7 +528,7 @@ funclit0(Node *t) ...@@ -528,7 +528,7 @@ funclit0(Node *t)
autodcl = dcl(); autodcl = dcl();
autodcl->back = autodcl; autodcl->back = autodcl;
walkexpr(&t, Etype, &t->ninit); typecheck(&t, Etype);
funcargs(t->type); funcargs(t->type);
return t; return t;
} }
...@@ -703,7 +703,7 @@ stotype(NodeList *l, int et, Type **t) ...@@ -703,7 +703,7 @@ stotype(NodeList *l, int et, Type **t)
if(n->op != ODCLFIELD) if(n->op != ODCLFIELD)
fatal("stotype: oops %N\n", n); fatal("stotype: oops %N\n", n);
if(n->right != N) { if(n->right != N) {
walkexpr(&n->right, Etype, &init); typecheck(&n->right, Etype);
n->type = n->right->type; n->type = n->right->type;
n->right = N; n->right = N;
if(n->embedded && n->type != T) { if(n->embedded && n->type != T) {
...@@ -1298,7 +1298,7 @@ xanondcl(Node *nt) ...@@ -1298,7 +1298,7 @@ xanondcl(Node *nt)
Node *n; Node *n;
Type *t; Type *t;
walkexpr(&nt, Etype, &nt->ninit); typecheck(&nt, Etype);
t = nt->type; t = nt->type;
if(nt->op != OTYPE) { if(nt->op != OTYPE) {
yyerror("%S is not a type", nt->sym); yyerror("%S is not a type", nt->sym);
...@@ -1318,7 +1318,7 @@ namedcl(Node *nn, Node *nt) ...@@ -1318,7 +1318,7 @@ namedcl(Node *nn, Node *nt)
if(nn->op == OKEY) if(nn->op == OKEY)
nn = nn->left; nn = nn->left;
if(nn->sym == S) { if(nn->sym == S) {
walkexpr(&nn, Etype, &nn->ninit); typecheck(&nn, Etype);
yyerror("cannot mix anonymous %T with named arguments", nn->type); yyerror("cannot mix anonymous %T with named arguments", nn->type);
return xanondcl(nn); return xanondcl(nn);
} }
...@@ -1326,7 +1326,7 @@ namedcl(Node *nn, Node *nt) ...@@ -1326,7 +1326,7 @@ namedcl(Node *nn, Node *nt)
if(nt == N) if(nt == N)
yyerror("missing type for argument %S", nn->sym); yyerror("missing type for argument %S", nn->sym);
else { else {
walkexpr(&nt, Etype, &nt->ninit); typecheck(&nt, Etype);
if(nt->op != OTYPE) if(nt->op != OTYPE)
yyerror("%S is not a type", nt->sym); yyerror("%S is not a type", nt->sym);
else else
...@@ -1650,7 +1650,7 @@ variter(NodeList *vl, Node *nt, NodeList *el) ...@@ -1650,7 +1650,7 @@ variter(NodeList *vl, Node *nt, NodeList *el)
t = T; t = T;
if(nt) { if(nt) {
walkexpr(&nt, Etype, &nt->ninit); typecheck(&nt, Etype);
t = nt->type; t = nt->type;
} }
...@@ -1763,7 +1763,7 @@ unsafenmagic(Node *fn, NodeList *args) ...@@ -1763,7 +1763,7 @@ unsafenmagic(Node *fn, NodeList *args)
n = nod(OLITERAL, N, N); n = nod(OLITERAL, N, N);
if(strcmp(s->name, "Sizeof") == 0) { if(strcmp(s->name, "Sizeof") == 0) {
walkexpr(&r, Erv, &n->ninit); typecheck(&r, Erv);
tr = r->type; tr = r->type;
if(r->op == OLITERAL && r->val.ctype == CTSTR) if(r->op == OLITERAL && r->val.ctype == CTSTR)
tr = types[TSTRING]; tr = types[TSTRING];
...@@ -1775,12 +1775,12 @@ unsafenmagic(Node *fn, NodeList *args) ...@@ -1775,12 +1775,12 @@ unsafenmagic(Node *fn, NodeList *args)
if(strcmp(s->name, "Offsetof") == 0) { if(strcmp(s->name, "Offsetof") == 0) {
if(r->op != ODOT && r->op != ODOTPTR) if(r->op != ODOT && r->op != ODOTPTR)
goto no; goto no;
walkexpr(&r, Erv, &n->ninit); typecheck(&r, Erv);
v = r->xoffset; v = r->xoffset;
goto yes; goto yes;
} }
if(strcmp(s->name, "Alignof") == 0) { if(strcmp(s->name, "Alignof") == 0) {
walkexpr(&r, Erv, &n->ninit); typecheck(&r, Erv);
tr = r->type; tr = r->type;
if(r->op == OLITERAL && r->val.ctype == CTSTR) if(r->op == OLITERAL && r->val.ctype == CTSTR)
tr = types[TSTRING]; tr = types[TSTRING];
......
...@@ -321,7 +321,7 @@ gen(Node *n) ...@@ -321,7 +321,7 @@ gen(Node *n)
cgen_callinter(n, N, 0); cgen_callinter(n, N, 0);
break; break;
case OCALL: case OCALLFUNC:
cgen_call(n, 0); cgen_call(n, 0);
break; break;
...@@ -360,7 +360,7 @@ cgen_callmeth(Node *n, int proc) ...@@ -360,7 +360,7 @@ cgen_callmeth(Node *n, int proc)
if(l->op != ODOTMETH) if(l->op != ODOTMETH)
fatal("cgen_callmeth: not dotmethod: %N"); fatal("cgen_callmeth: not dotmethod: %N");
n->op = OCALL; n->op = OCALLFUNC;
n->left = n->left->right; n->left = n->left->right;
n->left->type = l->type; n->left->type = l->type;
...@@ -387,7 +387,7 @@ cgen_proc(Node *n, int proc) ...@@ -387,7 +387,7 @@ cgen_proc(Node *n, int proc)
cgen_callinter(n->left, N, proc); cgen_callinter(n->left, N, proc);
break; break;
case OCALL: case OCALLFUNC:
cgen_call(n->left, proc); cgen_call(n->left, proc);
break; break;
} }
......
...@@ -343,14 +343,15 @@ enum ...@@ -343,14 +343,15 @@ enum
OCONTINUE, OCONTINUE,
OADDR, OADDR,
OIND, OIND,
OCALL, OCALLMETH, OCALLINTER, OCALL, OCALLFUNC, OCALLMETH, OCALLINTER,
OINDEX, OSLICE, OINDEX, OSLICE,
ONOT, OCOM, OPLUS, OMINUS, OSEND, ORECV, ONOT, OCOM, OPLUS, OMINUS, OSEND, ORECV,
OREGISTER, OINDREG, OREGISTER, OINDREG,
OKEY, OPARAM, OKEY, OPARAM,
OCOMPOS, OCOMPSLICE, OCOMPMAP, OCOMPOS, OCOMPSLICE, OCOMPMAP,
OCONV, OCONVNOP, OCONV, OCONVNOP, OCONVRUNE, OCONVSTRB, OCONVSTRI,
ODOTTYPE, OTYPESW, OCONVA2S,
ODOTTYPE, OTYPESW, OTYPECASE,
OBAD, OBAD,
OTCHAN, OTMAP, OTSTRUCT, OTINTER, OTFUNC, OTARRAY, OTCHAN, OTMAP, OTSTRUCT, OTINTER, OTFUNC, OTARRAY,
...@@ -440,7 +441,7 @@ enum ...@@ -440,7 +441,7 @@ enum
Elv = 1<<2, // evaluated in lvalue context Elv = 1<<2, // evaluated in lvalue context
Erv = 1<<3, // evaluated in rvalue context Erv = 1<<3, // evaluated in rvalue context
Etype = 1<<4, Etype = 1<<4,
Eideal = 1<<5, Ecall = 1<<5,
}; };
#define BITS 5 #define BITS 5
...@@ -593,6 +594,7 @@ EXTERN uchar okforcap[NTYPE]; ...@@ -593,6 +594,7 @@ EXTERN uchar okforcap[NTYPE];
EXTERN uchar okforlen[NTYPE]; EXTERN uchar okforlen[NTYPE];
EXTERN uchar okforarith[NTYPE]; EXTERN uchar okforarith[NTYPE];
EXTERN uchar* okfor[OEND]; EXTERN uchar* okfor[OEND];
EXTERN uchar iscmp[OEND];
EXTERN Mpint* minintval[NTYPE]; EXTERN Mpint* minintval[NTYPE];
EXTERN Mpint* maxintval[NTYPE]; EXTERN Mpint* maxintval[NTYPE];
...@@ -830,7 +832,6 @@ int Wconv(Fmt*); ...@@ -830,7 +832,6 @@ int Wconv(Fmt*);
int Zconv(Fmt*); int Zconv(Fmt*);
int lookdot0(Sym*, Type*, Type**); int lookdot0(Sym*, Type*, Type**);
Type* lookdot1(Sym*, Type*, Type*);
int adddot1(Sym*, Type*, int, Type**); int adddot1(Sym*, Type*, int, Type**);
Node* adddot(Node*); Node* adddot(Node*);
void expandmeth(Sym*, Type*); void expandmeth(Sym*, Type*);
...@@ -846,7 +847,7 @@ Type* dodcltype(Type*); ...@@ -846,7 +847,7 @@ Type* dodcltype(Type*);
void updatetype(Type*, Type*); void updatetype(Type*, Type*);
void dodclconst(Node*, Node*); void dodclconst(Node*, Node*);
void defaultlit(Node**, Type*); void defaultlit(Node**, Type*);
void defaultlit2(Node**, Node**); void defaultlit2(Node**, Node**, int);
int structcount(Type*); int structcount(Type*);
void addmethod(Node*, Type*, int); void addmethod(Node*, Type*, int);
Node* methodname(Node*, Type*); Node* methodname(Node*, Type*);
......
...@@ -400,7 +400,7 @@ typedclname: ...@@ -400,7 +400,7 @@ typedclname:
typedcl: typedcl:
typedclname ntype typedclname ntype
{ {
walkexpr(&$2, Etype, &$2->ninit); typecheck(&$2, Etype);
updatetype($1, $2->type); updatetype($1, $2->type);
resumecheckwidth(); resumecheckwidth();
} }
...@@ -478,21 +478,21 @@ case: ...@@ -478,21 +478,21 @@ case:
yyerror("type switch case cannot be list"); yyerror("type switch case cannot be list");
if(n->op == OLITERAL && n->val.ctype == CTNIL) { if(n->op == OLITERAL && n->val.ctype == CTNIL) {
// case nil // case nil
$$->list = list1(nod(OTYPESW, N, N)); $$->list = list1(nod(OTYPECASE, N, N));
break; break;
} }
// TODO: move // TODO: move
e = nerrors; e = nerrors;
walkexpr(&n, Etype | Erv, &$$->ninit); typecheck(&n, Etype | Erv);
if(n->op == OTYPE) { if(n->op == OTYPE) {
n = old2new(typeswvar->right, n->type, &$$->ninit); n = old2new(typeswvar->right, n->type, &$$->ninit);
$$->list = list1(nod(OTYPESW, n, N)); $$->list = list1(nod(OTYPECASE, n, N));
break; break;
} }
// maybe walkexpr found problems that keep // maybe typecheck found problems that keep
// e from being valid even outside a type switch. // e from being valid even outside a type switch.
// only complain if walkexpr didn't print new errors. // only complain if typecheck didn't print new errors.
if(nerrors == e) if(nerrors == e)
yyerror("non-type case in type switch"); yyerror("non-type case in type switch");
$$->diag = 1; $$->diag = 1;
...@@ -518,6 +518,7 @@ case: ...@@ -518,6 +518,7 @@ case:
// done in casebody() // done in casebody()
poptodcl(); poptodcl();
$$ = nod(OXCASE, N, N); $$ = nod(OXCASE, N, N);
typecheck(&$4, Erv);
$$->list = list1(nod(OAS, selectas($2, $4, &$$->ninit), $4)); $$->list = list1(nod(OAS, selectas($2, $4, &$$->ninit), $4));
} }
| LDEFAULT ':' | LDEFAULT ':'
...@@ -1143,7 +1144,7 @@ fndcl: ...@@ -1143,7 +1144,7 @@ fndcl:
n = nod(OTFUNC, N, N); n = nod(OTFUNC, N, N);
n->list = $3; n->list = $3;
n->rlist = $5; n->rlist = $5;
walkexpr(&n, Etype, &n->ninit); typecheck(&n, Etype);
$$->type = n->type; $$->type = n->type;
funchdr($$); funchdr($$);
} }
......
...@@ -24,7 +24,7 @@ void ...@@ -24,7 +24,7 @@ void
exprfmt(Fmt *f, Node *n, int prec) exprfmt(Fmt *f, Node *n, int prec)
{ {
int nprec; int nprec;
nprec = 0; nprec = 0;
if(n == nil) { if(n == nil) {
fmtprint(f, "<nil>"); fmtprint(f, "<nil>");
...@@ -38,7 +38,7 @@ exprfmt(Fmt *f, Node *n, int prec) ...@@ -38,7 +38,7 @@ exprfmt(Fmt *f, Node *n, int prec)
case OLITERAL: case OLITERAL:
nprec = 7; nprec = 7;
break; break;
case OMUL: case OMUL:
case ODIV: case ODIV:
case OMOD: case OMOD:
...@@ -48,14 +48,14 @@ exprfmt(Fmt *f, Node *n, int prec) ...@@ -48,14 +48,14 @@ exprfmt(Fmt *f, Node *n, int prec)
case OANDNOT: case OANDNOT:
nprec = 6; nprec = 6;
break; break;
case OADD: case OADD:
case OSUB: case OSUB:
case OOR: case OOR:
case OXOR: case OXOR:
nprec = 5; nprec = 5;
break; break;
case OEQ: case OEQ:
case OLT: case OLT:
case OLE: case OLE:
...@@ -64,15 +64,15 @@ exprfmt(Fmt *f, Node *n, int prec) ...@@ -64,15 +64,15 @@ exprfmt(Fmt *f, Node *n, int prec)
case ONE: case ONE:
nprec = 4; nprec = 4;
break; break;
case OSEND: case OSEND:
nprec = 3; nprec = 3;
break; break;
case OANDAND: case OANDAND:
nprec = 2; nprec = 2;
break; break;
case OOROR: case OOROR:
nprec = 1; nprec = 1;
break; break;
...@@ -117,7 +117,7 @@ exprfmt(Fmt *f, Node *n, int prec) ...@@ -117,7 +117,7 @@ exprfmt(Fmt *f, Node *n, int prec)
case ONONAME: case ONONAME:
fmtprint(f, "%S", n->sym); fmtprint(f, "%S", n->sym);
break; break;
case OTYPE: case OTYPE:
fmtprint(f, "%T", n->type); fmtprint(f, "%T", n->type);
break; break;
...@@ -126,7 +126,7 @@ exprfmt(Fmt *f, Node *n, int prec) ...@@ -126,7 +126,7 @@ exprfmt(Fmt *f, Node *n, int prec)
fmtprint(f, "[]"); fmtprint(f, "[]");
exprfmt(f, n->left, PFIXME); exprfmt(f, n->left, PFIXME);
break; break;
case OTMAP: case OTMAP:
fmtprint(f, "map["); fmtprint(f, "map[");
exprfmt(f, n->left, 0); exprfmt(f, n->left, 0);
...@@ -146,19 +146,31 @@ exprfmt(Fmt *f, Node *n, int prec) ...@@ -146,19 +146,31 @@ exprfmt(Fmt *f, Node *n, int prec)
exprfmt(f, n->left, PCHAN); exprfmt(f, n->left, PCHAN);
} }
break; break;
case OTSTRUCT: case OTSTRUCT:
fmtprint(f, "<struct>"); fmtprint(f, "<struct>");
break; break;
case OTINTER: case OTINTER:
fmtprint(f, "<inter>"); fmtprint(f, "<inter>");
break; break;
case OTFUNC: case OTFUNC:
fmtprint(f, "<func>"); fmtprint(f, "<func>");
break; break;
case OAS:
exprfmt(f, n->left, 0);
fmtprint(f, " = ");
exprfmt(f, n->right, 0);
break;
case OASOP:
exprfmt(f, n->left, 0);
fmtprint(f, " %#O= ", n->etype);
exprfmt(f, n->right, 0);
break;
case OADD: case OADD:
case OANDAND: case OANDAND:
case OANDNOT: case OANDNOT:
...@@ -182,7 +194,7 @@ exprfmt(Fmt *f, Node *n, int prec) ...@@ -182,7 +194,7 @@ exprfmt(Fmt *f, Node *n, int prec)
fmtprint(f, " %#O ", n->op); fmtprint(f, " %#O ", n->op);
exprfmt(f, n->right, nprec+1); exprfmt(f, n->right, nprec+1);
break; break;
case OADDR: case OADDR:
case OCOM: case OCOM:
case OIND: case OIND:
...@@ -195,35 +207,35 @@ exprfmt(Fmt *f, Node *n, int prec) ...@@ -195,35 +207,35 @@ exprfmt(Fmt *f, Node *n, int prec)
fmtprint(f, " "); fmtprint(f, " ");
exprfmt(f, n->left, 0); exprfmt(f, n->left, 0);
break; break;
case OCOMPOS: case OCOMPOS:
fmtprint(f, "<compos>"); fmtprint(f, "<compos>");
break; break;
case ODOT: case ODOT:
case ODOTINTER: case ODOTINTER:
case ODOTMETH: case ODOTMETH:
exprfmt(f, n->left, 7); exprfmt(f, n->left, 7);
if(n->sym == S) if(n->right == N || n->right->sym == S)
fmtprint(f, ".<nil>"); fmtprint(f, ".<nil>");
else else
fmtprint(f, ".%s", n->sym->name); fmtprint(f, ".%s", n->right->sym->name);
break; break;
case ODOTTYPE: case ODOTTYPE:
exprfmt(f, n->left, 7); exprfmt(f, n->left, 7);
fmtprint(f, ".("); fmtprint(f, ".(");
exprfmt(f, n->right, 0); exprfmt(f, n->right, 0);
fmtprint(f, ")"); fmtprint(f, ")");
break; break;
case OINDEX: case OINDEX:
exprfmt(f, n->left, 7); exprfmt(f, n->left, 7);
fmtprint(f, "["); fmtprint(f, "[");
exprfmt(f, n->right, 0); exprfmt(f, n->right, 0);
fmtprint(f, "]"); fmtprint(f, "]");
break; break;
case OSLICE: case OSLICE:
exprfmt(f, n->left, 7); exprfmt(f, n->left, 7);
fmtprint(f, "["); fmtprint(f, "[");
...@@ -232,8 +244,9 @@ exprfmt(Fmt *f, Node *n, int prec) ...@@ -232,8 +244,9 @@ exprfmt(Fmt *f, Node *n, int prec)
exprfmt(f, n->right->right, 0); exprfmt(f, n->right->right, 0);
fmtprint(f, "]"); fmtprint(f, "]");
break; break;
case OCALL: case OCALL:
case OCALLFUNC:
case OCALLINTER: case OCALLINTER:
case OCALLMETH: case OCALLMETH:
exprfmt(f, n->left, 7); exprfmt(f, n->left, 7);
...@@ -241,13 +254,13 @@ exprfmt(Fmt *f, Node *n, int prec) ...@@ -241,13 +254,13 @@ exprfmt(Fmt *f, Node *n, int prec)
exprlistfmt(f, n->list); exprlistfmt(f, n->list);
fmtprint(f, ")"); fmtprint(f, ")");
break; break;
case OCONV: case OCONV:
fmtprint(f, "%T(", n->type); fmtprint(f, "%T(", n->type);
exprfmt(f, n->left, 0); exprfmt(f, n->left, 0);
fmtprint(f, ")"); fmtprint(f, ")");
break; break;
case OCAP: case OCAP:
case OCLOSE: case OCLOSE:
case OCLOSED: case OCLOSED:
......
...@@ -461,7 +461,7 @@ aindex(Node *b, Type *t) ...@@ -461,7 +461,7 @@ aindex(Node *b, Type *t)
bound = -1; // open bound bound = -1; // open bound
init = nil; init = nil;
walkexpr(&b, Erv, &init); typecheck(&b, Erv);
if(b != nil) { if(b != nil) {
switch(consttype(b)) { switch(consttype(b)) {
default: default:
...@@ -638,6 +638,7 @@ opnames[] = ...@@ -638,6 +638,7 @@ opnames[] =
[OBAD] = "BAD", [OBAD] = "BAD",
[OBLOCK] = "BLOCK", [OBLOCK] = "BLOCK",
[OBREAK] = "BREAK", [OBREAK] = "BREAK",
[OCALLFUNC] = "CALLFUNC",
[OCALLINTER] = "CALLINTER", [OCALLINTER] = "CALLINTER",
[OCALLMETH] = "CALLMETH", [OCALLMETH] = "CALLMETH",
[OCALL] = "CALL", [OCALL] = "CALL",
...@@ -2100,6 +2101,7 @@ ullmancalc(Node *n) ...@@ -2100,6 +2101,7 @@ ullmancalc(Node *n)
ul++; ul++;
goto out; goto out;
case OCALL: case OCALL:
case OCALLFUNC:
case OCALLMETH: case OCALLMETH:
case OCALLINTER: case OCALLINTER:
ul = UINF; ul = UINF;
...@@ -2389,6 +2391,7 @@ saferef(Node *n, NodeList **init) ...@@ -2389,6 +2391,7 @@ saferef(Node *n, NodeList **init)
r = nod(OXXX, N, N); r = nod(OXXX, N, N);
*r = *n; *r = *n;
r->left = l; r->left = l;
typecheck(&r, Elv);
walkexpr(&r, Elv, init); walkexpr(&r, Elv, init);
return r; return r;
...@@ -2398,9 +2401,11 @@ saferef(Node *n, NodeList **init) ...@@ -2398,9 +2401,11 @@ saferef(Node *n, NodeList **init)
l = nod(OXXX, N, N); l = nod(OXXX, N, N);
tempname(l, ptrto(n->type)); tempname(l, ptrto(n->type));
a = nod(OAS, l, nod(OADDR, n, N)); a = nod(OAS, l, nod(OADDR, n, N));
typecheck(&a, Etop);
walkexpr(&a, Etop, init); walkexpr(&a, Etop, init);
*init = list(*init, a); *init = list(*init, a);
r = nod(OIND, l, N); r = nod(OIND, l, N);
typecheck(&r, Elv);
walkexpr(&r, Elv, init); walkexpr(&r, Elv, init);
return r; return r;
} }
...@@ -2555,13 +2560,11 @@ out: ...@@ -2555,13 +2560,11 @@ out:
Node* Node*
adddot(Node *n) adddot(Node *n)
{ {
NodeList *init;
Type *t; Type *t;
Sym *s; Sym *s;
int c, d; int c, d;
init = nil; typecheck(&n->left, Erv);
walkexpr(&n->left, Erv, &init);
t = n->left->type; t = n->left->type;
if(t == T) if(t == T)
goto ret; goto ret;
...@@ -2589,7 +2592,6 @@ out: ...@@ -2589,7 +2592,6 @@ out:
n->left->right = newname(dotlist[c].field->sym); n->left->right = newname(dotlist[c].field->sym);
} }
ret: ret:
n->ninit = concat(init, n->ninit);
return n; return n;
} }
......
...@@ -247,14 +247,15 @@ sw0(Node **cp, Type *place, int arg) ...@@ -247,14 +247,15 @@ sw0(Node **cp, Type *place, int arg)
switch(c->op) { switch(c->op) {
default: default:
if(arg == Stype) { if(arg == Stype) {
yyerror("inappropriate case for a type switch"); yyerror("expression case in a type switch");
return T; return T;
} }
walkexpr(cp, Erv, nil); walkexpr(cp, Erv, nil);
break; break;
case OTYPESW: case OTYPESW:
case OTYPECASE:
if(arg != Stype) if(arg != Stype)
yyerror("inappropriate type case"); yyerror("type case in an expression switch");
break; break;
case OAS: case OAS:
yyerror("inappropriate assignment in a case statement"); yyerror("inappropriate assignment in a case statement");
...@@ -542,12 +543,14 @@ exprbsw(Case *c0, int ncase, int arg) ...@@ -542,12 +543,14 @@ exprbsw(Case *c0, int ncase, int arg)
case Sfalse: case Sfalse:
a = nod(OIF, N, N); a = nod(OIF, N, N);
a->ntest = nod(ONOT, n->left, N); // if !val a->ntest = nod(ONOT, n->left, N); // if !val
typecheck(&a->ntest, Erv);
a->nbody = list1(n->right); // then goto l a->nbody = list1(n->right); // then goto l
break; break;
default: default:
a = nod(OIF, N, N); a = nod(OIF, N, N);
a->ntest = nod(OEQ, exprname, n->left); // if name == val a->ntest = nod(OEQ, exprname, n->left); // if name == val
typecheck(&a->ntest, Erv);
a->nbody = list1(n->right); // then goto l a->nbody = list1(n->right); // then goto l
break; break;
} }
...@@ -566,6 +569,7 @@ exprbsw(Case *c0, int ncase, int arg) ...@@ -566,6 +569,7 @@ exprbsw(Case *c0, int ncase, int arg)
c = c->link; c = c->link;
a = nod(OIF, N, N); a = nod(OIF, N, N);
a->ntest = nod(OLE, exprname, c->node->left); a->ntest = nod(OLE, exprname, c->node->left);
typecheck(&a->ntest, Erv);
a->nbody = list1(exprbsw(c0, half, arg)); a->nbody = list1(exprbsw(c0, half, arg));
a->nelse = list1(exprbsw(c->link, ncase-half, arg)); a->nelse = list1(exprbsw(c->link, ncase-half, arg));
return a; return a;
...@@ -619,6 +623,7 @@ exprswitch(Node *sw) ...@@ -619,6 +623,7 @@ exprswitch(Node *sw)
exprname = nod(OXXX, N, N); exprname = nod(OXXX, N, N);
tempname(exprname, sw->ntest->type); tempname(exprname, sw->ntest->type);
cas = list1(nod(OAS, exprname, sw->ntest)); cas = list1(nod(OAS, exprname, sw->ntest));
typechecklist(cas, Etop);
} }
c0 = mkcaselist(sw, arg); c0 = mkcaselist(sw, arg);
...@@ -686,6 +691,7 @@ typeone(Node *t) ...@@ -686,6 +691,7 @@ typeone(Node *t)
b = nod(ODOTTYPE, facename, N); b = nod(ODOTTYPE, facename, N);
b->type = t->left->left->type; // interface.(type) b->type = t->left->left->type; // interface.(type)
a->rlist = list1(b); a->rlist = list1(b);
typecheck(&a, Etop);
init = list(init, a); init = list(init, a);
b = nod(OIF, N, N); b = nod(OIF, N, N);
...@@ -716,6 +722,7 @@ typebsw(Case *c0, int ncase) ...@@ -716,6 +722,7 @@ typebsw(Case *c0, int ncase)
v.ctype = CTNIL; v.ctype = CTNIL;
a = nod(OIF, N, N); a = nod(OIF, N, N);
a->ntest = nod(OEQ, facename, nodlit(v)); a->ntest = nod(OEQ, facename, nodlit(v));
typecheck(&a->ntest, Erv);
a->nbody = list1(n->right); // if i==nil { goto l } a->nbody = list1(n->right); // if i==nil { goto l }
cas = list(cas, a); cas = list(cas, a);
break; break;
...@@ -728,6 +735,7 @@ typebsw(Case *c0, int ncase) ...@@ -728,6 +735,7 @@ typebsw(Case *c0, int ncase)
case Ttypeconst: case Ttypeconst:
a = nod(OIF, N, N); a = nod(OIF, N, N);
a->ntest = nod(OEQ, hashname, nodintconst(c0->hash)); a->ntest = nod(OEQ, hashname, nodintconst(c0->hash));
typecheck(&a->ntest, Erv);
a->nbody = list1(typeone(n)); a->nbody = list1(typeone(n));
cas = list(cas, a); cas = list(cas, a);
break; break;
...@@ -744,6 +752,7 @@ typebsw(Case *c0, int ncase) ...@@ -744,6 +752,7 @@ typebsw(Case *c0, int ncase)
c = c->link; c = c->link;
a = nod(OIF, N, N); a = nod(OIF, N, N);
a->ntest = nod(OLE, hashname, nodintconst(c->hash)); a->ntest = nod(OLE, hashname, nodintconst(c->hash));
typecheck(&a->ntest, Erv);
a->nbody = list1(typebsw(c0, half)); a->nbody = list1(typebsw(c0, half));
a->nelse = list1(typebsw(c->link, ncase-half)); a->nelse = list1(typebsw(c->link, ncase-half));
return a; return a;
...@@ -786,13 +795,16 @@ typeswitch(Node *sw) ...@@ -786,13 +795,16 @@ typeswitch(Node *sw)
facename = nod(OXXX, N, N); facename = nod(OXXX, N, N);
tempname(facename, sw->ntest->right->type); tempname(facename, sw->ntest->right->type);
a = nod(OAS, facename, sw->ntest->right); a = nod(OAS, facename, sw->ntest->right);
typecheck(&a, Etop);
cas = list(cas, a); cas = list(cas, a);
boolname = nod(OXXX, N, N); boolname = nod(OXXX, N, N);
tempname(boolname, types[TBOOL]); tempname(boolname, types[TBOOL]);
typecheck(&boolname, Erv);
hashname = nod(OXXX, N, N); hashname = nod(OXXX, N, N);
tempname(hashname, types[TUINT32]); tempname(hashname, types[TUINT32]);
typecheck(&hashname, Erv);
t = sw->ntest->right->type; t = sw->ntest->right->type;
if(isnilinter(t)) if(isnilinter(t))
...@@ -803,6 +815,7 @@ typeswitch(Node *sw) ...@@ -803,6 +815,7 @@ typeswitch(Node *sw)
a = nod(OCALL, a, N); a = nod(OCALL, a, N);
a->list = list1(facename); a->list = list1(facename);
a = nod(OAS, hashname, a); a = nod(OAS, hashname, a);
typecheck(&a, Etop);
cas = list(cas, a); cas = list(cas, a);
c0 = mkcaselist(sw, Stype); c0 = mkcaselist(sw, Stype);
...@@ -861,8 +874,10 @@ walkswitch(Node *sw) ...@@ -861,8 +874,10 @@ walkswitch(Node *sw)
* both have inserted OBREAK statements * both have inserted OBREAK statements
*/ */
walkstmtlist(sw->ninit); walkstmtlist(sw->ninit);
if(sw->ntest == N) if(sw->ntest == N) {
sw->ntest = nodbool(1); sw->ntest = nodbool(1);
typecheck(&sw->ntest, Erv);
}
casebody(sw); casebody(sw);
if(sw->ntest->op == OTYPESW) { if(sw->ntest->op == OTYPESW) {
......
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment