Annotation of 40BSD/cmd/lint/lint.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.