|
|
1.1 ! root 1: # include "mfile1" ! 2: ! 3: # include "lint.h" ! 4: ! 5: # include <ctype.h> ! 6: ! 7: # define VAL 0 ! 8: # define EFF 1 ! 9: ! 10: /* these are appropriate for the -p flag */ ! 11: int SZCHAR = 8; ! 12: int SZINT = 16; ! 13: int SZFLOAT = 32; ! 14: int SZDOUBLE = 64; ! 15: int SZLONG = 32; ! 16: int SZSHORT = 16; ! 17: int SZPOINT = 16; ! 18: int ALCHAR = 8; ! 19: int ALINT = 16; ! 20: int ALFLOAT = 32; ! 21: int ALDOUBLE = 64; ! 22: int ALLONG = 32; ! 23: int ALSHORT = 16; ! 24: int ALPOINT = 16; ! 25: int ALSTRUCT = 16; ! 26: ! 27: int vflag = 1; /* tell about unused argments */ ! 28: int xflag = 0; /* tell about unused externals */ ! 29: int argflag = 0; /* used to turn off complaints about arguments */ ! 30: int libflag = 0; /* used to generate library descriptions */ ! 31: int vaflag = -1; /* used to signal functions with a variable number of args */ ! 32: int aflag = 0; /* used to check precision of assignments */ ! 33: #ifdef FMTARGS ! 34: FILE *stmpfile; /* string tmp file pointer */ ! 35: char *stmpname; /* string tmp file name */ ! 36: int plkflag = -1, /* used to signal printf-like functions */ ! 37: slkflag = -1; /* used to signal scanf-like functions */ ! 38: #endif ! 39: ! 40: /* flags for the "outdef" function */ ! 41: # define USUAL (-101) ! 42: # define DECTY (-102) ! 43: # define NOFILE (-103) ! 44: # define SVLINE (-104) ! 45: ! 46: # define LNAMES 250 ! 47: ! 48: struct lnm { ! 49: short lid, flgs; ! 50: } lnames[LNAMES], *lnp; ! 51: ! 52: contx( p, down, pl, pr ) register NODE *p; register *pl, *pr; { ! 53: ! 54: *pl = *pr = VAL; ! 55: switch( p->in.op ){ ! 56: ! 57: case ANDAND: ! 58: case OROR: ! 59: case QUEST: ! 60: *pr = down; ! 61: break; ! 62: ! 63: case SCONV: ! 64: case PCONV: ! 65: case COLON: ! 66: *pr = *pl = down; ! 67: break; ! 68: ! 69: case COMOP: ! 70: *pl = EFF; ! 71: *pr = down; ! 72: ! 73: case FORCE: ! 74: case INIT: ! 75: case UNARY CALL: ! 76: case STCALL: ! 77: case UNARY STCALL: ! 78: case CALL: ! 79: case UNARY FORTCALL: ! 80: case FORTCALL: ! 81: case CBRANCH: ! 82: break; ! 83: ! 84: default: ! 85: if( asgop(p->in.op) ) break; ! 86: if( p->in.op == UNARY MUL && ( p->in.type == STRTY || p->in.type == UNIONTY || p->in.type == UNDEF) ) { ! 87: /* struct x f( ); main( ) { (void) f( ); } ! 88: * the the cast call appears as U* UNDEF ! 89: */ ! 90: break; /* the compiler does this... */ ! 91: } ! 92: if( down == EFF && hflag ) werror( "null effect" ); ! 93: ! 94: } ! 95: } ! 96: ! 97: ecode( p ) NODE *p; { ! 98: /* compile code for p */ ! 99: ! 100: fwalk( p, contx, EFF ); ! 101: lnp = lnames; ! 102: lprt( p, EFF, 0 ); ! 103: } ! 104: ! 105: ejobcode( flag ){ ! 106: /* called after processing each job */ ! 107: /* flag is nonzero if errors were detected */ ! 108: register k; ! 109: register struct symtab *p; ! 110: ! 111: for( p=stab; p< &stab[SYMTSZ]; ++p ){ ! 112: ! 113: if( p->stype != TNULL ) { ! 114: ! 115: if( p->stype == STRTY || p->stype == UNIONTY ){ ! 116: if( dimtab[p->sizoff+1] < 0 ){ /* never defined */ ! 117: #ifndef FLEXNAMES ! 118: if( hflag ) werror( "struct/union %.8s never defined", p->sname ); ! 119: #else ! 120: if( hflag ) werror( "struct/union %s never defined", p->sname ); ! 121: #endif ! 122: } ! 123: } ! 124: ! 125: switch( p->sclass ){ ! 126: ! 127: case STATIC: ! 128: if( p->suse > 0 ){ ! 129: k = lineno; ! 130: lineno = p->suse; ! 131: #ifndef FLEXNAMES ! 132: uerror( "static variable %.8s unused", ! 133: #else ! 134: uerror( "static variable %s unused", ! 135: #endif ! 136: p->sname ); ! 137: lineno = k; ! 138: break; ! 139: } ! 140: ! 141: case EXTERN: ! 142: case USTATIC: ! 143: /* with the xflag, worry about externs not used */ ! 144: /* the filename may be wrong here... */ ! 145: if( xflag && p->suse >= 0 && !libflag ){ ! 146: outdef( p, LDX, NOFILE ); ! 147: } ! 148: ! 149: case EXTDEF: ! 150: if( p->suse < 0 ){ /* used */ ! 151: outdef( p, LUM, SVLINE ); ! 152: } ! 153: break; ! 154: } ! 155: ! 156: } ! 157: ! 158: } ! 159: exit( 0 ); ! 160: } ! 161: ! 162: astype( t, i ) ATYPE *t; { ! 163: TWORD tt; ! 164: int j, k=0; ! 165: ! 166: if( (tt=BTYPE(t->aty))==STRTY || tt==UNIONTY ){ ! 167: if( i<0 || i>= DIMTABSZ-3 ){ ! 168: werror( "lint's little mind is blown" ); ! 169: } ! 170: else { ! 171: j = dimtab[i+3]; ! 172: if( j<0 || j>SYMTSZ ){ ! 173: k = ((-j)<<5)^dimtab[i]|1; ! 174: } ! 175: else { ! 176: if( stab[j].suse <= 0 ) { ! 177: #ifndef FLEXNAMES ! 178: werror( "no line number for %.8s", ! 179: #else ! 180: werror( "no line number for %s", ! 181: #endif ! 182: stab[j].sname ); ! 183: } ! 184: else k = (stab[j].suse<<5) ^ dimtab[i]; ! 185: } ! 186: } ! 187: ! 188: t->extra = k; ! 189: return( 1 ); ! 190: } ! 191: else return( 0 ); ! 192: } ! 193: ! 194: bfcode( a, n ) int a[]; { ! 195: /* code for the beginning of a function; a is an array of ! 196: indices in stab for the arguments; n is the number */ ! 197: /* this must also set retlab */ ! 198: register i, lty; ! 199: register struct symtab *cfp; ! 200: static ATYPE t; ! 201: ! 202: retlab = 1; ! 203: ! 204: cfp = &stab[curftn]; ! 205: lty = libflag ? LIB : LDI; ! 206: ! 207: #ifdef FMTARGS ! 208: /* ! 209: * printf-like and scanf-like functions. ! 210: * "n" should be both the number of required arguments and ! 211: * the position of the format string in the arg list. ! 212: */ ! 213: if (plkflag > 0) ! 214: if (n < plkflag) ! 215: uerror ("declare the required arguments!"); ! 216: else { ! 217: n = plkflag; ! 218: lty |= LPF; ! 219: } ! 220: if (slkflag > 0) ! 221: if (n < slkflag) ! 222: uerror ("declare the required arguments!"); ! 223: else { ! 224: n = slkflag; ! 225: lty |= LSF; ! 226: } ! 227: #endif ! 228: /* if variable number of arguments, only print the ones which will be checked */ ! 229: if( vaflag > 0 ){ ! 230: if( n < vaflag ) werror( "declare the VARARGS arguments you want checked!" ); ! 231: else n = vaflag; ! 232: } ! 233: fsave( ftitle ); ! 234: outdef( cfp, lty, vaflag>=0?-n:n ); ! 235: vaflag = -1; ! 236: #ifdef FMTARGS ! 237: plkflag = slkflag = -1; ! 238: #endif ! 239: ! 240: /* output the arguments */ ! 241: if( n ){ ! 242: for( i=0; i<n; ++i ) { ! 243: t.aty = stab[a[i]].stype; ! 244: t.extra = 0; ! 245: if( !astype( &t, stab[a[i]].sizoff ) ) { ! 246: switch( t.aty ){ ! 247: ! 248: case ULONG: ! 249: break; ! 250: ! 251: case CHAR: ! 252: case SHORT: ! 253: t.aty = INT; ! 254: break; ! 255: ! 256: case UCHAR: ! 257: case USHORT: ! 258: case UNSIGNED: ! 259: t.aty = UNSIGNED; ! 260: break; ! 261: ! 262: } ! 263: } ! 264: fwrite( (char *)&t, sizeof(ATYPE), 1, stdout ); ! 265: } ! 266: } ! 267: } ! 268: ! 269: ctargs( p ) NODE *p; { ! 270: /* count arguments; p points to at least one */ ! 271: /* the arguemnts are a tower of commas to the left */ ! 272: register c; ! 273: c = 1; /* count the rhs */ ! 274: while( p->in.op == CM ){ ! 275: ++c; ! 276: p = p->in.left; ! 277: } ! 278: return( c ); ! 279: } ! 280: ! 281: lpta( p ) NODE *p; { ! 282: static ATYPE t; ! 283: ! 284: if( p->in.op == CM ){ ! 285: lpta( p->in.left ); ! 286: p = p->in.right; ! 287: } ! 288: ! 289: t.aty = p->in.type; ! 290: t.extra = (p->in.op==ICON); ! 291: ! 292: if( !astype( &t, p->in.csiz ) ) { ! 293: switch( t.aty ){ ! 294: #ifdef FMTARGS ! 295: case CHAR+PTR: ! 296: t.straddr = -p->tn.rval; ! 297: t.extra = 0; ! 298: break; ! 299: #endif ! 300: ! 301: case CHAR: ! 302: case SHORT: ! 303: t.aty = INT; ! 304: case LONG: ! 305: case ULONG: ! 306: case INT: ! 307: case UNSIGNED: ! 308: break; ! 309: ! 310: case UCHAR: ! 311: case USHORT: ! 312: t.aty = UNSIGNED; ! 313: break; ! 314: ! 315: case FLOAT: ! 316: t.aty = DOUBLE; ! 317: t.extra = 0; ! 318: break; ! 319: ! 320: default: ! 321: t.extra = 0; ! 322: break; ! 323: } ! 324: } ! 325: fwrite( (char *)&t, sizeof(ATYPE), 1, stdout ); ! 326: } ! 327: ! 328: # define VALSET 1 ! 329: # define VALUSED 2 ! 330: # define VALASGOP 4 ! 331: # define VALADDR 8 ! 332: ! 333: lprt( p, down, uses ) register NODE *p; { ! 334: register struct symtab *q; ! 335: register id; ! 336: register acount; ! 337: register down1, down2; ! 338: register use1, use2; ! 339: register struct lnm *np1, *np2; ! 340: ! 341: /* first, set variables which are set... */ ! 342: ! 343: use1 = use2 = VALUSED; ! 344: if( p->in.op == ASSIGN ) use1 = VALSET; ! 345: else if( p->in.op == UNARY AND ) use1 = VALADDR; ! 346: else if( asgop( p->in.op ) ){ /* =ops */ ! 347: use1 = VALUSED|VALSET; ! 348: if( down == EFF ) use1 |= VALASGOP; ! 349: } ! 350: ! 351: ! 352: /* print the lines for lint */ ! 353: ! 354: down2 = down1 = VAL; ! 355: acount = 0; ! 356: ! 357: switch( p->in.op ){ ! 358: ! 359: case EQ: ! 360: case NE: ! 361: case GT: ! 362: case GE: ! 363: case LT: ! 364: case LE: ! 365: if( p->in.left->in.type == CHAR && p->in.right->in.op==ICON && p->in.right->tn.lval < 0 ){ ! 366: werror( "nonportable character comparison" ); ! 367: } ! 368: if( (p->in.op==EQ || p->in.op==NE ) && ISUNSIGNED(p->in.left->in.type) && p->in.right->in.op == ICON ){ ! 369: if( p->in.right->tn.lval < 0 && p->in.right->tn.rval == NONAME && !ISUNSIGNED(p->in.right->in.type) ){ ! 370: werror( "comparison of unsigned with negative constant" ); ! 371: } ! 372: } ! 373: break; ! 374: ! 375: case UGE: ! 376: case ULT: ! 377: if( p->in.right->in.op == ICON && p->in.right->tn.lval == 0 && p->in.right->tn.rval == NONAME ){ ! 378: werror( "unsigned comparison with 0?" ); ! 379: break; ! 380: } ! 381: case UGT: ! 382: case ULE: ! 383: if( p->in.right->in.op == ICON && p->in.right->tn.lval <= 0 && !ISUNSIGNED(p->in.right->in.type) && p->in.right->tn.rval == NONAME ){ ! 384: werror( "degenerate unsigned comparison" ); ! 385: } ! 386: break; ! 387: ! 388: case COMOP: ! 389: down1 = EFF; ! 390: ! 391: case ANDAND: ! 392: case OROR: ! 393: case QUEST: ! 394: down2 = down; ! 395: /* go recursively left, then right */ ! 396: np1 = lnp; ! 397: lprt( p->in.left, down1, use1 ); ! 398: np2 = lnp; ! 399: lprt( p->in.right, down2, use2 ); ! 400: lmerge( np1, np2, 0 ); ! 401: return; ! 402: ! 403: case SCONV: ! 404: case PCONV: ! 405: case COLON: ! 406: down1 = down2 = down; ! 407: break; ! 408: ! 409: case CALL: ! 410: case STCALL: ! 411: case FORTCALL: ! 412: acount = ctargs( p->in.right ); ! 413: case UNARY CALL: ! 414: case UNARY STCALL: ! 415: case UNARY FORTCALL: ! 416: if( p->in.left->in.op == ICON && (id=p->in.left->tn.rval) != NONAME ){ /* used to be &name */ ! 417: struct symtab *sp = &stab[id]; ! 418: int lty; ! 419: /* if a function used in an effects context is ! 420: * cast to type void then consider its value ! 421: * to have been disposed of properly ! 422: * thus a call of type undef in an effects ! 423: * context is construed to be used in a value ! 424: * context ! 425: */ ! 426: if ((down == EFF) && (p->in.type != UNDEF)) { ! 427: lty = LUE; ! 428: } else if (down == EFF) { ! 429: lty = LUV | LUE; ! 430: } else { ! 431: lty = LUV; ! 432: } ! 433: fsave( ftitle ); ! 434: outdef(sp, lty, acount); ! 435: if( acount ) { ! 436: lpta( p->in.right ); ! 437: } ! 438: } ! 439: break; ! 440: ! 441: case ICON: ! 442: /* look for &name case */ ! 443: if( (id = p->tn.rval) >= 0 && id != NONAME ){ ! 444: q = &stab[id]; ! 445: q->sflags |= (SREF|SSET); ! 446: q->suse = -lineno; ! 447: } ! 448: return; ! 449: ! 450: case NAME: ! 451: if( (id = p->tn.rval) >= 0 && id != NONAME ){ ! 452: q = &stab[id]; ! 453: if( (uses&VALUSED) && !(q->sflags&SSET) ){ ! 454: if( q->sclass == AUTO || q->sclass == REGISTER ){ ! 455: if( !ISARY(q->stype ) && !ISFTN(q->stype) && q->stype!=STRTY ){ ! 456: #ifndef FLEXNAMES ! 457: werror( "%.8s may be used before set", q->sname ); ! 458: #else ! 459: werror( "%s may be used before set", q->sname ); ! 460: #endif ! 461: q->sflags |= SSET; ! 462: } ! 463: } ! 464: } ! 465: if( uses & VALASGOP ) break; /* not a real use */ ! 466: if( uses & VALSET ) q->sflags |= SSET; ! 467: if( uses & VALUSED ) q->sflags |= SREF; ! 468: if( uses & VALADDR ) q->sflags |= (SREF|SSET); ! 469: if( p->tn.lval == 0 ){ ! 470: lnp->lid = id; ! 471: lnp->flgs = (uses&VALADDR)?0:((uses&VALSET)?VALSET:VALUSED); ! 472: if( ++lnp >= &lnames[LNAMES] ) --lnp; ! 473: } ! 474: } ! 475: return; ! 476: ! 477: } ! 478: ! 479: /* recurse, going down the right side first if we can */ ! 480: ! 481: switch( optype(p->in.op) ){ ! 482: ! 483: case BITYPE: ! 484: np1 = lnp; ! 485: lprt( p->in.right, down2, use2 ); ! 486: case UTYPE: ! 487: np2 = lnp; ! 488: lprt( p->in.left, down1, use1 ); ! 489: } ! 490: ! 491: if( optype(p->in.op) == BITYPE ){ ! 492: if( p->in.op == ASSIGN && p->in.left->in.op == NAME ){ /* special case for a = .. a .. */ ! 493: lmerge( np1, np2, 0 ); ! 494: } ! 495: else lmerge( np1, np2, p->in.op != COLON ); ! 496: /* look for assignments to fields, and complain */ ! 497: if( p->in.op == ASSIGN && p->in.left->in.op == FLD && p->in.right->in.op == ICON ) fldcon( p ); ! 498: } ! 499: ! 500: } ! 501: ! 502: lmerge( np1, np2, flag ) struct lnm *np1, *np2; { ! 503: /* np1 and np2 point to lists of lnm members, for the two sides ! 504: * of a binary operator ! 505: * flag is 1 if commutation is possible, 0 otherwise ! 506: * lmerge returns a merged list, starting at np1, resetting lnp ! 507: * it also complains, if appropriate, about side effects ! 508: */ ! 509: ! 510: register struct lnm *npx, *npy; ! 511: ! 512: for( npx = np2; npx < lnp; ++npx ){ ! 513: ! 514: /* is it already there? */ ! 515: for( npy = np1; npy < np2; ++npy ){ ! 516: if( npx->lid == npy->lid ){ /* yes */ ! 517: if( npx->flgs == 0 || npx->flgs == (VALSET|VALUSED) ) ! 518: ; /* do nothing */ ! 519: else if( (npx->flgs|npy->flgs)== (VALSET|VALUSED) || ! 520: (npx->flgs&npy->flgs&VALSET) ){ ! 521: #ifndef FLEXNAMES ! 522: if( flag ) werror( "%.8s evaluation order undefined", stab[npy->lid].sname ); ! 523: #else ! 524: if( flag ) werror( "%s evaluation order undefined", stab[npy->lid].sname ); ! 525: #endif ! 526: } ! 527: if( npy->flgs == 0 ) npx->flgs = 0; ! 528: else npy->flgs |= npx->flgs; ! 529: goto foundit; ! 530: } ! 531: } ! 532: ! 533: /* not there: update entry */ ! 534: np2->lid = npx->lid; ! 535: np2->flgs = npx->flgs; ! 536: ++np2; ! 537: ! 538: foundit: ; ! 539: } ! 540: ! 541: /* all finished: merged list is at np1 */ ! 542: lnp = np2; ! 543: } ! 544: ! 545: efcode(){ ! 546: /* code for the end of a function */ ! 547: register struct symtab *cfp; ! 548: ! 549: cfp = &stab[curftn]; ! 550: if( retstat & RETVAL ) outdef( cfp, LRV, DECTY ); ! 551: if( !vflag ){ ! 552: vflag = argflag; ! 553: argflag = 0; ! 554: } ! 555: if( retstat == RETVAL+NRETVAL ) ! 556: #ifndef FLEXNAMES ! 557: werror( "function %.8s has return(e); and return;", cfp->sname); ! 558: #else ! 559: werror( "function %s has return(e); and return;", cfp->sname); ! 560: #endif ! 561: } ! 562: ! 563: aocode(p) struct symtab *p; { ! 564: /* called when automatic p removed from stab */ ! 565: register struct symtab *cfs; ! 566: cfs = &stab[curftn]; ! 567: if(p->suse>0 && !(p->sflags&(SMOS|STAG)) ){ ! 568: if( p->sclass == PARAM ){ ! 569: #ifndef FLEXNAMES ! 570: if( vflag ) werror( "argument %.8s unused in function %.8s", ! 571: #else ! 572: if( vflag ) werror( "argument %s unused in function %s", ! 573: #endif ! 574: p->sname, ! 575: cfs->sname ); ! 576: } ! 577: else { ! 578: #ifndef FLEXNAMES ! 579: if( p->sclass != TYPEDEF ) werror( "%.8s unused in function %.8s", ! 580: #else ! 581: if( p->sclass != TYPEDEF ) werror( "%s unused in function %s", ! 582: #endif ! 583: p->sname, cfs->sname ); ! 584: } ! 585: } ! 586: ! 587: if( p->suse < 0 && (p->sflags & (SSET|SREF|SMOS)) == SSET && ! 588: !ISARY(p->stype) && !ISFTN(p->stype) ){ ! 589: ! 590: #ifndef FLEXNAMES ! 591: werror( "%.8s set but not used in function %.8s", p->sname, cfs->sname ); ! 592: #else ! 593: werror( "%s set but not used in function %s", p->sname, cfs->sname ); ! 594: #endif ! 595: } ! 596: ! 597: if( p->stype == STRTY || p->stype == UNIONTY || p->stype == ENUMTY ){ ! 598: #ifndef FLEXNAMES ! 599: if( dimtab[p->sizoff+1] < 0 ) werror( "structure %.8s never defined", p->sname ); ! 600: #else ! 601: if( dimtab[p->sizoff+1] < 0 ) werror( "structure %s never defined", p->sname ); ! 602: #endif ! 603: } ! 604: ! 605: } ! 606: ! 607: defnam( p ) register struct symtab *p; { ! 608: /* define the current location as the name p->sname */ ! 609: ! 610: if( p->sclass == STATIC && p->slevel>1 ) return; ! 611: ! 612: if( !ISFTN( p->stype ) ) outdef( p, libflag?LIB:LDI, USUAL ); ! 613: } ! 614: ! 615: zecode( n ){ ! 616: /* n integer words of zeros */ ! 617: OFFSZ temp; ! 618: temp = n; ! 619: inoff += temp*SZINT; ! 620: ; ! 621: } ! 622: ! 623: andable( p ) NODE *p; { /* p is a NAME node; can it accept & ? */ ! 624: register r; ! 625: ! 626: if( p->in.op != NAME ) cerror( "andable error" ); ! 627: ! 628: if( (r = p->tn.rval) < 0 ) return(1); /* labels are andable */ ! 629: ! 630: if( stab[r].sclass == AUTO || stab[r].sclass == PARAM ) return(0); ! 631: #ifndef FLEXNAMES ! 632: if( stab[r].sclass == REGISTER ) uerror( "can't take & of %.8s", stab[r].sname ); ! 633: #else ! 634: if( stab[r].sclass == REGISTER ) uerror( "can't take & of %s", stab[r].sname ); ! 635: #endif ! 636: return(1); ! 637: } ! 638: ! 639: NODE * ! 640: clocal(p) NODE *p; { ! 641: ! 642: /* this is called to do local transformations on ! 643: an expression tree preparitory to its being ! 644: written out in intermediate code. ! 645: */ ! 646: ! 647: /* the major essential job is rewriting the ! 648: automatic variables and arguments in terms of ! 649: REG and OREG nodes */ ! 650: /* conversion ops which are not necessary are also clobbered here */ ! 651: /* in addition, any special features (such as rewriting ! 652: exclusive or) are easily handled here as well */ ! 653: ! 654: register o; ! 655: register unsigned t, tl; ! 656: ! 657: switch( o = p->in.op ){ ! 658: ! 659: case SCONV: ! 660: case PCONV: ! 661: if( p->in.left->in.type==ENUMTY ){ ! 662: p->in.left = pconvert( p->in.left ); ! 663: } ! 664: /* assume conversion takes place; type is inherited */ ! 665: t = p->in.type; ! 666: tl = p->in.left->in.type; ! 667: if( aflag && (tl==LONG||tl==ULONG) && (t!=LONG&&t!=ULONG) ){ ! 668: werror( "long assignment may lose accuracy" ); ! 669: } ! 670: if( aflag>=2 && (tl!=LONG&&tl!=ULONG) && (t==LONG||t==ULONG) && p->in.left->in.op != ICON ){ ! 671: werror( "assignment to long may sign-extend incorrectly" ); ! 672: } ! 673: if( ISPTR(tl) && ISPTR(t) ){ ! 674: tl = DECREF(tl); ! 675: t = DECREF(t); ! 676: switch( ISFTN(t) + ISFTN(tl) ){ ! 677: ! 678: case 0: /* neither is a function pointer */ ! 679: if( talign(t,p->fn.csiz) > talign(tl,p->in.left->fn.csiz) ){ ! 680: if( hflag||pflag ) werror( "possible pointer alignment problem" ); ! 681: } ! 682: break; ! 683: ! 684: case 1: ! 685: werror( "questionable conversion of function pointer" ); ! 686: ! 687: case 2: ! 688: ; ! 689: } ! 690: } ! 691: p->in.left->in.type = p->in.type; ! 692: p->in.left->fn.cdim = p->fn.cdim; ! 693: p->in.left->fn.csiz = p->fn.csiz; ! 694: p->in.op = FREE; ! 695: return( p->in.left ); ! 696: ! 697: case PVCONV: ! 698: case PMCONV: ! 699: if( p->in.right->in.op != ICON ) cerror( "bad conversion"); ! 700: p->in.op = FREE; ! 701: return( buildtree( o==PMCONV?MUL:DIV, p->in.left, p->in.right ) ); ! 702: ! 703: } ! 704: ! 705: return(p); ! 706: } ! 707: ! 708: NODE * ! 709: offcon( off, t, d, s ) OFFSZ off; TWORD t;{ /* make a structure offset node */ ! 710: register NODE *p; ! 711: p = bcon(0); ! 712: p->tn.lval = off/SZCHAR; ! 713: return(p); ! 714: } ! 715: ! 716: noinit(){ ! 717: /* storage class for such as "int a;" */ ! 718: return( pflag ? EXTDEF : EXTERN ); ! 719: } ! 720: ! 721: ! 722: cinit( p, sz ) NODE *p; { /* initialize p into size sz */ ! 723: inoff += sz; ! 724: if( p->in.op == INIT ){ ! 725: if( p->in.left->in.op == ICON ) return; ! 726: if( p->in.left->in.op == NAME && p->in.left->in.type == MOE ) return; ! 727: } ! 728: uerror( "illegal initialization" ); ! 729: } ! 730: ! 731: char * ! 732: exname( p ) char *p; { ! 733: /* make a name look like an external name in the local machine */ ! 734: static char aa[8]; ! 735: register int i; ! 736: ! 737: if( !pflag ) return(p); ! 738: for( i=0; i<6; ++i ){ ! 739: if( isupper(*p ) ) aa[i] = tolower( *p ); ! 740: else aa[i] = *p; ! 741: if( *p ) ++p; ! 742: } ! 743: aa[6] = '\0'; ! 744: return( aa ); ! 745: } ! 746: ! 747: char * ! 748: strip(s) char *s; { ! 749: #ifndef FLEXNAMES ! 750: static char x[LFNM+1]; ! 751: #else ! 752: static char x[BUFSIZ]; ! 753: #endif ! 754: register char *p; ! 755: ! 756: for( p=x; *s; ++s ){ ! 757: if( *s == '/' ) p=x; ! 758: else if( *s != '"' ){ ! 759: #ifndef FLEXNAMES ! 760: /* PATCHED by ROBERT HENRY on 8Jul80 to fix 14 character file name bug */ ! 761: if( p >= &x[LFNM] ) ! 762: cerror( "filename too long" ); ! 763: #endif ! 764: *p++ = *s; ! 765: } ! 766: } ! 767: *p = '\0'; ! 768: #ifndef FLEXNAMES ! 769: return( x ); ! 770: #else ! 771: return( hash(x) ); ! 772: #endif ! 773: } ! 774: ! 775: fsave( s ) char *s; { ! 776: static union rec fsname; ! 777: s = strip( s ); ! 778: #ifndef FLEXNAMES ! 779: if( strncmp( s, fsname.f.fn, LFNM ) ){ ! 780: #else ! 781: if( strcmp(s, fsname.f.fn)) { ! 782: #endif ! 783: /* new one */ ! 784: #ifndef FLEXNAMES ! 785: strncpy( fsname.f.fn, s, LFNM ); ! 786: #else ! 787: fsname.f.fn = s; ! 788: #endif ! 789: fsname.f.decflag = LFN; ! 790: fwrite( (char *)&fsname, sizeof(fsname), 1, stdout ); ! 791: #ifdef FLEXNAMES ! 792: fwrite( fsname.f.fn, strlen(fsname.f.fn)+1, 1, stdout ); ! 793: #endif ! 794: } ! 795: } ! 796: ! 797: where(f){ /* print true location of error */ ! 798: if( f == 'u' && nerrors>1 ) --nerrors; /* don't get "too many errors" */ ! 799: fprintf( stderr, "%s(%d): ", (f == 'c') ? ftitle : strip(ftitle), lineno ); ! 800: } ! 801: ! 802: /* a number of dummy routines, unneeded by lint */ ! 803: ! 804: branch(n){;} ! 805: defalign(n){;} ! 806: deflab(n){;} ! 807: #ifndef FMTARGS ! 808: bycode(t,i){;} ! 809: #endif ! 810: cisreg(t) TWORD t; {return(1);} /* everyting is a register variable! */ ! 811: ! 812: fldty(p) struct symtab *p; { ! 813: ; /* all types are OK here... */ ! 814: } ! 815: ! 816: fldal(t) unsigned t; { /* field alignment... */ ! 817: if( t == ENUMTY ) return( ALCHAR ); /* this should be thought through better... */ ! 818: if( ISPTR(t) ){ /* really for the benefit of honeywell (and someday IBM) */ ! 819: if( pflag ) uerror( "nonportable field type" ); ! 820: } ! 821: else uerror( "illegal field type" ); ! 822: return(ALINT); ! 823: } ! 824: ! 825: main( argc, argv ) char *argv[]; { ! 826: char *p; ! 827: ! 828: /* handle options */ ! 829: ! 830: for( p=argv[1]; argc>1 && *p; ++p ){ ! 831: ! 832: switch( *p ){ ! 833: ! 834: case '-': ! 835: continue; ! 836: ! 837: case '\0': ! 838: break; ! 839: ! 840: case 'b': ! 841: brkflag = 1; ! 842: continue; ! 843: ! 844: case 'p': ! 845: pflag = 1; ! 846: continue; ! 847: ! 848: case 'c': ! 849: cflag = 1; ! 850: continue; ! 851: ! 852: case 's': ! 853: /* for the moment, -s triggers -h */ ! 854: ! 855: case 'h': ! 856: hflag = 1; ! 857: continue; ! 858: ! 859: case 'L': ! 860: libflag = 1; ! 861: case 'v': ! 862: vflag = 0; ! 863: continue; ! 864: ! 865: case 'x': ! 866: xflag = 1; ! 867: continue; ! 868: ! 869: case 'a': ! 870: ++aflag; ! 871: case 'u': /* done in second pass */ ! 872: case 'n': /* done in shell script */ ! 873: continue; ! 874: ! 875: case 't': ! 876: werror( "option %c now default: see `man 6 lint'", *p ); ! 877: continue; ! 878: ! 879: #ifdef FMTARGS ! 880: case 'S': ! 881: for (stmpname = p + 1; p[1]; p++); ! 882: if (stmpfile = fopen (stmpname, "r+")) ! 883: fseek (stmpfile, 0L, 2); ! 884: else if (stmpfile = fopen (stmpname, "w")) ! 885: /* see getlab() */ ! 886: fputs ("0123456789\n", stmpfile); ! 887: else { ! 888: uerror ("%s: can't open", stmpname); ! 889: exit (1); ! 890: } ! 891: continue; ! 892: #endif ! 893: default: ! 894: uerror( "illegal option: %c", *p ); ! 895: continue; ! 896: } ! 897: } ! 898: ! 899: if( !pflag ){ /* set sizes to sizes of target machine */ ! 900: # ifdef gcos ! 901: SZCHAR = ALCHAR = 9; ! 902: # else ! 903: SZCHAR = ALCHAR = 8; ! 904: # endif ! 905: SZINT = ALINT = sizeof(int)*SZCHAR; ! 906: SZFLOAT = ALFLOAT = sizeof(float)*SZCHAR; ! 907: SZDOUBLE = ALDOUBLE = sizeof(double)*SZCHAR; ! 908: SZLONG = ALLONG = sizeof(long)*SZCHAR; ! 909: SZSHORT = ALSHORT = sizeof(short)*SZCHAR; ! 910: SZPOINT = ALPOINT = sizeof(int *)*SZCHAR; ! 911: ALSTRUCT = ALINT; ! 912: /* now, fix some things up for various machines (I wish we had "alignof") */ ! 913: ! 914: # ifdef pdp11 ! 915: ALLONG = ALDOUBLE = ALFLOAT = ALINT; ! 916: #endif ! 917: # ifdef ibm ! 918: ALSTRUCT = ALCHAR; ! 919: #endif ! 920: } ! 921: ! 922: return( mainp1( argc, argv ) ); ! 923: } ! 924: ! 925: ctype( type ) unsigned type; { /* are there any funny types? */ ! 926: return( type ); ! 927: } ! 928: ! 929: commdec( i ){ ! 930: /* put out a common declaration */ ! 931: outdef( &stab[i], libflag?LIB:LDC, USUAL ); ! 932: } ! 933: ! 934: isitfloat ( s ) char *s; { ! 935: /* s is a character string; ! 936: if floating point is implemented, set dcon to the value of s */ ! 937: /* lint version ! 938: */ ! 939: dcon = atof( s ); ! 940: return( FCON ); ! 941: } ! 942: ! 943: fldcon( p ) register NODE *p; { ! 944: /* p is an assignment of a constant to a field */ ! 945: /* check to see if the assignment is going to overflow, or otherwise cause trouble */ ! 946: register s; ! 947: CONSZ v; ! 948: ! 949: if( !hflag & !pflag ) return; ! 950: ! 951: s = UPKFSZ(p->in.left->tn.rval); ! 952: v = p->in.right->tn.lval; ! 953: ! 954: switch( p->in.left->in.type ){ ! 955: ! 956: case CHAR: ! 957: case INT: ! 958: case SHORT: ! 959: case LONG: ! 960: case ENUMTY: ! 961: if( v>=0 && (v>>(s-1))==0 ) return; ! 962: werror( "precision lost in assignment to (possibly sign-extended) field" ); ! 963: default: ! 964: return; ! 965: ! 966: case UNSIGNED: ! 967: case UCHAR: ! 968: case USHORT: ! 969: case ULONG: ! 970: if( v<0 || (v>>s)!=0 ) werror( "precision lost in field assignment" ); ! 971: ! 972: return; ! 973: } ! 974: ! 975: } ! 976: ! 977: outdef( p, lty, mode ) struct symtab *p; { ! 978: /* output a definition for the second pass */ ! 979: /* if mode is > USUAL, it is the number of args */ ! 980: char *fname; ! 981: TWORD t; ! 982: int line; ! 983: static union rec rc; ! 984: ! 985: if( mode == NOFILE ){ ! 986: fname = "???"; ! 987: line = p->suse; ! 988: } ! 989: else if( mode == SVLINE ){ ! 990: fname = ftitle; ! 991: line = -p->suse; ! 992: } ! 993: else { ! 994: fname = ftitle; ! 995: line = lineno; ! 996: } ! 997: fsave( fname ); ! 998: #ifndef FLEXNAMES ! 999: strncpy( rc.l.name, exname(p->sname), LCHNM ); ! 1000: #endif ! 1001: rc.l.decflag = lty; ! 1002: t = p->stype; ! 1003: if( mode == DECTY ) t = DECREF(t); ! 1004: rc.l.type.aty = t; ! 1005: rc.l.type.extra = 0; ! 1006: astype( &rc.l.type, p->sizoff ); ! 1007: rc.l.nargs = (mode>USUAL) ? mode : 0; ! 1008: rc.l.fline = line; ! 1009: fwrite( (char *)&rc, sizeof(rc), 1, stdout ); ! 1010: #ifdef FLEXNAMES ! 1011: rc.l.name = exname(p->sname); ! 1012: fwrite( rc.l.name, strlen(rc.l.name)+1, 1, stdout ); ! 1013: #endif ! 1014: } ! 1015: int proflg; ! 1016: int gdebug; ! 1017: ! 1018: #ifdef FMTARGS ! 1019: ! 1020: extern long ftell(); ! 1021: ! 1022: ! 1023: /* ARGSUSED */ ! 1024: ! 1025: bycode (c, i) ! 1026: int c, i; ! 1027: { ! 1028: if (c >= 0 && stmpfile) ! 1029: fputc (c & 0177, stmpfile); ! 1030: return; ! 1031: } ! 1032: ! 1033: ! 1034: /* ! 1035: * returned value should be at least 10. see tmpopen(). ! 1036: */ ! 1037: ! 1038: int ! 1039: getlab() ! 1040: { ! 1041: return ((int) ftell (stmpfile)); ! 1042: } ! 1043: #endif FMTARGS
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.