diff options
-rw-r--r-- | sys/src/cmd/cc/cc.h | 1 | ||||
-rw-r--r-- | sys/src/cmd/cc/com.c | 32 | ||||
-rw-r--r-- | sys/src/cmd/cc/sub.c | 36 |
3 files changed, 62 insertions, 7 deletions
diff --git a/sys/src/cmd/cc/cc.h b/sys/src/cmd/cc/cc.h index dbaddffb5..87aceb598 100644 --- a/sys/src/cmd/cc/cc.h +++ b/sys/src/cmd/cc/cc.h @@ -662,6 +662,7 @@ void dclfunct(Type*, Sym*); * sub.c */ void arith(Node*, int); +int castucom(Node*); int deadheads(Node*); Type* dotsearch(Sym*, Type*, Node*, long*); long dotoffset(Type*, Type*, Node*); diff --git a/sys/src/cmd/cc/com.c b/sys/src/cmd/cc/com.c index 5072c8a21..9fcf9861f 100644 --- a/sys/src/cmd/cc/com.c +++ b/sys/src/cmd/cc/com.c @@ -266,12 +266,15 @@ tcomo(Node *n, int f) arith(n, 0); while(n->left->op == OCAST) n->left = n->left->left; - if(!sametype(t, n->type) && !mixedasop(t, n->type)) { - r = new1(OCAST, n->right, Z); - r->type = t; - n->right = r; + if(!mixedasop(t, n->type)) { + if(!sametype(t, n->type)) { + r = new1(OCAST, n->right, Z); + r->type = t; + n->right = r; + n->type = t; + } + }else n->type = t; - } if(typeu[n->type->etype]) { if(n->op == OASMOD) n->op = OASLMOD; @@ -1044,6 +1047,23 @@ loop: case OASADD: ccom(l); ccom(r); + if(n->op == OASMOD || n->op == OASLMOD || n->op == OASDIV || n->op == OASLDIV) + if(r->op == OCONST){ + if(!typefd[r->type->etype] && r->vconst == 0) { + if(n->op == OASMOD || n->op == OASLMOD) + diag(n, "modulo by zero"); + else + diag(n, "divide by zero"); + r->vconst = ~0; + } + if(typefd[r->type->etype] && r->fconst == 0.) { + if(n->op == OASMOD || n->op == OASLMOD) + diag(n, "modulo by zero"); + else + diag(n, "divide by zero"); + r->fconst = 1e10; + } + } if(n->op == OASLSHR || n->op == OASASHR || n->op == OASASHL) if(r->op == OCONST) { t = n->type->width * 8; /* bits per byte */ @@ -1053,6 +1073,8 @@ loop: break; case OCAST: + if(castucom(n)) + warn(n, "32-bit unsigned complement zero-extended to 64 bits"); ccom(l); if(l->op == OCONST) { evconst(n); diff --git a/sys/src/cmd/cc/sub.c b/sys/src/cmd/cc/sub.c index 3026683fb..ee4ab07ce 100644 --- a/sys/src/cmd/cc/sub.c +++ b/sys/src/cmd/cc/sub.c @@ -659,7 +659,7 @@ arith(Node *n, int f) Type *t1, *t2; int i, j, k; Node *n1; - long w; + long w, x; t1 = n->left->type; if(n->right == Z) @@ -689,7 +689,19 @@ arith(Node *n, int f) if(n->op == OSUB) if(i == TIND && j == TIND) { w = n->right->type->link->width; - if(w < 1 || n->left->type->link == T || n->left->type->link->width < 1) + if(w < 1) { + snap(n->right->type->link); + w = n->right->type->link->width; + } + x = 0; + if(n->left->type->link != T) { + x = n->left->type->link->width; + if(x < 1) { + snap(n->left->type->link); + x = n->left->type->link->width; + } + } + if(w < 1 || x < 1) goto bad; n->type = types[ewidth[TIND] <= ewidth[TLONG]? TLONG: TVLONG]; if(w > 1) { @@ -991,6 +1003,8 @@ loop: case OOROR: case OCOMMA: case ODOT: + case OFAS: + case OINDEX: if(side(n->left)) break; n = n->right; @@ -2074,3 +2088,21 @@ mixedasop(Type *l, Type *r) { return !typefd[l->etype] && typefd[r->etype]; } + + +/* + * (uvlong)~ul creates a ul mask with top bits zero, which is usually wrong + * an explicit cast to ulong after ~ suppresses the diagnostic + */ +int +castucom(Node *r) +{ + Node *rl; + + if(r->op == OCAST && + (rl = r->left)->op == OCOM && + (r->type->etype == TVLONG || r->type->etype == TUVLONG) && + typeu[rl->type->etype] && typechl[rl->type->etype]) + return 1; + return 0; +} |