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) ...@@ -192,6 +192,12 @@ cgen(Node *n, Node *res)
goto ret; goto ret;
case OMINUS: 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); a = optoas(n->op, nl->type);
goto uop; goto uop;
......
...@@ -365,6 +365,13 @@ flt: // floating-point. 387 (not SSE2) to interoperate with 6c ...@@ -365,6 +365,13 @@ flt: // floating-point. 387 (not SSE2) to interoperate with 6c
if(nr != N) if(nr != N)
goto flt2; goto flt2;
if(n->op == OMINUS) {
nr = nodintconst(-1);
convlit(&nr, n->type);
n->op = OMUL;
goto flt2;
}
// unary // unary
cgen(nl, &f0); cgen(nl, &f0);
if(n->op != OCONV) if(n->op != OCONV)
......
...@@ -967,6 +967,9 @@ Jconv(Fmt *fp) ...@@ -967,6 +967,9 @@ Jconv(Fmt *fp)
if(n->funcdepth != 0) if(n->funcdepth != 0)
fmtprint(fp, " f(%d)", n->funcdepth); fmtprint(fp, " f(%d)", n->funcdepth);
if(n->typecheck != 0)
fmtprint(fp, " tc(%d)", n->typecheck);
return 0; return 0;
} }
......
...@@ -28,7 +28,7 @@ typechecklist(NodeList *l, int top) ...@@ -28,7 +28,7 @@ typechecklist(NodeList *l, int top)
Node* Node*
typecheck(Node **np, int top) typecheck(Node **np, int top)
{ {
int et, et1, et2, op, nerr, len; int et, op, nerr, len;
NodeList *ll; NodeList *ll;
Node *n, *l, *r; Node *n, *l, *r;
NodeList *args; NodeList *args;
...@@ -256,6 +256,7 @@ reswitch: ...@@ -256,6 +256,7 @@ reswitch:
et = TINT; et = TINT;
if(t->etype != TIDEAL && !eqtype(l->type, r->type)) { if(t->etype != TIDEAL && !eqtype(l->type, r->type)) {
badbinary: badbinary:
defaultlit2(&l, &r, 1);
yyerror("invalid operation: %#N (type %T %#O %T)", n, l->type, op, r->type); yyerror("invalid operation: %#N (type %T %#O %T)", n, l->type, op, r->type);
goto error; goto error;
} }
...@@ -270,8 +271,15 @@ reswitch: ...@@ -270,8 +271,15 @@ reswitch:
if(isslice(l->type) && !isnil(l) && !isnil(r)) if(isslice(l->type) && !isnil(l) && !isnil(r))
goto badbinary; goto badbinary;
t = l->type; t = l->type;
if(iscmp[n->op]) if(iscmp[n->op]) {
t = types[TBOOL]; t = types[TBOOL];
evconst(n);
if(n->op != OLITERAL) {
defaultlit2(&l, &r, 1);
n->left = l;
n->right = r;
}
}
n->type = t; n->type = t;
goto ret; goto ret;
...@@ -637,6 +645,8 @@ yyerror("skip %#N", n); ...@@ -637,6 +645,8 @@ yyerror("skip %#N", n);
yyerror("invalid operation: %#N (non-chan type %T)", n, t); yyerror("invalid operation: %#N (non-chan type %T)", n, t);
goto error; goto error;
} }
if(n->op == OCLOSED)
n->type = types[TBOOL];
goto ret; goto ret;
case OCONV: case OCONV:
...@@ -1023,7 +1033,6 @@ convert(Node **np, Type *t, int explicit) ...@@ -1023,7 +1033,6 @@ convert(Node **np, Type *t, int explicit)
// no-op conversion // no-op conversion
if(cvttype(t, n->type) == 1) { if(cvttype(t, n->type) == 1) {
nop:
if(n->op == OLITERAL) { if(n->op == OLITERAL) {
// can convert literal in place // can convert literal in place
n1 = nod(OXXX, N, N); n1 = nod(OXXX, N, N);
......
...@@ -356,11 +356,32 @@ reswitch: ...@@ -356,11 +356,32 @@ reswitch:
goto ret; goto ret;
case OTYPE: 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; goto ret;
case OKEY: case OIND:
walkexpr(&n->left, top | typeok, init); walkexpr(&n->left, Erv | Etype, init);
walkexpr(&n->right, top | typeok, init);
goto ret; goto ret;
case OPRINT: case OPRINT:
...@@ -398,18 +419,6 @@ reswitch: ...@@ -398,18 +419,6 @@ reswitch:
n->addable = 1; n->addable = 1;
goto ret; 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: case ONAME:
if(top == Etop) if(top == Etop)
goto nottop; goto nottop;
...@@ -427,11 +436,6 @@ reswitch: ...@@ -427,11 +436,6 @@ reswitch:
} }
goto ret; goto ret;
case OCALLMETH:
case OCALLINTER:
case OCALLFUNC:
goto ret;
case OCALL: case OCALL:
if(top == Elv) if(top == Elv)
goto nottop; goto nottop;
...@@ -686,10 +690,6 @@ reswitch: ...@@ -686,10 +690,6 @@ reswitch:
} }
goto ret; goto ret;
case OINDREG:
case OEMPTY:
goto ret;
case ODOTTYPE: case ODOTTYPE:
walkdottype(n, init); walkdottype(n, init);
// fall through // fall through
...@@ -699,13 +699,6 @@ reswitch: ...@@ -699,13 +699,6 @@ reswitch:
walkconv(&n, init); walkconv(&n, init);
goto ret; goto ret;
case OCONVNOP:
goto ret;
case OCOMPMAP:
case OCOMPSLICE:
goto ret;
case OCOMPOS: case OCOMPOS:
walkexpr(&n->right, Etype, init); walkexpr(&n->right, Etype, init);
t = n->right->type; t = n->right->type;
...@@ -733,17 +726,6 @@ reswitch: ...@@ -733,17 +726,6 @@ reswitch:
n = r; n = r;
goto ret; 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: case OASOP:
if(top != Etop) if(top != Etop)
goto nottop; goto nottop;
...@@ -777,7 +759,7 @@ reswitch: ...@@ -777,7 +759,7 @@ reswitch:
if(issigned[et] || !isint[et]) if(issigned[et] || !isint[et])
goto badt; goto badt;
// check of n->left->type happens in second switch. // check of n->left->type happens in second switch.
break; goto ret;
case OMOD: case OMOD:
case OAND: case OAND:
...@@ -804,14 +786,8 @@ reswitch: ...@@ -804,14 +786,8 @@ reswitch:
walkexpr(&n->right, Erv, init); walkexpr(&n->right, Erv, init);
if(n->left == N || n->right == N) if(n->left == N || n->right == N)
goto ret; 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) if(n->left->type == T || n->right->type == T)
goto ret; goto ret;
if(!eqtype(n->left->type, n->right->type))
goto badt;
switch(n->op) { switch(n->op) {
case OANDNOT: case OANDNOT:
...@@ -846,80 +822,60 @@ reswitch: ...@@ -846,80 +822,60 @@ reswitch:
} }
break; break;
} }
break;
switch(n->op) {
case OMINUS: case OEQ:
case OPLUS: case ONE:
case OCOM: if(isinter(n->left->type)) {
if(!(top & Erv)) n = ifaceop(n);
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");
goto ret; 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; 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; * rewrite div and mod into function calls
if(t == T) * on 32-bit architectures.
goto ret; */
switch(t->etype) { switch(n->op) {
default: case ODIV:
goto badt; case OMOD:
case TARRAY: et = n->left->type->etype;
if(t->bound >= 0) if(widthptr > 4 || (et != TUINT64 && et != TINT64))
nodconst(n, types[TINT], t->bound); 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; break;
} }
n->type = types[TINT];
goto ret; goto ret;
case OINDEX: case OINDEX:
...@@ -1040,13 +996,6 @@ reswitch: ...@@ -1040,13 +996,6 @@ reswitch:
badtype(OSLICE, n->left->type, T); badtype(OSLICE, n->left->type, T);
goto ret; goto ret;
case ODOT:
case ODOTPTR:
case ODOTMETH:
case ODOTINTER:
walkexpr(&n->left, Erv, init);
goto ret;
case OADDR: case OADDR:
if(!(top & Erv)) if(!(top & Erv))
goto nottop; goto nottop;
...@@ -1112,28 +1061,6 @@ reswitch: ...@@ -1112,28 +1061,6 @@ reswitch:
n->type = ptrto(t); n->type = ptrto(t);
goto ret; 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: case OMAKE:
if(!(top & Erv)) if(!(top & Erv))
goto nottop; goto nottop;
...@@ -1157,151 +1084,7 @@ reswitch: ...@@ -1157,151 +1084,7 @@ reswitch:
n = callnew(t); n = callnew(t);
goto ret; goto ret;
} }
fatal("missing switch %#O", n->op);
/*
* ======== 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;
nottop: nottop:
if(n->diag) if(n->diag)
......
...@@ -7,6 +7,6 @@ ...@@ -7,6 +7,6 @@
package main package main
func main() { func main() {
var x int64 = 0; var x int64 = 0;
println(x != nil); // ERROR "illegal|incompatible|nil constant" println(x != nil); // ERROR "illegal|incompatible|nil"
println(0 != nil); // ERROR "illegal|incompatible|nil constant" println(0 != nil); // ERROR "illegal|incompatible|nil"
} }
...@@ -8,5 +8,5 @@ package main ...@@ -8,5 +8,5 @@ package main
func f() { func f() {
a := true; a := true;
a |= a; // ERROR "illegal.*OR" a |= a; // ERROR "illegal.*OR|bool"
} }
...@@ -36,16 +36,16 @@ func f() ...@@ -36,16 +36,16 @@ func f()
// it decides there are type errors. // it decides there are type errors.
x := x :=
len(m0)+ len(m0)+
len(m1)+ // ERROR "illegal|must be" len(m1)+ // ERROR "illegal|invalid|must be"
len(m2)+ // ERROR "illegal|must be" len(m2)+ // ERROR "illegal|invalid|must be"
len(m3)+ len(m3)+
len(m4)+ // ERROR "illegal|must be" len(m4)+ // ERROR "illegal|invalid|must be"
len(s0)+ len(s0)+
len(s1)+ // ERROR "illegal|must be" len(s1)+ // ERROR "illegal|invalid|must be"
len(s2)+ // ERROR "illegal|must be" len(s2)+ // ERROR "illegal|invalid|must be"
len(s3)+ len(s3)+
len(s4)+ // ERROR "illegal|must be" len(s4)+ // ERROR "illegal|invalid|must be"
len(a0)+ len(a0)+
len(a1)+ len(a1)+
...@@ -56,14 +56,14 @@ func f() ...@@ -56,14 +56,14 @@ func f()
cap(a2)+ cap(a2)+
len(b0)+ len(b0)+
len(b1)+ // ERROR "illegal|must be" len(b1)+ // ERROR "illegal|invalid|must be"
len(b2)+ // ERROR "illegal|must be" len(b2)+ // ERROR "illegal|invalid|must be"
len(b3)+ len(b3)+
len(b4)+ // ERROR "illegal|must be" len(b4)+ // ERROR "illegal|invalid|must be"
cap(b0)+ cap(b0)+
cap(b1)+ // ERROR "illegal|must be" cap(b1)+ // ERROR "illegal|invalid|must be"
cap(b2)+ // ERROR "illegal|must be" cap(b2)+ // ERROR "illegal|invalid|must be"
cap(b3)+ 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