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