⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lint.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
				WERROR( MESSAGE( 21 ) );			if ( htmpname != NULL && p->in.right->tn.lval == 0 )				/* "unsigned comparison with 0?" */				WERROR( MESSAGE( 115 ) );	    }	    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, 0 );		np2 = lnp;		lprt( p->in.right, down2, use2, 0 );		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		    && (q = STP(p->in.left->tn.rval)) != NULL ){			/* used to be &name */			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  void  in an effects			 *  context is construed to be used in a value			 *  context			 */			if (down == EFF) lty = (p->in.type == TVOID) ? LUV | LUE : LUE;			else lty = LUV;			outdef(q, lty, acount);			if( acount )				lpta( p->in.right );			}		break;	case ICON:		/* look for &name case */		if( (q = STP(p->tn.rval)) != NULL ) {			q->sflags |= (SREF|SSET);		}		return;	case NAME:		if( (q = STP(p->tn.rval)) != NULL ) {			if( (uses&VALUSED) && !(q->sflags&SSET) ){				if( q->sclass == AUTO || q->sclass == REGISTER ){					if( !ISARY(q->stype ) && !ISFTN(q->stype) &&					    (q->stype != STRTY || stasg) && q->stype!=UNIONTY ){						/* "%s may be used before set" */						WERROR( MESSAGE( 1 ), q->sname );						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 = p->tn.rval;				lnp->flgs = (uses&VALADDR)?0:((uses&VALSET)?VALSET:VALUSED);				if( ++lnp >= &lnames[LNAMES] ) --lnp;			}		}		return;	}	if (stasg && (p->in.left->in.type == STRTY)){		if (stasg == STASG_RIGHT) use1 = VALUSED;		else if (stasg == STASG_LEFT) use1 = VALSET;	}		/* 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,		      (p->in.op == STASG) ? STASG_RIGHT : 0 );	case UTYPE:		np2 = lnp;		lprt( p->in.left, down1, use1,		      (p->in.op == STASG | stasg) ? STASG_LEFT : 0 );	}	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 */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) ) {						struct symtab *q;						char *s;						q = STP(npy->lid);						s = (q == NULL ? "(null)" : q->sname);						/* "evaluation order for ``%s'' undefined" */						if( flag ) WERROR( MESSAGE( 0 ), s );					  	}				if( npy->flgs == 0 ) npx->flgs = 0;				else npy->flgs |= npx->flgs;				goto foundit;			}		}		/* not there: update entry */		np2->lid = npx->lid;		np2->flgs = npx->flgs;		++np2;		foundit: ;	}	/* all finished: merged list is at np1 */	lnp = np2;}/* efcode - handle end of a function */efcode(){	/* code for the end of a function */	register struct symtab *cfp;	cfp = STP(curftn);	if (cfp == NULL) return;	if( retstat & RETVAL && !(Cflag && cfp->sclass==STATIC) )		outdef( cfp, LRV, DECTY );	if( !vflag ){		vflag = argflag;		argflag = 0;	}	if( retstat == RETVAL+NRETVAL )		/* "function %s has return(e); and return;" */		WERROR( MESSAGE( 43 ), cfp->sname);	/*	* See if main() falls off its end or has just a return;	*/	if (!strcmp(cfp->sname, "main") && (reached || (retstat & NRETVAL)))		/* "main() returns random value to invocation environment" */		WERROR(MESSAGE(127));}/* aocode - called when automatic p is removed from stab */aocode(p) struct symtab *p;{	register struct symtab *cfs;	cfs = STP(curftn);	if (cfs == NULL) return;	if(p->suse>0 && !(p->sflags&(SMOS|STAG)) ){		if( p->sclass == PARAM		    || p->sclass == REGISTER && p->slevel == 1 ) {			/* "argument %s unused in function %s" */			if( vflag ) WERROR( MESSAGE( 13 ), p->sname, cfs->sname );		}		else			/* "%s unused in function %s" */			if( p->sclass != TYPEDEF ) WERROR( MESSAGE( 6 ),			  p->sname, cfs->sname );	}	if( p->suse < 0 && (p->sflags & (SSET|SREF|SMOS)) == SSET	  && !ISARY(p->stype) && !ISFTN(p->stype) )		/* "%s set but not used in function %s" */		WERROR( MESSAGE( 3 ), p->sname, cfs->sname );	if( p->stype == STRTY || p->stype == UNIONTY || p->stype == ENUMTY )		if( !zflag && dimtab[p->sizoff+1] < 0 ){			if (p->stype == ENUMTY)				/* "enum %s never defined" */				WERROR( MESSAGE( 104 ), p->sname );			else				/* "struct/union %s never defined" */				WERROR( MESSAGE( 102 ), p->sname );			}}/* defname - define the current location as the name p->sname */defnam( p ) register struct symtab *p;{	if( p->sclass == STATIC && (p->slevel>1 || Cflag) ) return;	if( !ISFTN( p->stype ) )		outdef( p, p->sclass==STATIC? LDS : (libflag?LIB:LDI), USUAL );}#endif	/* ifndef CXREF *//* zecode - n integer words of zeros */zecode( n ){	OFFSZ temp;	temp = n;	inoff += temp*SZINT;}/*ARGSUSED*/mklval( p ) NODE *p; {	/* can we make this operand into a legal lvalue, if it	   isn't one already?  One version of pcc does so if it is	   a cast on the left hand side of an assignment.  Since	   that is highly nonportable, we won't bother. */	return 0;	}/* andable - can the NAME node p accept &  ? */andable( p ) NODE *p;{	register struct symtab *s;	if( p->in.op != NAME ) cerror( "andable error" );	if( p->tn.rval < 0 ) return(1);  /* labels are andable */	if( (s = STP(p->tn.rval)) == NULL ) return(0);	if( s->sclass == AUTO || s->sclass == PARAM ) return(0); 	/* "cannot take address of %s" */	if( s->sclass == REGISTER ) UERROR( MESSAGE( 18 ), s->sname );	return(1);}/* clocal - do local checking on tree *	(pcc uses this routine to do local tree rewriting) */NODE *clocal(p) NODE *p;{	register o;	register TWORD t, tl;	int s;	switch( o = p->in.op ){	case SCONV:	case PCONV:		if( p->in.left->in.type==ENUMTY )			p->in.left = pconvert( p->in.left );		/* assume conversion takes place; type is inherited */		t = p->in.type;		tl = p->in.left->in.type;#ifndef CXREF/* for the future: put aflag in a place where NAME is available; that is, check * assignment and arithmetic operators for leftchild NAME and rightchild SCONV * so that when message is printed it is possible to name the offending lval * note that the lval may be a temporary (NONAME) */		if( aflag		   && ( tl == LONG || tl == ULONG )		   && t!=LONG && t!=ULONG && t!=TVOID		   && t!=FLOAT && t!=DOUBLE ) 			/* "conversion from long may lose accuracy" */			WERROR( MESSAGE( 26 ) );		if( aflag && pflag && tl != LONG && tl != ULONG 		  && tl != FLOAT && tl != DOUBLE		  && ( t == LONG || t == ULONG )		  && p->in.left->in.op != ICON )			/* conversion to long may sign-extend incorrectly */			WERROR( MESSAGE( 27 ) );		if( ISPTR(tl) && ISPTR(t) ){			tl = DECREF(tl);			t = DECREF(t);			switch( ISFTN(t) + ISFTN(tl) ){			case 0:  /* neither is a function pointer */				if( talign(t,p->fn.csiz) > talign(tl,p->in.left->fn.csiz) ) {					/* "possible pointer alignment problem" */					if( hflag || pflag || (target == sparcAL))						WERROR( MESSAGE( 91 ) );				}				break;			case 1:				/* "questionable conversion of function pointer" */				WERROR( MESSAGE( 95 ) );			case 2:				;			}		}#endif		if (o == SCONV) {			/*			 * Must do integer <-> floating conversions here, so			 * that if e.g. a floating-point expression cast to			 * "int" is being used as an array dimension, we check			 * it properly.			 */			if( p->in.left->in.op == ICON ) {				if( p->in.type == FLOAT				    || p->in.type == DOUBLE ) {					if (ISUNSIGNED(tl)) {						p->in.left->fpn.dval =						    (unsigned)p->in.left->tn.lval;					} else {						p->in.left->fpn.dval =						    p->in.left->tn.lval;					}					p->in.left->in.op = FCON;				    }			} else if( p->in.left->in.op == FCON ) {				if( p->in.type != FLOAT				    && p->in.type != DOUBLE ) {					p->in.left->in.op = ICON;					p->in.left->tn.lval =					    (CONSZ)p->in.left->fpn.dval;					p->in.left->tn.rval = NONAME;					p->in.left->tn.name = (char*)0;				}			}		}		p->in.left->in.type = p->in.type;		p->in.left->fn.cdim = p->fn.cdim;		p->in.left->fn.csiz = p->fn.csiz;		p->in.op = FREE;		return( p->in.left );	case PVCONV:	case PMCONV:		if( p->in.right->in.op != ICON ) cerror( "bad conversion");		p->in.op = FREE;		return( buildtree( o==PMCONV?MUL:DIV, p->in.left, p->in.right ) );	case RS:	case LS:	case ASG RS:	case ASG LS:		if( p->in.right->in.op != ICON )			break;		s = p->in.right->tn.lval;		if( s < 0 )			/* "negative shift" */			WERROR( MESSAGE( 136 ) );		else		if( s >= dimtab[ p->fn.csiz ] )			/* "shift greater than size of object" */			WERROR( MESSAGE( 137 ) );		break;	}	return(p);}/* offcon - make structure offset node */NODE *offcon( off, t, d, s ) OFFSZ off; TWORD t;{	register NODE *p;	p = bcon(0);	p->tn.lval = off/SZCHAR;	return(p);}/* noinit - return storage class for such as "int a;" */noinit(){	return( pflag ? EXTDEF : EXTERN );}/* cinit - initialize p into size sz */cinit( p, sz ) NODE *p;{	inoff += sz;	if( p->in.op == INIT ){		if( p->in.left->in.op == ICON ) return;		if( p->in.left->in.op == FCON ) return;		if( p->in.left->in.op == NAME && p->in.left->in.type == MOE ) return;	}	/* "illegal initialization" */	UERROR( MESSAGE( 61 ) );}#ifndef CXREF/* exname - make a name look like an external name *		if checking for portability or if running on gcos or ibm, *		truncate name to six characters */char *exname( p ) char *p;{	static char aa[8];	register int i;#if !( ibm | gcos )	if( !pflag ) return(p);#endif	for( i=0; i<6; ++i ){		if( isupper(*p ) ) aa[i] = tolower( *p );		else aa[i] = *p;		if( *p ) ++p;	}	aa[6] = '\0';	return( aa );}/* strip - strip full name to get basename */char *strip(s) register char *s;{	static char x[BUFSIZ+1];	register char *p;	register char c;	/*	 * Trim off leading quote, if any.	 */	if (*s == '"')		s++;	/*	 * Trim off leading "./"; "cpp" tends to insert it before include	 * file names.	 */	if (strncmp(s, "./", 2) == 0)		s += 2;	/*	 * Copy until the end of the string or until a trailing quote.	 */	p = x;	while( (c = *s++) != '\0' && c != '"' ){		if ( p > &x[BUFSIZ] ) {			/* 5 feb 80:  simulate a call to cerror( ) */			fprintf(stderr, "%s: compiler error: filename too long\n", x);			exit(1);			/* cannot call cerror( )			 * because cerror( ) calls where( ) and where( ) calls			 * strip( ) and this is strip			 */		}		*p++ = c;	}	*p = '\0';	return( x );}/* fsave - save file name on intermediate file */fsave( s ) char *s; {	static union rec fsname;	static char buf[BUFSIZ+1];	s = strip( s );	if( strcmp( s, buf ) ){		/* new one */		strcpy( buf, s );		fsname.f.decflag = LFN;		fsname.f.mno = getpid();		fwrite( (char *)&fsname, sizeof(fsname), 1, stdout );		fwrite( buf, strlen( buf ) + 1, 1, stdout );	}}#endif	/* ifndef CXREF *//* where  - print the location of an error *  if the filename is a C file (the source file) then just print the lineno *    the filename is taken care of in a title *  if the file is a header file ( unlikely but possible) *    then the filename is printed with the line number of the error *    where is called by cerror, uerror and werror *    (it is not called by luerror or lwerror) */where( f ) char	f;{    extern		fprintf( );#ifndef CXREF    extern enum boolean	iscfile( );    extern char		*strip( );    char		*filename;    extern char		*htmpname;#endif    if( f == 'u' && nerrors > 1 ) --nerrors; /* don't get "too many errors" */

⌨️ 快捷键说明

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