home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V7 / usr / src / cmd / lint / lint.c next >
Encoding:
C/C++ Source or Header  |  1979-01-10  |  16.3 KB  |  794 lines

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