lint.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 831 行 · 第 1/2 页

C
831
字号
#ifndef lintstatic char sccsid[] = "@(#)lint.c	1.5	(Berkeley)	3/30/83";#endif lint# include "mfile1"# include "lmanifest"# include <ctype.h># define VAL 0# define EFF 1extern int ddebug, idebug, bdebug, tdebug, edebug, xdebug;	/* CXREF */int blocknos[20];	/* CXREF */int blockptr = 0;	/* CXREF */int nextblock = 1;	/* CXREF *//* these are appropriate for the -p flag *//* int  SZCHAR = 8;int  SZINT = 16;int  SZFLOAT = 32;int  SZDOUBLE = 64;int  SZLONG = 32;int  SZSHORT = 16;int SZPOINT = 16;int ALCHAR = 8;int ALINT = 16;int ALFLOAT = 32;int ALDOUBLE = 64;int ALLONG = 32;int ALSHORT = 16;int ALPOINT = 16;int ALSTRUCT = 16;*/int vflag = 1;  /* tell about unused argments */int xflag = 0;  /* tell about unused externals */int argflag = 0;  /* used to turn off complaints about arguments */int libflag = 0;  /* used to generate library descriptions */int vaflag = -1;  /* used to signal functions with a variable number of args */int aflag = 0;  /* used to check precision of assignments */int zflag = 0;  /* no 'structure never defined' error */int Cflag = 0;  /* filter out certain output, for generating libraries */char *libname = 0;  /* name of the library we're generating */	/* flags for the "outdef" function */# define USUAL (-101)# define DECTY (-102)# define NOFILE (-103)# define SVLINE (-104)# define LNAMES 250struct lnm {	short lid, flgs;	}  lnames[LNAMES], *lnp;contx( p, down, pl, pr ) register NODE *p; register *pl, *pr; {	*pl = *pr = VAL;	switch( p->in.op ){	case ANDAND:	case OROR:	case QUEST:		*pr = down;		break;	case SCONV:	case PCONV:	case COLON:		*pr = *pl = down;		break;	case COMOP:		*pl = EFF;		*pr = down;	case FORCE:	case INIT:	case UNARY CALL:	case STCALL:	case UNARY STCALL:	case CALL:	case UNARY FORTCALL:	case FORTCALL:	case CBRANCH:		break;	default:		if( asgop(p->in.op) ) break;		if( p->in.op == UNARY MUL && ( p->in.type == STRTY || p->in.type == UNIONTY || p->in.type == UNDEF) ) {		/* struct x f( );  main( ) {  (void) f( ); }		 * the the cast call appears as U* UNDEF		 */			break;  /* the compiler does this... */			}		if( down == EFF && hflag ) werror( "null effect" );		}	}ecode( p ) NODE *p; {	/* compile code for p *//*	fwalk( p, contx, EFF );	lnp = lnames;	lprt( p, EFF, 0 );	CXREF */	}astype( t, i ) ATYPE *t; {	TWORD tt;	int j, k=0, l=0;	if( (tt=BTYPE(t->aty))==STRTY || tt==UNIONTY ){		if( i<0 || i>= DIMTABSZ-3 ){			werror( "lint's little mind is blown" );			}		else {			j = dimtab[i+3];			if( j<0 || j>SYMTSZ ){				k = dimtab[i];				l = X_NONAME | stab[j].suse;				}			else {				if( stab[j].suse <= 0 ) {#ifndef FLEXNAMES					werror( "no line number for %.8s",#else					werror( "no line number for %s",#endif						stab[j].sname );					}				else {					k = dimtab[i];#ifdef FLEXNAMES					l = hashstr(stab[j].sname);#else					l = hashstr(stab[j].sname, LCHNM);#endif					}				}			}				t->extra = k;		t->extra1 = l;		return( 1 );		}	else return( 0 );	}ctargs( p ) NODE *p; {	/* count arguments; p points to at least one */	/* the arguemnts are a tower of commas to the left */	register c;	c = 1; /* count the rhs */	while( p->in.op == CM ){		++c;		p = p->in.left;		}	return( c );	}lpta( p ) NODE *p; {	static ATYPE t;	if( p->in.op == CM ){		lpta( p->in.left );		p = p->in.right;		}	t.aty = p->in.type;	t.extra = (p->in.op==ICON);	t.extra1 = 0;	if( !astype( &t, p->fn.csiz ) ) {		switch( t.aty ){			case CHAR:			case SHORT:				t.aty = INT;			case LONG:			case ULONG:			case INT:			case UNSIGNED:				break;			case UCHAR:			case USHORT:				t.aty = UNSIGNED;				break;			case FLOAT:				t.aty = DOUBLE;				t.extra = 0;				break;			default:				t.extra = 0;				break;			}		}	fwrite( (char *)&t, sizeof(ATYPE), 1, stdout );	}# define VALSET 1# define VALUSED 2# define VALASGOP 4# define VALADDR 8lprt( p, down, uses ) register NODE *p; {	register struct symtab *q;	register id;	register acount;	register down1, down2;	register use1, use2;	register struct lnm *np1, *np2;	/* first, set variables which are set... */	use1 = use2 = VALUSED;	if( p->in.op == ASSIGN ) use1 = VALSET;	else if( p->in.op == UNARY AND ) use1 = VALADDR;	else if( asgop( p->in.op ) ){ /* =ops */		use1 = VALUSED|VALSET;		if( down == EFF ) use1 |= VALASGOP;		}	/* print the lines for lint */	down2 = down1 = VAL;	acount = 0;	switch( p->in.op ){	case EQ:	case NE:	case GT:	case GE:	case LT:	case LE:		if( p->in.left->in.type == CHAR && p->in.right->in.op==ICON && p->in.right->tn.lval < 0 ){			werror( "nonportable character comparison" );			}		if( (p->in.op==EQ || p->in.op==NE ) && ISUNSIGNED(p->in.left->in.type) && p->in.right->in.op == ICON ){			if( p->in.right->tn.lval < 0 && p->in.right->tn.rval == NONAME && !ISUNSIGNED(p->in.right->in.type) ){				werror( "comparison of unsigned with negative constant" );				}			}		break;	case UGE:	case ULT:		if( p->in.right->in.op == ICON && p->in.right->tn.lval == 0 && p->in.right->tn.rval == NONAME ){			werror( "unsigned comparison with 0?" );			break;			}	case UGT:	case ULE:		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 ){			werror( "degenerate unsigned comparison" );			}		break;	case COMOP:		down1 = EFF;	case ANDAND:	case OROR:	case QUEST:		down2 = down;		/* go recursively left, then right  */		np1 = lnp;		lprt( p->in.left, down1, use1 );		np2 = lnp;		lprt( p->in.right, down2, use2 );		lmerge( np1, np2, 0 );		return;	case SCONV:	case PCONV:	case COLON:		down1 = down2 = down;		break;	case CALL:	case STCALL:	case FORTCALL:		acount = ctargs( p->in.right );	case UNARY CALL:	case UNARY STCALL:	case UNARY FORTCALL:		if( p->in.left->in.op == ICON && (id=p->in.left->tn.rval) != NONAME ){ /* used to be &name */			struct symtab *sp = &stab[id];			int lty;			fsave( ftitle );			/*			 * if we're generating a library -C then			 * we don't want to output references to functions			 */			if( Cflag ) break;			/*  if a function used in an effects context is			 *  cast to type  void  then consider its value			 *  to have been disposed of properly			 *  thus a call of type  undef  in an effects			 *  context is construed to be used in a value			 *  context			 */			if ((down == EFF) && (p->in.type != UNDEF)) {				lty = LUE;			} else if (down == EFF) {				lty = LUV | LUE;			} else {				lty = LUV;			}			outdef( sp, lty, acount );			if( acount ) {				lpta( p->in.right );				}			}		break;	case ICON:		/* look for &name case */		if( (id = p->tn.rval) >= 0 && id != NONAME ){			q = &stab[id];			q->sflags |= (SREF|SSET);			q->suse = -lineno;			}		return;	case NAME:		if( (id = p->tn.rval) >= 0 && id != NONAME ){			q = &stab[id];			if( (uses&VALUSED) && !(q->sflags&SSET) ){				if( q->sclass == AUTO || q->sclass == REGISTER ){					if( !ISARY(q->stype ) && !ISFTN(q->stype) && q->stype!=STRTY && q->stype!=UNIONTY ){#ifndef FLEXNAMES						werror( "%.8s may be used before set", q->sname );#else						werror( "%s may be used before set", q->sname );#endif						q->sflags |= SSET;						}					}				}			if( uses & VALASGOP ) break;  /* not a real use */			if( uses & VALSET ) q->sflags |= SSET;			if( uses & VALUSED ) q->sflags |= SREF;			if( uses & VALADDR ) q->sflags |= (SREF|SSET);			if( p->tn.lval == 0 ){				lnp->lid = id;				lnp->flgs = (uses&VALADDR)?0:((uses&VALSET)?VALSET:VALUSED);				if( ++lnp >= &lnames[LNAMES] ) --lnp;				}			}		return;		}	/* recurse, going down the right side first if we can */	switch( optype(p->in.op) ){	case BITYPE:		np1 = lnp;		lprt( p->in.right, down2, use2 );	case UTYPE:		np2 = lnp;		lprt( p->in.left, down1, use1 );		}	if( optype(p->in.op) == BITYPE ){		if( p->in.op == ASSIGN && p->in.left->in.op == NAME ){ /* special case for a =  .. a .. */			lmerge( np1, np2, 0 );			}		else lmerge( np1, np2, p->in.op != COLON );		/* look for assignments to fields, and complain */		if( p->in.op == ASSIGN && p->in.left->in.op == FLD && p->in.right->in.op == ICON ) fldcon( p );		}	}lmerge( np1, np2, flag ) struct lnm *np1, *np2; {	/* np1 and np2 point to lists of lnm members, for the two sides	 * of a binary operator	 * flag is 1 if commutation is possible, 0 otherwise	 * lmerge returns a merged list, starting at np1, resetting lnp	 * it also complains, if appropriate, about side effects	 */	register struct lnm *npx, *npy;	for( npx = np2; npx < lnp; ++npx ){		/* is it already there? */		for( npy = np1; npy < np2; ++npy ){			if( npx->lid == npy->lid ){ /* yes */				if( npx->flgs == 0 || npx->flgs == (VALSET|VALUSED) )					;  /* do nothing */				else if( (npx->flgs|npy->flgs)== (VALSET|VALUSED) ||					(npx->flgs&npy->flgs&VALSET) ){#ifndef FLEXNAMES					if( flag ) werror( "%.8s evaluation order undefined", stab[npy->lid].sname );#else					if( flag ) werror( "%s evaluation order undefined", stab[npy->lid].sname );#endif					}				if( npy->flgs == 0 ) npx->flgs = 0;				else npy->flgs |= npx->flgs;				goto foundit;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?