# 2.11BSD#431 - /usr/src/usr.bin/lint/lint.c

##### Functions

    andable           X
    aocode            X
    astype            X
    bfcode            X
    branch            X
    bycode            X
    cinit             X
    cisreg            X
    clocal            X
    commdec           X
    contx             X
    ctargs            X
    ctype             X
    defalign          X
    deflab            X
    defnam            X
    ecode             X
    efcode            X
    ejobcode          X
    exname            X
    fldal             X
    fldcon            X
    fldty             X
    fsave             X
    isitfloat         X
    lmerge            X
    lprt              X
    lpta              X
    main              X
    noinit            X
    offcon            X
    outdef            X
    strip             X
    where             X
    zecode            X

##### Variables

    ALCHAR            X
    ALDOUBLE          X
    ALFLOAT           X
    ALINT             X
    ALLONG            X
    ALPOINT           X
    ALSHORT           X
    ALSTRUCT          X
    Cflag             X
    SZCHAR            X
    SZDOUBLE          X
    SZFLOAT           X
    SZINT             X
    SZLONG            X
    SZPOINT           X
    SZSHORT           X
    aflag             X
    argflag           X
    gdebug            X
    libflag           X
    libname           X
    lnames            X
    lnp               X
    proflg            X
    vaflag            X
    vflag             X
    xflag             X
    zflag             X

##### Macros

    DECTY             X
    EFF               X
    LNAMES            X
    NOFILE            X
    SVLINE            X
    USUAL             X
    VAL               X
    VALADDR           X
    VALASGOP          X
    VALSET            X
    VALUSED           X

##### struct's

    lnm               X

       1: #if !defined(lint) && defined(DOSCCS)
       2: static char sccsid[] = "@(#)lint.c	1.10.1	(2.11BSD GTE)	1/17/95";
       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: char *hash();
      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 = (int)dimtab[i+3];
     176:             if( j<0 || j>SYMTSZ ){
     177:                 k = (int)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 = (int)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 ) OFFSZ 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:     ATYPE t;        /* XXX static */
     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:     ATYPE t;        /* XXX static */
     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:     CONSZ 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; OFFSZ sz; { /* 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:     static char x[128];     /* was BUFSIZ */
     763:     register char *p;
     764:     static  int stripping = 0;
     765:
     766:     if (stripping)
     767:         return(s);
     768:     stripping++;
     769:     for( p=x; *s; ++s ){
     770:         if( *s != '"' ){
     771:             if( p >= &x[sizeof (x)] )
     772:                 cerror("filename too long" );
     773:             *p++ = *s;
     774:         }
     775:     }
     776:     stripping = 0;
     777:     *p = '\0';
     778:     return( hash(x) );
     779:     }
     780:
     781: fsave( s ) char *s; {
     782:     static union rec fsname;
     783:
     784:     s = strip( s );
     785:     if (fsname.f.fn == NULL || strcmp(s, fsname.f.fn))
     786:         {
     787:         /* new one */
     788:         fsname.f.fn = s;
     789:         fsname.f.decflag = LFN;
     790:         fwrite( (char *)&fsname, sizeof(fsname), 1, stdout );
     791:         /* if generating a library, prefix with the library name */
     792:         if( libname ){
     793:             fwrite( libname, strlen(libname), 1, stdout );
     794:             putchar( ':' );
     795:             }
     796:         fwrite( fsname.f.fn, strlen(fsname.f.fn)+1, 1, stdout );
     797:         }
     798:     }
     799:
     800: where(f){ /* print true location of error */
     801:     if( f == 'u' && nerrors > 1 )
     802:         --nerrors; /* don't get "too many errors" */
     803:     fprintf( stderr, "%s(%d): ", strip(ftitle), lineno);
     804:     }
     805:
     806:     /* a number of dummy routines, unneeded by lint */
     807:
     808: branch(n){;}
     809: defalign(n){;}
     810: deflab(n){;}
     811: bycode(t,i){;}
     812: cisreg(t) TWORD t; {return(1);}  /* everyting is a register variable! */
     813:
     814: fldty(p) struct symtab *p; {
     815:     ; /* all types are OK here... */
     816:     }
     817:
     818: fldal(t) unsigned t; { /* field alignment... */
     819:     if( t == ENUMTY ) return( ALCHAR );  /* this should be thought through better... */
     820:     if( ISPTR(t) ){ /* really for the benefit of honeywell (and someday IBM) */
     821:         if( pflag ) uerror("nonportable field type" );
     822:         }
     823:     else uerror("illegal field type" );
     824:     return(ALINT);
     825:     }
     826:
     827: main( argc, argv ) char *argv[]; {
     828:     char *p;
     829:     int i;
     830:     char ibuf[BUFSIZ];
     831:
     832:     setbuf(stdin, ibuf);
     833:
     834:     /* handle options */
     835:
     836:     for( i = 1; i < argc; i++ )
     837:         for( p=argv[i]; *p; ++p ){
     838:
     839:             switch( *p ){
     840:
     841:             case '-':
     842:                 continue;
     843:
     844:             case '\0':
     845:                 break;
     846:
     847:             case 'b':
     848:                 brkflag = 1;
     849:                 continue;
     850:
     851:             case 'p':
     852:                 pflag = 1;
     853:                 continue;
     854:
     855:             case 'c':
     856:                 cflag = 1;
     857:                 continue;
     858:
     859:             case 's':
     860:                 /* for the moment, -s triggers -h */
     861:
     862:             case 'h':
     863:                 hflag = 1;
     864:                 continue;
     865:
     866:             case 'L':
     867:                 libflag = 1;
     868:             case 'v':
     869:                 vflag = 0;
     870:                 continue;
     871:
     872:             case 'x':
     873:                 xflag = 1;
     874:                 continue;
     875:
     876:             case 'a':
     877:                 ++aflag;
     878:             case 'u':   /* done in second pass */
     879:             case 'n':   /* done in shell script */
     880:                 continue;
     881:
     882:             case 'z':
     883:                 zflag = 1;
     884:                 continue;
     885:
     886:             case 't':
     887:                 werror("option %c now default: see `man 6 lint'", *p );
     888:                 continue;
     889:
     890:             case 'P':   /* debugging, done in second pass */
     891:                 continue;
     892:
     893:             case 'C':
     894:                 Cflag = 1;
     895:                 if( p[1] ) libname = p + 1;
     896:                 while( p[1] ) p++;
     897:                 continue;
     898:
     899:             default:
     900:                 uerror("illegal option: %c", *p );
     901:                 continue;
     902:
     903:                 }
     904:             }
     905:
     906:     if( !pflag ){  /* set sizes to sizes of target machine */
     907: # ifdef gcos
     908:         SZCHAR = ALCHAR = 9;
     909: # else
     910:         SZCHAR = ALCHAR = 8;
     911: # endif
     912:         SZINT = ALINT = sizeof(int)*SZCHAR;
     913:         SZFLOAT = ALFLOAT = sizeof(float)*SZCHAR;
     914:         SZDOUBLE = ALDOUBLE = sizeof(double)*SZCHAR;
     915:         SZLONG = ALLONG = sizeof(long)*SZCHAR;
     916:         SZSHORT = ALSHORT = sizeof(short)*SZCHAR;
     917:         SZPOINT = ALPOINT = sizeof(int *)*SZCHAR;
     918:         ALSTRUCT = ALINT;
     919:         /* now, fix some things up for various machines (I wish we had "alignof") */
     920:
     921: # ifdef pdp11
     922:         ALLONG = ALDOUBLE = ALFLOAT = ALINT;
     923: #endif
     924: # ifdef ibm
     925:         ALSTRUCT = ALCHAR;
     926: #endif
     927:         }
     928:
     929:     return( mainp1( argc, argv ) );
     930:     }
     931:
     932: ctype( type ) unsigned type; { /* are there any funny types? */
     933:     return( type );
     934:     }
     935:
     936: commdec( i ){
     937:     /* put out a common declaration */
     938:     if( stab[i].sclass == STATIC ) outdef( &stab[i], LST, USUAL );
     939:     else outdef( &stab[i], libflag?LIB:LDC, USUAL );
     940:     }
     941:
     942: isitfloat ( s ) char *s; {
     943:     /* s is a character string;
     944: 	   if floating point is implemented, set dcon to the value of s */
     945:     /* lint version
     946: 	*/
     947:     dcon = atof( s );
     948:     return( DCON );
     949:     }
     950:
     951: fldcon( p ) register NODE *p; {
     952:     /* p is an assignment of a constant to a field */
     953:     /* check to see if the assignment is going to overflow, or otherwise cause trouble */
     954:     register s;
     955:     CONSZ v;
     956:
     957:     if( !hflag & !pflag ) return;
     958:
     959:     s = UPKFSZ(p->in.left->tn.rval);
     960:     v = p->in.right->tn.lval;
     961:
     962:     switch( p->in.left->in.type ){
     963:
     964:     case CHAR:
     965:     case INT:
     966:     case SHORT:
     967:     case LONG:
     968:     case ENUMTY:
     969:         if( v>=0 && (v>>(s-1))==0 ) return;
     970:         werror("precision lost in assignment to (possibly sign-extended) field" );
     971:     default:
     972:         return;
     973:
     974:     case UNSIGNED:
     975:     case UCHAR:
     976:     case USHORT:
     977:     case ULONG:
     978:         if( v<0 || (v>>s)!=0 ) werror("precision lost in field assignment" );
     979:
     980:         return;
     981:         }
     982:
     983:     }
     984:
     985: outdef( p, lty, mode ) struct symtab *p; {
     986:     /* output a definition for the second pass */
     987:     /* if mode is > USUAL, it is the number of args */
     988:     char *fname;
     989:     TWORD t;
     990:     int line;
     991:     static union rec rc;
     992:
     993:     if( mode == NOFILE ){
     994:         fname = "???";
     995:         line = p->suse;
     996:         }
     997:     else if( mode == SVLINE ){
     998:         fname = ftitle;
     999:         line = -p->suse;
    1000:         }
    1001:     else {
    1002:         fname = ftitle;
    1003:         line = lineno;
    1004:         }
    1005:     fsave( fname );
    1006: #ifndef FLEXNAMES
    1007:     strncpy( rc.l.name, exname(p->sname), LCHNM );
    1008: #endif
    1009:     rc.l.decflag = lty;
    1010:     t = p->stype;
    1011:     if( mode == DECTY ) t = DECREF(t);
    1012:     rc.l.type.aty = t;
    1013:     rc.l.type.extra = 0;
    1014:     rc.l.type.extra1 = 0;
    1015:     astype( &rc.l.type, p->sizoff );
    1016:     rc.l.nargs = (mode>USUAL) ? mode : 0;
    1017:     rc.l.fline = line;
    1018:     fwrite( (char *)&rc, sizeof(rc), 1, stdout );
    1019: #ifdef FLEXNAMES
    1020:     rc.l.name = exname(p->sname);
    1021:     fwrite( rc.l.name, strlen(rc.l.name)+1, 1, stdout );
    1022: #endif
    1023:     }
    1024: int proflg;
    1025: int gdebug;

#### Defined functions

andable defined in line 621; never used
aocode defined in line 558; never used
astype defined in line 166; used 3 times

- in line 238, 286, 1015

bfcode defined in line 207; never used
branch defined in line 808; never used
bycode defined in line 811; never used
cinit defined in line 735; never used
cisreg defined in line 812; never used
clocal defined in line 637; never used
commdec defined in line 936; never used
contx defined in line 53; used 1 times

- in line 101

ctargs defined in line 262; used 1 times

- in line 400

ctype defined in line 932; never used
defalign defined in line 809; never used
deflab defined in line 810; never used
defnam defined in line 603; never used
ecode defined in line 98; never used
efcode defined in line 539; never used
ejobcode defined in line 106; never used
exname defined in line 744; used 2 times

- in line 1007, 1020

fldal defined in line 818; never used
fldcon defined in line 951; used 1 times

- in line 491

fldty defined in line 814; never used
fsave defined in line 781; used 3 times

- in line 227, 408, 1005

isitfloat defined in line 942; never used
lmerge defined in line 496; used 3 times

- in line 388, 487-489(2)

lprt defined in line 321; used 5 times

- in line 103, 385-387(2), 479-482(2)

lpta defined in line 274; used 2 times

- in line 278, 430

main defined in line 827; never used
noinit defined in line 729; never used
offcon defined in line 721; never used
outdef defined in line 985; used 10 times

- in line 150-155(2), 228-229(2), 428, 545, 609-610(2), 938-939(2)

strip defined in line 760; used 2 times

- in line 784, 803

where defined in line 800; never used
zecode defined in line 613; never used

#### Defined variables

ALCHAR defined in line 22; used 4 times

- in line 819, 908-910(2), 925

ALDOUBLE defined in line 25; used 2 times

- in line 914, 922

ALFLOAT defined in line 24; used 2 times

- in line 913, 922

ALINT defined in line 23; used 4 times

- in line 824, 912, 918-922(2)

ALLONG defined in line 26; used 2 times

- in line 915, 922

ALPOINT defined in line 28; used 1 times

- in line 917

ALSHORT defined in line 27; used 1 times

- in line 916

ALSTRUCT defined in line 29; used 2 times

- in line 918, 925

Cflag defined in line 38; used 6 times

- in line 143, 220, 413, 544, 606, 894

SZCHAR defined in line 15; used 9 times

- in line 725, 908-917(8)

SZDOUBLE defined in line 18; used 1 times

- in line 914

SZFLOAT defined in line 17; used 1 times

- in line 913

SZINT defined in line 16; used 2 times

- in line 617, 912

SZLONG defined in line 19; used 1 times

- in line 915

SZPOINT defined in line 21; used 1 times

- in line 917

SZSHORT defined in line 20; used 1 times

- in line 916

aflag defined in line 36; used 3 times

- in line 666-669(2), 877

argflag defined in line 33; used 2 times

- in line 547-548(2)

gdebug defined in line 1025; never used
libflag defined in line 34; used 5 times

- in line 149, 229, 610, 867, 939

libname defined in line 39; used 4 times

- in line 792-793(3), 895

lnames defined in line 51; used 2 times

- in line 102, 466

lnp defined in line 51; used 11 times

- in line 102, 384-386(2), 464-466(4), 478-481(2), 506, 536

proflg defined in line 1024; never used
sccsid defined in line 2; never used
vaflag defined in line 35; used 6 times

- in line 223-230(6)

vflag defined in line 31; used 5 times

- in line 546-547(2), 565-567(2), 869

xflag defined in line 32; used 2 times

- in line 149, 873

zflag defined in line 37; used 3 times

- in line 117, 593, 883

#### Defined struct's

lnm defined in line 49; used 6 times

- in line 327(2), 496(2), 504(2)

#### Defined macros

DECTY defined in line 43; used 2 times

- in line 545, 1011

EFF defined in line 12; used 8 times

- in line 71, 93, 101-103(2), 336, 377, 421-423(2)

LNAMES defined in line 47; used 2 times

- in line 51, 466

NOFILE defined in line 44; used 2 times

- in line 150, 993

SVLINE defined in line 45; used 2 times

- in line 155, 997

USUAL defined in line 42; used 5 times

- in line 609-610(2), 938-939(2), 1016

VAL defined in line 11; used 2 times

- in line 55, 342

VALADDR defined in line 319; used 3 times

- in line 333, 462-465(2)

VALASGOP defined in line 318; used 2 times

- in line 336, 459

VALSET defined in line 316; used 8 times

- in line 332-335(2), 460-465(3), 511-514(3)

VALUSED defined in line 317; used 7 times

- in line 331-335(2), 447, 461-465(2), 511-513(2)

Last modified: 1995-01-18 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2818 |