Commit b754b434 authored by Russ Cox's avatar Russ Cox

delete some code from walkexpr that is now

handled by typecheck.

second switch is gone

move floating point minus into back end

R=ken
OCL=32558
CL=32558
parent d9c914e9
......@@ -192,6 +192,12 @@ cgen(Node *n, Node *res)
goto ret;
case OMINUS:
if(isfloat[nl->type->etype]) {
nr = nodintconst(-1);
convlit(&nr, n->type);
a = optoas(OMUL, nl->type);
goto sbop;
}
a = optoas(n->op, nl->type);
goto uop;
......
......@@ -365,6 +365,13 @@ flt: // floating-point. 387 (not SSE2) to interoperate with 6c
if(nr != N)
goto flt2;
if(n->op == OMINUS) {
nr = nodintconst(-1);
convlit(&nr, n->type);
n->op = OMUL;
goto flt2;
}
// unary
cgen(nl, &f0);
if(n->op != OCONV)
......
......@@ -967,6 +967,9 @@ Jconv(Fmt *fp)
if(n->funcdepth != 0)
fmtprint(fp, " f(%d)", n->funcdepth);
if(n->typecheck != 0)
fmtprint(fp, " tc(%d)", n->typecheck);
return 0;
}
......
......@@ -28,7 +28,7 @@ typechecklist(NodeList *l, int top)
Node*
typecheck(Node **np, int top)
{
int et, et1, et2, op, nerr, len;
int et, op, nerr, len;
NodeList *ll;
Node *n, *l, *r;
NodeList *args;
......@@ -256,6 +256,7 @@ reswitch:
et = TINT;
if(t->etype != TIDEAL && !eqtype(l->type, r->type)) {
badbinary:
defaultlit2(&l, &r, 1);
yyerror("invalid operation: %#N (type %T %#O %T)", n, l->type, op, r->type);
goto error;
}
......@@ -270,8 +271,15 @@ reswitch:
if(isslice(l->type) && !isnil(l) && !isnil(r))
goto badbinary;
t = l->type;
if(iscmp[n->op])
if(iscmp[n->op]) {
t = types[TBOOL];
evconst(n);
if(n->op != OLITERAL) {
defaultlit2(&l, &r, 1);
n->left = l;
n->right = r;
}
}
n->type = t;
goto ret;
......@@ -637,6 +645,8 @@ yyerror("skip %#N", n);
yyerror("invalid operation: %#N (non-chan type %T)", n, t);
goto error;
}
if(n->op == OCLOSED)
n->type = types[TBOOL];
goto ret;
case OCONV:
......@@ -1023,7 +1033,6 @@ convert(Node **np, Type *t, int explicit)
// no-op conversion
if(cvttype(t, n->type) == 1) {
nop:
if(n->op == OLITERAL) {
// can convert literal in place
n1 = nod(OXXX, N, N);
......
......@@ -356,11 +356,32 @@ reswitch:
goto ret;
case OTYPE:
case OCALLMETH:
case OCALLINTER:
case OCALLFUNC:
case ONONAME:
case OINDREG:
case OEMPTY:
case OCONVNOP:
case OCOMPMAP:
case OCOMPSLICE:
goto ret;
case ONOT:
case OMINUS:
case OPLUS:
case OCOM:
case OLEN:
case OCAP:
case ODOT:
case ODOTPTR:
case ODOTMETH:
case ODOTINTER:
walkexpr(&n->left, Erv, init);
goto ret;
case OKEY:
walkexpr(&n->left, top | typeok, init);
walkexpr(&n->right, top | typeok, init);
case OIND:
walkexpr(&n->left, Erv | Etype, init);
goto ret;
case OPRINT:
......@@ -398,18 +419,6 @@ reswitch:
n->addable = 1;
goto ret;
case ONONAME:
s = n->sym;
if(n->diag == 0) {
s->undef = 1;
n->diag = 1;
yyerror("undefined: %S", s);
goto ret;
}
if(top == Etop)
goto nottop;
goto ret;
case ONAME:
if(top == Etop)
goto nottop;
......@@ -427,11 +436,6 @@ reswitch:
}
goto ret;
case OCALLMETH:
case OCALLINTER:
case OCALLFUNC:
goto ret;
case OCALL:
if(top == Elv)
goto nottop;
......@@ -686,10 +690,6 @@ reswitch:
}
goto ret;
case OINDREG:
case OEMPTY:
goto ret;
case ODOTTYPE:
walkdottype(n, init);
// fall through
......@@ -699,13 +699,6 @@ reswitch:
walkconv(&n, init);
goto ret;
case OCONVNOP:
goto ret;
case OCOMPMAP:
case OCOMPSLICE:
goto ret;
case OCOMPOS:
walkexpr(&n->right, Etype, init);
t = n->right->type;
......@@ -733,17 +726,6 @@ reswitch:
n = r;
goto ret;
case ONOT:
if(!(top & Erv))
goto nottop;
if(n->op == OLITERAL)
goto ret;
walkexpr(&n->left, Erv, init);
if(n->left == N || n->left->type == T)
goto ret;
et = n->left->type->etype;
break;
case OASOP:
if(top != Etop)
goto nottop;
......@@ -777,7 +759,7 @@ reswitch:
if(issigned[et] || !isint[et])
goto badt;
// check of n->left->type happens in second switch.
break;
goto ret;
case OMOD:
case OAND:
......@@ -804,14 +786,8 @@ reswitch:
walkexpr(&n->right, Erv, init);
if(n->left == N || n->right == N)
goto ret;
evconst(n);
if(n->op == OLITERAL)
goto ret;
defaultlit2(&n->left, &n->right, iscmp[n->op]);
if(n->left->type == T || n->right->type == T)
goto ret;
if(!eqtype(n->left->type, n->right->type))
goto badt;
switch(n->op) {
case OANDNOT:
......@@ -846,80 +822,60 @@ reswitch:
}
break;
}
break;
case OMINUS:
case OPLUS:
case OCOM:
if(!(top & Erv))
goto nottop;
walkexpr(&n->left, Erv, init);
if(n->left == N)
goto ret;
if(n->op == OLITERAL)
goto ret;
break;
case OLEN:
if(!(top & Erv))
goto nottop;
if(n->left == N) {
if(n->list == nil) {
yyerror("missing argument to len");
switch(n->op) {
case OEQ:
case ONE:
if(isinter(n->left->type)) {
n = ifaceop(n);
goto ret;
}
if(n->list->next)
yyerror("too many arguments to len");
n->left = n->list->n;
}
walkexpr(&n->left, Erv, init);
defaultlit(&n->left, T);
t = n->left->type;
if(t == T)
goto ret;
switch(t->etype) {
default:
goto badt;
case TSTRING:
if(isconst(n->left, CTSTR))
nodconst(n, types[TINT], n->left->val.u.sval->len);
break;
case TMAP:
break;
case TARRAY:
if(t->bound >= 0)
nodconst(n, types[TINT], t->bound);
break;
}
n->type = types[TINT];
goto ret;
case OCAP:
if(!(top & Erv))
goto nottop;
if(n->left == N) {
if(n->list == nil) {
yyerror("missing argument to cap");
goto ret;
}
if(n->list->next)
yyerror("too many arguments to cap");
n->left = n->list->n;
}
walkexpr(&n->left, Erv, init);
defaultlit(&n->left, T);
t = n->left->type;
if(t == T)
goto ret;
switch(t->etype) {
default:
goto badt;
case TARRAY:
if(t->bound >= 0)
nodconst(n, types[TINT], t->bound);
/*
* rewrite div and mod into function calls
* on 32-bit architectures.
*/
switch(n->op) {
case ODIV:
case OMOD:
et = n->left->type->etype;
if(widthptr > 4 || (et != TUINT64 && et != TINT64))
break;
if(et == TINT64)
strcpy(namebuf, "int64");
else
strcpy(namebuf, "uint64");
if(n->op == ODIV)
strcat(namebuf, "div");
else
strcat(namebuf, "mod");
l = syslook(namebuf, 0);
n->left = nod(OCONV, n->left, N);
n->left->type = types[et];
n->right = nod(OCONV, n->right, N);
n->right->type = types[et];
r = nod(OCALL, l, N);
r->list = list(list1(n->left), n->right);
r = nod(OCONV, r, N);
r->type = n->left->left->type;
typecheck(&r, Erv);
walkexpr(&r, Erv, init);
n = r;
break;
case OASOP:
et = n->left->type->etype;
if(widthptr > 4 || (et != TUINT64 && et != TINT64))
break;
l = saferef(n->left, init);
r = nod(OAS, l, nod(n->etype, l, n->right));
typecheck(&r, Etop);
walkexpr(&r, Etop, init);
n = r;
break;
}
n->type = types[TINT];
goto ret;
case OINDEX:
......@@ -1040,13 +996,6 @@ reswitch:
badtype(OSLICE, n->left->type, T);
goto ret;
case ODOT:
case ODOTPTR:
case ODOTMETH:
case ODOTINTER:
walkexpr(&n->left, Erv, init);
goto ret;
case OADDR:
if(!(top & Erv))
goto nottop;
......@@ -1112,28 +1061,6 @@ reswitch:
n->type = ptrto(t);
goto ret;
case OIND:
if(top == Etop)
goto nottop;
if(top == Elv) // even if n is lvalue, n->left is rvalue
top = Erv;
if(n->left == N)
goto ret;
walkexpr(&n->left, top | Etype, init);
defaultlit(&n->left, T);
if(n->left->op == OTYPE) {
n->op = OTYPE;
n->type = ptrto(n->left->type);
goto ret;
}
t = n->left->type;
if(t == T)
goto ret;
if(!isptr[t->etype])
goto badt;
n->type = t->type;
goto ret;
case OMAKE:
if(!(top & Erv))
goto nottop;
......@@ -1157,151 +1084,7 @@ reswitch:
n = callnew(t);
goto ret;
}
/*
* ======== second switch ========
*/
op = n->op;
if(op == OASOP)
op = n->etype;
switch(op) {
default:
fatal("walkexpr: switch 2 unknown op %N", n, init);
goto ret;
case OASOP:
break;
case ONOT:
case OANDAND:
case OOROR:
if(n->left->type == T)
goto ret;
et = n->left->type->etype;
if(et != TBOOL)
goto badt;
t = types[TBOOL];
break;
case OEQ:
case ONE:
if(n->left->type == T)
goto ret;
et = n->left->type->etype;
if(!okforeq[et] && !isslice(n->left->type))
goto badt;
if(isinter(n->left->type)) {
n = ifaceop(n);
goto ret;
}
t = types[TBOOL];
break;
case OLT:
case OLE:
case OGE:
case OGT:
if(n->left->type == T)
goto ret;
et = n->left->type->etype;
if(!okforarith[et] && et != TSTRING)
goto badt;
t = types[TBOOL];
break;
case OADD:
case OSUB:
case OMUL:
case ODIV:
case OPLUS:
if(n->left->type == T)
goto ret;
et = n->left->type->etype;
if(!okforarith[et])
goto badt;
break;
case OMINUS:
if(n->left->type == T)
goto ret;
et = n->left->type->etype;
if(!okforarith[et])
goto badt;
if(isfloat[et]) {
// TODO(rsc): Can do this more efficiently,
// but OSUB is wrong. Should be in back end anyway.
n = nod(OMUL, n->left, nodintconst(-1));
typecheck(&n, Erv);
walkexpr(&n, Erv, init);
goto ret;
}
break;
case OLSH:
case ORSH:
case OAND:
case OANDNOT:
case OOR:
case OXOR:
case OMOD:
case OCOM:
if(n->left->type == T)
goto ret;
et = n->left->type->etype;
if(et != TIDEAL && !okforand[et])
goto badt;
break;
}
/*
* rewrite div and mod into function calls
* on 32-bit architectures.
*/
switch(n->op) {
case ODIV:
case OMOD:
et = n->left->type->etype;
if(widthptr > 4 || (et != TUINT64 && et != TINT64))
break;
if(et == TINT64)
strcpy(namebuf, "int64");
else
strcpy(namebuf, "uint64");
if(n->op == ODIV)
strcat(namebuf, "div");
else
strcat(namebuf, "mod");
l = syslook(namebuf, 0);
n->left = nod(OCONV, n->left, N);
n->left->type = types[et];
n->right = nod(OCONV, n->right, N);
n->right->type = types[et];
r = nod(OCALL, l, N);
r->list = list(list1(n->left), n->right);
r = nod(OCONV, r, N);
r->type = n->left->left->type;
typecheck(&r, Erv);
walkexpr(&r, Erv, init);
n = r;
goto ret;
case OASOP:
et = n->left->type->etype;
if(widthptr > 4 || (et != TUINT64 && et != TINT64))
break;
l = saferef(n->left, init);
r = nod(OAS, l, nod(n->etype, l, n->right));
typecheck(&r, Etop);
walkexpr(&r, Etop, init);
n = r;
goto ret;
}
if(t == T)
t = n->left->type;
n->type = t;
goto ret;
fatal("missing switch %#O", n->op);
nottop:
if(n->diag)
......
......@@ -7,6 +7,6 @@
package main
func main() {
var x int64 = 0;
println(x != nil); // ERROR "illegal|incompatible|nil constant"
println(0 != nil); // ERROR "illegal|incompatible|nil constant"
println(x != nil); // ERROR "illegal|incompatible|nil"
println(0 != nil); // ERROR "illegal|incompatible|nil"
}
......@@ -8,5 +8,5 @@ package main
func f() {
a := true;
a |= a; // ERROR "illegal.*OR"
a |= a; // ERROR "illegal.*OR|bool"
}
......@@ -36,16 +36,16 @@ func f()
// it decides there are type errors.
x :=
len(m0)+
len(m1)+ // ERROR "illegal|must be"
len(m2)+ // ERROR "illegal|must be"
len(m1)+ // ERROR "illegal|invalid|must be"
len(m2)+ // ERROR "illegal|invalid|must be"
len(m3)+
len(m4)+ // ERROR "illegal|must be"
len(m4)+ // ERROR "illegal|invalid|must be"
len(s0)+
len(s1)+ // ERROR "illegal|must be"
len(s2)+ // ERROR "illegal|must be"
len(s1)+ // ERROR "illegal|invalid|must be"
len(s2)+ // ERROR "illegal|invalid|must be"
len(s3)+
len(s4)+ // ERROR "illegal|must be"
len(s4)+ // ERROR "illegal|invalid|must be"
len(a0)+
len(a1)+
......@@ -56,14 +56,14 @@ func f()
cap(a2)+
len(b0)+
len(b1)+ // ERROR "illegal|must be"
len(b2)+ // ERROR "illegal|must be"
len(b1)+ // ERROR "illegal|invalid|must be"
len(b2)+ // ERROR "illegal|invalid|must be"
len(b3)+
len(b4)+ // ERROR "illegal|must be"
len(b4)+ // ERROR "illegal|invalid|must be"
cap(b0)+
cap(b1)+ // ERROR "illegal|must be"
cap(b2)+ // ERROR "illegal|must be"
cap(b1)+ // ERROR "illegal|invalid|must be"
cap(b2)+ // ERROR "illegal|invalid|must be"
cap(b3)+
cap(b4); // ERROR "illegal|must be"
cap(b4); // ERROR "illegal|invalid|must be"
}
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