Annotation of researchv10no/cmd/lint/olint1.c, revision 1.1

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

unix.superglobalmegacorp.com

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