diff options
| author | Charles.Forsyth <devnull@localhost> | 2007-06-01 10:45:32 +0000 |
|---|---|---|
| committer | Charles.Forsyth <devnull@localhost> | 2007-06-01 10:45:32 +0000 |
| commit | 309cc03618e34c9a5ddf367fc14e57097285dc8e (patch) | |
| tree | 8e30385304dd31ff1cc553426a0a089673f1dd7b | |
| parent | dd7f661c1e9a0167d1d500b21866f267efa8dc5f (diff) | |
20070601-1143
| -rw-r--r-- | CHANGES | 2 | ||||
| -rw-r--r-- | appl/cmd/auth/factotum/factotum.b | 8 | ||||
| -rw-r--r-- | dis/auth/factotum.dis | bin | 13405 -> 13393 bytes | |||
| -rw-r--r-- | include/version.h | 2 | ||||
| -rw-r--r-- | utils/cc/com.c | 186 |
5 files changed, 191 insertions, 7 deletions
@@ -1,3 +1,5 @@ +20070601 + /apl/cmd/auth/factotum/factotum.b: ignore empty writes, don't fail; make a few diagnostics match plan 9 20070510 quickly remove references to udp's "oldheaders" because plan 9 removed it remove obootpd completely diff --git a/appl/cmd/auth/factotum/factotum.b b/appl/cmd/auth/factotum/factotum.b index 5f5b02a3..07169747 100644 --- a/appl/cmd/auth/factotum/factotum.b +++ b/appl/cmd/auth/factotum/factotum.b @@ -133,11 +133,11 @@ factotumsrv() wc <-= (0, "multiline write not allowed"); break; } - s := hd flds; - if(s == nil || s[0] == '#'){ + if(flds == nil || (hd flds)[0] == '#'){ wc <-= (len data, nil); break; } + s := hd flds; for(i := 0; i < len s && s[i] != ' '; i++){ # skip } @@ -174,7 +174,7 @@ factotumsrv() "debug" => wc <-= (len data, nil); * => - wc <-= (0, "unknown ctl request"); + wc <-= (0, "unknown verb"); } (nil, nbytes, fid, rc) := <-files.rpc.read => @@ -182,7 +182,7 @@ factotumsrv() break; r := findfid(fid); if(r == nil){ - rc <-= (nil, "unknown request"); + rc <-= (nil, "no rpc pending"); break; } alt{ diff --git a/dis/auth/factotum.dis b/dis/auth/factotum.dis Binary files differindex 4a0af835..47cedcca 100644 --- a/dis/auth/factotum.dis +++ b/dis/auth/factotum.dis diff --git a/include/version.h b/include/version.h index e36545a4..beae7a5c 100644 --- a/include/version.h +++ b/include/version.h @@ -1 +1 @@ -#define VERSION "Fourth Edition (20070510)" +#define VERSION "Fourth Edition (20070601)" diff --git a/utils/cc/com.c b/utils/cc/com.c index af16e8d9..558077b7 100644 --- a/utils/cc/com.c +++ b/utils/cc/com.c @@ -1,5 +1,7 @@ #include "cc.h" +int compar(Node*, int); + void complex(Node *n) { @@ -985,6 +987,8 @@ loop: case OHI: ccom(l); ccom(r); + if(compar(n, 0) || compar(n, 1)) + break; relcon(l, r); relcon(r, l); goto common; @@ -1082,7 +1086,7 @@ loop: *n = *l; break; } - goto commun; + goto commute; case OAND: ccom(l); @@ -1096,7 +1100,7 @@ loop: break; } - commun: + commute: /* look for commutative constant */ if(r->op == OCONST) { if(l->op == n->op) { @@ -1162,3 +1166,181 @@ loop: evconst(n); } } + +/* OEQ, ONE, OLE, OLS, OLT, OLO, OGE, OHS, OGT, OHI */ +static char *cmps[12] = +{ + "==", "!=", "<=", "<=", "<", "<", ">=", ">=", ">", ">", +}; + +/* 128-bit numbers */ +typedef struct Big Big; +struct Big +{ + vlong a; + uvlong b; +}; +static int +cmp(Big x, Big y) +{ + if(x.a != y.a){ + if(x.a < y.a) + return -1; + return 1; + } + if(x.b != y.b){ + if(x.b < y.b) + return -1; + return 1; + } + return 0; +} +static Big +add(Big x, int y) +{ + uvlong ob; + + ob = x.b; + x.b += y; + if(y > 0 && x.b < ob) + x.a++; + if(y < 0 && x.b > ob) + x.a--; + return x; +} + +Big +big(vlong a, uvlong b) +{ + Big x; + + x.a = a; + x.b = b; + return x; +} + +int +compar(Node *n, int reverse) +{ + Big lo, hi, x; + int op; + char xbuf[40], cmpbuf[50]; + Node *l, *r; + Type *lt, *rt; + + /* + * The point of this function is to diagnose comparisons + * that can never be true or that look misleading because + * of the `usual arithmetic conversions'. As an example + * of the latter, if x is a ulong, then if(x <= -1) really means + * if(x <= 0xFFFFFFFF), while if(x <= -1LL) really means + * what it says (but 8c compiles it wrong anyway). + */ + + if(reverse){ + r = n->left; + l = n->right; + op = comrel[relindex(n->op)]; + }else{ + l = n->left; + r = n->right; + op = n->op; + } + + /* + * Skip over left casts to find out the original expression range. + */ + while(l->op == OCAST) + l = l->left; + if(l->op == OCONST) + return 0; + lt = l->type; + if(l->op == ONAME && l->sym->type){ + lt = l->sym->type; + if(lt->etype == TARRAY) + lt = lt->link; + } + if(lt == T) + return 0; + if(lt->etype == TXXX || lt->etype > TUVLONG) + return 0; + + /* + * Skip over the right casts to find the on-screen value. + */ + if(r->op != OCONST) + return 0; + while(r->oldop == OCAST && !r->xcast) + r = r->left; + rt = r->type; + if(rt == T) + return 0; + + x.b = r->vconst; + x.a = 0; + if((rt->etype&1) && r->vconst < 0) /* signed negative */ + x.a = ~(uvlong)0; + + if((lt->etype&1)==0){ + /* unsigned */ + lo = big(0, 0); + if(lt->width == 8) + hi = big(0, ~(uvlong)0); + else + hi = big(0, ((uvlong)1<<(l->type->width*8))-1); + }else{ + lo = big(~(uvlong)0, -((uvlong)1<<(l->type->width*8-1))); + hi = big(0, ((uvlong)1<<(l->type->width*8-1))-1); + } + + switch(op){ + case OLT: + case OLO: + case OGE: + case OHS: + if(cmp(x, lo) <= 0) + goto useless; + if(cmp(x, add(hi, 1)) >= 0) + goto useless; + break; + case OLE: + case OLS: + case OGT: + case OHI: + if(cmp(x, add(lo, -1)) <= 0) + goto useless; + if(cmp(x, hi) >= 0) + goto useless; + break; + case OEQ: + case ONE: + /* + * Don't warn about comparisons if the expression + * is as wide as the value: the compiler-supplied casts + * will make both outcomes possible. + */ + if(lt->width >= rt->width && debug['w'] < 2) + return 0; + if(cmp(x, lo) < 0 || cmp(x, hi) > 0) + goto useless; + break; + } + return 0; + +useless: + if((x.a==0 && x.b<=9) || (x.a==~(uvlong)0 && x.b >= -(uvlong)9)) + snprint(xbuf, sizeof xbuf, "%lld", x.b); + else if(x.a == 0) + snprint(xbuf, sizeof xbuf, "%#llux", x.b); + else + snprint(xbuf, sizeof xbuf, "%#llx", x.b); + if(reverse) + snprint(cmpbuf, sizeof cmpbuf, "%s %s %T", + xbuf, cmps[relindex(n->op)], lt); + else + snprint(cmpbuf, sizeof cmpbuf, "%T %s %s", + lt, cmps[relindex(n->op)], xbuf); + warn(n, "useless or misleading comparison: %s", cmpbuf); + return 0; +} + |
