Annotation of 42BSD/usr.bin/lint/lint.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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