|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)lint.c 1.10 (Berkeley) 3/20/86"; ! 3: #endif lint ! 4: ! 5: # include "pass1.h" ! 6: ! 7: # include "lmanifest.h" ! 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->fn.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: int s; ! 655: ! 656: switch( o = p->in.op ){ ! 657: ! 658: case SCONV: ! 659: case PCONV: ! 660: if( p->in.left->in.type==ENUMTY ){ ! 661: p->in.left = pconvert( p->in.left ); ! 662: } ! 663: /* assume conversion takes place; type is inherited */ ! 664: t = p->in.type; ! 665: tl = p->in.left->in.type; ! 666: if( aflag && (tl==LONG||tl==ULONG) && (t!=LONG&&t!=ULONG&&t!=UNDEF) ){ ! 667: werror( "long assignment may lose accuracy" ); ! 668: } ! 669: if( aflag>=2 && (tl!=LONG&&tl!=ULONG) && (t==LONG||t==ULONG) && p->in.left->in.op != ICON ){ ! 670: werror( "assignment to long may sign-extend incorrectly" ); ! 671: } ! 672: if( ISPTR(tl) && ISPTR(t) ){ ! 673: tl = DECREF(tl); ! 674: t = DECREF(t); ! 675: switch( ISFTN(t) + ISFTN(tl) ){ ! 676: ! 677: case 0: /* neither is a function pointer */ ! 678: if( talign(t,p->fn.csiz) > talign(tl,p->in.left->fn.csiz) ){ ! 679: if( hflag||pflag ) werror( "possible pointer alignment problem" ); ! 680: } ! 681: break; ! 682: ! 683: case 1: ! 684: werror( "questionable conversion of function pointer" ); ! 685: ! 686: case 2: ! 687: ; ! 688: } ! 689: } ! 690: p->in.left->in.type = p->in.type; ! 691: p->in.left->fn.cdim = p->fn.cdim; ! 692: p->in.left->fn.csiz = p->fn.csiz; ! 693: p->in.op = FREE; ! 694: return( p->in.left ); ! 695: ! 696: case PVCONV: ! 697: case PMCONV: ! 698: if( p->in.right->in.op != ICON ) cerror( "bad conversion"); ! 699: p->in.op = FREE; ! 700: return( buildtree( o==PMCONV?MUL:DIV, p->in.left, p->in.right ) ); ! 701: ! 702: case RS: ! 703: case LS: ! 704: case ASG RS: ! 705: case ASG LS: ! 706: if( p->in.right->in.op != ICON ) ! 707: break; ! 708: s = p->in.right->tn.lval; ! 709: if( s < 0 ) ! 710: werror( "negative shift" ); ! 711: else ! 712: if( s >= dimtab[ p->fn.csiz ] ) ! 713: werror( "shift greater than size of object" ); ! 714: break; ! 715: ! 716: } ! 717: ! 718: return(p); ! 719: } ! 720: ! 721: NODE * ! 722: offcon( off, t, d, s ) OFFSZ off; TWORD t;{ /* make a structure offset node */ ! 723: register NODE *p; ! 724: p = bcon(0); ! 725: p->tn.lval = off/SZCHAR; ! 726: return(p); ! 727: } ! 728: ! 729: noinit(){ ! 730: /* storage class for such as "int a;" */ ! 731: return( pflag ? EXTDEF : EXTERN ); ! 732: } ! 733: ! 734: ! 735: cinit( p, sz ) NODE *p; { /* initialize p into size sz */ ! 736: inoff += sz; ! 737: if( p->in.op == INIT ){ ! 738: if( p->in.left->in.op == ICON ) return; ! 739: if( p->in.left->in.op == NAME && p->in.left->in.type == MOE ) return; ! 740: } ! 741: uerror( "illegal initialization" ); ! 742: } ! 743: ! 744: char * ! 745: exname( p ) char *p; { ! 746: /* make a name look like an external name in the local machine */ ! 747: static char aa[8]; ! 748: register int i; ! 749: ! 750: if( !pflag ) return(p); ! 751: for( i=0; i<6; ++i ){ ! 752: if( isupper(*p ) ) aa[i] = tolower( *p ); ! 753: else aa[i] = *p; ! 754: if( *p ) ++p; ! 755: } ! 756: aa[6] = '\0'; ! 757: return( aa ); ! 758: } ! 759: ! 760: char * ! 761: strip(s) char *s; { ! 762: #ifndef FLEXNAMES ! 763: static char x[LFNM+1]; ! 764: #else ! 765: static char x[BUFSIZ]; ! 766: #endif ! 767: register char *p; ! 768: static int stripping = 0; ! 769: ! 770: if (stripping) ! 771: return(s); ! 772: stripping++; ! 773: for( p=x; *s; ++s ){ ! 774: if( *s != '"' ){ ! 775: #ifndef FLEXNAMES ! 776: /* PATCHED by ROBERT HENRY on 8Jul80 to fix 14 character file name bug */ ! 777: if( p >= &x[LFNM] ) ! 778: #else ! 779: if( p >= &x[BUFSIZ] ) ! 780: #endif ! 781: cerror( "filename too long" ); ! 782: *p++ = *s; ! 783: } ! 784: } ! 785: stripping = 0; ! 786: *p = '\0'; ! 787: #ifndef FLEXNAMES ! 788: return( x ); ! 789: #else ! 790: return( hash(x) ); ! 791: #endif ! 792: } ! 793: ! 794: fsave( s ) char *s; { ! 795: static union rec fsname; ! 796: s = strip( s ); ! 797: #ifndef FLEXNAMES ! 798: if( strncmp( s, fsname.f.fn, LFNM ) ) ! 799: #else ! 800: if (fsname.f.fn == NULL || strcmp(s, fsname.f.fn)) ! 801: #endif ! 802: { ! 803: /* new one */ ! 804: #ifndef FLEXNAMES ! 805: strncpy( fsname.f.fn, s, LFNM ); ! 806: #else ! 807: fsname.f.fn = s; ! 808: #endif ! 809: fsname.f.decflag = LFN; ! 810: fwrite( (char *)&fsname, sizeof(fsname), 1, stdout ); ! 811: #ifdef FLEXNAMES ! 812: /* if generating a library, prefix with the library name */ ! 813: /* only do this for flexnames */ ! 814: if( libname ){ ! 815: fwrite( libname, strlen(libname), 1, stdout ); ! 816: putchar( ':' ); ! 817: } ! 818: fwrite( fsname.f.fn, strlen(fsname.f.fn)+1, 1, stdout ); ! 819: #endif ! 820: } ! 821: } ! 822: ! 823: where(f){ /* print true location of error */ ! 824: if( f == 'u' && nerrors > 1 ) ! 825: --nerrors; /* don't get "too many errors" */ ! 826: fprintf( stderr, "%s(%d): ", strip(ftitle), lineno); ! 827: } ! 828: ! 829: /* a number of dummy routines, unneeded by lint */ ! 830: ! 831: branch(n){;} ! 832: defalign(n){;} ! 833: deflab(n){;} ! 834: bycode(t,i){;} ! 835: cisreg(t) TWORD t; {return(1);} /* everyting is a register variable! */ ! 836: ! 837: fldty(p) struct symtab *p; { ! 838: ; /* all types are OK here... */ ! 839: } ! 840: ! 841: fldal(t) unsigned t; { /* field alignment... */ ! 842: if( t == ENUMTY ) return( ALCHAR ); /* this should be thought through better... */ ! 843: if( ISPTR(t) ){ /* really for the benefit of honeywell (and someday IBM) */ ! 844: if( pflag ) uerror( "nonportable field type" ); ! 845: } ! 846: else uerror( "illegal field type" ); ! 847: return(ALINT); ! 848: } ! 849: ! 850: main( argc, argv ) char *argv[]; { ! 851: char *p; ! 852: int i; ! 853: ! 854: /* handle options */ ! 855: ! 856: for( i = 1; i < argc; i++ ) ! 857: for( p=argv[i]; *p; ++p ){ ! 858: ! 859: switch( *p ){ ! 860: ! 861: case '-': ! 862: continue; ! 863: ! 864: case '\0': ! 865: break; ! 866: ! 867: case 'b': ! 868: brkflag = 1; ! 869: continue; ! 870: ! 871: case 'p': ! 872: pflag = 1; ! 873: continue; ! 874: ! 875: case 'c': ! 876: cflag = 1; ! 877: continue; ! 878: ! 879: case 's': ! 880: /* for the moment, -s triggers -h */ ! 881: ! 882: case 'h': ! 883: hflag = 1; ! 884: continue; ! 885: ! 886: case 'L': ! 887: libflag = 1; ! 888: case 'v': ! 889: vflag = 0; ! 890: continue; ! 891: ! 892: case 'x': ! 893: xflag = 1; ! 894: continue; ! 895: ! 896: case 'a': ! 897: ++aflag; ! 898: case 'u': /* done in second pass */ ! 899: case 'n': /* done in shell script */ ! 900: continue; ! 901: ! 902: case 'z': ! 903: zflag = 1; ! 904: continue; ! 905: ! 906: case 't': ! 907: werror( "option %c now default: see `man 6 lint'", *p ); ! 908: continue; ! 909: ! 910: case 'P': /* debugging, done in second pass */ ! 911: continue; ! 912: ! 913: case 'C': ! 914: Cflag = 1; ! 915: if( p[1] ) libname = p + 1; ! 916: while( p[1] ) p++; ! 917: continue; ! 918: ! 919: default: ! 920: uerror( "illegal option: %c", *p ); ! 921: continue; ! 922: ! 923: } ! 924: } ! 925: ! 926: if( !pflag ){ /* set sizes to sizes of target machine */ ! 927: # ifdef gcos ! 928: SZCHAR = ALCHAR = 9; ! 929: # else ! 930: SZCHAR = ALCHAR = 8; ! 931: # endif ! 932: SZINT = ALINT = sizeof(int)*SZCHAR; ! 933: SZFLOAT = ALFLOAT = sizeof(float)*SZCHAR; ! 934: SZDOUBLE = ALDOUBLE = sizeof(double)*SZCHAR; ! 935: SZLONG = ALLONG = sizeof(long)*SZCHAR; ! 936: SZSHORT = ALSHORT = sizeof(short)*SZCHAR; ! 937: SZPOINT = ALPOINT = sizeof(int *)*SZCHAR; ! 938: ALSTRUCT = ALINT; ! 939: /* now, fix some things up for various machines (I wish we had "alignof") */ ! 940: ! 941: # ifdef pdp11 ! 942: ALLONG = ALDOUBLE = ALFLOAT = ALINT; ! 943: #endif ! 944: # ifdef ibm ! 945: ALSTRUCT = ALCHAR; ! 946: #endif ! 947: } ! 948: ! 949: return( mainp1( argc, argv ) ); ! 950: } ! 951: ! 952: ctype( type ) unsigned type; { /* are there any funny types? */ ! 953: return( type ); ! 954: } ! 955: ! 956: commdec( i ){ ! 957: /* put out a common declaration */ ! 958: if( stab[i].sclass == STATIC ) outdef( &stab[i], LST, USUAL ); ! 959: else outdef( &stab[i], libflag?LIB:LDC, USUAL ); ! 960: } ! 961: ! 962: isitfloat ( s ) char *s; { ! 963: /* s is a character string; ! 964: if floating point is implemented, set dcon to the value of s */ ! 965: /* lint version ! 966: */ ! 967: dcon = atof( s ); ! 968: return( DCON ); ! 969: } ! 970: ! 971: fldcon( p ) register NODE *p; { ! 972: /* p is an assignment of a constant to a field */ ! 973: /* check to see if the assignment is going to overflow, or otherwise cause trouble */ ! 974: register s; ! 975: CONSZ v; ! 976: ! 977: if( !hflag & !pflag ) return; ! 978: ! 979: s = UPKFSZ(p->in.left->tn.rval); ! 980: v = p->in.right->tn.lval; ! 981: ! 982: switch( p->in.left->in.type ){ ! 983: ! 984: case CHAR: ! 985: case INT: ! 986: case SHORT: ! 987: case LONG: ! 988: case ENUMTY: ! 989: if( v>=0 && (v>>(s-1))==0 ) return; ! 990: werror( "precision lost in assignment to (possibly sign-extended) field" ); ! 991: default: ! 992: return; ! 993: ! 994: case UNSIGNED: ! 995: case UCHAR: ! 996: case USHORT: ! 997: case ULONG: ! 998: if( v<0 || (v>>s)!=0 ) werror( "precision lost in field assignment" ); ! 999: ! 1000: return; ! 1001: } ! 1002: ! 1003: } ! 1004: ! 1005: outdef( p, lty, mode ) struct symtab *p; { ! 1006: /* output a definition for the second pass */ ! 1007: /* if mode is > USUAL, it is the number of args */ ! 1008: char *fname; ! 1009: TWORD t; ! 1010: int line; ! 1011: static union rec rc; ! 1012: ! 1013: if( mode == NOFILE ){ ! 1014: fname = "???"; ! 1015: line = p->suse; ! 1016: } ! 1017: else if( mode == SVLINE ){ ! 1018: fname = ftitle; ! 1019: line = -p->suse; ! 1020: } ! 1021: else { ! 1022: fname = ftitle; ! 1023: line = lineno; ! 1024: } ! 1025: fsave( fname ); ! 1026: #ifndef FLEXNAMES ! 1027: strncpy( rc.l.name, exname(p->sname), LCHNM ); ! 1028: #endif ! 1029: rc.l.decflag = lty; ! 1030: t = p->stype; ! 1031: if( mode == DECTY ) t = DECREF(t); ! 1032: rc.l.type.aty = t; ! 1033: rc.l.type.extra = 0; ! 1034: rc.l.type.extra1 = 0; ! 1035: astype( &rc.l.type, p->sizoff ); ! 1036: rc.l.nargs = (mode>USUAL) ? mode : 0; ! 1037: rc.l.fline = line; ! 1038: fwrite( (char *)&rc, sizeof(rc), 1, stdout ); ! 1039: #ifdef FLEXNAMES ! 1040: rc.l.name = exname(p->sname); ! 1041: fwrite( rc.l.name, strlen(rc.l.name)+1, 1, stdout ); ! 1042: #endif ! 1043: } ! 1044: int proflg; ! 1045: int gdebug;
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.