|
|
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;
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.