Some useful warnings. [rsc] --rw-rw-r-- M 84741 glenda sys 12122 Dec 11 12:22 sys/src/cmd/cc/cc.h /n/sourcesdump/2005/1211/plan9/sys/src/cmd/cc/cc.h:57,62 - /n/sourcesdump/2005/1212/plan9/sys/src/cmd/cc/cc.h:57,64 Type* type; long lineno; char op; + char oldop; + char xcast; char class; char etype; char complex; /n/sourcesdump/2005/1211/plan9/sys/src/cmd/cc/cc.h:497,502 - /n/sourcesdump/2005/1212/plan9/sys/src/cmd/cc/cc.h:499,505 extern char typeilp[]; extern char typechl[]; extern char typechlv[]; + extern char typechlvp[]; extern char typechlp[]; extern char typechlpfd[]; [rsc] --rw-rw-r-- M 84741 glenda sys 16058 Dec 11 12:21 sys/src/cmd/cc/cc.y /n/sourcesdump/2005/1211/plan9/sys/src/cmd/cc/cc.y:656,661 - /n/sourcesdump/2005/1212/plan9/sys/src/cmd/cc/cc.y:656,662 $$ = new(OCAST, $5, Z); dodecl(NODECL, CXXX, $2, $3); $$->type = lastdcl; + $$->xcast = 1; } | '(' tlist abdecor ')' '{' ilist '}' /* extension */ { /n/sourcesdump/2005/1211/plan9/sys/src/cmd/cc/cc.y:760,765 - /n/sourcesdump/2005/1212/plan9/sys/src/cmd/cc/cc.y:761,767 $$ = new(OCONST, Z, Z); $$->type = types[TINT]; $$->vconst = $1; + $$->cstring = strdup(symb); } | LLCONST { /n/sourcesdump/2005/1211/plan9/sys/src/cmd/cc/cc.y:766,771 - /n/sourcesdump/2005/1212/plan9/sys/src/cmd/cc/cc.y:768,774 $$ = new(OCONST, Z, Z); $$->type = types[TLONG]; $$->vconst = $1; + $$->cstring = strdup(symb); } | LUCONST { /n/sourcesdump/2005/1211/plan9/sys/src/cmd/cc/cc.y:772,777 - /n/sourcesdump/2005/1212/plan9/sys/src/cmd/cc/cc.y:775,781 $$ = new(OCONST, Z, Z); $$->type = types[TUINT]; $$->vconst = $1; + $$->cstring = strdup(symb); } | LULCONST { /n/sourcesdump/2005/1211/plan9/sys/src/cmd/cc/cc.y:778,783 - /n/sourcesdump/2005/1212/plan9/sys/src/cmd/cc/cc.y:782,788 $$ = new(OCONST, Z, Z); $$->type = types[TULONG]; $$->vconst = $1; + $$->cstring = strdup(symb); } | LDCONST { /n/sourcesdump/2005/1211/plan9/sys/src/cmd/cc/cc.y:784,789 - /n/sourcesdump/2005/1212/plan9/sys/src/cmd/cc/cc.y:789,795 $$ = new(OCONST, Z, Z); $$->type = types[TDOUBLE]; $$->fconst = $1; + $$->cstring = strdup(symb); } | LFCONST { /n/sourcesdump/2005/1211/plan9/sys/src/cmd/cc/cc.y:790,795 - /n/sourcesdump/2005/1212/plan9/sys/src/cmd/cc/cc.y:796,802 $$ = new(OCONST, Z, Z); $$->type = types[TFLOAT]; $$->fconst = $1; + $$->cstring = strdup(symb); } | LVLCONST { /n/sourcesdump/2005/1211/plan9/sys/src/cmd/cc/cc.y:796,801 - /n/sourcesdump/2005/1212/plan9/sys/src/cmd/cc/cc.y:803,809 $$ = new(OCONST, Z, Z); $$->type = types[TVLONG]; $$->vconst = $1; + $$->cstring = strdup(symb); } | LUVLCONST { /n/sourcesdump/2005/1211/plan9/sys/src/cmd/cc/cc.y:802,807 - /n/sourcesdump/2005/1212/plan9/sys/src/cmd/cc/cc.y:810,816 $$ = new(OCONST, Z, Z); $$->type = types[TUVLONG]; $$->vconst = $1; + $$->cstring = strdup(symb); } | string | lstring [rsc] --rw-rw-r-- M 84741 glenda sys 22202 Dec 11 12:22 sys/src/cmd/cc/com.c /n/sourcesdump/2005/1211/plan9/sys/src/cmd/cc/com.c:1,5 - /n/sourcesdump/2005/1212/plan9/sys/src/cmd/cc/com.c:1,7 #include "cc.h" + int compar(Node*, int); + void complex(Node *n) { /n/sourcesdump/2005/1211/plan9/sys/src/cmd/cc/com.c:985,990 - /n/sourcesdump/2005/1212/plan9/sys/src/cmd/cc/com.c:987,994 case OHI: ccom(l); ccom(r); + if(compar(n, 0) || compar(n, 1)) + break; relcon(l, r); relcon(r, l); goto common; /n/sourcesdump/2005/1211/plan9/sys/src/cmd/cc/com.c:1082,1088 - /n/sourcesdump/2005/1212/plan9/sys/src/cmd/cc/com.c:1086,1092 *n = *l; break; } - goto commun; + goto commute; case OAND: ccom(l); /n/sourcesdump/2005/1211/plan9/sys/src/cmd/cc/com.c:1096,1102 - /n/sourcesdump/2005/1212/plan9/sys/src/cmd/cc/com.c:1100,1106 break; } - commun: + commute: /* look for commutative constant */ if(r->op == OCONST) { if(l->op == n->op) { /n/sourcesdump/2005/1211/plan9/sys/src/cmd/cc/com.c:1162,1164 - /n/sourcesdump/2005/1212/plan9/sys/src/cmd/cc/com.c:1166,1346 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){ + lt = l->sym->type; + if(lt && 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 = ~0ULL; + + if((lt->etype&1)==0){ + /* unsigned */ + lo = big(0, 0); + if(lt->width == 8) + hi = big(0, ~0ULL); + else + hi = big(0, (1LL<<(l->type->width*8))-1); + }else{ + lo = big(~0ULL, -(1LL<<(l->type->width*8-1))); + hi = big(0, (1LL<<(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==~0LL && x.b >= -9ULL)) + 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; + } + [rsc] --rw-rw-r-- M 84741 glenda sys 23923 Dec 11 12:22 sys/src/cmd/cc/lex.c /n/sourcesdump/2005/1211/plan9/sys/src/cmd/cc/lex.c:395,401 - /n/sourcesdump/2005/1212/plan9/sys/src/cmd/cc/lex.c:395,401 yylex(void) { vlong vv; - long c, c1; + long c, c1, t; char *cp; Rune rune; Sym *s; /n/sourcesdump/2005/1211/plan9/sys/src/cmd/cc/lex.c:540,547 - /n/sourcesdump/2005/1212/plan9/sys/src/cmd/cc/lex.c:540,549 if(yylval.vval != vv) yyerror("overflow in character constant: 0x%lx", c); else - if(c & 0x80) + if(c & 0x80){ + nearln = lineno; warn(Z, "sign-extended character constant"); + } yylval.vval = convvtox(vv, TCHAR); return LCONST; /n/sourcesdump/2005/1211/plan9/sys/src/cmd/cc/lex.c:784,828 - /n/sourcesdump/2005/1212/plan9/sys/src/cmd/cc/lex.c:786,827 if(mpatov(symb, &yylval.vval)) yyerror("overflow in constant"); + vv = yylval.vval; if(c1 & Numvlong) { - if(c1 & Numuns) { + if((c1 & Numuns) || convvtox(vv, TVLONG) < 0) { c = LUVLCONST; + t = TUVLONG; goto nret; } - yylval.vval = convvtox(yylval.vval, TVLONG); - if(yylval.vval < 0) { - c = LUVLCONST; - goto nret; - } c = LVLCONST; + t = TVLONG; goto nret; } if(c1 & Numlong) { - if(c1 & Numuns) { + if((c1 & Numuns) || convvtox(vv, TLONG) < 0) { c = LULCONST; + t = TULONG; goto nret; } - yylval.vval = convvtox(yylval.vval, TLONG); - if(yylval.vval < 0) { - c = LULCONST; - goto nret; - } c = LLCONST; + t = TLONG; goto nret; } - if(c1 & Numuns) { + if((c1 & Numuns) || convvtox(vv, TINT) < 0) { c = LUCONST; + t = TUINT; goto nret; } - yylval.vval = convvtox(yylval.vval, TINT); - if(yylval.vval < 0) { - c = LUCONST; - goto nret; - } c = LCONST; + t = TINT; goto nret; nret: + yylval.vval = convvtox(vv, t); + if(yylval.vval != vv){ + nearln = lineno; + warn(Z, "truncated constant: %T %s", types[t], symb); + } return c; casedot: [rsc] --rw-rw-r-- M 84741 jmk sys 8645 Dec 11 12:22 sys/src/cmd/cc/scon.c /n/sourcesdump/2005/1211/plan9/sys/src/cmd/cc/scon.c:226,231 - /n/sourcesdump/2005/1212/plan9/sys/src/cmd/cc/scon.c:226,232 } else { n->vconst = convvtox(v, n->type->etype); } + n->oldop = n->op; n->op = OCONST; } /n/sourcesdump/2005/1211/plan9/sys/src/cmd/cc/scon.c:375,380 - /n/sourcesdump/2005/1212/plan9/sys/src/cmd/cc/scon.c:376,382 } c1 = trm[0].mult; if(j == 0) { + n->oldop = n->op; n->op = OCONST; n->vconst = c1; return; [rsc] --rw-rw-r-- M 84741 glenda sys 34315 Dec 11 12:22 sys/src/cmd/cc/sub.c /n/sourcesdump/2005/1211/plan9/sys/src/cmd/cc/sub.c:1484,1489 - /n/sourcesdump/2005/1212/plan9/sys/src/cmd/cc/sub.c:1484,1490 -1, 0, 0, }; + /* OEQ, ONE, OLE, OLS, OLT, OLO, OGE, OHS, OGT, OHI */ char comrel[12] = { ONE, OEQ, OGT, OHI, OGE, OHS, OLT, OLO, OLE, OLS, /n/sourcesdump/2005/1211/plan9/sys/src/cmd/cc/sub.c:1522,1527 - /n/sourcesdump/2005/1212/plan9/sys/src/cmd/cc/sub.c:1523,1529 char typechl[NTYPE]; char typechlv[NTYPE]; + char typechlvp[NTYPE]; int typechlinit[] = { TCHAR, TUCHAR, TSHORT, TUSHORT, TINT, TUINT, TLONG, TULONG, -1, /n/sourcesdump/2005/1211/plan9/sys/src/cmd/cc/sub.c:1868,1877 - /n/sourcesdump/2005/1212/plan9/sys/src/cmd/cc/sub.c:1870,1881 urk("typechl", nelem(typechl), typechlinit[i]); typechl[typechlinit[i]] = 1; typechlv[typechlinit[i]] = 1; + typechlvp[typechlinit[i]] = 1; } for(i=0; typechlpinit[i] >= 0; i++) { urk("typechlp", nelem(typechlp), typechlpinit[i]); typechlp[typechlpinit[i]] = 1; + typechlvp[typechlinit[i]] = 1; } for(i=0; typechlpfdinit[i] >= 0; i++) { urk("typechlpfd", nelem(typechlpfd), typechlpfdinit[i]); /n/sourcesdump/2005/1211/plan9/sys/src/cmd/cc/sub.c:1893,1898 - /n/sourcesdump/2005/1212/plan9/sys/src/cmd/cc/sub.c:1897,1903 urk("typev", nelem(typev), typevinit[i]); typev[typevinit[i]] = 1; typechlv[typevinit[i]] = 1; + typechlvp[typechlinit[i]] = 1; } for(i=0; typefdinit[i] >= 0; i++) { urk("typefd", nelem(typefd), typefdinit[i]);