Annotation of 40BSD/cmd/lint/lint.c, revision 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.