Index: usr.bin/xlint/lint1/cgram.y
===================================================================
RCS file: /home/dcvs/src/usr.bin/xlint/lint1/cgram.y,v
retrieving revision 1.6
diff -u -r1.6 cgram.y
--- usr.bin/xlint/lint1/cgram.y	7 Jul 2004 12:26:51 -0000	1.6
+++ usr.bin/xlint/lint1/cgram.y	25 Dec 2006 09:50:08 -0000
@@ -1,4 +1,5 @@
 %{
+/*	$OpenBSD: cgram.y,v 1.20 2006/05/29 20:47:22 cloder Exp $	*/
 /*	$NetBSD: cgram.y,v 1.8 1995/10/02 17:31:35 jpo Exp $	*/
 
 /*
@@ -31,7 +32,6 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $NetBSD: cgram.y,v 1.8 1995/10/02 17:31:35 jpo Exp $
  * $DragonFly: src/usr.bin/xlint/lint1/cgram.y,v 1.6 2004/07/07 12:26:51 asmodai Exp $
  */
 
@@ -105,7 +105,7 @@
 /* types (char, int, short, long, unsigned, signed, float, double, void) */
 %token	<y_tspec>	T_TYPE
 
-/* qualifiers (const, volatile) */
+/* qualifiers (const, volatile, restrict) */
 %token	<y_tqual>	T_QUAL
 
 /* struct or union */
@@ -128,6 +128,8 @@
 %token			T_BREAK
 %token			T_RETURN
 %token			T_ASM
+%token			T_LEQUAL
+%token			T_ATTRIBUTE
 
 %left	T_COMMA
 %right	T_ASSIGN T_OPASS
@@ -213,7 +215,7 @@
 		if (sflag) {
 			/* empty translation unit */
 			error(272);
-		} else if (!tflag) {
+		} else {
 			/* empty translation unit */
 			warning(272);
 		}
@@ -235,23 +237,49 @@
 		glclup(0);
 		clrwflgs();
 	  }
-	;
+	| T_LEQUAL T_LPARN identifier T_COMMA identifier T_RPARN T_SEMI {
+		sym_t *new, *old;
 
-data_def:
-	  T_SEMI {
-		if (sflag) {
-			/* syntax error: empty declaration */
-			error(0);
-		} else if (!tflag) {
-			/* syntax error: empty declaration */
-			warning(0);
+		if ($5->sb_sym && $3->sb_sym /*== NULL*/) {
+			new = getsym($5);
+			old = $3->sb_sym;
+			new->s_dpos = old->s_dpos;
+			new->s_spos = old->s_spos;
+			new->s_upos = old->s_upos;
+			new->s_kind = old->s_kind;
+			new->s_keyw = old->s_keyw;
+			new->s_field = old->s_field;
+			new->s_set = old->s_set;
+			new->s_used = old->s_used;
+			new->s_arg = old->s_arg;
+			new->s_reg = old->s_reg;
+			new->s_defarg = old->s_defarg;
+			new->s_rimpl = old->s_rimpl;
+			new->s_osdef = old->s_osdef;
+			new->s_inline = old->s_inline;
+			new->s_def = old->s_def;
+			new->s_scl = old->s_scl;
+			new->s_blklev = old->s_blklev;
+			new->s_type = old->s_type;
+			new->s_value = old->s_value;
+			new->u = old->u;
+
+			/* XXX missing 'r' because do not know return type
+			   of parent... */
+			/* outsym(new, new->s_scl, DEF); */
+			outfdef(new, &csrc_pos,
+			    new->s_rimpl || new->s_type->t_subt->t_tspec != VOID,
+			    0, NULL);
 		}
 	  }
+	;
+
+data_def: T_SEMI
 	| clrtyp deftyp notype_init_decls T_SEMI {
 		if (sflag) {
 			/* old style declaration; add "int" */
 			error(1);
-		} else if (!tflag) {
+		} else {
 			/* old style declaration; add "int" */
 			warning(1);
 		}
@@ -275,7 +303,7 @@
 			warning(2);
 		}
 	  }
-	| declspecs deftyp type_init_decls T_SEMI
+	| declspecs deftyp type_init_decls opt_attribute_spec T_SEMI
 	| error T_SEMI {
 		globclup();
 	  }
@@ -310,6 +338,11 @@
 	  }
 	;
 
+opt_attribute_spec:
+	/* empty */
+	| T_ATTRIBUTE T_LPARN T_LPARN read_until_rparn T_RPARN
+	;
+
 func_decl:
 	  clrtyp deftyp notype_decl {
 		$$ = $3;
@@ -706,13 +739,6 @@
 		$$ = $1;
 	  }
 	| enums T_COMMA {
-		if (sflag) {
-			/* trailing "," prohibited in enum declaration */
-			error(54);
-		} else {
-			/* trailing "," prohibited in enum declaration */
-			warning(54);
-		}
 		$$ = $1;
 	  }
 	;
@@ -756,7 +782,7 @@
 	;
 
 notype_init_decl:
-	  notype_decl opt_asm_spec {
+	  notype_decl opt_attribute_spec opt_asm_spec {
 		idecl($1, 0);
 		chksz($1);
 	  }
@@ -1004,7 +1030,7 @@
 		if (sflag) {
 			/* ANSI C requires formal parameter before "..." */
 			error(84);
-		} else if (!tflag) {
+		} else {
 			/* ANSI C requires formal parameter before "..." */
 			warning(84);
 		}
@@ -1052,9 +1078,7 @@
 
 opt_asm_spec:
 	  /* empty */
-	| T_ASM T_LPARN T_STRING T_RPARN {
-		freeyyv(&$3, T_STRING);
-	  }
+	| T_ASM T_LPARN read_until_rparn
 	;
 
 initializer:
@@ -1067,6 +1091,7 @@
 	  }
 	| init_lbrace init_expr_list init_rbrace
 	| init_lbrace init_expr_list T_COMMA init_rbrace
+	| init_lbrace init_rbrace
 	| error
 	;
 
@@ -1176,6 +1201,14 @@
 		label(T_CASE, NULL, $2);
 		ftflg = 1;
 	  }
+	| T_CASE constant T_ELLIPSE constant T_COLON {
+		/* XXX: only using the first value of this gcc-ism */
+		label(T_CASE, NULL, $2);
+		ftflg = 1;
+
+		if (!gflag)
+			gnuism(311);
+	  }
 	| T_DEFAULT T_COLON {
 		label(T_DEFAULT, NULL, NULL);
 		ftflg = 1;
@@ -1440,7 +1473,7 @@
 
 term:
 	  T_NAME {
-		/* XXX realy neccessary? */
+		/* XXX really necessary? */
 		if (yychar < 0)
 			yychar = yylex();
 		$$ = getnnode(getsym($1), yychar);
@@ -1472,10 +1505,6 @@
 		$$ = build($1, $2, NULL);
 	  }
 	| T_ADDOP term {
-		if (tflag && $1 == PLUS) {
-			/* unary + is illegal in traditional C */
-			warning(100);
-		}
 		$$ = build($1 == PLUS ? UPLUS : UMINUS, $2, NULL);
 	  }
 	| term T_LBRACK expr T_RBRACK {
@@ -1502,7 +1531,7 @@
 		}
 	  }
 	| T_SIZEOF term					%prec T_SIZEOF {
-		if (($$ = $2 == NULL ? NULL : bldszof($2->tn_type)) != NULL)
+		if (($$ = $2 == NULL ? NULL : bldszoftrm($2)) != NULL)
 			chkmisc($2, 0, 0, 0, 0, 0, 1);
 	  }
 	| T_SIZEOF T_LPARN type_name T_RPARN		%prec T_SIZEOF {
@@ -1524,10 +1553,6 @@
 
 string2:
 	 T_STRING {
-		if (tflag) {
-			/* concatenated strings are illegal in traditional C */
-			warning(219);
-		}
 		$$ = $1;
 	  }
 	| string2 T_STRING {
@@ -1604,26 +1629,15 @@
 	} else {
 		i = (int)v->v_quad;
 		if (isutyp(t)) {
-			if ((u_quad_t)v->v_quad > INT_MAX) {
+			if ((u_quad_t)v->v_quad > UINT_MAX) {
 				/* integral constant too large */
 				warning(56);
 			}
 		} else {
-#ifdef XXX_BROKEN_GCC
-			if (v->v_quad > INT_MAX) {
-				/* integral constant too large */
-				warning(56);
-			}
-			else if (v->v_quad < INT_MIN) {
-				/* integral constant too large */
-				warning(56);
-			}
-#else
 			if (v->v_quad > INT_MAX || v->v_quad < INT_MIN) {
 				/* integral constant too large */
 				warning(56);
 			}
-#endif
 		}
 	}
 	free(v);
@@ -1636,6 +1650,9 @@
 	initerr = 0;
 	initsym = decl;
 
+	if (usedflg)
+		setuflg(decl, 0, 0);
+
 	switch (dcs->d_ctx) {
 	case EXTERN:
 		decl1ext(decl, initflg);
Index: usr.bin/xlint/lint1/decl.c
===================================================================
RCS file: /home/dcvs/src/usr.bin/xlint/lint1/decl.c,v
retrieving revision 1.6
diff -u -r1.6 decl.c
--- usr.bin/xlint/lint1/decl.c	7 Jul 2004 12:24:00 -0000	1.6
+++ usr.bin/xlint/lint1/decl.c	25 Dec 2006 09:52:38 -0000
@@ -1,3 +1,4 @@
+/*	$OpenBSD: decl.c,v 1.23 2006/05/29 20:47:22 cloder Exp $	*/
 /*	$NetBSD: decl.c,v 1.11 1995/10/02 17:34:16 jpo Exp $	*/
 
 /*
@@ -46,7 +47,7 @@
 /* contains various information and classification on types */
 ttab_t	ttab[NTSPEC];
 
-/* shared type structures for arithmtic types and void */
+/* shared type structures for arithmetic types and void */
 static	type_t	*typetab;
 
 /* value of next enumerator during declaration of enum types */
@@ -89,73 +90,73 @@
 		tspec_t	it_tspec;
 		ttab_t	it_ttab;
 	} ittab[] = {
-		{ SIGNED,   { 0, 0,
+		{ SIGNED,   { 0, 0, 0,
 			      SIGNED, UNSIGN,
 			      0, 0, 0, 0, 0, "signed" } },
-		{ UNSIGN,   { 0, 0,
+		{ UNSIGN,   { 0, 0, 0,
 			      SIGNED, UNSIGN,
 			      0, 0, 0, 0, 0, "unsigned" } },
-		{ CHAR,	    { CHAR_BIT, CHAR_BIT,
+		{ CHAR,	    { CHAR_BIT, CHAR_BIT, 20,
 			      SCHAR, UCHAR,
 			      1, 0, 0, 1, 1, "char" } },
-		{ SCHAR,    { CHAR_BIT, CHAR_BIT,
+		{ SCHAR,    { CHAR_BIT, CHAR_BIT, 20,
 			      SCHAR, UCHAR,
 			      1, 0, 0, 1, 1, "signed char" } },
-		{ UCHAR,    { CHAR_BIT, CHAR_BIT,
+		{ UCHAR,    { CHAR_BIT, CHAR_BIT, 20,
 			      SCHAR, UCHAR,
 			      1, 1, 0, 1, 1, "unsigned char" } },
-		{ SHORT,    { sizeof (short) * CHAR_BIT, 2 * CHAR_BIT,
+		{ SHORT,    { sizeof (short) * CHAR_BIT, 2 * CHAR_BIT, 30,
 			      SHORT, USHORT,
 			      1, 0, 0, 1, 1, "short" } },
-		{ USHORT,   { sizeof (u_short) * CHAR_BIT, 2 * CHAR_BIT,
+		{ USHORT,   { sizeof (u_short) * CHAR_BIT, 2 * CHAR_BIT, 30,
 			      SHORT, USHORT,
 			      1, 1, 0, 1, 1, "unsigned short" } },
-		{ INT,      { sizeof (int) * CHAR_BIT, 3 * CHAR_BIT,
+		{ INT,      { sizeof (int) * CHAR_BIT, 3 * CHAR_BIT, 40,
 			      INT, UINT,
 			      1, 0, 0, 1, 1, "int" } },
-		{ UINT,     { sizeof (u_int) * CHAR_BIT, 3 * CHAR_BIT,
+		{ UINT,     { sizeof (u_int) * CHAR_BIT, 3 * CHAR_BIT, 40,
 			      INT, UINT,
 			      1, 1, 0, 1, 1, "unsigned int" } },
-		{ LONG,     { sizeof (long) * CHAR_BIT, 4 * CHAR_BIT,
+		{ LONG,     { sizeof (long) * CHAR_BIT, 4 * CHAR_BIT, 50,
 			      LONG, ULONG,
 			      1, 0, 0, 1, 1, "long" } },
-		{ ULONG,    { sizeof (u_long) * CHAR_BIT, 4 * CHAR_BIT,
+		{ ULONG,    { sizeof (u_long) * CHAR_BIT, 4 * CHAR_BIT, 50,
 			      LONG, ULONG,
 			      1, 1, 0, 1, 1, "unsigned long" } },
-		{ QUAD,     { sizeof (quad_t) * CHAR_BIT, 8 * CHAR_BIT,
+		{ QUAD,     { sizeof (quad_t) * CHAR_BIT, 8 * CHAR_BIT, 60,
 			      QUAD, UQUAD,
 			      1, 0, 0, 1, 1, "long long" } },
-		{ UQUAD,    { sizeof (u_quad_t) * CHAR_BIT, 8 * CHAR_BIT,
+		{ UQUAD,    { sizeof (u_quad_t) * CHAR_BIT, 8 * CHAR_BIT, 60,
 			      QUAD, UQUAD,
 			      1, 1, 0, 1, 1, "unsigned long long" } },
-		{ FLOAT,    { sizeof (float) * CHAR_BIT, 4 * CHAR_BIT,
+		{ FLOAT,    { sizeof (float) * CHAR_BIT, 4 * CHAR_BIT, -1,
 			      FLOAT, FLOAT,
 			      0, 0, 1, 1, 1, "float" } },
-		{ DOUBLE,   { sizeof (double) * CHAR_BIT, 8 * CHAR_BIT,
+		{ DOUBLE,   { sizeof (double) * CHAR_BIT, 8 * CHAR_BIT, -1,
 			      DOUBLE, DOUBLE,
 			      0, 0, 1, 1, 1, "double" } },
-		{ LDOUBLE,  { sizeof (ldbl_t) * CHAR_BIT, 10 * CHAR_BIT,
+		{ LDOUBLE,  { sizeof (ldbl_t) * CHAR_BIT, 10 * CHAR_BIT, -1,
 			      LDOUBLE, LDOUBLE,
 			      0, 0, 1, 1, 1, "long double" } },
-		{ VOID,     { -1, -1,
+		{ VOID,     { -1, -1, -1,
 			      VOID, VOID,
 			      0, 0, 0, 0, 0, "void" } },
-		{ STRUCT,   { -1, -1,
+		{ STRUCT,   { -1, -1, -1,
 			      STRUCT, STRUCT,
 			      0, 0, 0, 0, 0, "struct" } },
-		{ UNION,    { -1, -1,
+		{ UNION,    { -1, -1, -1,
 			      UNION, UNION,
 			      0, 0, 0, 0, 0, "union" } },
-		{ ENUM,     { sizeof (int) * CHAR_BIT, 3 * CHAR_BIT,
+		{ ENUM,     { sizeof (int) * CHAR_BIT, 3 * CHAR_BIT, 40,
 			      ENUM, ENUM,
 			      1, 0, 0, 1, 1, "enum" } },
-		{ PTR,      { sizeof (void *) * CHAR_BIT, 4 * CHAR_BIT,
+		{ PTR,      { sizeof (void *) * CHAR_BIT, 4 * CHAR_BIT, -1,
 			      PTR, PTR,
 			      0, 1, 0, 0, 1, "pointer" } },
-		{ ARRAY,    { -1, -1,
+		{ ARRAY,    { -1, -1, -1,
 			      ARRAY, ARRAY,
 			      0, 0, 0, 0, 0, "array" } },
-		{ FUNC,     { -1, -1,
+		{ FUNC,     { -1, -1, -1,
 			      FUNC, FUNC,
 			      0, 0, 0, 0, 0, "function" } },
 	};
@@ -203,7 +204,7 @@
 /*
  * Returns a shared type structure vor arithmetic types and void.
  *
- * It's important do duplicate this structure (using duptyp() or tdupdyp())
+ * It's important to duplicate this structure (using duptyp() or tduptyp())
  * if it is to be modified (adding qualifiers or anything else).
  */
 type_t *
@@ -371,7 +372,7 @@
 		dcs->d_lmod = NOTSPEC;
 		if (!quadflg)
 			/* %s C does not support 'long long' */
-			(void)gnuism(265, tflag ? "traditional" : "ANSI");
+			(void)gnuism(265, "ANSI");
 	}
 
 	if (dcs->d_type != NULL && dcs->d_type->t_typedef) {
@@ -385,7 +386,7 @@
 		/* remeber specifiers "signed" and "unsigned" in dcs->d_smod */
 		if (dcs->d_smod != NOTSPEC)
 			/*
-			 * more then one "signed" and/or "unsigned"; print
+			 * more than one "signed" and/or "unsigned"; print
 			 * an error in deftyp()
 			 */
 			dcs->d_terr = 1;
@@ -427,9 +428,8 @@
 	case UNSIGN:
 		if (t2 == CHAR || t2 == SHORT || t2 == INT || t2 == LONG ||
 		    t2 == QUAD) {
-			if (!tflag)
-				/* modifying typedef with ... */
-				warning(5, ttab[t].tt_name);
+			/* modifying typedef with ... */
+			warning(5, ttab[t].tt_name);
 			td = duptyp(gettyp(mrgtspec(t2, t)));
 			td->t_typedef = 1;
 			return (td);
@@ -468,8 +468,6 @@
 		}
 		break;
 		/* LINTED (enumeration values not handled in switch) */
-	default:
-		break;
 	}
 
 	/* Anything other is not accepted. */
@@ -483,7 +481,7 @@
  * or enum tag if the typedef name is the first defined for this tag.
  *
  * If the tag is unnamed, the typdef name is used for identification
- * of this tag in lint2. Although its possible that more then one typedef
+ * of this tag in lint2. Although its possible that more than one typedef
  * name is defined for one tag, the first name defined should be unique
  * if the tag is unnamed.
  */
@@ -506,7 +504,7 @@
  * (and not the declarator) in the top element of the declaration stack.
  * Also detect multiple qualifiers of the same kind.
 
- * The rememberd qualifier is used by deftyp() to construct the type
+ * The remembered qualifier is used by deftyp() to construct the type
  * for all declarators.
  */
 void
@@ -518,15 +516,20 @@
 			warning(10, "const");
 		}
 		dcs->d_const = 1;
-	} else {
-		if (q != VOLATILE)
-			lerror("addqual() 1");
+	} else if (q == VOLATILE) {
 		if (dcs->d_volatile) {
 			/* duplicate "%s" */
 			warning(10, "volatile");
 		}
 		dcs->d_volatile = 1;
-	}
+	} else if (q == RESTRICT) {
+		if (dcs->d_restrict) {
+			/* duplicate "%s" */
+			warning(10, "restrict");
+		}
+		dcs->d_restrict = 1;
+	} else
+		lerror("addqual() 1");
 }
 
 /*
@@ -709,18 +712,14 @@
 			if (l == LONG) {
 				l = NOTSPEC;
 				t = DOUBLE;
-				if (!tflag)
-					/* use 'double' instead of ...  */
-					warning(6);
+				/* use 'double' instead of ...  */
+				warning(6);
 			}
 			break;
 		case DOUBLE:
 			if (l == LONG) {
 				l = NOTSPEC;
 				t = LDOUBLE;
-				if (tflag)
-					/* 'long double' is illegal in ... */
-					warning(266);
 			}
 			break;
 		case VOID:
@@ -818,14 +817,17 @@
 	int	elem, elsz;
 
 	elem = 1;
-	while (tp->t_tspec == ARRAY) {
+	while (tp && tp->t_tspec == ARRAY) {
 		elem *= tp->t_dim;
 		tp = tp->t_subt;
 	}
+	if (tp == NULL)
+		return (-1);
+
 	switch (tp->t_tspec) {
 	case FUNC:
 		/* compiler takes size of function */
-		lerror("%s", msgs[12]);
+		lerror(msgs[12]);
 		/* NOTREACHED */
 	case STRUCT:
 	case UNION:
@@ -851,7 +853,7 @@
 }
 
 /*
- * Get the alignment of the given Type in bits.
+ * Get the alignment of the given type in bits.
  */
 int
 getbound(type_t *tp)
@@ -859,9 +861,12 @@
 	int	a;
 	tspec_t	t;
 
-	while (tp->t_tspec == ARRAY)
+	while (tp && tp->t_tspec == ARRAY)
 		tp = tp->t_subt;
 
+	if (tp == NULL)
+		return (-1);
+
 	if ((t = tp->t_tspec) == STRUCT || t == UNION) {
 		a = tp->t_str->align;
 	} else if (t == FUNC) {
@@ -937,7 +942,7 @@
 				}
 				return;
 			} else if (tp->t_const || tp->t_volatile) {
-				if (sflag) {	/* XXX oder better !tflag ? */
+				if (sflag) {
 					/* function cannot return const... */
 					warning(228);
 				}
@@ -984,10 +989,11 @@
 			}
 		}
 		if (t == VOID && to != PTR) {
-			if (tp->t_const || tp->t_volatile) {
+			if (tp->t_const || tp->t_volatile || tp->t_restrict) {
 				/* inappropriate qualifiers with "void" */
 				warning(69);
 				tp->t_const = tp->t_volatile = 0;
+				tp->t_restrict = 0;
 			}
 		}
 		tpp = &tp->t_subt;
@@ -1028,8 +1034,8 @@
 		/*
 		 * bit field
 		 *
-		 * only unsigned und signed int are protable bit-field types
-		 *(at least in ANSI C, in traditional C only unsigned int)
+		 * only unsigned and signed int are portable bit-field types
+		 * (at least in ANSI C, in traditional C only unsigned int)
 		 */
 		if (t == CHAR || t == UCHAR || t == SCHAR ||
 		    t == SHORT || t == USHORT || t == ENUM) {
@@ -1040,12 +1046,19 @@
 				/* nonportable bit-field type */
 				warning(34);
 			}
+			if (isutyp(t))
+				tp->t_tspec = UINT;
+			else
+				tp->t_tspec = INT;
+
+			tp->t_isenum = 0;
 		} else if (t == INT && dcs->d_smod == NOTSPEC) {
 			if (pflag) {
 				/* nonportable bit-field type */
 				warning(34);
 			}
-		} else if (t != INT && t != UINT) {
+		} else if (t != INT && t != UINT && t != LONG &&
+		    t != ULONG && t != QUAD && t != UQUAD) {
 			/* illegal bit-field type */
 			error(35);
 			sz = tp->t_flen;
@@ -1149,6 +1162,8 @@
 	}
 	dsym->s_type = duptyp(dsym->s_type);
 	dsym->s_type->t_isfield = 1;
+	dsym->s_type->t_proto = 0;
+	dsym->s_type->t_isenum = 0;
 	dsym->s_type->t_flen = len;
 	dsym->s_field = 1;
 	return (dsym);
@@ -1194,7 +1209,7 @@
  * Followint 3 functions extend the type of a declarator with
  * pointer, function and array types.
  *
- * The current type is the Type built by deftyp() (dcs->d_type) and
+ * The current type is the type built by deftyp() (dcs->d_type) and
  * pointer, function and array types already added for this
  * declarator. The new type extension is inserted between both.
  */
@@ -1205,8 +1220,10 @@
 	pqinf_t	*npi;
 
 	tpp = &decl->s_type;
-	while (*tpp != dcs->d_type)
+	while (*tpp && *tpp != dcs->d_type)
 		tpp = &(*tpp)->t_subt;
+	if (*tpp == NULL)
+		return (decl);
 
 	while (pi != NULL) {
 		*tpp = tp = getblk(sizeof (type_t));
@@ -1231,8 +1248,10 @@
 	type_t	**tpp, *tp;
 
 	tpp = &decl->s_type;
-	while (*tpp != dcs->d_type)
+	while (*tpp && *tpp != dcs->d_type)
 		tpp = &(*tpp)->t_subt;
+	if (*tpp == NULL)
+	    return (decl);
 
 	*tpp = tp = getblk(sizeof (type_t));
 	tp->t_tspec = ARRAY;
@@ -1260,9 +1279,6 @@
 	type_t	**tpp, *tp;
 
 	if (dcs->d_proto) {
-		if (tflag)
-			/* function prototypes are illegal in traditional C */
-			warning(270);
 		args = nsfunc(decl, args);
 	} else {
 		osfunc(decl, args);
@@ -1285,8 +1301,10 @@
 	}
 
 	tpp = &decl->s_type;
-	while (*tpp != dcs->d_nxt->d_type)
+	while (*tpp && *tpp != dcs->d_nxt->d_type)
 		tpp = &(*tpp)->t_subt;
+	if (*tpp == NULL)
+	    return (decl);
 
 	*tpp = tp = getblk(sizeof (type_t));
 	tp->t_tspec = FUNC;
@@ -1392,7 +1410,7 @@
 sym_t *
 dname(sym_t *sym)
 {
-	scl_t	sc;
+	scl_t	sc = NOSCL;
 
 	if (sym->s_scl == NOSCL) {
 		dcs->d_rdcsym = NULL;
@@ -1455,7 +1473,7 @@
 			 * XXX somewhat ugly because we dont know whether
 			 * this is AUTO or EXTERN (functions). If we are
 			 * wrong it must be corrected in decl1loc(), where
-			 * we have the neccessary type information.
+			 * we have the necessary type information.
 			 */
 			sc = AUTO;
 			sym->s_def = DEF;
@@ -1518,7 +1536,7 @@
 type_t *
 mktag(sym_t *tag, tspec_t kind, int decl, int semi)
 {
-	scl_t	scl;
+	scl_t	scl = NOSCL;
 	type_t	*tp;
 
 	if (kind == STRUCT) {
@@ -1538,7 +1556,7 @@
 			/* a new tag, no empty declaration */
 			dcs->d_nxt->d_nedecl = 1;
 			if (scl == ENUMTAG && !decl) {
-				if (!tflag && (sflag || pflag))
+				if (sflag || pflag)
 					/* forward reference to enum type */
 					warning(42);
 			}
@@ -1571,7 +1589,7 @@
 			tp->t_enum = getblk(sizeof (enum_t));
 			tp->t_enum->etag = tag;
 		}
-		/* ist unvollstaendiger Typ */
+		/* is incomplete type */
 		setcompl(tp, 1);
 	}
 
@@ -1589,15 +1607,10 @@
 	if (tag->s_blklev < blklev) {
 		if (semi) {
 			/* "struct a;" */
-			if (!tflag) {
-				if (!sflag)
-					/* decl. introduces new type ... */
-					warning(44, scltoa(scl), tag->s_name);
-				tag = pushdown(tag);
-			} else if (tag->s_scl != scl) {
-				/* base type is really "%s %s" */
-				warning(45, scltoa(tag->s_scl), tag->s_name);
-			}
+			if (!sflag)
+				/* decl. introduces new type ... */
+				warning(44, scltoa(scl), tag->s_name);
+			tag = pushdown(tag);
 			dcs->d_nxt->d_nedecl = 1;
 		} else if (decl) {
 			/* "struct a { ..." */
@@ -1701,7 +1714,7 @@
  *
  * sym points to the enumerator
  * val is the value of the enumerator
- * impl is 1 if the the value of the enumerator was not explicit specified.
+ * impl is 1 if the value of the enumerator was not explicitly specified.
  */
 sym_t *
 ename(sym_t *sym, int val, int impl)
@@ -1775,6 +1788,12 @@
 		}
 	}
 
+	if (dsym->s_type->t_tspec == FUNC) {
+		if (noretflg)
+			dsym->s_noreturn = 1;
+	}
+	noretflg = 0;
+
 	/* Write the declaration into the output file */
 	if (plibflg && llibflg &&
 	    dsym->s_type->t_tspec == FUNC && dsym->s_type->t_proto) {
@@ -1789,7 +1808,6 @@
 	}
 
 	if ((rdsym = dcs->d_rdcsym) != NULL) {
-
 		/*
 		 * If the old symbol stems from a old style function definition
 		 * we have remembered the params in rdsmy->s_args and compare
@@ -1802,7 +1820,6 @@
 		}
 
 		if (!redec && !isredec(dsym, (warn = 0, &warn))) {
-
 			if (warn) {
 				/* redeclaration of %s */
 				(*(sflag ? error : warning))(27, dsym->s_name);
@@ -1921,7 +1938,7 @@
 		return(0);
 	if (rsym->s_scl == EXTERN && rsym->s_def == DEF) {
 		/*
-		 * All cases except "int a = 1; static int a;" are catched
+		 * All cases except "int a = 1; static int a;" are caught
 		 * above with or without a warning
 		 */
 		/* redeclaration of %s */
@@ -1952,7 +1969,7 @@
  * Checks if two types are compatible. Returns 0 if not, otherwise 1.
  *
  * ignqual	ignore qualifiers of type; used for function params
- * promot	promote left type; used for comparision of params of
+ * promot	promote left type; used for comparison of params of
  *		old style function definitions with params of prototypes.
  * *warn	set to 1 if an old style function declaration is not
  *		compatible with a prototype
@@ -1963,7 +1980,6 @@
 	tspec_t	t;
 
 	while (tp1 != NULL && tp2 != NULL) {
-
 		t = tp1->t_tspec;
 		if (promot) {
 			if (t == FLOAT) {
@@ -1971,22 +1987,25 @@
 			} else if (t == CHAR || t == SCHAR) {
 				t = INT;
 			} else if (t == UCHAR) {
-				t = tflag ? UINT : INT;
+				t = INT;
 			} else if (t == SHORT) {
 				t = INT;
 			} else if (t == USHORT) {
 				/* CONSTCOND */
-				t = INT_MAX < USHRT_MAX || tflag ? UINT : INT;
+				t = INT_MAX < USHRT_MAX ? UINT : INT;
 			}
 		}
 
 		if (t != tp2->t_tspec)
 			return (0);
 
-		if (tp1->t_const != tp2->t_const && !ignqual && !tflag)
+		if (tp1->t_const != tp2->t_const && !ignqual)
 			return (0);
 
-		if (tp1->t_volatile != tp2->t_volatile && !ignqual && !tflag)
+		if (tp1->t_volatile != tp2->t_volatile && !ignqual)
+			return (0);
+
+		if (tp1->t_restrict != tp2->t_restrict && !ignqual)
 			return (0);
 
 		if (t == STRUCT || t == UNION)
@@ -1998,7 +2017,7 @@
 		}
 
 		/* dont check prototypes for traditional */
-		if (t == FUNC && !tflag) {
+		if (t == FUNC) {
 			if (tp1->t_proto && tp2->t_proto) {
 				if (!eqargs(tp1, tp2, warn))
 					return (0);
@@ -2035,7 +2054,6 @@
 	a2 = tp2->t_args;
 
 	while (a1 != NULL && a2 != NULL) {
-
 		if (eqtype(a1->s_type, a2->s_type, 1, 0, warn) == 0)
 			return (0);
 
@@ -2134,7 +2152,7 @@
 }
 
 /*
- * Complets a type by copying the dimension and prototype information
+ * Completes a type by copying the dimension and prototype information
  * from a second compatible type.
  *
  * Following lines are legal:
@@ -2159,7 +2177,7 @@
 			if (dst->t_dim == 0 && src->t_dim != 0) {
 				*dstp = dst = duptyp(dst);
 				dst->t_dim = src->t_dim;
-				/* now a complete Typ */
+				/* now a complete type */
 				setcompl(dst, 0);
 			}
 		} else if (dst->t_tspec == FUNC) {
@@ -2208,13 +2226,7 @@
 	if ((t = sym->s_type->t_tspec) == ARRAY) {
 		sym->s_type = incref(sym->s_type->t_subt, PTR);
 	} else if (t == FUNC) {
-		if (tflag)
-			/* a function is declared as an argument: %s */
-			warning(50, sym->s_name);
 		sym->s_type = incref(sym->s_type, PTR);
-	} else if (t == FLOAT) {
-		if (tflag)
-			sym->s_type = gettyp(DOUBLE);
 	}
 
 	if (dcs->d_inline)
@@ -2238,7 +2250,7 @@
  * Does some checks for lint directives which apply to functions.
  * Processes arguments in old style function definitions which default
  * to int.
- * Checks compatiblility of old style function definition with previous
+ * Checks compatibility of old style function definition with previous
  * prototype.
  */
 void
@@ -2309,7 +2321,7 @@
 	}
 
 	/*
-	 * print a warning for each argument off an old style function
+	 * print a warning for each argument of an old style function
 	 * definition which defaults to int
 	 */
 	for (arg = args; arg != NULL; arg = arg->s_nxt) {
@@ -2322,7 +2334,7 @@
 	}
 
 	/*
-	 * If this is an old style function definition and a prototyp
+	 * If this is an old style function definition and a prototype
 	 * exists, compare the types of arguments.
 	 */
 	if (funcsym->s_osdef && funcsym->s_type->t_proto) {
@@ -2425,8 +2437,6 @@
 	 * functions may be declared inline at local scope, although
 	 * this has no effect for a later definition of the same
 	 * function.
-	 * XXX it should have an effect if tflag is set. this would
-	 * also be the way gcc behaves.
 	 */
 	if (dcs->d_inline) {
 		if (dsym->s_type->t_tspec == FUNC) {
@@ -2457,9 +2467,7 @@
 	}
 
 	if (dcs->d_rdcsym != NULL) {
-
 		if (dcs->d_rdcsym->s_blklev == 0) {
-
 			switch (dsym->s_scl) {
 			case AUTO:
 				/* automatic hides external declaration: %s */
@@ -2484,39 +2492,26 @@
 			default:
 				lerror("decl1loc() 1");
 			}
-
 		} else if (dcs->d_rdcsym->s_blklev == blklev) {
-
 			/* no hflag, because its illegal! */
 			if (dcs->d_rdcsym->s_arg) {
 				/*
-				 * if !tflag, a "redeclaration of %s" error
+				 * a "redeclaration of %s" error
 				 * is produced below
 				 */
-				if (tflag) {
-					if (hflag)
-						/* decl. hides parameter: %s */
-						warning(91, dsym->s_name);
-					rmsym(dcs->d_rdcsym);
-				}
 			}
 
 		} else if (dcs->d_rdcsym->s_blklev < blklev) {
-
 			if (hflag)
 				/* declaration hides earlier one: %s */
 				warning(95, dsym->s_name);
-
 		}
 
 		if (dcs->d_rdcsym->s_blklev == blklev) {
-
 			/* redeclaration of %s */
 			error(27, dsym->s_name);
 			rmsym(dcs->d_rdcsym);
-
 		}
-
 	}
 
 	if (initflg && !(initerr = chkinit(dsym))) {
@@ -2590,8 +2585,8 @@
 }
 
 /*
- * Print an error or a warning if the symbol cant be initialized due
- * to type/storage class. Returnvalue is 1 if an error has been
+ * Print an error or a warning if the symbol can't be initialized due
+ * to type/storage class. Return value is 1 if an error has been
  * detected.
  */
 static int
@@ -2664,7 +2659,7 @@
 	mblklev = 0;
 
 	/*
-	 * remove all informations about pending lint directives without
+	 * remove all information about pending lint directives without
 	 * warnings.
 	 */
 	glclup(1);
@@ -2701,11 +2696,7 @@
 	if (length(dsym->s_type, dsym->s_name) == 0 &&
 	    dsym->s_type->t_tspec == ARRAY && dsym->s_type->t_dim == 0) {
 		/* empty array declaration: %s */
-		if (tflag) {
-			warning(190, dsym->s_name);
-		} else {
-			error(190, dsym->s_name);
-		}
+		error(190, dsym->s_name);
 	}
 }
 
@@ -2993,7 +2984,7 @@
 				warning(307, sym->s_name);
 			}
 		}
-		if (!tflag && sym->s_def == TDEF && sym->s_type->t_const) {
+		if (sym->s_def == TDEF && sym->s_type->t_const) {
 			STRUCT_ASSIGN(curr_pos, sym->s_dpos);
 			/* const object %s should have initializer */
 			warning(227, sym->s_name);
@@ -3007,7 +2998,7 @@
 	if (sym->s_def == TDEF) {
 		if (sym->s_type->t_tspec == FUNC)
 			/*
-			 * this can happen if an syntax error occured
+			 * this can happen if a syntax error occurred
 			 * after a function declaration
 			 */
 			return;
@@ -3015,7 +3006,7 @@
 		if (length(sym->s_type, sym->s_name) == 0 &&
 		    sym->s_type->t_tspec == ARRAY && sym->s_type->t_dim == 0) {
 			/* empty array declaration: %s */
-			if (tflag || (sym->s_scl == EXTERN && !sflag)) {
+			if (sym->s_scl == EXTERN && !sflag) {
 				warning(190, sym->s_name);
 			} else {
 				error(190, sym->s_name);
Index: usr.bin/xlint/lint1/emit.c
===================================================================
RCS file: /home/dcvs/src/usr.bin/xlint/lint1/emit.c,v
retrieving revision 1.5
diff -u -r1.5 emit.c
--- usr.bin/xlint/lint1/emit.c	7 Jul 2004 12:13:26 -0000	1.5
+++ usr.bin/xlint/lint1/emit.c	25 Dec 2006 09:59:26 -0000
@@ -1,3 +1,4 @@
+/*	$OpenBSD: emit.c,v 1.9 2005/12/10 18:58:50 martin Exp $	*/
 /*	$NetBSD: emit.c,v 1.2 1995/07/03 21:24:00 cgd Exp $	*/
 
 /*
@@ -32,8 +33,6 @@
  *
  * $FreeBSD: src/usr.bin/xlint/lint1/emit.c,v 1.1.1.1.8.1 2001/03/04 09:27:26 kris Exp $
  * $DragonFly: src/usr.bin/xlint/lint1/emit.c,v 1.5 2004/07/07 12:13:26 asmodai Exp $
- *
- * $NetBSD: emit.c,v 1.2 1995/07/03 21:24:00 cgd Exp $
  */
 
 #include <stdio.h>
@@ -61,11 +60,11 @@
 {
 	loname = name;
 
-	/* Ausgabedatei oeffnen */
+	/* open output file */
 	if ((lout = fopen(name, "w")) == NULL)
 		err(1, "cannot open '%s'", name);
 
-	/* Ausgabepuffer anlegen */
+	/* generate output buffer */
 	ob.o_len = 1024;
 	ob.o_end = (ob.o_buf = ob.o_nxt = xmalloc(ob.o_len)) + ob.o_len;
 }
@@ -197,9 +196,10 @@
 void
 outint(int i)
 {
-	if ((ob.o_end - ob.o_nxt) < 3 * sizeof (int))
+	if ((ob.o_end - ob.o_nxt) < 12)
 		outxbuf();
-	ob.o_nxt += sprintf(ob.o_nxt, "%d", i);
+	snprintf(ob.o_nxt, ob.o_end - ob.o_nxt, "%d", i);
+	ob.o_nxt += strlen(ob.o_nxt);
 }
 
 /*
Index: usr.bin/xlint/lint1/emit1.c
===================================================================
RCS file: /home/dcvs/src/usr.bin/xlint/lint1/emit1.c,v
retrieving revision 1.5
diff -u -r1.5 emit1.c
--- usr.bin/xlint/lint1/emit1.c	7 Jul 2004 12:13:26 -0000	1.5
+++ usr.bin/xlint/lint1/emit1.c	25 Dec 2006 10:01:22 -0000
@@ -1,3 +1,4 @@
+/*	$OpenBSD: emit1.c,v 1.6 2005/11/29 19:38:09 cloder Exp $	*/
 /*	$NetBSD: emit1.c,v 1.4 1995/10/02 17:21:28 jpo Exp $	*/
 
 /*
@@ -30,7 +31,6 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $NetBSD: emit1.c,v 1.4 1995/10/02 17:21:28 jpo Exp $
  * $DragonFly: src/usr.bin/xlint/lint1/emit1.c,v 1.5 2004/07/07 12:13:26 asmodai Exp $
  */
 
@@ -404,7 +404,7 @@
 			if (isityp(t = arg->tn_type->t_tspec)) {
 				/*
 				 * XXX it would probably be better to
-				 * explizitly test the sign
+				 * explicitly test the sign
 				 */
 				if ((q = arg->tn_val->v_quad) == 0) {
 					/* zero constant */
@@ -418,13 +418,17 @@
 				}
 				outint(n);
 			}
-		} else if (arg->tn_op == AMPER &&
-			   arg->tn_left->tn_op == STRING &&
-			   arg->tn_left->tn_strg->st_tspec == CHAR) {
-			/* constant string, write all format specifiers */
-			outchar('s');
-			outint(n);
-			outfstrg(arg->tn_left->tn_strg);
+		} else {
+			if (arg->tn_op == CVT && !arg->tn_cast)
+				arg = arg->tn_left;
+			if (arg->tn_op == AMPER &&
+			    arg->tn_left->tn_op == STRING &&
+			    arg->tn_left->tn_strg->st_tspec == CHAR) {
+				/* constant string, write format specifiers */
+				outchar('s');
+				outint(n);
+				outfstrg(arg->tn_left->tn_strg);
+			}
 		}
 
 	}
@@ -448,7 +452,7 @@
 
 /*
  * extracts potential format specifiers for printf() and scanf() and
- * writes them, enclosed in "" and qouted if necessary, to the output buffer
+ * writes them, enclosed in "" and quoted if necessary, to the output buffer
  */
 static void
 outfstrg(strg_t *strg)
Index: usr.bin/xlint/lint1/err.c
===================================================================
RCS file: /home/dcvs/src/usr.bin/xlint/lint1/err.c,v
retrieving revision 1.6
diff -u -r1.6 err.c
--- usr.bin/xlint/lint1/err.c	7 Jul 2004 12:13:26 -0000	1.6
+++ usr.bin/xlint/lint1/err.c	25 Dec 2006 10:04:48 -0000
@@ -1,3 +1,4 @@
+/*	$OpenBSD: err.c,v 1.26 2006/06/02 17:38:59 cloder Exp $	*/
 /*	$NetBSD: err.c,v 1.8 1995/10/02 17:37:00 jpo Exp $	*/
 
 /*
@@ -30,7 +31,6 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $NetBSD: err.c,v 1.8 1995/10/02 17:37:00 jpo Exp $
  * $DragonFly: src/usr.bin/xlint/lint1/err.c,v 1.6 2004/07/07 12:13:26 asmodai Exp $
  */
 
@@ -42,13 +42,14 @@
 
 #include <stdlib.h>
 #include <stdarg.h>
+#include <err.h>
 
 #include "lint1.h"
 
-static	const	char *basename(const char *);
+static	const	char *lbasename(const char *);
 static	void	verror(int, va_list);
 static	void	vwarning(int, va_list);
-
+static	void	excerpt(pos_t *);
 
 const	char *msgs[] = {
 	"syntax error: empty declaration",			      /* 0 */
@@ -182,8 +183,8 @@
 	"operands have incompatible pointer types, op %s",	      /* 128 */
 	"expression has null effect",				      /* 129 */
 	"enum type mismatch, op %s",				      /* 130 */
-	"conversion to '%s' may sign-extend incorrectly",	      /* 131 */
-	"conversion from '%s' may lose accuracy",		      /* 132 */
+	"conversion from '%s' to '%s' may sign-extend incorrectly",   /* 131 */
+	"converted from '%s' to '%s'",	                              /* 132 */
 	"conversion of pointer to '%s' loses bits",		      /* 133 */
 	"conversion of pointer to '%s' may lose bits",		      /* 134 */
 	"possible pointer alignment problem",			      /* 135 */
@@ -204,16 +205,16 @@
 	"argument mismatch: %d arg%s passed, %d expected",	      /* 150 */
 	"void expressions may not be arguments, arg #%d",	      /* 151 */
 	"argument cannot have unknown size, arg #%d",		      /* 152 */
-	"argument has incompatible pointer type, arg #%d",	      /* 153 */
-	"illegal combination of pointer and integer, arg #%d",	      /* 154 */
-	"argument is incompatible with prototype, arg #%d",	      /* 155 */
-	"enum type mismatch, arg #%d",			       	      /* 156 */
+	"%s() arg #%d: incompatible pointer type",		      /* 153 */
+	"%s() arg #%d: illegal combination of pointer and integer",   /* 154 */
+	"%s() arg #%d: argument is incompatible with prototype",      /* 155 */
+	"%s() arg #%d: enum type mismatch",			      /* 156 */
 	"ANSI C treats constant as unsigned",			      /* 157 */
-	"%s may be used before set",			      	      /* 158 */
+	"%s may be used before set",				      /* 158 */
 	"assignment in conditional context",			      /* 159 */
 	"operator '==' found where '=' was expected",		      /* 160 */
 	"constant in conditional context",			      /* 161 */
-	"comparision of %s with %s, op %s",			      /* 162 */
+	"comparison of %s with %s, op %s",			      /* 162 */
 	"a cast does not yield an lvalue",			      /* 163 */
 	"assignment of negative constant to unsigned type",	      /* 164 */
 	"constant truncated by assignment",			      /* 165 */
@@ -242,7 +243,7 @@
 	"no automatic aggregate initialization in traditional C",     /* 188 */
 	"assignment of struct/union illegal in traditional C",	      /* 189 */
 	"empty array declaration: %s",				      /* 190 */
-	"%s set but not used in function %s",		      	      /* 191 */
+	"%s set but not used in function %s",			      /* 191 */
 	"%s unused in function %s",				      /* 192 */
 	"statement not reached",				      /* 193 */
 	"label %s redefined",					      /* 194 */
@@ -281,9 +282,9 @@
 	"const object %s should have initializer",		      /* 227 */
 	"function cannot return const or volatile object",	      /* 228 */
 	"questionable conversion of function pointer",		      /* 229 */
-	"nonportable character comparision, op %s",		      /* 230 */
-	"argument %s unused in function %s",			      /* 231 */
-	"label %s unused in function %s",			      /* 232 */
+	"nonportable character comparison, op %s",		      /* 230 */
+	"argument %s unused in function %s()",			      /* 231 */
+	"label %s unused in function %s()",			      /* 232 */
 	"struct %s never defined",				      /* 233 */
 	"union %s never defined",				      /* 234 */
 	"enum %s never defined",				      /* 235 */
@@ -294,7 +295,7 @@
 	"assignment of different structures",			      /* 240 */
 	"dubious operation on enum, op %s",			      /* 241 */
 	"combination of '%s' and '%s', op %s",			      /* 242 */
-	"dubious comparision of enums, op %s",			      /* 243 */
+	"dubious comparison of enums, op %s",			      /* 243 */
 	"illegal structure pointer combination",		      /* 244 */
 	"illegal structure pointer combination, op %s",		      /* 245 */
 	"dubious conversion of enum to '%s'",			      /* 246 */
@@ -310,7 +311,7 @@
 	"unterminated comment",					      /* 256 */
 	"extra characters in lint comment",			      /* 257 */
 	"unterminated string constant",				      /* 258 */
-	"conversion to '%s' due to prototype, arg #%d",		      /* 259 */
+	"%s() arg #%d: converted from '%s' to '%s'",		      /* 259 */
 	"previous declaration of %s",				      /* 260 */
 	"previous definition of %s",				      /* 261 */
 	"\\\" inside character constants undefined in traditional C", /* 262 */
@@ -325,11 +326,11 @@
 	"switch expression must be of type `int' in traditional C",   /* 271 */
 	"empty translation unit",				      /* 272 */
 	"bit-field type '%s' invalid in ANSI C",		      /* 273 */
-	"ANSI C forbids comparision of %s with %s",		      /* 274 */
+	"ANSI C forbids comparison of %s with %s",		      /* 274 */
 	"cast discards 'const' from pointer target type",	      /* 275 */
 	"",							      /* 276 */
 	"initialisation of '%s' with '%s'",			      /* 277 */
-	"combination of '%s' and '%s', arg #%d",		      /* 278 */
+	"%s() arg #%d: combination of '%s' and '%s'",		      /* 278 */
 	"combination of '%s' and '%s' in return",		      /* 279 */
 	"must be outside function: /* %s */",			      /* 280 */
 	"duplicate use of /* %s */",				      /* 281 */
@@ -346,10 +347,10 @@
 	"cannot concatenate wide and regular string literals",	      /* 292 */
 	"argument %d must be 'char *' for PRINTFLIKE/SCANFLIKE",      /* 293 */
 	"multi-character character constant",			      /* 294 */
-	"conversion of '%s' to '%s' is out of range, arg #%d",	      /* 295 */
-	"conversion of negative constant to unsigned type, arg #%d",  /* 296 */
-	"conversion to '%s' may sign-extend incorrectly, arg #%d",    /* 297 */
-	"conversion from '%s' may lose accuracy, arg #%d",	      /* 298 */
+	"%s() arg #%d: conversion of '%s' to '%s' is out of range",   /* 295 */
+	"%s() arg #%d: conversion of negative constant to unsigned type",  /* 296 */
+	"%s() arg #%d: conversion from '%s' to '%s' may sign-extend incorrectly",    /* 297 */
+	"%s() arg #%d: converted from '%s' to '%s'",		      /* 298 */
 	"prototype does not match old style definition, arg #%d",     /* 299 */
 	"old style definition",					      /* 300 */
 	"array of incomplete type",				      /* 301 */
@@ -361,14 +362,19 @@
 	"static variable %s set but not used",			      /* 307 */
 	"",							      /* 308 */
 	"extra bits set to 0 in conversion of '%s' to '%s', op %s",   /* 309 */
+	"right shift of %d-bit quantity by %lld bits",		      /* 310 */
+	"case ranges are illegal in ANSI C",			      /* 311 */
+	"suspicious operator for sizeof: %s",			      /* 312 */
+	"conversion of %s() return value from '%s' to '%s'",	      /* 313 */
+	"hexadecimal float constants are illegal in traditional C",   /* 314 */
 };
 
 /*
- * If Fflag is not set basename() returns a pointer to the last
+ * If Fflag is not set lbasename() returns a pointer to the last
  * component of the path, otherwise it returns the argument.
  */
 static const char *
-basename(const char *path)
+lbasename(const char *path)
 {
 	const	char *cp, *cp1, *cp2;
 
@@ -390,11 +396,14 @@
 {
 	const	char *fn;
 
-	fn = basename(curr_pos.p_file);
+	fn = lbasename(curr_pos.p_file);
 	(void)printf("%s:%d: ", fn, curr_pos.p_line);
 	(void)vprintf(msgs[n], ap);
 	(void)printf("\n");
 	nerr++;
+
+	if (fflag)
+		excerpt(&curr_pos);
 }
 
 static void
@@ -406,10 +415,13 @@
 		/* this warning is suppressed by a LINTED comment */
 		return;
 
-	fn = basename(curr_pos.p_file);
+	fn = lbasename(curr_pos.p_file);
 	(void)printf("%s:%d: warning: ", fn, curr_pos.p_line);
 	(void)vprintf(msgs[n], ap);
 	(void)printf("\n");
+
+	if (fflag)
+		excerpt(&curr_pos);
 }
 
 void
@@ -429,7 +441,7 @@
 	const	char *fn;
 
 	va_start(ap, msg);
-	fn = basename(curr_pos.p_file);
+	fn = lbasename(curr_pos.p_file);
 	(void)fprintf(stderr, "%s:%d: lint error: ", fn, curr_pos.p_line);
 	(void)vfprintf(stderr, msg, ap);
 	(void)fprintf(stderr, "\n");
@@ -454,11 +466,14 @@
 	const	char *fn;
 
 	va_start(ap, n);
-	fn = basename(curr_pos.p_file);
+	fn = lbasename(curr_pos.p_file);
 	(void)printf("%s:%d: ", fn, curr_pos.p_line);
 	(void)vprintf(msgs[n], ap);
 	(void)printf("\n");
 	va_end(ap);
+
+	if (fflag)
+		excerpt(&curr_pos);
 }
 
 int
@@ -481,3 +496,51 @@
 
 	return (msg);
 }
+
+static void
+excerpt(pos_t *pos)
+{
+	static	FILE *fp = NULL;
+	static	const char *file = NULL;
+	static	int lineno = 0;
+	char	*buf, *lbuf;
+	size_t	len;
+
+	if (!pos || !pos->p_file)
+		return;
+
+	/* don't print the same line twice */
+	if (pos->p_line == lineno)
+		return;
+
+	if (fp == NULL || file != pos->p_file || pos->p_line < lineno) {
+		if (fp)
+			fclose(fp);
+
+		if (!(fp = fopen(pos->p_file, "r")))
+			return;
+
+		file = pos->p_file;
+		lineno = 0;
+	}
+
+	lbuf = NULL;
+	while (lineno < pos->p_line && (buf = fgetln(fp, &len))) {
+		if (buf[len - 1] == '\n')
+			buf[len - 1] = '\0';
+		else {
+			/* EOF without EOL, copy and add the NUL */
+			if (!(lbuf = malloc(len + 1)))
+				err(1, NULL);
+
+			lbuf[len] = '\0';
+			buf = lbuf;
+		}
+		lineno++;
+	}
+
+	if (buf)
+		printf("%s:%d:   %s\n", pos->p_file, lineno, buf);
+
+	free(lbuf);
+}
Index: usr.bin/xlint/lint1/externs.h
===================================================================
RCS file: /home/dcvs/src/usr.bin/xlint/lint1/externs.h,v
retrieving revision 1.3
diff -u -r1.3 externs.h
--- usr.bin/xlint/lint1/externs.h	3 Nov 2003 19:31:34 -0000	1.3
+++ usr.bin/xlint/lint1/externs.h	25 Dec 2006 10:06:05 -0000
@@ -1,3 +1,4 @@
+/*	$OpenBSD: externs.h,v 1.4 2006/03/08 07:18:51 moritz Exp $	*/
 /*	$NetBSD: externs.h,v 1.2 1995/07/03 21:24:06 cgd Exp $	*/
 
 /*
@@ -40,7 +41,6 @@
 extern	void	*xcalloc(size_t, size_t);
 extern	void	*xrealloc(void *, size_t);
 extern	char	*xstrdup(const char *);
-extern	void	nomem(void);
 
 /*
  * emit.c
Index: usr.bin/xlint/lint1/externs1.h
===================================================================
RCS file: /home/dcvs/src/usr.bin/xlint/lint1/externs1.h,v
retrieving revision 1.3
diff -u -r1.3 externs1.h
--- usr.bin/xlint/lint1/externs1.h	3 Nov 2003 19:31:34 -0000	1.3
+++ usr.bin/xlint/lint1/externs1.h	25 Dec 2006 10:06:57 -0000
@@ -1,3 +1,4 @@
+/*	$OpenBSD: externs1.h,v 1.15 2006/05/29 20:47:22 cloder Exp $	*/
 /*	$NetBSD: externs1.h,v 1.7 1995/10/02 17:31:39 jpo Exp $	*/
 
 /*
@@ -37,18 +38,16 @@
 /*
  * main.c
  */
-extern	int	aflag;
-extern	int	bflag;
 extern	int	cflag;
 extern	int	dflag;
 extern	int	eflag;
+extern	int	fflag;
 extern	int	Fflag;
 extern	int	gflag;
 extern	int	hflag;
 extern	int	pflag;
 extern	int	rflag;
 extern	int	sflag;
-extern	int	tflag;
 extern	int	uflag;
 extern	int	vflag;
 extern	int	yflag;
@@ -120,7 +119,7 @@
 extern	void	warning(int, ...);
 extern	void	message(int, ...);
 extern	int	gnuism(int, ...);
-extern	void	lerror(const char *, ...) __printflike(1, 2);
+extern	void	lerror(const char *, ...);
 
 /*
  * decl.c
@@ -191,12 +190,13 @@
 extern	sym_t	*strmemb(tnode_t *, op_t, sym_t *);
 extern	tnode_t	*build(op_t, tnode_t *, tnode_t *);
 extern	tnode_t	*cconv(tnode_t *);
-extern	int	typeok(op_t, int, tnode_t *, tnode_t *);
+extern	int	typeok(op_t, farg_t *, tnode_t *, tnode_t *);
 extern	tnode_t	*promote(op_t, int, tnode_t *);
-extern	tnode_t	*convert(op_t, int, type_t *, tnode_t *);
-extern	void	cvtcon(op_t, int, type_t *, val_t *, val_t *);
+extern	tnode_t	*convert(op_t, farg_t *, type_t *, tnode_t *);
+extern	void	cvtcon(op_t, farg_t *, type_t *, val_t *, val_t *);
 extern	const	char *tyname(type_t *);
 extern	tnode_t	*bldszof(type_t *);
+extern	tnode_t	*bldszoftrm(tnode_t *);
 extern	tnode_t	*cast(tnode_t *, type_t *);
 extern	tnode_t	*funcarg(tnode_t *, tnode_t *);
 extern	tnode_t	*funccall(tnode_t *, tnode_t *);
@@ -205,6 +205,7 @@
 extern	void	chkmisc(tnode_t *, int, int, int, int, int, int);
 extern	int	conaddr(tnode_t *, sym_t **, ptrdiff_t *);
 extern	strg_t	*catstrg(strg_t *, strg_t *);
+extern	void	displexpr(tnode_t *, int);
 
 /*
  * func.c
@@ -224,6 +225,8 @@
 extern	int	ccflg;
 extern	int	llibflg;
 extern	int	nowarn;
+extern	int	noretflg;
+extern	int	usedflg;
 extern	int	plibflg;
 extern	int	quadflg;
 
@@ -250,6 +253,8 @@
 extern	void	doreturn(tnode_t *);
 extern	void	glclup(int);
 extern	void	argsused(int);
+extern	void	noreturn(int);
+extern	void	lintused(int);
 extern	void	constcond(int);
 extern	void	fallthru(int);
 extern	void	notreach(int);
Index: usr.bin/xlint/lint1/func.c
===================================================================
RCS file: /home/dcvs/src/usr.bin/xlint/lint1/func.c,v
retrieving revision 1.3
diff -u -r1.3 func.c
--- usr.bin/xlint/lint1/func.c	7 Jul 2004 12:13:26 -0000	1.3
+++ usr.bin/xlint/lint1/func.c	25 Dec 2006 10:07:59 -0000
@@ -1,3 +1,4 @@
+/*	$OpenBSD: func.c,v 1.18 2006/05/29 20:47:22 cloder Exp $	*/
 /*	$NetBSD: func.c,v 1.7 1995/10/02 17:31:40 jpo Exp $	*/
 
 /*
@@ -55,7 +56,7 @@
 int	rchflg;
 
 /*
- * In conjunction with reached ontrols printing of "fallthrough on ..."
+ * In conjunction with reached controls printing of "fallthrough on ..."
  * warnings.
  * Reset by each statement and set by FALLTHROUGH, switch (switch1())
  * and case (label()).
@@ -81,6 +82,18 @@
 pos_t	aupos;
 
 /*
+ * If the following function has been declared NORETURN, noretflg is set
+ * to 1. Otherwise it is set to 0.
+ */
+int	noretflg = 0;
+
+/*
+ * If the following symbol should be marked as having been used, even if
+ * lint thinks otherwise, usedflg is set to 1. Otherwise it is set to 0.
+ */
+int	usedflg = 0;
+
+/*
  * Number of arguments of the following function definition whose types
  * shall be checked by lint2. -1 stands for all arguments.
  *
@@ -103,13 +116,13 @@
 pos_t	scflpos;
 
 /*
- * Are both plibflg and llibflg set, prototypes are writen as function
+ * Are both plibflg and llibflg set, prototypes are written as function
  * definitions to the output file.
  */
 int	plibflg;
 
 /*
- * Nonzero means that no warnings about constands in conditional
+ * Nonzero means that no warnings about constants in conditional
  * context are printed.
  */
 int	ccflg;
@@ -130,7 +143,7 @@
  * Nonzero if complaints about use of "long long" are suppressed in
  * the next statement or declaration.
  */
-int	quadflg;
+int	quadflg = 1;
 
 /*
  * Puts a new element at the top of the stack used for control statements.
@@ -188,7 +201,7 @@
  * Called after a function declaration which introduces a function definition
  * and before an (optional) old style argument declaration list.
  *
- * Puts all symbols declared in the Prototype or in an old style argument
+ * Puts all symbols declared in the prototype or in an old style argument
  * list back to the symbol table.
  *
  * Does the usual checking of storage class, type (return value),
@@ -215,6 +228,26 @@
 	}
 
 	/*
+	 * __func__ is a "predefined identifier" in c99, which means it is a
+	 * block-scope variable supplying the name of the enclosing function.
+	 * It is defined as:
+	 *
+	 * static const char __func__[] = "function-name";
+	 *
+	 */
+	sym = getblk(sizeof (sym_t));
+	sym->s_name = "__func__";
+	sym->s_kind = FVFT;
+	sym->s_scl = STATIC;
+	sym->s_type = incref(gettyp(CHAR), ARRAY);
+	sym->s_blklev = 1;
+	sym->s_def = DEF;
+	sym->s_type->t_dim = strlen(fsym->s_name) + 1;
+	sym->s_type->t_subt = duptyp(gettyp(CHAR));
+	sym->s_type->t_subt->t_const = 1;
+	inssym(1, sym);
+
+	/*
 	 * In osfunc() we did not know whether it is an old style function
 	 * definition or only an old style declaration, if there are no
 	 * arguments inside the argument list ("f()").
@@ -317,7 +350,7 @@
 	}
 
 	if (dcs->d_notyp)
-		/* return value is implizitly declared to be int */
+		/* return value is implicitly declared to be int */
 		fsym->s_rimpl = 1;
 
 	reached = 1;
@@ -342,7 +375,7 @@
 	}
 
 	/*
-	 * This warning is printed only if the return value was implizitly
+	 * This warning is printed only if the return value was implicitly
 	 * declared to be int. Otherwise the wrong return statement
 	 * has already printed a warning.
 	 */
@@ -360,10 +393,14 @@
 	}
 	nargusg = -1;
 
+	if (noretflg)
+		funcsym->s_noreturn = 1;
+	noretflg = 0;
+
 	/*
 	 * write the information about the function definition to the
 	 * output file
-	 * inline functions explicitely declared extern are written as
+	 * inline functions explicitly declared extern are written as
 	 * declarations only.
 	 */
 	if (dcs->d_scl == EXTERN && funcsym->s_inline) {
@@ -442,12 +479,6 @@
 			}
 
 			t = tn->tn_type->t_tspec;
-			if (t == LONG || t == ULONG ||
-			    t == QUAD || t == UQUAD) {
-				if (tflag)
-					/* case label must be of type ... */
-					warning(203);
-			}
 
 			/*
 			 * get the value of the expression and convert it
@@ -455,7 +486,7 @@
 			 */
 			v = constant(tn);
 			nv = xcalloc(1, sizeof (val_t));
-			cvtcon(CASE, 0, ci->c_swtype, nv, v);
+			cvtcon(CASE, NULL, ci->c_swtype, nv, v);
 			free(v);
 
 			/* look if we had this value already */
@@ -565,13 +596,6 @@
 		error(205);
 		tn = NULL;
 	}
-	if (tn != NULL && tflag) {
-		t = tn->tn_type->t_tspec;
-		if (t == LONG || t == ULONG || t == QUAD || t == UQUAD) {
-			/* switch expr. must be of type `int' in trad. C */
-			warning(271);
-		}
-	}
 
 	/*
 	 * Remember the type of the expression. Because its possible
@@ -903,7 +927,17 @@
 			ci->c_break = 1;
 	}
 
-	if (bflag)
+	/* Don't warn about unreachable breaks in a switch, e.g.:
+	 *
+	 * switch (foo) {
+	 * case 1:
+	 *     return 1;
+	 *     break;
+	 * case 2:
+	 *     // etc...
+	 * }
+	 */
+	if (ci == NULL || !ci->c_switch)
 		chkreach();
 
 	reached = rchflg = 0;
@@ -1074,6 +1108,29 @@
 }
 
 /*
+ * NORETURN comment
+ *
+ * The following function will never return, which means any code
+ * following a call to this function is unreachable.
+ */
+void
+noreturn(int n)
+{
+	noretflg = 1;
+}
+
+/*
+ * LINTUSED comment
+ *
+ * Mark a symbol as used, so lint2 does not complain.
+ */
+void
+lintused(int n)
+{
+	usedflg = 1;
+}
+
+/*
  * VARARGS comment
  *
  * Makes that lint2 checks only the first n arguments for compatibility
Index: usr.bin/xlint/lint1/init.c
===================================================================
RCS file: /home/dcvs/src/usr.bin/xlint/lint1/init.c,v
retrieving revision 1.6
diff -u -r1.6 init.c
--- usr.bin/xlint/lint1/init.c	7 Jul 2004 12:24:00 -0000	1.6
+++ usr.bin/xlint/lint1/init.c	25 Dec 2006 10:10:02 -0000
@@ -1,3 +1,4 @@
+/*	$OpenBSD: init.c,v 1.10 2006/05/29 20:47:22 cloder Exp $	*/
 /*	$NetBSD: init.c,v 1.4 1995/10/02 17:21:37 jpo Exp $	*/
 
 /*
@@ -30,7 +31,6 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $NetBSD: init.c,v 1.4 1995/10/02 17:21:37 jpo Exp $
  * $DragonFly: src/usr.bin/xlint/lint1/init.c,v 1.6 2004/07/07 12:24:00 asmodai Exp $
  */
 
@@ -39,7 +39,7 @@
 #include "lint1.h"
 
 /*
- * initerr is set as soon as a fatal error occured in an initialisation.
+ * initerr is set as soon as a fatal error occurred in an initialisation.
  * The effect is that the rest of the initialisation is ignored (parsed
  * by yacc, expression trees built, but no initialisation takes place).
  */
@@ -198,9 +198,6 @@
 		istk->i_cnt = istk->i_type->t_dim;
 		break;
 	case UNION:
-		if (tflag)
-			/* initialisation of union is illegal in trad. C */
-			warning(238);
 		/* FALLTHROUGH */
 	case STRUCT:
 		if (incompl(istk->i_type)) {
@@ -305,13 +302,6 @@
 	if (initerr)
 		return;
 
-	if ((initsym->s_scl == AUTO || initsym->s_scl == REG) &&
-	    initstk->i_nxt == NULL) {
-		if (tflag && !issclt(initstk->i_subt->t_tspec))
-			/* no automatic aggregate initialization in trad. C*/
-			warning(188);
-	}
-
 	/*
 	 * Remove all entries which cannot be used for further initializers
 	 * and do not expect a closing brace.
@@ -346,7 +336,7 @@
 	sc = initsym->s_scl;
 
 	/*
-	 * Do not test for automatic aggregat initialisation. If the
+	 * Do not test for automatic aggregate initialisation. If the
 	 * initalizer starts with a brace we have the warning already.
 	 * If not, an error will be printed that the initializer must
 	 * be enclosed by braces.
@@ -398,7 +388,7 @@
 	if (!issclt(lt))
 		lerror("mkinit() 1");
 
-	if (!typeok(INIT, 0, ln, tn))
+	if (!typeok(INIT, NULL, ln, tn))
 		goto end;
 
 	/*
@@ -409,18 +399,8 @@
 	expr(tn, 1, 0);
 	trestor(tmem);
 
-	if (isityp(lt) && ln->tn_type->t_isfield && !isityp(rt)) {
-		/*
-		 * Bit-fields can be initialized in trad. C only by integer
-		 * constants.
-		 */
-		if (tflag)
-			/* bit-field initialisation is illegal in trad. C */
-			warning(186);
-	}
-
 	if (lt != rt || (initstk->i_type->t_isfield && tn->tn_op == CON))
-		tn = convert(INIT, 0, initstk->i_type, tn);
+		tn = convert(INIT, NULL, initstk->i_type, tn);
 
 	if (tn != NULL && tn->tn_op != CON) {
 		sym = NULL;
@@ -459,7 +439,7 @@
 	 * Check if we have an array type which can be initialized by
 	 * the string.
 	 */
-	if (istk->i_subt->t_tspec == ARRAY) {
+	if (istk->i_subt != NULL && istk->i_subt->t_tspec == ARRAY) {
 		t = istk->i_subt->t_subt->t_tspec;
 		if (!((strg->st_tspec == CHAR &&
 		       (t == CHAR || t == UCHAR || t == SCHAR)) ||
Index: usr.bin/xlint/lint1/lint.h
===================================================================
RCS file: /home/dcvs/src/usr.bin/xlint/lint1/lint.h,v
retrieving revision 1.1
diff -u -r1.1 lint.h
--- usr.bin/xlint/lint1/lint.h	17 Jun 2003 02:56:38 -0000	1.1
+++ usr.bin/xlint/lint1/lint.h	25 Dec 2006 10:11:07 -0000
@@ -1,3 +1,4 @@
+/*	$OpenBSD: lint.h,v 1.6 2006/05/29 20:47:22 cloder Exp $	*/
 /*	$NetBSD: lint.h,v 1.2 1995/07/03 21:24:18 cgd Exp $	*/
 
 /*
@@ -29,6 +30,8 @@
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $DragonFly$
  */
 
 #include <sys/types.h>
@@ -38,7 +41,7 @@
 #include "param.h"
 
 /*
- * Type specifiers, used in type structures (type_t) and otherwere.
+ * Type specifiers, used in type structures (type_t) and elsewhere.
  */
 typedef enum {
 	NOTSPEC,
@@ -56,7 +59,7 @@
 	QUAD,		/* (signed) long long */
 	UQUAD,		/* unsigned long long */
 	FLOAT,		/* float */
-	DOUBLE,		/* double or, with tflag, long float */
+	DOUBLE,		/* double */
 	LDOUBLE,	/* long double */
 	VOID,		/* void */
 	STRUCT,		/* structure tag */
@@ -75,6 +78,7 @@
 	int	tt_sz;			/* size in bits */
 	int	tt_psz;			/* size, different from tt_sz
 					   if pflag is set */
+	int	tt_rank;		/* rank (C99), similar to tt_psz */
 	tspec_t	tt_styp;		/* signed counterpart */
 	tspec_t	tt_utyp;		/* unsigned counterpart */
 	u_int	tt_isityp : 1;		/* 1 if integer type */
@@ -82,11 +86,12 @@
 	u_int	tt_isftyp : 1;		/* 1 if floating point type */
 	u_int	tt_isatyp : 1;		/* 1 if arithmetic type */
 	u_int	tt_issclt : 1;		/* 1 if scalar type */
-	char	*tt_name;		/* Bezeichnung des Typs */
+	char	*tt_name;		/* type name */
 } ttab_t;
 
 #define size(t)		(ttab[t].tt_sz)
 #define psize(t)	(ttab[t].tt_psz)
+#define rank(t)		(ttab[t].tt_rank)
 #define styp(t)		(ttab[t].tt_styp)
 #define utyp(t)		(ttab[t].tt_utyp)
 #define isityp(t)	(ttab[t].tt_isityp)
Index: usr.bin/xlint/lint1/lint1.h
===================================================================
RCS file: /home/dcvs/src/usr.bin/xlint/lint1/lint1.h,v
retrieving revision 1.1
diff -u -r1.1 lint1.h
--- usr.bin/xlint/lint1/lint1.h	17 Jun 2003 02:56:38 -0000	1.1
+++ usr.bin/xlint/lint1/lint1.h	25 Dec 2006 10:12:18 -0000
@@ -1,3 +1,4 @@
+/*	$OpenBSD: lint1.h,v 1.13 2006/04/18 02:59:40 cloder Exp $	*/
 /*	$NetBSD: lint1.h,v 1.6 1995/10/02 17:31:41 jpo Exp $	*/
 
 /*
@@ -29,6 +30,8 @@
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $DragonFly$
  */
 
 #include "lint.h"
@@ -65,7 +68,7 @@
  * qualifiers (only for lex/yacc interface)
  */
 typedef enum {
-	CONST, VOLATILE
+	CONST, VOLATILE, RESTRICT
 } tqual_t;
 
 /*
@@ -75,6 +78,7 @@
 	tspec_t	v_tspec;
 	int	v_ansiu;		/* set if an integer constant is
 					   unsigned in ANSI C */
+	tspec_t	v_lspec;		/* the underlying type of a literal */
 	union {
 		quad_t	_v_quad;	/* integers */
 		ldbl_t	_v_ldbl;	/* floats */
@@ -88,7 +92,7 @@
  * Structures of type str_t uniqely identify structures. This can't
  * be done in structures of type type_t, because these are copied
  * if they must be modified. So it would not be possible to check
- * if to structures are identical by comparing the pointers to
+ * if two structures are identical by comparing the pointers to
  * the type structures.
  *
  * The typename is used if the structure is unnamed to identify
@@ -122,6 +126,7 @@
 	u_int	t_aincompl : 1;	/* incomplete array type */
 	u_int	t_const : 1;	/* const modifier */
 	u_int	t_volatile : 1;	/* volatile modifier */
+	u_int	t_restrict : 1;	/* restrict modifier */
 	u_int	t_proto : 1;	/* function prototype (t_args valid) */
 	u_int	t_vararg : 1;	/* protoype with ... */
 	u_int	t_typedef : 1;	/* type defined with typedef */
@@ -202,9 +207,10 @@
 	u_int	s_reg : 1;	/* symbol is register variable */
 	u_int	s_defarg : 1;	/* undefined symbol in old style function
 				   definition */
-	u_int	s_rimpl : 1;	/* return value of function implizit decl. */
+	u_int	s_rimpl : 1;	/* return value of function implicit decl. */
 	u_int	s_osdef : 1;	/* symbol stems from old style function def. */
 	u_int	s_inline : 1;	/* true if this is a inline function */
+	u_int	s_noreturn : 1;	/* true if this is a NORETURN function */
 	struct	sym *s_xsym;	/* for local declared external symbols pointer
 				   to external symbol with same name */
 	def_t	s_def;		/* declared, tentative defined, defined */
@@ -225,7 +231,7 @@
 	struct	sym **s_rlink;	/* pointer to s_link of prev. symbol */
 	struct	sym *s_nxt;	/* next struct/union member, enumerator,
 				   argument */
-	struct	sym *s_dlnxt; 	/* next symbol declared on same level */
+	struct	sym *s_dlnxt;	/* next symbol declared on same level */
 } sym_t;
 
 #define	s_styp	u._s_st
@@ -254,7 +260,7 @@
 	op_t	tn_op;		/* operator */
 	type_t	*tn_type;	/* type */
 	u_int	tn_lvalue : 1;	/* node is lvalue */
-	u_int	tn_cast : 1;	/* if tn_op == CVT its an explizit cast */
+	u_int	tn_cast : 1;	/* if tn_op == CVT its an explicit cast */
 	u_int	tn_parn : 1;	/* node parenthesized */
 	union {
 		struct {
@@ -302,6 +308,7 @@
 	scl_t	d_ctx;		/* context of declaration */
 	u_int	d_const : 1;	/* const in declaration specifiers */
 	u_int	d_volatile : 1;	/* volatile in declaration specifiers */
+	u_int	d_restrict : 1;	/* restrict in declaration specifiers */
 	u_int	d_inline : 1;	/* inline in declaration specifiers */
 	u_int	d_mscl : 1;	/* multiple storage classes */
 	u_int	d_terr : 1;	/* invalid type combination */
@@ -341,6 +348,7 @@
 	int	p_pcnt;			/* number of asterisks */
 	u_int	p_const : 1;
 	u_int	p_volatile : 1;
+	u_int	p_restrict : 1;
 	struct	pqinf *p_nxt;
 } pqinf_t;
 
@@ -377,4 +385,14 @@
 	struct	cstk *c_nxt;		/* outer control statement */
 } cstk_t;
 
+/*
+ * Used to keep information about arguments passed to functions with
+ * prototypes.
+ */
+typedef struct farg {
+	int	fa_num;			/* argument number (1-basde) */
+	sym_t	*fa_sym;		/* argument symbol */
+	tnode_t	*fa_func;		/* function name */
+} farg_t;
+
 #include "externs1.h"
Index: usr.bin/xlint/lint1/main1.c
===================================================================
RCS file: /home/dcvs/src/usr.bin/xlint/lint1/main1.c,v
retrieving revision 1.6
diff -u -r1.6 main1.c
--- usr.bin/xlint/lint1/main1.c	7 Jul 2004 12:24:00 -0000	1.6
+++ usr.bin/xlint/lint1/main1.c	25 Dec 2006 10:14:15 -0000
@@ -1,3 +1,4 @@
+/*	$OpenBSD: main1.c,v 1.11 2006/05/29 20:47:22 cloder Exp $	*/
 /*	$NetBSD: main1.c,v 1.3 1995/10/02 17:29:56 jpo Exp $	*/
 
 /*
@@ -30,7 +31,6 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $NetBSD: main1.c,v 1.3 1995/10/02 17:29:56 jpo Exp $
  * $DragonFly: src/usr.bin/xlint/lint1/main1.c,v 1.6 2004/07/07 12:24:00 asmodai Exp $
  */
 
@@ -44,17 +44,6 @@
 /* set yydebug to 1*/
 int	yflag;
 
-/*
- * Print warnings if an assignment of an integertype to another integertype
- * causes an implizit narrowing conversion. If aflag is 1, these warnings
- * are printed only if the source type is at least as wide as long. If aflag
- * is greather then 1, they are always printed.
- */
-int	aflag;
-
-/* Print a warning if a break statement cannot be reached. */
-int	bflag;
-
 /* Print warnings for pointer casts. */
 int	cflag;
 
@@ -65,7 +54,10 @@
 int	eflag;
 
 /* Print complete pathnames, not only the basename. */
-int	Fflag;
+int	Fflag = 1;
+
+/* After an error or warning, print the actual text of the program source code */
+int	fflag = 0;
 
 /* Enable some extensions of gcc */
 int	gflag;
@@ -88,9 +80,6 @@
 /* Strict ANSI C mode. */
 int	sflag;
 
-/* Traditional C mode. */
-int	tflag;
-
 /*
  * Complain about functions and external variables used and not defined,
  * or defined and not used.
@@ -101,7 +90,7 @@
 int	vflag = 1;
 
 /* Complain about structures which are never defined. */
-int	zflag = 1;
+int	zflag = 0;
 
 static	void	usage(void);
 
@@ -110,20 +99,21 @@
 {
 	int	c;
 
-	while ((c = getopt(argc, argv, "abcdeghprstuvyzF")) != -1) {
+	while ((c = getopt(argc, argv, "abcdefghprstuvyzF")) != -1) {
 		switch (c) {
-		case 'a':	aflag++;	break;
-		case 'b':	bflag = 1;	break;
+		case 'a':	/* obsolete */	break;
+		case 'b':	/* obsolete */	break;
 		case 'c':	cflag = 1;	break;
 		case 'd':	dflag = 1;	break;
 		case 'e':	eflag = 1;	break;
 		case 'F':	Fflag = 1;	break;
 		case 'g':	gflag = 1;	break;
 		case 'h':	hflag = 1;	break;
+		case 'f':	fflag = 1;	break;
 		case 'p':	pflag = 1;	break;
 		case 'r':	rflag = 1;	break;
 		case 's':	sflag = 1;	break;
-		case 't':	tflag = 1;	break;
+		case 't':	/* obsolete */	break;
 		case 'u':	uflag = 0;	break;
 		case 'v':	vflag = 0;	break;
 		case 'y':	yflag = 1;	break;
@@ -144,8 +134,10 @@
 	/* initialize output */
 	outopen(argv[1]);
 
+#if YYDEBUG
 	if (yflag)
 		yydebug = 1;
+#endif
 
 	initmem();
 	initdecl();
Index: usr.bin/xlint/lint1/mem.c
===================================================================
RCS file: /home/dcvs/src/usr.bin/xlint/lint1/mem.c,v
retrieving revision 1.3
diff -u -r1.3 mem.c
--- usr.bin/xlint/lint1/mem.c	7 Jul 2004 12:13:26 -0000	1.3
+++ usr.bin/xlint/lint1/mem.c	25 Dec 2006 10:15:49 -0000
@@ -1,3 +1,4 @@
+/*	$OpenBSD: mem.c,v 1.4 2006/03/08 07:18:51 moritz Exp $	*/
 /*	$NetBSD: mem.c,v 1.2 1995/07/03 21:24:24 cgd Exp $	*/
 
 /*
@@ -45,7 +46,7 @@
 	void	*p;
 
 	if ((p = malloc(s)) == NULL)
-		nomem();
+		err(1, NULL);
 	return (p);
 }
 
@@ -55,7 +56,7 @@
 	void	*p;
 
 	if ((p = calloc(n, s)) == NULL)
-		nomem();
+		err(1, NULL);
 	return (p);
 }
 
@@ -63,7 +64,7 @@
 xrealloc(void *p, size_t s)
 {
 	if ((p = realloc(p, s)) == NULL)
-		nomem();
+		err(1, NULL);
 	return (p);
 }
 
@@ -73,12 +74,6 @@
 	char	*s2;
 
 	if ((s2 = strdup(s)) == NULL)
-		nomem();
+		err(1, NULL);
 	return (s2);
 }
-
-void
-nomem(void)
-{
-	errx(1, "virtual memory exhausted");
-}
Index: usr.bin/xlint/lint1/mem1.c
===================================================================
RCS file: /home/dcvs/src/usr.bin/xlint/lint1/mem1.c,v
retrieving revision 1.7
diff -u -r1.7 mem1.c
--- usr.bin/xlint/lint1/mem1.c	3 Aug 2006 16:40:48 -0000	1.7
+++ usr.bin/xlint/lint1/mem1.c	25 Dec 2006 10:17:08 -0000
@@ -1,3 +1,4 @@
+/*	$OpenBSD: mem1.c,v 1.10 2006/03/08 07:18:51 moritz Exp $	*/
 /*	$NetBSD: mem1.c,v 1.2 1995/07/03 21:24:25 cgd Exp $	*/
 
 /*
@@ -30,7 +31,6 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $NetBSD: mem1.c,v 1.2 1995/07/03 21:24:25 cgd Exp $
  * $DragonFly: src/usr.bin/xlint/lint1/mem1.c,v 1.7 2006/08/03 16:40:48 swildner Exp $
  */
 
@@ -164,22 +164,10 @@
 xnewblk(void)
 {
 	mbl_t	*mb;
-	int	prot, flags;
 
 	mb = xmalloc(sizeof (mbl_t));
-
-	/* use mmap instead of malloc to avoid malloc's size overhead */
-
-	prot = PROT_READ | PROT_WRITE;
-	flags = MAP_ANON | MAP_PRIVATE;
-	mb->blk = mmap(NULL, mblklen, prot, flags, -1, (off_t)0);
-	if (mb->blk == (void *)MAP_FAILED)
-		err(1, "can't map memory");
-	if (ALIGN((u_long)mb->blk) != (u_long)mb->blk)
-		errx(1, "mapped address is not aligned");
-
+	mb->blk = xmalloc(mblklen);
 	mb->size = mblklen;
-
 	return (mb);
 }
 
@@ -302,7 +290,7 @@
 }
 
 /*
- * Free all memory which is allocated by the the current expression.
+ * Free all memory which is allocated by the current expression.
  */
 void
 tfreeblk(void)
Index: usr.bin/xlint/lint1/op.h
===================================================================
RCS file: /home/dcvs/src/usr.bin/xlint/lint1/op.h,v
retrieving revision 1.1
diff -u -r1.1 op.h
--- usr.bin/xlint/lint1/op.h	17 Jun 2003 02:56:38 -0000	1.1
+++ usr.bin/xlint/lint1/op.h	25 Dec 2006 10:17:56 -0000
@@ -1,3 +1,4 @@
+/*	$OpenBSD: op.h,v 1.3 2005/11/29 20:09:57 cloder Exp $	*/
 /*	$NetBSD: op.h,v 1.2 1995/07/03 21:24:27 cgd Exp $	*/
 
 /*
@@ -29,6 +30,8 @@
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $DragonFly$
  */
 
 /*
@@ -48,7 +51,7 @@
 	u_int	m_tlansiu : 1;	/* warning if left op. is unsign. in ANSI C */
 	u_int	m_transiu : 1;	/* warning if right op. is unsign. in ANSI C */
 	u_int	m_tpconf : 1;	/* test possible precedence confusion */
-	u_int	m_comp : 1;	/* op. performs comparision */
+	u_int	m_comp : 1;	/* op. performs comparison */
 	u_int	m_enumop : 1;	/* valid operation on enums */
 	u_int	m_badeop : 1;	/* dubious operation on enums */
 	u_int	m_eqwarn : 1;	/* warning if on operand stems from == */
Index: usr.bin/xlint/lint1/param.h
===================================================================
RCS file: /home/dcvs/src/usr.bin/xlint/lint1/param.h,v
retrieving revision 1.4
diff -u -r1.4 param.h
--- usr.bin/xlint/lint1/param.h	25 Aug 2006 22:37:09 -0000	1.4
+++ usr.bin/xlint/lint1/param.h	25 Dec 2006 10:18:53 -0000
@@ -1,4 +1,5 @@
-/*	$NetBSD: param.h,v 1.4 1995/07/23 18:14:41 ragge Exp $	*/
+/*	$OpenBSD: param.h,v 1.14 2006/04/03 13:55:02 espie Exp $	*/
+/*	$NetBSD: param.h,v 1.6 1996/04/01 21:47:57 mark Exp $	*/
 
 /*
  * Copyright (c) 1994, 1995 Jochen Pohl
@@ -63,32 +64,13 @@
  * Should be set to 1 if the difference of two pointers is of type long
  * or the value of sizeof is of type unsigned long.
  */
-#ifdef __amd64__
 #define PTRDIFF_IS_LONG		1
 #define SIZEOF_IS_ULONG		1
-#elif __i386__
-#define PTRDIFF_IS_LONG		0
-#define SIZEOF_IS_ULONG		0
-#elif __m68k__
-#define PTRDIFF_IS_LONG		0
-#define SIZEOF_IS_ULONG		0
-#elif __ns32k__
-#define PTRDIFF_IS_LONG		0
-#define SIZEOF_IS_ULONG		0
-#elif __sparc__
-#define PTRDIFF_IS_LONG		0
-#define SIZEOF_IS_ULONG		0
-#elif __vax__
-#define PTRDIFF_IS_LONG         0
-#define SIZEOF_IS_ULONG         0
-#else
-#error unknown machine type
-#endif
 
 /*
  * Make sure this matches wchar_t.
  */
-#define WCHAR	SHORT
+#define WCHAR	INT
 
 #ifndef __GNUC__
 #ifndef lint
@@ -101,14 +83,9 @@
 typedef	u_long	u_quad_t;
 #endif
 #endif
-
-
-/*
- * long double only in ANSI C.
- */
 typedef	long double ldbl_t;
 
 /*
- * Some traditional compilers are not able to assign structures.
+ * Modern compilers are able to assign structures.
  */
 #define STRUCT_ASSIGN(dest, src)	(dest) = (src)
Index: usr.bin/xlint/lint1/scan.l
===================================================================
RCS file: /home/dcvs/src/usr.bin/xlint/lint1/scan.l,v
retrieving revision 1.8
diff -u -r1.8 scan.l
--- usr.bin/xlint/lint1/scan.l	17 Jan 2006 23:49:13 -0000	1.8
+++ usr.bin/xlint/lint1/scan.l	25 Dec 2006 10:22:11 -0000
@@ -1,4 +1,5 @@
 %{
+/*	$OpenBSD: scan.l,v 1.30 2006/05/29 20:47:22 cloder Exp $	*/
 /*	$NetBSD: scan.l,v 1.8 1995/10/23 13:38:51 jpo Exp $	*/
 
 /*
@@ -31,7 +32,6 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $NetBSD: scan.l,v 1.8 1995/10/23 13:38:51 jpo Exp $
  * $DragonFly: src/usr.bin/xlint/lint1/scan.l,v 1.8 2006/01/17 23:49:13 dillon Exp $
  */
 
@@ -69,12 +69,14 @@
 static	int	keyw(sym_t *);
 static	int	icon(int);
 static	int	fcon(void);
+static  int	fhexcon(void);
 static	int	operator(int, op_t);
 static	int	ccon(void);
 static	int	wccon(void);
 static	int	getescc(int);
 static	void	directive(void);
 static	void	comment(void);
+static	void	slashslashcomment(void);
 static	int	string(void);
 static	int	wcstrg(void);
 
@@ -86,16 +88,20 @@
 OD	[0-7]
 HD	[0-9A-Fa-f]
 EX	([eE][+-]?[0-9]+)
+HEX	([pP][+-]?[0-9]+)
 
 %%
 
-{L}({L}|{D})*		 	return (name());
+{L}({L}|{D})*			return (name());
 0{OD}*[lLuU]*			return (icon(8));
 {NZD}{D}*[lLuU]*		return (icon(10));
 0[xX]{HD}+[lLuU]*		return (icon(16));
 {D}+\.{D}*{EX}?[fFlL]?		|
 {D}+{EX}[fFlL]?			|
 \.{D}+{EX}?[fFlL]?		return (fcon());
+0[xX]{HD}+\.{HD}*{HEX}[fFlL]?	|
+0[xX]{HD}+{HEX}[fFlL]?		|
+0[xX]\.{HD}+{HEX}[fFlL]?	return (fhexcon());
 "="				return (operator(T_ASSIGN, ASSIGN));
 "*="				return (operator(T_OPASS, MULASS));
 "/="				return (operator(T_OPASS, DIVASS));
@@ -150,12 +156,13 @@
 \n				incline();
 \t|" "|\f|\v			;
 "/*"				comment();
+"//"				slashslashcomment();
 .				badchar(yytext[0]);
 
 %%
 
 static void
-incline()
+incline(void)
 {
 	curr_pos.p_line++;
 	if (curr_pos.p_file == csrc_pos.p_file)
@@ -163,8 +170,7 @@
 }
 
 static void
-badchar(c)
-	int	c;
+badchar(int c)
 {
 	/* unknown character \%o */
 	error(250, c);
@@ -177,59 +183,69 @@
 static	struct	kwtab {
 	const	char *kw_name;	/* keyword */
 	int	kw_token;	/* token returned by yylex() */
-	scl_t	kw_scl;		/* storage class if kw_token T_SCLASS */
-	tspec_t	kw_tspec;	/* type spec. if kw_token T_TYPE or T_SOU */
-	tqual_t	kw_tqual;	/* type qual. fi kw_token T_QUAL */
+	union {
+		scl_t	kw_scl;		/* storage class if kw_token T_SCLASS */
+		tspec_t	kw_tspec;	/* type spec. if kw_token T_TYPE or T_SOU */
+		tqual_t	kw_tqual;	/* type qual. if kw_token T_QUAL */
+	} kw_u;
 	u_int	kw_stdc : 1;	/* STDC keyword */
 	u_int	kw_gcc : 1;	/* GCC keyword */
 } kwtab[] = {
-	{ "asm",	T_ASM,		0,	0,	0,	  0, 1 },
-	{ "__asm",	T_ASM,		0,	0,	0,	  0, 0 },
-	{ "__asm__",	T_ASM,		0,	0,	0,	  0, 0 },
-	{ "auto",	T_SCLASS,	AUTO,	0,	0,	  0, 0 },
-	{ "break",	T_BREAK,	0,	0,	0,	  0, 0 },
-	{ "case",	T_CASE,		0,	0,	0,	  0, 0 },
-	{ "char",	T_TYPE,		0,	CHAR,	0,	  0, 0 },
-	{ "const",	T_QUAL,		0,	0,	CONST,	  1, 0 },
-	{ "__const__",	T_QUAL,		0,	0,	CONST,	  0, 0 },
-	{ "__const",	T_QUAL,		0,	0,	CONST,	  0, 0 },
-	{ "continue",	T_CONTINUE,	0,	0,	0,	  0, 0 },
-	{ "default",	T_DEFAULT,	0,	0,	0,	  0, 0 },
-	{ "do",		T_DO,		0,	0,	0,	  0, 0 },
-	{ "double",	T_TYPE,		0,	DOUBLE,	0,	  0, 0 },
-	{ "else",	T_ELSE,		0,	0,	0,	  0, 0 },
-	{ "enum",	T_ENUM,		0,	0,	0,	  0, 0 },
-	{ "extern",	T_SCLASS,	EXTERN,	0,	0,	  0, 0 },
-	{ "float",	T_TYPE,		0,	FLOAT,	0,	  0, 0 },
-	{ "for",	T_FOR,		0,	0,	0,	  0, 0 },
-	{ "goto",	T_GOTO,		0,	0,	0,	  0, 0 },
-	{ "if",		T_IF,		0,	0,	0,	  0, 0 },
-	{ "inline",	T_SCLASS,	INLINE,	0,	0,	  0, 1 },
-	{ "__inline__",	T_SCLASS,	INLINE,	0,	0,	  0, 0 },
-	{ "__inline",	T_SCLASS,	INLINE,	0,	0,	  0, 0 },
-	{ "int",	T_TYPE,		0,	INT,	0,	  0, 0 },
-	{ "long",	T_TYPE,		0,	LONG,	0,	  0, 0 },
-	{ "register",	T_SCLASS,	REG,	0,	0,	  0, 0 },
-	{ "return",	T_RETURN,	0,	0,	0,	  0, 0 },
-	{ "short",	T_TYPE,		0,	SHORT,	0,	  0, 0 },
-	{ "signed",	T_TYPE,		0,	SIGNED,	0,	  1, 0 },
-	{ "__signed__",	T_TYPE,		0,	SIGNED,	0,	  0, 0 },
-	{ "__signed",	T_TYPE,		0,	SIGNED,	0,	  0, 0 },
-	{ "sizeof",	T_SIZEOF,	0,	0,	0,	  0, 0 },
-	{ "static",	T_SCLASS,	STATIC,	0,	0,	  0, 0 },
-	{ "struct",	T_SOU,		0,	STRUCT,	0,	  0, 0 },
-	{ "switch",	T_SWITCH,	0,	0,	0,	  0, 0 },
-	{ "typedef",	T_SCLASS,	TYPEDEF, 0,	0,	  0, 0 },
-	{ "union",	T_SOU,		0,	UNION,	0,	  0, 0 },
-	{ "unsigned",	T_TYPE,		0,	UNSIGN,	0,	  0, 0 },
-	{ "void",	T_TYPE,		0,	VOID,	0,	  0, 0 },
-	{ "volatile",	T_QUAL,		0,	0,	VOLATILE, 1, 0 },
-	{ "__volatile__", T_QUAL,	0,	0,	VOLATILE, 0, 0 },
-	{ "__volatile",	T_QUAL,		0,	0,	VOLATILE, 0, 0 },
-	{ "while",	T_WHILE,	0,	0,	0,	  0, 0 },
-	{ NULL,		0,		0,	0,	0,	  0, 0 }
+	{ "asm",		T_ASM,		{ 0 },		0, 1 },
+	{ "__asm",		T_ASM,		{ 0 },		0, 0 },
+	{ "__asm__",		T_ASM,		{ 0 },		0, 0 },
+	{ "__attribute__",	T_ATTRIBUTE,	{ 0 },		0, 0 },
+	{ "auto",		T_SCLASS,	{ AUTO },	0, 0 },
+	{ "break",		T_BREAK,	{ 0 },		0, 0 },
+	{ "case",		T_CASE,		{ 0 },		0, 0 },
+	{ "char",		T_TYPE,		{ CHAR },	0, 0 },
+	{ "const",		T_QUAL,		{ CONST },	1, 0 },
+	{ "__const__",		T_QUAL,		{ CONST },	0, 0 },
+	{ "__const",		T_QUAL,		{ CONST },	0, 0 },
+	{ "continue",		T_CONTINUE,	{ 0 },		0, 0 },
+	{ "default",		T_DEFAULT,	{ 0 },		0, 0 },
+	{ "do",			T_DO,		{ 0 },		0, 0 },
+	{ "double",		T_TYPE,		{ DOUBLE },	0, 0 },
+	{ "else",		T_ELSE,		{ 0 },		0, 0 },
+	{ "enum",		T_ENUM,		{ 0 },		0, 0 },
+	{ "extern",		T_SCLASS,	{ EXTERN },	0, 0 },
+	{ "float",		T_TYPE,		{ FLOAT },	0, 0 },
+	{ "for",		T_FOR,		{ 0 },		0, 0 },
+	{ "goto",		T_GOTO,		{ 0 },		0, 0 },
+	{ "if",			T_IF,		{ 0 },		0, 0 },
+	{ "inline",		T_SCLASS,	{ INLINE },	1, 0 },
+	{ "__inline__",		T_SCLASS,	{ INLINE },	0, 0 },
+	{ "__inline",		T_SCLASS,	{ INLINE },	0, 0 },
+	{ "int",		T_TYPE,		{ INT },	0, 0 },
+	{ "__lint_equal__",	T_LEQUAL,	{ 0 },		0, 0 },
+	{ "long",		T_TYPE,		{ LONG },	0, 0 },
+	{ "register",		T_SCLASS,	{ REG },	0, 0 },
+	{ "__restrict",		T_QUAL,		{ RESTRICT },	0, 0 },
+	{ "__restrict__",	T_QUAL,		{ RESTRICT },	0, 0 },
+	{ "return",		T_RETURN,	{ 0 },		0, 0 },
+	{ "short",		T_TYPE,		{ SHORT },	0, 0 },
+	{ "signed",		T_TYPE,		{ SIGNED },	1, 0 },
+	{ "__signed__",		T_TYPE,		{ SIGNED },	0, 0 },
+	{ "__signed",		T_TYPE,		{ SIGNED },	0, 0 },
+	{ "sizeof",		T_SIZEOF,	{ 0 },		0, 0 },
+	{ "static",		T_SCLASS,	{ STATIC },	0, 0 },
+	{ "struct",		T_SOU,		{ STRUCT },	0, 0 },
+	{ "switch",		T_SWITCH,	{ 0 },		0, 0 },
+	{ "typedef",		T_SCLASS,	{ TYPEDEF },	0, 0 },
+	{ "union",		T_SOU,		{ UNION },	0, 0 },
+	{ "unsigned",		T_TYPE,		{ UNSIGN },	0, 0 },
+	{ "void",		T_TYPE,		{ VOID },	0, 0 },
+	{ "volatile",		T_QUAL,		{ VOLATILE },	1, 0 },
+	{ "__volatile__",	T_QUAL,		{ VOLATILE },	0, 0 },
+	{ "__volatile",		T_QUAL,		{ VOLATILE },	0, 0 },
+	{ "while",		T_WHILE,	{ 0 },		0, 0 },
+	{ NULL,			0,		{ 0 },		0, 0 }
 };
 
+#define kw_scl		kw_u.kw_scl
+#define kw_tspec	kw_u.kw_tspec
+#define kw_tqual	kw_u.kw_tqual
+
 /* Symbol table */
 static	sym_t	*symtab[HSHSIZ1];
 
@@ -245,7 +261,7 @@
 /* free list for sbuf structures */
 static	sbuf_t	 *sbfrlst;
 
-/* Typ of next expected symbol */
+/* type of next expected symbol */
 symt_t	symtyp;
 
 
@@ -254,7 +270,7 @@
  * in a extra table for each name we found.
  */
 void
-initscan()
+initscan(void)
 {
 	struct	kwtab *kw;
 	sym_t	*sym;
@@ -262,8 +278,6 @@
 	u_quad_t uq;
 
 	for (kw = kwtab; kw->kw_name != NULL; kw++) {
-		if (kw->kw_stdc && tflag)
-			continue;
 		if (kw->kw_gcc && !gflag)
 			continue;
 		sym = getblk(sizeof (sym_t));
@@ -298,7 +312,7 @@
  * Get a free sbuf structure, if possible from the free list
  */
 static sbuf_t *
-allocsb()
+allocsb(void)
 {
 	sbuf_t	*sb;
 
@@ -307,7 +321,7 @@
 	} else {
 		sb = xmalloc(sizeof (sbuf_t));
 	}
-	(void)memset(sb, 0, sizeof (*sb));
+	(void)memset(sb, 0, sizeof (sbuf_t));
 	return (sb);
 }
 
@@ -315,8 +329,7 @@
  * Put a sbuf structure to the free list
  */
 static void
-freesb(sb)
-	sbuf_t	*sb;
+freesb(sbuf_t *sb)
 {
 	sb->sb_nxt = sbfrlst;
 	sbfrlst = sb;
@@ -327,7 +340,7 @@
  * Increment line count(s) if necessary.
  */
 static int
-inpc()
+inpc(void)
 {
 	int	c;
 
@@ -337,8 +350,7 @@
 }
 
 static int
-hash(s)
-	const	char *s;
+hash(const char *s)
 {
 	u_int	v;
 	const	u_char *us;
@@ -367,7 +379,7 @@
  * to the symbol table entry.
  */
 static int
-name()
+name(void)
 {
 	char	*s;
 	sbuf_t	*sb;
@@ -405,8 +417,7 @@
 }
 
 static sym_t *
-search(sb)
-	sbuf_t	*sb;
+search(sbuf_t *sb)
 {
 	sym_t	*sym;
 
@@ -421,8 +432,7 @@
 }
 
 static int
-keyw(sym)
-	sym_t	*sym;
+keyw(sym_t *sym)
 {
 	int	t;
 
@@ -441,8 +451,7 @@
  * The value is returned in yylval. icon() (and yylex()) returns T_CON.
  */
 static int
-icon(base)
-	int	base;
+icon(int base)
 {
 	int	l_suffix, u_suffix;
 	int	len;
@@ -486,10 +495,6 @@
 		if (u_suffix > 1)
 			u_suffix = 1;
 	}
-	if (tflag && u_suffix != 0) {
-		/* suffix U is illegal in traditional C */
-		warning(97);
-	}
 	typ = contypes[u_suffix][l_suffix];
 
 	errno = 0;
@@ -505,7 +510,7 @@
 		warning(252);
 
 	/*
-         * If the value is to big for the current type, we must choose
+         * If the value is too big for the current type, we must choose
 	 * another type.
 	 */
 	ansiu = 0;
@@ -521,9 +526,7 @@
 			typ = ULONG;
 		}
 		if (typ == UINT || typ == ULONG) {
-			if (tflag) {
-				typ = LONG;
-			} else if (!sflag) {
+			if (!sflag) {
 				/*
 				 * Remember that the constant is unsigned
 				 * only in ANSI C
@@ -537,22 +540,20 @@
 			typ = ULONG;
 		break;
 	case LONG:
-		if (ul > LONG_MAX && !tflag) {
+		if (ul > LONG_MAX) {
 			typ = ULONG;
 			if (!sflag)
 				ansiu = 1;
 		}
 		break;
 	case QUAD:
-		if (uq > QUAD_MAX && !tflag) {
+		if (uq > QUAD_MAX) {
 			typ = UQUAD;
 			if (!sflag)
 				ansiu = 1;
 		}
 		break;
 		/* LINTED (enumeration values not handled in switch) */
-	default:
-		break;
 	}
 
 	if (typ != QUAD && typ != UQUAD) {
@@ -579,10 +580,7 @@
  * to the width of type t.
  */
 int
-sign(q, t, len)
-	quad_t	q;
-	tspec_t	t;
-	int	len;
+sign(quad_t q, tspec_t t, int len)
 {
 	if (t == PTR || isutyp(t))
 		return (0);
@@ -590,10 +588,7 @@
 }
 
 int
-msb(q, t, len)
-	quad_t	q;
-	tspec_t	t;
-	int	len;
+msb(quad_t q, tspec_t t, int len)
 {
 	if (len <= 0)
 		len = size(t);
@@ -604,10 +599,7 @@
  * Extends the sign of q.
  */
 quad_t
-xsign(q, t, len)
-	quad_t	q;
-	tspec_t	t;
-	int	len;
+xsign(quad_t q, tspec_t t, int len)
 {
 	if (len <= 0)
 		len = size(t);
@@ -621,14 +613,14 @@
 }
 
 /*
- * Convert a string representing a floating point value into its interal
+ * Convert a string representing a floating point value into its integral
  * representation. Type and value are returned in yylval. fcon()
  * (and yylex()) returns T_CON.
  * XXX Currently it is not possible to convert constants of type
  * long double which are greater then DBL_MAX.
  */
 static int
-fcon()
+fcon(void)
 {
 	const	char *cp;
 	int	len;
@@ -650,11 +642,6 @@
 		typ = DOUBLE;
 	}
 
-	if (tflag && typ != DOUBLE) {
-		/* suffixes F and L are illegal in traditional C */
-		warning(98);
-	}
-
 	errno = 0;
 	d = strtod(cp, &eptr);
 	if (eptr != cp + len)
@@ -682,20 +669,65 @@
 	return (T_CON);
 }
 
+/*
+ * Convert an hexadecimal representation of a floating point value 
+ * into its integral representation. 
+ * Type and value are returned in yylval. fhexcon()
+ * (and yylex()) returns T_CON.
+ * XXX Currently no actual values are parsed.
+ */
 static int
-operator(t, o)
-	int	t;
-	op_t	o;
+fhexcon(void)
+{
+	const	char *cp;
+	int	len;
+	tspec_t typ;
+	char	c;
+	double	d;
+	float	f;
+
+	cp = yytext;
+	len = yyleng;
+
+	if ((c = cp[len - 1]) == 'f' || c == 'F') {
+		typ = FLOAT;
+		len--;
+	} else if (c == 'l' || c == 'L') {
+		typ = LDOUBLE;
+		len--;
+	} else {
+		typ = DOUBLE;
+	}
+
+	/* arbitrary value, until strtod can cope */
+	d = 1.0;
+
+	if (typ == FLOAT) {
+		f = (float)d;
+	}
+
+	(yylval.y_val = xcalloc(1, sizeof (val_t)))->v_tspec = typ;
+	if (typ == FLOAT) {
+		yylval.y_val->v_ldbl = f;
+	} else {
+		yylval.y_val->v_ldbl = d;
+	}
+
+	return (T_CON);
+}
+
+static int
+operator(int t, op_t o)
 {
 	yylval.y_op = o;
 	return (t);
 }
 
 /*
- * Called if lex found a leading \'.
+ * Called if lex found a leading '.
  */
 static int
-ccon()
+ccon(void)
 {
 	int	n, val, c;
 	char	cv;
@@ -728,6 +760,7 @@
 
 	yylval.y_val = xcalloc(1, sizeof (val_t));
 	yylval.y_val->v_tspec = INT;
+	yylval.y_val->v_lspec = CHAR;
 	yylval.y_val->v_quad = val;
 
 	return (T_CON);
@@ -737,7 +770,7 @@
  * Called if lex found a leading L\'
  */
 static int
-wccon()
+wccon(void)
 {
 	static	char buf[MB_LEN_MAX + 1];
 	int	i, c;
@@ -790,8 +823,7 @@
  * -2 if the EOF is reached, and the charachter otherwise.
  */
 static int
-getescc(d)
-	int	d;
+getescc(int d)
 {
 	static	int pbc = -1;
 	int	n, c, v;
@@ -814,23 +846,14 @@
 	case '\\':
 		switch (c = inpc()) {
 		case '"':
-			if (tflag && d == '\'')
-				/* \" inside character constant undef. ... */
-				warning(262);
 			return ('"');
 		case '\'':
 			return ('\'');
 		case '?':
-			if (tflag)
-				/* \? undefined in traditional C */
-				warning(263);
 			return ('?');
 		case '\\':
 			return ('\\');
 		case 'a':
-			if (tflag)
-				/* \a undefined in traditional C */
-				warning(81);
 			return ('\a');
 		case 'b':
 			return ('\b');
@@ -843,9 +866,6 @@
 		case 't':
 			return ('\t');
 		case 'v':
-			if (tflag)
-				/* \v undefined in traditional C */
-				warning(264);
 			return ('\v');
 		case '8': case '9':
 			/* bad octal digit %c */
@@ -858,10 +878,7 @@
 			do {
 				v = (v << 3) + (c - '0');
 				c = inpc();
-			} while (--n && isdigit(c) && (tflag || c <= '7'));
-			if (tflag && n > 0 && isdigit(c))
-				/* bad octal digit %c */
-				warning(77, c);
+			} while (--n && isdigit(c) && (c <= '7'));
 			pbc = c;
 			if (v > UCHAR_MAX) {
 				/* character escape does not fit in char. */
@@ -870,9 +887,6 @@
 			}
 			return (v);
 		case 'x':
-			if (tflag)
-				/* \x undefined in traditional C */
-				warning(82);
 			v = 0;
 			n = 0;
 			while ((c = inpc()) >= 0 && isxdigit(c)) {
@@ -920,7 +934,7 @@
  *	# lineno "filename"
  */
 static void
-directive()
+directive(void)
 {
 	const	char *cp, *fn;
 	char	c, *eptr;
@@ -992,7 +1006,7 @@
  * parsed and a function which handles this comment is called.
  */
 static void
-comment()
+comment(void)
 {
 	int	c, lc;
 	static struct {
@@ -1004,10 +1018,12 @@
 		{ "CONSTCOND",		0,	constcond	},
 		{ "CONSTANTCOND",	0,	constcond	},
 		{ "CONSTANTCONDITION",	0,	constcond	},
+		{ "NORETURN",		1,	noreturn	},
 		{ "FALLTHRU",		0,	fallthru	},
 		{ "FALLTHROUGH",	0,	fallthru	},
 		{ "LINTLIBRARY",	0,	lintlib		},
 		{ "LINTED",		0,	linted		},
+		{ "LINTUSED",		0,	lintused	},
 		{ "LONGLONG",		0,	longlong	},
 		{ "NOSTRICT",		0,	linted		},
 		{ "NOTREACHED",		0,	notreach	},
@@ -1090,6 +1106,17 @@
 }
 
 /*
+ * Handle // style comments, which are valid in C99.
+ */
+static void
+slashslashcomment(void)
+{
+	int c;
+
+	while ((c = inpc()) != EOF && c != '\n');
+}
+
+/*
  * Clear flags for lint comments LINTED, LONGLONG and CONSTCOND.
  * clrwflgs() is called after function definitions and global and
  * local declarations and definitions. It is also called between
@@ -1097,11 +1124,12 @@
  * (if, switch, for, while).
  */
 void
-clrwflgs()
+clrwflgs(void)
 {
 	nowarn = 0;
-	quadflg = 0;
+	quadflg = 1;
 	ccflg = 0;
+	usedflg = 0;
 }
 
 /*
@@ -1110,7 +1138,7 @@
  * by the parser are responsible for freeing this buffer.
  */
 static int
-string()
+string(void)
 {
 	u_char	*s;
 	int	c;
@@ -1141,7 +1169,7 @@
 }
 
 static int
-wcstrg()
+wcstrg(void)
 {
 	char	*s;
 	int	c, i, n, wi;
@@ -1211,8 +1239,7 @@
  * XXX calls to getsym() should be delayed until decl1*() is called
  */
 sym_t *
-getsym(sb)
-	sbuf_t	*sb;
+getsym(sbuf_t *sb)
 {
 	dinfo_t	*di;
 	char	*s;
@@ -1283,8 +1310,7 @@
  * back to the symbol table.
  */
 void
-rmsym(sym)
-	sym_t	*sym;
+rmsym(sym_t *sym)
 {
 	if ((*sym->s_rlink = sym->s_link) != NULL)
 		sym->s_link->s_rlink = sym->s_rlink;
@@ -1297,8 +1323,7 @@
  * table.
  */
 void
-rmsyms(syms)
-	sym_t	*syms;
+rmsyms(sym_t *syms)
 {
 	sym_t	*sym;
 
@@ -1316,9 +1341,7 @@
  * Put a symbol into the symbol table
  */
 void
-inssym(bl, sym)
-	int	bl;
-	sym_t	*sym;
+inssym(int bl, sym_t *sym)
 {
 	int	h;
 
@@ -1338,7 +1361,7 @@
  * level 0.
  */
 void
-cleanup()
+cleanup(void)
 {
 	sym_t	*sym, *nsym;
 	int	i;
@@ -1361,8 +1384,7 @@
  * Create a new symbol with the name of an existing symbol.
  */
 sym_t *
-pushdown(sym)
-	sym_t	*sym;
+pushdown(sym_t *sym)
 {
 	int	h;
 	sym_t	*nsym;
@@ -1392,9 +1414,7 @@
  * The type of information in yylval is described by tok.
  */
 void
-freeyyv(sp, tok)
-	void	*sp;
-	int	tok;
+freeyyv(void *sp, int tok)
 {
 	if (tok == T_NAME || tok == T_TYPENAME) {
 		sbuf_t *sb = *(sbuf_t **)sp;
Index: usr.bin/xlint/lint1/tree.c
===================================================================
RCS file: /home/dcvs/src/usr.bin/xlint/lint1/tree.c,v
retrieving revision 1.7
diff -u -r1.7 tree.c
--- usr.bin/xlint/lint1/tree.c	7 Jul 2004 12:24:00 -0000	1.7
+++ usr.bin/xlint/lint1/tree.c	25 Dec 2006 10:25:25 -0000
@@ -1,3 +1,4 @@
+/*	$OpenBSD: tree.c,v 1.44 2006/10/26 22:36:54 cloder Exp $	*/
 /*	$NetBSD: tree.c,v 1.12 1995/10/02 17:37:57 jpo Exp $	*/
 
 /*
@@ -30,7 +31,6 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $NetBSD: tree.c,v 1.12 1995/10/02 17:37:57 jpo Exp $
  * $DragonFly: src/usr.bin/xlint/lint1/tree.c,v 1.7 2004/07/07 12:24:00 asmodai Exp $
  */
 
@@ -48,18 +48,18 @@
 
 static	tnode_t	*getinode(tspec_t, quad_t);
 static	void	ptrcmpok(op_t, tnode_t *, tnode_t *);
-static	int	asgntypok(op_t, int, tnode_t *, tnode_t *);
+static	int	asgntypok(op_t, farg_t *, tnode_t *, tnode_t *);
 static	void	chkbeop(op_t, tnode_t *, tnode_t *);
-static	void	chkeop2(op_t, int, tnode_t *, tnode_t *);
-static	void	chkeop1(op_t, int, tnode_t *, tnode_t *);
+static	void	chkeop2(op_t, farg_t *, tnode_t *, tnode_t *);
+static	void	chkeop1(op_t, farg_t *, tnode_t *, tnode_t *);
 static	tnode_t	*mktnode(op_t, type_t *, tnode_t *, tnode_t *);
 static	void	balance(op_t, tnode_t **, tnode_t **);
 static	void	incompat(op_t, tspec_t, tspec_t);
 static	void	illptrc(mod_t *, type_t *, type_t *);
 static	void	mrgqual(type_t **, type_t *, type_t *);
 static	int	conmemb(type_t *);
-static	void	ptconv(int, tspec_t, tspec_t, type_t *, tnode_t *);
-static	void	iiconv(op_t, int, tspec_t, tspec_t, type_t *, tnode_t *);
+static	tspec_t	fcnconv(farg_t *, tspec_t, tspec_t, type_t *, tnode_t *);
+static	void	iiconv(op_t, farg_t *, tspec_t, tspec_t, type_t *, tnode_t *);
 static	void	piconv(op_t, tspec_t, type_t *, tnode_t *);
 static	void	ppconv(op_t, tnode_t *, type_t *);
 static	tnode_t	*bldstr(op_t, tnode_t *, tnode_t *);
@@ -73,13 +73,15 @@
 static	tnode_t	*fold(tnode_t *);
 static	tnode_t	*foldtst(tnode_t *);
 static	tnode_t	*foldflt(tnode_t *);
-static	tnode_t	*chkfarg(type_t *, tnode_t *);
-static	tnode_t	*parg(int, type_t *, tnode_t *);
+static	tnode_t	*chkfarg(tnode_t *, tnode_t *);
+static	tnode_t	*parg(farg_t *, tnode_t *);
+static	int	chkdbz(op_t, tnode_t *);
 static	void	nulleff(tnode_t *);
-static	void	displexpr(tnode_t *, int);
+static	int	nulleffexpr(tnode_t *);
 static	void	chkaidx(tnode_t *, int);
 static	void	chkcomp(op_t, tnode_t *, tnode_t *);
 static	void	precconf(tnode_t *);
+static	const char *funcname(tnode_t *);
 
 /*
  * Initialize mods of operators.
@@ -137,7 +139,7 @@
 		    ">" } },
 		{ GE,     { 1,1,0,1,0,1,1,0,1,0,1,1,0,1,1,0,1,
 		    ">=" } },
-		{ EQ,     { 1,1,0,1,0,1,1,0,1,0,0,0,0,1,1,0,1,
+		{ EQ,     { 1,1,0,1,0,1,1,0,1,0,0,0,0,1,1,0,0,
 		    "==" } },
 		{ NE,     { 1,1,0,1,0,1,1,0,1,0,0,0,0,1,1,0,1,
 		    "!=" } },
@@ -153,7 +155,7 @@
 		    "||" } },
 		{ QUEST,  { 1,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,
 		    "?" } },
-		{ COLON,  { 1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,
+		{ COLON,  { 1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,
 		    ":" } },
 		{ ASSIGN, { 1,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,
 		    "=" } },
@@ -253,6 +255,7 @@
 	n->tn_type = tp;
 	n->tn_val = tgetblk(sizeof (val_t));
 	n->tn_val->v_tspec = tp->t_tspec;
+	n->tn_val->v_lspec = v->v_lspec;
 	n->tn_val->v_ansiu = v->v_ansiu;
 	n->tn_val->v_u = v->v_u;
 	free(v);
@@ -293,10 +296,6 @@
 				/* function implicitly declared to ... */
 				warning(215);
 			}
-			/*
-			 * XXX if tflag is set the symbol should be
-			 * exported to level 0
-			 */
 			sym->s_type = incref(sym->s_type, FUNC);
 		} else {
 			/* %s undefined */
@@ -472,11 +471,7 @@
 	 */
 	if (str != NULL) {
 		/* illegal member use: %s */
-		if (eq && tflag) {
-			warning(102, msym->s_name);
-		} else {
-			error(102, msym->s_name);
-		}
+		error(102, msym->s_name);
 		return (msym);
 	}
 
@@ -487,27 +482,14 @@
 	if (eq) {
 		if (op == POINT) {
 			/* left operand of "." must be struct/union object */
-			if (tflag) {
-				warning(103);
-			} else {
-				error(103);
-			}
+			error(103);
 		} else {
 			/* left operand of "->" must be pointer to ... */
-			if (tflag && tn->tn_type->t_tspec == PTR) {
-				warning(104);
-			} else {
-				error(104);
-			}
+			error(104);
 		}
 	} else {
-		if (tflag) {
-			/* non-unique member requires struct/union %s */
-			error(105, op == POINT ? "object" : "pointer");
-		} else {
-			/* unacceptable operand of %s */
-			error(111, modtab[op].m_name);
-		}
+		/* unacceptable operand of %s */
+		error(111, modtab[op].m_name);
 	}
 
 	return (msym);
@@ -536,7 +518,7 @@
 
 	/*
 	 * Apply class conversions to the left operand, but only if its
-	 * value is needed or it is compaired with null.
+	 * value is needed or it is compared with null.
 	 */
 	if (mp->m_vctx || mp->m_tctx)
 		ln = cconv(ln);
@@ -548,7 +530,7 @@
 		rn = cconv(rn);
 
 	/*
-	 * Print some warnings for comparisions of unsigned values with
+	 * Print some warnings for comparisons of unsigned values with
 	 * constants lower than or equal to null. This must be done
 	 * before promote() because otherwise unsigned char and unsigned
 	 * short would be promoted to int. Also types are tested to be
@@ -588,14 +570,14 @@
 	}
 
 	/* Make sure both operands are of the same type */
-	if (mp->m_balance || (tflag && (op == SHL || op == SHR)))
+	if (mp->m_balance)
 		balance(op, &ln, &rn);
 
 	/*
 	 * Check types for compatibility with the operation and mutual
-	 * compatibility. Return if there are serios problems.
+	 * compatibility. Return if there are serious problems.
 	 */
-	if (!typeok(op, 0, ln, rn))
+	if (!typeok(op, NULL, ln, rn))
 		return (NULL);
 
 	/* And now create the node. */
@@ -653,7 +635,7 @@
 		break;
 	}
 
-	/* Return if an error occured. */
+	/* Return if an error occurred. */
 	if (ntn == NULL)
 		return (NULL);
 
@@ -668,9 +650,10 @@
 	if (mp->m_tctx) {
 		if (ln->tn_op == CON ||
 		    ((mp->m_binary && op != QUEST) && rn->tn_op == CON)) {
-			if (hflag && !ccflg)
+			if (hflag && !ccflg) {
 				/* constant in conditional context */
 				warning(161);
+			}
 		}
 	}
 
@@ -710,7 +693,7 @@
 	 */
 	if (tn->tn_type->t_tspec == ARRAY) {
 		if (!tn->tn_lvalue) {
-			/* %soperand of '%s' must be lvalue */
+			/* operand of '%s' must be lvalue */
 			/* XXX print correct operator */
 			(void)gnuism(114, "", modtab[AMPER].m_name);
 		}
@@ -738,18 +721,20 @@
 
 /*
  * Perform most type checks. First the types are checked using
- * informations from modtab[]. After that it is done by hand for
+ * information from modtab[]. After that it is done by hand for
  * more complicated operators and type combinations.
  *
  * If the types are ok, typeok() returns 1, otherwise 0.
  */
 int
-typeok(op_t op, int arg, tnode_t *ln, tnode_t *rn)
+typeok(op_t op, farg_t *farg, tnode_t *ln, tnode_t *rn)
 {
 	mod_t	*mp;
-	tspec_t	lt, rt, lst, rst, olt, ort;
+	tspec_t	lt, rt = NOTSPEC, lst = NOTSPEC, rst = NOTSPEC,
+		olt = NOTSPEC, ort = NOTSPEC;
 	type_t	*ltp, *rtp, *lstp, *rstp;
 	tnode_t	*tn;
+	int arg = (farg) ? farg->fa_num : 0;
 
 	mp = &modtab[op];
 
@@ -761,7 +746,7 @@
 	}
 
 	if (mp->m_rqint) {
-		/* integertypes required */
+		/* integer types required */
 		if (!isityp(lt) || (mp->m_binary && !isityp(rt))) {
 			incompat(op, lt, rt);
 			return (0);
@@ -795,24 +780,18 @@
 	case POINT:
 		/*
 		 * Most errors required by ANSI C are reported in strmemb().
-		 * Here we only must check for totaly wrong things.
+		 * Here we only must check for totally wrong things.
 		 */
 		if (lt == FUNC || lt == VOID || ltp->t_isfield ||
 		    ((lt != STRUCT && lt != UNION) && !ln->tn_lvalue)) {
-			/* Without tflag we got already an error */
-			if (tflag)
-				/* unacceptable operand of %s */
-				error(111, mp->m_name);
+			/* we already have an error from strmemb() */
 			return (0);
 		}
 		/* Now we have an object we can create a pointer to */
 		break;
 	case ARROW:
-		if (lt != PTR && !(tflag && isityp(lt))) {
-			/* Without tflag we got already an error */
-			if (tflag)
-				/* unacceptabel operand of %s */
-				error(111, mp->m_name);
+		if (lt != PTR) {
+			/* we already have an error from strmemb() */
 			return (0);
 		}
 		break;
@@ -832,8 +811,7 @@
 			return (0);
 		} else if (ltp->t_const) {
 			/* %soperand of %s must be modifiable lvalue */
-			if (!tflag)
-				warning(115, "", mp->m_name);
+			warning(115, "", mp->m_name);
 		}
 		break;
 	case AMPER:
@@ -910,7 +888,7 @@
 			} else if (ln->tn_val->v_quad < 0) {
 				warning(120);
 			}
-		} else if (!tflag && !sflag && !isutyp(olt) && isutyp(ort)) {
+		} else if (!sflag && !isutyp(olt) && isutyp(ort)) {
 			/*
 			 * The left operand would become unsigned in
 			 * traditional C.
@@ -920,7 +898,7 @@
 				/* semantics of %s change in ANSI C; use ... */
 				warning(118, mp->m_name);
 			}
-		} else if (!tflag && !sflag && !isutyp(olt) && !isutyp(ort) &&
+		} else if (!sflag && !isutyp(olt) && !isutyp(ort) &&
 			   psize(lt) < psize(rt)) {
 			/*
 			 * In traditional C the left operand would be extended,
@@ -932,20 +910,25 @@
 				warning(118, mp->m_name);
 			}
 		}
+
+		/* right shift of %d-bit quantity by %lld bits */
+		if (rn->tn_op == CON && size(olt) <= rn->tn_val->v_quad)
+			warning(310, size(olt), rn->tn_val->v_quad);
+
 		goto shift;
 	case SHL:
 		/*
 		 * ANSI C does not perform balancing for shift operations,
 		 * but traditional C does. If the width of the right operand
 		 * is greather than the width of the left operand, than in
-		 * traditional C the left operand would be extendet to the
+		 * traditional C the left operand would be extended to the
 		 * width of the right operand. For SHL this may result in
 		 * different results.
 		 */
 		if (psize(lt) < psize(rt)) {
 			/*
 			 * XXX If both operands are constant make sure
-			 * that there is really a differencs between
+			 * that there is really a difference between
 			 * ANSI C and traditional C.
 			 */
 			if (hflag)
@@ -958,7 +941,7 @@
 				/* negative shift */
 				warning(121);
 			} else if ((u_quad_t)rn->tn_val->v_quad == size(lt)) {
-				/* shift equal to size fo object */
+				/* shift equal to size of object */
 				warning(267);
 			} else if ((u_quad_t)rn->tn_val->v_quad > size(lt)) {
 				/* shift greater than size of object */
@@ -970,7 +953,7 @@
 	case NE:
 		/*
 		 * Accept some things which are allowed with EQ and NE,
-		 * but not with ordered comparisions.
+		 * but not with ordered comparisons.
 		 */
 		if (lt == PTR && ((rt == PTR && rst == VOID) || isityp(rt))) {
 			if (rn->tn_op == CON && rn->tn_val->v_quad == 0)
@@ -1063,7 +1046,7 @@
 	case INIT:
 	case FARG:
 	case RETURN:
-		if (!asgntypok(op, arg, ln, rn))
+		if (!asgntypok(op, farg, ln, rn))
 			return (0);
 		goto assign;
 	case MULASS:
@@ -1081,10 +1064,15 @@
 	case SHLASS:
 		goto assign;
 	case SHRASS:
-		if (pflag && !isutyp(lt) && !(tflag && isutyp(rt))) {
-			/* bitwise operation on s.v. possibly nonportabel */
+		if (pflag && !isutyp(lt)) {
+			/* bitwise operation on s.v. possibly nonportable */
 			warning(117);
 		}
+
+		/* right shift of %d-bit quantity by %d bits */
+		if (rn->tn_op == CON && size(olt) <= rn->tn_val->v_quad)
+			warning(310, size(olt), rn->tn_val->v_quad);
+
 		goto assign;
 	case ANDASS:
 	case XORASS:
@@ -1103,8 +1091,7 @@
 		} else if (ltp->t_const || ((lt == STRUCT || lt == UNION) &&
 					    conmemb(ltp))) {
 			/* %soperand of %s must be modifiable lvalue */
-			if (!tflag)
-				warning(115, "left ", mp->m_name);
+			warning(115, "left ", mp->m_name);
 		}
 		break;
 	case COMMA:
@@ -1112,17 +1099,15 @@
 			nulleff(ln);
 		break;
 		/* LINTED (enumeration values not handled in switch) */
-	default:
-		break;
 	}
 
 	if (mp->m_badeop &&
 	    (ltp->t_isenum || (mp->m_binary && rtp->t_isenum))) {
 		chkbeop(op, ln, rn);
 	} else if (mp->m_enumop && (ltp->t_isenum && rtp->t_isenum)) {
-		chkeop2(op, arg, ln, rn);
+		chkeop2(op, farg, ln, rn);
 	} else if (mp->m_enumop && (ltp->t_isenum || rtp->t_isenum)) {
-		chkeop1(op, arg, ln, rn);
+		chkeop1(op, farg, ln, rn);
 	}
 
 	return (1);
@@ -1143,7 +1128,7 @@
 			/* (void *)0 already handled in typeok() */
 			*(lt == FUNC ? &lts : &rts) = "function pointer";
 			*(lt == VOID ? &lts : &rts) = "'void *'";
-			/* ANSI C forbids comparision of %s with %s */
+			/* ANSI C forbids comparison of %s with %s */
 			warning(274, lts, rts);
 		}
 		return;
@@ -1167,12 +1152,13 @@
  * If the types are (almost) compatible, 1 is returned, otherwise 0.
  */
 static int
-asgntypok(op_t op, int arg, tnode_t *ln, tnode_t *rn)
+asgntypok(op_t op, farg_t *farg, tnode_t *ln, tnode_t *rn)
 {
-	tspec_t	lt, rt, lst, rst;
+	tspec_t	lt, rt, lst = NOTSPEC, rst = NOTSPEC;
 	type_t	*ltp, *rtp, *lstp, *rstp;
 	mod_t	*mp;
 	const	char *lts, *rts;
+	int	arg = (farg) ? farg->fa_num : 0;
 
 	if ((lt = (ltp = ln->tn_type)->t_tspec) == PTR)
 		lst = (lstp = ltp->t_subt)->t_tspec;
@@ -1180,6 +1166,15 @@
 		rst = (rstp = rtp->t_subt)->t_tspec;
 	mp = &modtab[op];
 
+	/* be picky about conversion of function return types */
+	if (rn->tn_op == CALL) {
+		if (size(lt) < size(rt) ||
+		    (size(lt) == size(rt) && isutyp(lt) && !isutyp(rt))) {
+			warning(313, funcname(rn),
+			    tyname(rn->tn_type), tyname(ln->tn_type));
+		}
+	}
+
 	if (isatyp(lt) && isatyp(rt))
 		return (1);
 
@@ -1220,8 +1215,7 @@
 	if (lt == PTR && rt == PTR && (lst == VOID || rst == VOID ||
 				       eqtype(lstp, rstp, 1, 0, NULL))) {
 		/* compatible pointer types (qualifiers ignored) */
-		if (!tflag &&
-		    ((!lstp->t_const && rstp->t_const) ||
+		if (((!lstp->t_const && rstp->t_const) ||
 		     (!lstp->t_volatile && rstp->t_volatile))) {
 			/* left side has not all qualifiers of right */
 			switch (op) {
@@ -1231,8 +1225,8 @@
 				warning(182);
 				break;
 			case FARG:
-				/* argument has incompat. ptr. type, arg #%d */
-				warning(153, arg);
+				/* %s arg #%d: incompatible ptr. type */
+				warning(153, funcname(farg->fa_func), arg);
 				break;
 			default:
 				/* operands have incompat. ptr. types, op %s */
@@ -1251,8 +1245,8 @@
 			warning(183);
 			break;
 		case FARG:
-			/* illegal comb. of ptr. and int., arg #%d */
-			warning(154, arg);
+			/* %s arg #%d: illegal comb. of ptr. and int. */
+			warning(154, funcname(farg->fa_func), arg);
 			break;
 		default:
 			/* illegal comb. of ptr. and int., op %s */
@@ -1269,8 +1263,8 @@
 			illptrc(NULL, ltp, rtp);
 			break;
 		case FARG:
-			/* argument has incompatible pointer type, arg #%d */
-			warning(153, arg);
+			/* %s arg #%d: incompatible pointer type */
+			warning(153, funcname(farg->fa_func), arg);
 			break;
 		default:
 			illptrc(mp, ltp, rtp);
@@ -1289,8 +1283,8 @@
 		error(211);
 		break;
 	case FARG:
-		/* argument is incompatible with prototype, arg #%d */
-		warning(155, arg);
+		/* %s arg #%d: argument is incompatible with prototype */
+		warning(155, funcname(farg->fa_func), arg);
 		break;
 	default:
 		incompat(op, lt, rt);
@@ -1338,9 +1332,10 @@
  * Prints a warning if an operator is applied to two different enum types.
  */
 static void
-chkeop2(op_t op, int arg, tnode_t *ln, tnode_t *rn)
+chkeop2(op_t op, farg_t *farg, tnode_t *ln, tnode_t *rn)
 {
 	mod_t	*mp;
+	int	arg = (farg) ? farg->fa_num : 0;
 
 	mp = &modtab[op];
 
@@ -1351,8 +1346,8 @@
 			warning(210);
 			break;
 		case FARG:
-			/* enum type mismatch, arg #%d */
-			warning(156, arg);
+			/* %s arg #%d: enum type mismatch */
+			warning(156, funcname(farg->fa_func), arg);
 			break;
 		case RETURN:
 			/* return value type mismatch */
@@ -1366,7 +1361,7 @@
 #if 0
 	} else if (mp->m_comp && op != EQ && op != NE) {
 		if (eflag)
-			/* dubious comparisions of enums */
+			/* dubious comparisons of enums */
 			warning(243, mp->m_name);
 #endif
 	}
@@ -1377,8 +1372,10 @@
  * types.
  */
 static void
-chkeop1(op_t op, int arg, tnode_t *ln, tnode_t *rn)
+chkeop1(op_t op, farg_t *farg, tnode_t *ln, tnode_t *rn)
 {
+	int	arg = (farg) ? farg->fa_num : 0;
+
 	if (!eflag)
 		return;
 
@@ -1397,8 +1394,8 @@
 		warning(277, tyname(ln->tn_type), tyname(rn->tn_type));
 		break;
 	case FARG:
-		/* combination of '%s' and '%s', arg #%d */
-		warning(278, tyname(ln->tn_type), tyname(rn->tn_type), arg);
+		/* %s arg #%d: combination of '%s' and '%s' */
+		warning(278, funcname(farg->fa_func), arg, tyname(ln->tn_type), tyname(rn->tn_type));
 		break;
 	case RETURN:
 		/* combination of '%s' and '%s' in return */
@@ -1444,9 +1441,8 @@
 /*
  * Performs usual conversion of operands to (unsigned) int.
  *
- * If tflag is set or the operand is a function argument with no
- * type information (no prototype or variable # of args), convert
- * float to double.
+ * If the operand is a function argument with no type information
+ * (no prototype or variable # of args), convert float to double.
  */
 tnode_t *
 promote(op_t op, int farg, tnode_t *tn)
@@ -1460,50 +1456,38 @@
 	if (!isatyp(t))
 		return (tn);
 
-	if (!tflag) {
-		/*
-		 * ANSI C requires that the result is always of type INT
-		 * if INT can represent all possible values of the previous
-		 * type.
-		 */
-		if (tn->tn_type->t_isfield) {
-			len = tn->tn_type->t_flen;
-			if (size(INT) > len) {
-				t = INT;
+	/*
+	 * ANSI C requires that the result is always of type INT
+	 * if INT can represent all possible values of the previous
+	 * type (it is "value preserving" rather than "sign
+	 * preserving").
+	 *
+	 * XXX: Adjust value-preserving rules for longs and long
+	 * longs, too.
+	 */
+	if (tn->tn_type->t_isfield) {
+		len = tn->tn_type->t_flen;
+		if (size(INT) > len) {
+			t = INT;
+		} else {
+			if (size(INT) != len)
+				lerror("promote() 1");
+			if (isutyp(t)) {
+				t = UINT;
 			} else {
-				if (size(INT) != len)
-					lerror("promote() 1");
-				if (isutyp(t)) {
-					t = UINT;
-				} else {
-					t = INT;
-				}
+				t = INT;
 			}
-		} else if (t == CHAR || t == UCHAR || t == SCHAR) {
-			t = (size(CHAR) < size(INT) || t != UCHAR) ?
-				INT : UINT;
-		} else if (t == SHORT || t == USHORT) {
-			t = (size(SHORT) < size(INT) || t == SHORT) ?
-				INT : UINT;
-		} else if (t == ENUM) {
-			t = INT;
-		} else if (farg && t == FLOAT) {
-			t = DOUBLE;
-		}
-	} else {
-		/*
-		 * In traditional C, keep unsigned and promote FLOAT
-		 * to DOUBLE.
-		 */
-		if (t == UCHAR || t == USHORT) {
-			t = UINT;
-		} else if (t == CHAR || t == SCHAR || t == SHORT) {
-			t = INT;
-		} else if (t == FLOAT) {
-			t = DOUBLE;
-		} else if (t == ENUM) {
-			t = INT;
 		}
+	} else if (t == CHAR || t == UCHAR || t == SCHAR) {
+		t = (size(CHAR) < size(INT) || t != UCHAR) ?
+			INT : UINT;
+	} else if (t == SHORT || t == USHORT) {
+		t = (size(SHORT) < size(INT) || t == SHORT) ?
+			INT : UINT;
+	} else if (t == ENUM) {
+		t = INT;
+	} else if (farg && t == FLOAT) {
+		t = DOUBLE;
 	}
 
 	if (t != tn->tn_type->t_tspec) {
@@ -1513,7 +1497,7 @@
 		 * Keep t_isenum so we are later able to check compatibility
 		 * of enum types.
 		 */
-		tn = convert(op, 0, ntp, tn);
+		tn = convert(op, NULL, ntp, tn);
 	}
 
 	return (tn);
@@ -1521,7 +1505,7 @@
 
 /*
  * Insert conversions which are necessary to give both operands the same
- * type. This is done in different ways for traditional C and ANIS C.
+ * type. This is done in different ways for traditional C and ANSI C.
  */
 static void
 balance(op_t op, tnode_t **lnp, tnode_t **rnp)
@@ -1539,70 +1523,59 @@
 	if (!isatyp(lt) || !isatyp(rt))
 		return;
 
-	if (!tflag) {
-		if (lt == rt) {
+	if (lt == rt) {
+		t = lt;
+	} else if (lt == LDOUBLE || rt == LDOUBLE) {
+		t = LDOUBLE;
+	} else if (lt == DOUBLE || rt == DOUBLE) {
+		t = DOUBLE;
+	} else if (lt == FLOAT || rt == FLOAT) {
+		t = FLOAT;
+	} else {
+		/*
+		 * If type A has more bits than type B it should
+		 * be able to hold all possible values of type B.
+		 */
+		if (size(lt) > size(rt)) {
 			t = lt;
-		} else if (lt == LDOUBLE || rt == LDOUBLE) {
-			t = LDOUBLE;
-		} else if (lt == DOUBLE || rt == DOUBLE) {
-			t = DOUBLE;
-		} else if (lt == FLOAT || rt == FLOAT) {
-			t = FLOAT;
+		} else if (size(lt) < size(rt)) {
+			t = rt;
 		} else {
-			/*
-			 * If type A has more bits than type B it should
-			 * be able to hold all possible values of type B.
-			 */
-			if (size(lt) > size(rt)) {
-				t = lt;
-			} else if (size(lt) < size(rt)) {
-				t = rt;
-			} else {
-				for (i = 3; tl[i] != INT; i++) {
-					if (tl[i] == lt || tl[i] == rt)
-						break;
-				}
-				if ((isutyp(lt) || isutyp(rt)) &&
-				    !isutyp(tl[i])) {
-					i--;
-				}
-				t = tl[i];
+			for (i = 3; tl[i] != INT; i++) {
+				if (tl[i] == lt || tl[i] == rt)
+					break;
 			}
+			if ((isutyp(lt) || isutyp(rt)) &&
+			    !isutyp(tl[i])) {
+				i--;
+			}
+			t = tl[i];
 		}
-	} else {
-		/* Keep unsigned in traditional C */
-		u = isutyp(lt) || isutyp(rt);
-		for (i = 0; tl[i] != INT; i++) {
-			if (lt == tl[i] || rt == tl[i])
-				break;
-		}
-		t = tl[i];
-		if (u && isityp(t) && !isutyp(t))
-			t = utyp(t);
 	}
 
 	if (t != lt) {
 		ntp = tduptyp((*lnp)->tn_type);
 		ntp->t_tspec = t;
-		*lnp = convert(op, 0, ntp, *lnp);
+		*lnp = convert(op, NULL, ntp, *lnp);
 	}
 	if (t != rt) {
 		ntp = tduptyp((*rnp)->tn_type);
 		ntp->t_tspec = t;
-		*rnp = convert(op, 0, ntp, *rnp);
+		*rnp = convert(op, NULL, ntp, *rnp);
 	}
 }
 
 /*
  * Insert a conversion operator, which converts the type of the node
  * to another given type.
- * If op is FARG, arg is the number of the argument (used for warnings).
+ * If op is FARG, farg contains the passed argument information.
  */
 tnode_t *
-convert(op_t op, int arg, type_t *tp, tnode_t *tn)
+convert(op_t op, farg_t *farg, type_t *tp, tnode_t *tn)
 {
 	tnode_t	*ntn;
-	tspec_t	nt, ot, ost;
+	tspec_t	nt, ot, ost = NOTSPEC;
+	int arg = (farg) ? farg->fa_num : 0;
 
 	if (tn->tn_lvalue)
 		lerror("convert() 1");
@@ -1611,10 +1584,11 @@
 	if ((ot = tn->tn_type->t_tspec) == PTR)
 		ost = tn->tn_type->t_subt->t_tspec;
 
-	if (!tflag && !sflag && op == FARG)
-		ptconv(arg, nt, ot, tp, tn);
+	if (op == FARG)
+		nt = fcnconv(farg, nt, ot, tp, tn);
+
 	if (isityp(nt) && isityp(ot)) {
-		iiconv(op, arg, nt, ot, tp, tn);
+		iiconv(op, farg, nt, ot, tp, tn);
 	} else if (nt == PTR && ((ot == PTR && ost == VOID) || isityp(ot)) &&
 		   tn->tn_op == CON && tn->tn_val->v_quad == 0) {
 		/* 0, 0L and (void *)0 may be assigned to any pointer. */
@@ -1622,6 +1596,19 @@
 		piconv(op, nt, tp, tn);
 	} else if (nt == PTR && ot == PTR) {
 		ppconv(op, tn, tp);
+	} else if (isftyp(ot) && !isftyp(nt)) {
+		/* conversion from floating point to fixed point */
+		if (tn->tn_op == CON) {
+			/* ok. cvtcon() warns if constant out of range */
+		} else {
+			if (op == FARG)
+				/* %s arg #%d: converted from '%s' to '%s' */
+				warning(259, funcname(farg->fa_func), arg,
+				    tyname(tn->tn_type), tyname(tp));
+			else
+				warning(132, tyname(tn->tn_type),
+				    tyname(tp));
+		}
 	}
 
 	ntn = getnode();
@@ -1633,27 +1620,39 @@
 	} else {
 		ntn->tn_op = CON;
 		ntn->tn_val = tgetblk(sizeof (val_t));
-		cvtcon(op, arg, ntn->tn_type, ntn->tn_val, tn->tn_val);
+		cvtcon(op, farg, ntn->tn_type, ntn->tn_val, tn->tn_val);
 	}
 
 	return (ntn);
 }
 
 /*
- * Print a warning if a prototype causes a type conversion that is
- * different from what would happen to the same argument in the
- * absence of a prototype.
+ * Print warnings for conversions of function call arguments.  Conversions
+ * happen differently between standard C and traditional C, and also happen
+ * differently in standard C depending on whether a prototype is present.
  *
  * Errors/Warnings about illegal type combinations are already printed
  * in asgntypok().
  */
-static void
-ptconv(int arg, tspec_t nt, tspec_t ot, type_t *tp, tnode_t *tn)
+static tspec_t
+fcnconv(farg_t *farg, tspec_t nt, tspec_t ot, type_t *tp, tnode_t *tn)
 {
 	tnode_t	*ptn;
+	type_t *fcn = farg->fa_func->tn_type->t_subt;
+	tspec_t pt;
+	int arg = farg->fa_num;
+
+	/* In standard C, if the function call is governed by a prototype,
+	 * the arguments don't necessarily undergo the usual argument conversions
+	 * before the call. They can be converted directly to the type of the
+	 * formal parameter, without necessarily widening/narrowing.
+	 */
+	if (fcn->t_proto || !isatyp(nt) || !isatyp(ot))
+		return nt;
 
-	if (!isatyp(nt) || !isatyp(ot))
-		return;
+	/* get default promotion */
+	ptn = promote(NOOP, 1, tn);
+	pt = ptn->tn_type->t_tspec;
 
 	/*
 	 * If the type of the formal parameter is char/short, a warning
@@ -1661,21 +1660,23 @@
 	 * can't expect char/short arguments.
 	 */
 	if (nt == CHAR || nt == UCHAR || nt == SHORT || nt == USHORT)
-		return;
-
-	/* get default promotion */
-	ptn = promote(NOOP, 1, tn);
-	ot = ptn->tn_type->t_tspec;
+		return pt;
 
-	/* return if types are the same with and without prototype */
-	if (nt == ot || (nt == ENUM && ot == INT))
-		return;
+	/* return if types are the same with and without promotion */
+	if (nt == pt || (nt == ENUM && pt == INT))
+		return pt;
 
-	if (isftyp(nt) != isftyp(ot) || psize(nt) != psize(ot)) {
+	if (isftyp(nt) != isftyp(pt) || psize(nt) != psize(pt)) {
 		/* representation and/or width change */
-		if (styp(nt) != SHORT || !isityp(ot) || psize(ot) > psize(INT))
-			/* conversion to '%s' due to prototype, arg #%d */
-			warning(259, tyname(tp), arg);
+		if (styp(nt) != SHORT || !isityp(pt) || psize(pt) > psize(INT)) {
+			if (ptn->tn_op == CON) {
+				/* ok. promote() warns if constant out of range */
+			} else {
+				/* %s arg #%d: converted from '%s' to '%s' */
+				warning(259, funcname(farg->fa_func), arg,
+				    tyname(tn->tn_type), tyname(tp));
+			}
+		}
 	} else if (hflag) {
 		/*
 		 * they differ in sign or base type (char, short, int,
@@ -1684,53 +1685,58 @@
 		 * if they differ only in sign and the argument is a constant
 		 * and the msb of the argument is not set, print no warning
 		 */
-		if (ptn->tn_op == CON && isityp(nt) && styp(nt) == styp(ot) &&
+		if (ptn->tn_op == CON && isityp(nt) && styp(nt) == styp(pt) &&
 		    msb(ptn->tn_val->v_quad, ot, -1) == 0) {
 			/* ok */
-		} else {
-			/* conversion to '%s' due to prototype, arg #%d */
-			warning(259, tyname(tp), arg);
+		} else if (ptn->tn_op != CON) {
+			/* %s arg #%d: converted from '%s' to '%s' */
+			warning(259, funcname(farg->fa_func), arg,
+			    tyname(tn->tn_type), tyname(tp));
 		}
 	}
+
+	return pt;
 }
 
 /*
- * Print warnings for conversions of integer types which my cause
+ * Print warnings for conversions of integer types which may cause
  * problems.
  */
 /* ARGSUSED */
 static void
-iiconv(op_t op, int arg, tspec_t nt, tspec_t ot, type_t *tp, tnode_t *tn)
+iiconv(op_t op, farg_t *farg, tspec_t nt, tspec_t ot, type_t *tp, tnode_t *tn)
 {
+	int arg = (farg) ? farg->fa_num : 0;
+
 	if (tn->tn_op == CON)
 		return;
 
 	if (op == CVT)
 		return;
 
-#if 0
-	if (psize(nt) > psize(ot) && isutyp(nt) != isutyp(ot)) {
-		/* conversion to %s may sign-extend incorrectly (, arg #%d) */
-		if (aflag && pflag) {
-			if (op == FARG) {
-				warning(297, tyname(tp), arg);
-			} else {
-				warning(131, tyname(tp));
-			}
-		}
-	}
-#endif
-
-	if (psize(nt) < psize(ot) &&
-	    (ot == LONG || ot == ULONG || ot == QUAD || ot == UQUAD ||
-	     aflag > 1)) {
-		/* conversion from '%s' may lose accuracy */
-		if (aflag) {
-			if (op == FARG) {
-				warning(298, tyname(tn->tn_type), arg);
-			} else {
-				warning(132, tyname(tn->tn_type));
-			}
+	if (rank(nt) < rank(ot)) {
+		/* coercion from greater to lesser width */
+		if (op == FARG) {
+			warning(259, funcname(farg->fa_func), arg,
+			    tyname(tn->tn_type), tyname(tp));
+		} else {
+			warning(132, tyname(tn->tn_type), tyname(tp));
+		}
+	} else if (!isutyp(ot) && isutyp(nt)) {
+		/* signed to unsigned conversion */
+		if (op == FARG) {
+			warning(259, funcname(farg->fa_func), arg,
+			    tyname(tn->tn_type), tyname(tp));
+		} else {
+			warning(132, tyname(tn->tn_type), tyname(tp));
+		}
+	} else if (isutyp(ot) && !isutyp(nt) && rank(nt) == rank(ot)) {
+		/* signed to unsigned conversion */
+		if (op == FARG) {
+			warning(259, funcname(farg->fa_func), arg,
+			    tyname(tn->tn_type), tyname(tp));
+		} else {
+			warning(132, tyname(tn->tn_type), tyname(tp));
 		}
 	}
 }
@@ -1745,7 +1751,7 @@
 		return;
 
 	if (op != CVT) {
-		/* We got already an error. */
+		/* We already have an error. */
 		return;
 	}
 
@@ -1770,7 +1776,7 @@
 	const	char *nts, *ots;
 
 	/*
-	 * We got already an error (pointers of different types
+	 * We already have an error (pointers of different types
 	 * without a cast) or we will not get a warning.
 	 */
 	if (op != CVT)
@@ -1803,7 +1809,7 @@
 	}
 	if (((nt == STRUCT || nt == UNION) &&
 	     tp->t_subt->t_str != tn->tn_type->t_subt->t_str) ||
-	    psize(nt) != psize(ot)) {
+	    (psize(nt) != CHAR_BIT && psize(nt) != psize(ot))) {
 		if (cflag) {
 			/* pointer casts may be troublesome */
 			warning(247);
@@ -1812,22 +1818,22 @@
 }
 
 /*
- * Converts a typed constant in a constant of another type.
+ * Converts a typed constant to a constant of another type.
  *
  * op		operator which requires conversion
- * arg		if op is FARG, # of argument
- * tp		type in which to convert the constant
+ * farg		if op is FARG, the passed argument info (else NULL)
+ * tp		type to which to convert the constant
  * nv		new constant
  * v		old constant
  */
 void
-cvtcon(op_t op, int arg, type_t *tp, val_t *nv, val_t *v)
+cvtcon(op_t op, farg_t *farg, type_t *tp, val_t *nv, val_t *v)
 {
 	tspec_t	ot, nt;
-	ldbl_t	max, min;
+	ldbl_t	max = 0, min = 0;
 	int	sz, rchk;
 	quad_t	xmask, xmsk1;
-	int	osz, nsz;
+	int	osz, nsz, arg = (farg) ? farg->fa_num : 0;
 
 	ot = v->v_tspec;
 	nt = nv->v_tspec = tp->t_tspec;
@@ -1863,7 +1869,7 @@
 		case DOUBLE:
 			max = DBL_MAX;		min = -DBL_MAX;		break;
 		case PTR:
-			/* Got already an error because of float --> ptr */
+			/* Already an error because of float --> ptr */
 		case LDOUBLE:
 			max = LDBL_MAX;		min = -LDBL_MAX;	break;
 		default:
@@ -1873,9 +1879,9 @@
 			if (nt == LDOUBLE)
 				lerror("cvtcon() 2");
 			if (op == FARG) {
-				/* conv. of %s to %s is out of rng., arg #%d */
-				warning(295, tyname(gettyp(ot)), tyname(tp),
-					arg);
+				/* %s arg #%d: conv. of %s to %s is out of range */
+				warning(295, funcname(farg->fa_func), arg,
+				    tyname(gettyp(ot)), tyname(tp));
 			} else {
 				/* conversion of %s to %s is out of range */
 				warning(119, tyname(gettyp(ot)), tyname(tp));
@@ -1966,15 +1972,22 @@
 			}
 		} else if ((nt != PTR && isutyp(nt)) &&
 			   (ot != PTR && !isutyp(ot)) && v->v_quad < 0) {
-			if (op == ASSIGN) {
+			if ((nt == CHAR || nt == UCHAR || nt == SCHAR) &&
+			   v->v_lspec == CHAR) {
+				/*
+				 * Don't warn when assigning a character
+				 * literal to any kind of character (signed,
+				 * unsigned, or unspecified).
+				 */
+			} else if (op == ASSIGN) {
 				/* assignment of negative constant to ... */
 				warning(164);
 			} else if (op == INIT) {
 				/* initialisation of unsigned with neg. ... */
 				warning(221);
 			} else if (op == FARG) {
-				/* conversion of neg. const. to ..., arg #%d */
-				warning(296, arg);
+				/* %s arg #%d: conversion of neg. const... */
+				warning(296, funcname(farg->fa_func), arg);
 			} else if (modtab[op].m_comp) {
 				/* we get this warning already in chkcomp() */
 			} else {
@@ -2000,7 +2013,14 @@
 			 *	i = c;			** yields -128 **
 			 *	i = (unsigned char)c;	** yields 128 **
 			 */
-			if (op == ASSIGN && tp->t_isfield) {
+			if ((nt == CHAR || nt == UCHAR || nt == SCHAR) &&
+			   v->v_lspec == CHAR) {
+				/*
+				 * Don't warn when assigning a character
+				 * literal to any kind of character (signed,
+				 * unsigned, or unspecified).
+				 */
+			} else if (op == ASSIGN && tp->t_isfield) {
 				/* precision lost in bit-field assignment */
 				warning(166);
 			} else if (op == ASSIGN) {
@@ -2016,15 +2036,22 @@
 				/* case label affected by conversion */
 				warning(196);
 			} else if (op == FARG) {
-				/* conv. of %s to %s is out of rng., arg #%d */
-				warning(295, tyname(gettyp(ot)), tyname(tp),
-					arg);
+				/* %s arg #%d: conv. of %s to %s is out of rng. */
+				warning(295, funcname(farg->fa_func), arg,
+				    tyname(gettyp(ot)), tyname(tp));
 			} else {
 				/* conversion of %s to %s is out of range */
 				warning(119, tyname(gettyp(ot)), tyname(tp));
 			}
 		} else if (nv->v_quad != v->v_quad) {
-			if (op == ASSIGN && tp->t_isfield) {
+			if ((nt == CHAR || nt == UCHAR || nt == SCHAR) &&
+			    v->v_lspec == CHAR) {
+				/*
+				 * Don't warn when assigning a character
+				 * literal to any kind of character (signed,
+				 * unsigned, or unspecified).
+				 */
+			} else if (op == ASSIGN && tp->t_isfield) {
 				/* precision lost in bit-field assignment */
 				warning(166);
 			} else if (op == INIT && tp->t_isfield) {
@@ -2034,9 +2061,9 @@
 				/* case label affected by conversion */
 				warning(196);
 			} else if (op == FARG) {
-				/* conv. of %s to %s is out of rng., arg #%d */
-				warning(295, tyname(gettyp(ot)), tyname(tp),
-					arg);
+				/* %s arg #%d: conv. of %s to %s is out of rng. */
+				warning(295, funcname(farg->fa_func), arg,
+				    tyname(gettyp(ot)), tyname(tp));
 			} else {
 				/* conversion of %s to %s is out of range */
 				warning(119, tyname(gettyp(ot)), tyname(tp));
@@ -2223,9 +2250,8 @@
 	if (op == POINT) {
 		ln = bldamper(ln, 1);
 	} else if (ln->tn_type->t_tspec != PTR) {
-		if (!tflag || !isityp(ln->tn_type->t_tspec))
-			lerror("bldstr() 4");
-		ln = convert(NOOP, 0, tincref(gettyp(VOID), PTR), ln);
+		lerror("bldstr() 4");
+		ln = convert(NOOP, NULL, tincref(gettyp(VOID), PTR), ln);
 	}
 
 #if PTRDIFF_IS_LONG
@@ -2282,8 +2308,6 @@
 
 	if (!noign && ((t = tn->tn_type->t_tspec) == ARRAY || t == FUNC)) {
 		/* & before array or function: ignored */
-		if (tflag)
-			warning(127);
 		return (tn);
 	}
 
@@ -2322,7 +2346,7 @@
 
 		ctn = plength(ln->tn_type);
 		if (rn->tn_type->t_tspec != ctn->tn_type->t_tspec)
-			rn = convert(NOOP, 0, ctn->tn_type, rn);
+			rn = convert(NOOP, NULL, ctn->tn_type, rn);
 		rn = mktnode(MULT, rn->tn_type, rn, ctn);
 		if (rn->tn_left->tn_op == CON)
 			rn = fold(rn);
@@ -2362,7 +2386,7 @@
 	tnode_t	*ntn;
 
 	if ((t = rn->tn_type->t_tspec) != INT && t != UINT)
-		rn = convert(CVT, 0, gettyp(INT), rn);
+		rn = convert(CVT, NULL, gettyp(INT), rn);
 	ntn = mktnode(op, ln->tn_type, ln, rn);
 	return (ntn);
 }
@@ -2407,13 +2431,13 @@
 		rtp = ln->tn_type;
 	} else if (lt == PTR && isityp(rt)) {
 		if (rt != pdt) {
-			rn = convert(NOOP, 0, gettyp(pdt), rn);
+			rn = convert(NOOP, NULL, gettyp(pdt), rn);
 			rt = pdt;
 		}
 		rtp = ln->tn_type;
 	} else if (rt == PTR && isityp(lt)) {
 		if (lt != pdt) {
-			ln = convert(NOOP, 0, gettyp(pdt), ln);
+			ln = convert(NOOP, NULL, gettyp(pdt), ln);
 			lt = pdt;
 		}
 		rtp = rn->tn_type;
@@ -2432,7 +2456,7 @@
 			lerror("bldcol() 6");
 		/*
 		 * XXX For now we simply take the left type. This is
-		 * probably wrong, if one type contains a functionprototype
+		 * probably wrong, if one type contains a function prototype
 		 * and the other one, at the same place, only an old style
 		 * declaration.
 		 */
@@ -2465,7 +2489,7 @@
 			lerror("bldasgn() 2");
 		ctn = plength(ln->tn_type);
 		if (rn->tn_type->t_tspec != ctn->tn_type->t_tspec)
-			rn = convert(NOOP, 0, ctn->tn_type, rn);
+			rn = convert(NOOP, NULL, ctn->tn_type, rn);
 		rn = mktnode(MULT, rn->tn_type, rn, ctn);
 		if (rn->tn_left->tn_op == CON)
 			rn = fold(rn);
@@ -2488,14 +2512,14 @@
 
 	if (op == SHLASS || op == SHRASS) {
 		if (rt != INT) {
-			rn = convert(NOOP, 0, gettyp(INT), rn);
+			rn = convert(NOOP, NULL, gettyp(INT), rn);
 			rt = INT;
 		}
 	} else {
 		if (op == ASSIGN || lt != PTR) {
 			if (lt != rt ||
 			    (ln->tn_type->t_isfield && rn->tn_op == CON)) {
-				rn = convert(op, 0, ln->tn_type, rn);
+				rn = convert(op, NULL, ln->tn_type, rn);
 				rt = lt;
 			}
 		}
@@ -2507,6 +2531,49 @@
 }
 
 /*
+ * Check for division by zero.  Returns 1 if a division by zero is
+ * present, 0 otherwise.
+ */
+static int
+chkdbz(op_t op, tnode_t *rn)
+{
+	int code;
+
+	switch (op) {
+	case DIV:
+	case DIVASS:
+		code = 139;	/* division by 0 */
+		break;
+	case MOD:
+	case MODASS:
+		code = 140;	/* modular division by 0 */
+		break;
+	default:
+		return 0;
+	}
+
+	/* no way of checking unless right side is a constant */
+	if (rn->tn_op != CON)
+		return 0;
+
+	if (isftyp(rn->tn_type->t_tspec)) {
+		if (rn->tn_val->v_ldbl == 0.0) {
+			/* division by 0 */
+			warning(code);
+			return 1;
+		}
+	} else {
+		if (rn->tn_val->v_quad == 0) {
+			/* division by 0 */
+			warning(code);
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+/*
  * Get length of type tp->t_subt.
  */
 static tnode_t *
@@ -2575,20 +2642,6 @@
 	return (getinode(st, (quad_t)(elem * elsz / CHAR_BIT)));
 }
 
-#ifdef XXX_BROKEN_GCC
-static int
-quad_t_eq(quad_t x, quad_t y)
-{
-	return (x == y);
-}
-
-static int
-u_quad_t_eq(u_quad_t x, u_quad_t y)
-{
-	return (x == y);
-}
-#endif
-
 /*
  * Do only as much as necessary to compute constant expressions.
  * Called only if the operator allows folding and (both) operands
@@ -2632,18 +2685,14 @@
 			ovfl = 1;
 		break;
 	case DIV:
-		if (sr == 0) {
-			/* division by 0 */
-			error(139);
-			q = utyp ? UQUAD_MAX : QUAD_MAX;
+		if (chkdbz(tn->tn_op, tn->tn_right)) {
+			q = utyp ? 0U: 0;
 		} else {
 			q = utyp ? ul / ur : sl / sr;
 		}
 		break;
 	case MOD:
-		if (sr == 0) {
-			/* modulus by 0 */
-			error(140);
+		if (chkdbz(tn->tn_op, tn->tn_right)) {
 			q = 0;
 		} else {
 			q = utyp ? ul % ur : sl % sr;
@@ -2674,7 +2723,7 @@
 		break;
 	case SHR:
 		/*
-		 * The sign must be explizitly extended because
+		 * The sign must be explicitly extended because
 		 * shifts of signed values are implementation dependent.
 		 */
 		q = ul >> sr;
@@ -2693,11 +2742,7 @@
 		q = utyp ? ul > ur : sl > sr;
 		break;
 	case EQ:
-#ifdef XXX_BROKEN_GCC
-		q = utyp ? u_quad_t_eq(ul, ur) : quad_t_eq(sl, sr);
-#else
 		q = utyp ? ul == ur : sl == sr;
-#endif
 		break;
 	case NE:
 		q = utyp ? ul != ur : sl != sr;
@@ -2731,14 +2776,6 @@
 	return (cn);
 }
 
-#ifdef XXX_BROKEN_GCC
-int
-ldbl_t_neq(ldbl_t x, ldbl_t y)
-{
-	return (x != y);
-}
-#endif
-
 /*
  * Same for operators whose operands are compared with 0 (test context).
  */
@@ -2754,22 +2791,14 @@
 		lerror("foldtst() 1");
 
 	if (isftyp(tn->tn_left->tn_type->t_tspec)) {
-#ifdef XXX_BROKEN_GCC
-		l = ldbl_t_neq(tn->tn_left->tn_val->v_ldbl, 0.0);
-#else
 		l = tn->tn_left->tn_val->v_ldbl != 0.0;
-#endif
 	} else {
 		l = tn->tn_left->tn_val->v_quad != 0;
 	}
 
 	if (modtab[tn->tn_op].m_binary) {
 		if (isftyp(tn->tn_right->tn_type->t_tspec)) {
-#ifdef XXX_BROKEN_GCC
-			r = ldbl_t_neq(tn->tn_right->tn_val->v_ldbl, 0.0);
-#else
 			r = tn->tn_right->tn_val->v_ldbl != 0.0;
-#endif
 		} else {
 			r = tn->tn_right->tn_val->v_quad != 0;
 		}
@@ -2831,9 +2860,7 @@
 		v->v_ldbl = l * r;
 		break;
 	case DIV:
-		if (r == 0.0) {
-			/* division by 0 */
-			error(139);
+		if (chkdbz(tn->tn_op, tn->tn_right)) {
 			if (t == FLOAT) {
 				v->v_ldbl = l < 0 ? -FLT_MAX : FLT_MAX;
 			} else if (t == DOUBLE) {
@@ -2895,6 +2922,26 @@
 }
 
 /*
+ * Create a constant node for sizeof(term).
+ */
+tnode_t *
+bldszoftrm(tnode_t *tn)
+{
+	switch (tn->tn_op) {
+	case POINT:
+	case STAR:
+	case NAME:
+	case STRING:
+		break;
+	default:
+		warning(312, modtab[tn->tn_op].m_name);
+	}
+
+
+	return bldszof(tn->tn_type);
+}
+
+/*
  * Create a constant node for sizeof.
  */
 tnode_t *
@@ -3012,7 +3059,7 @@
 		return (NULL);
 	}
 
-	tn = convert(CVT, 0, tp, tn);
+	tn = convert(CVT, NULL, tp, tn);
 	tn->tn_cast = 1;
 
 	return (tn);
@@ -3060,6 +3107,9 @@
 		fcop = ICALL;
 	}
 
+	if (func->tn_sym->s_noreturn)
+		notreach(0);
+
 	/*
 	 * after cconv() func will always be a pointer to a function
 	 * if it is a valid function designator.
@@ -3073,7 +3123,7 @@
 		return (NULL);
 	}
 
-	args = chkfarg(func->tn_type->t_subt, args);
+	args = chkfarg(func, args);
 
 	ntn = mktnode(fcop, func->tn_type->t_subt->t_subt, func, args);
 
@@ -3083,15 +3133,22 @@
 /*
  * Check types of all function arguments and insert conversions,
  * if necessary.
+ *
+ * func: called function
+ * args: arguments to function
  */
 static tnode_t *
-chkfarg(type_t *ftp, tnode_t *args)
+chkfarg(tnode_t *func, tnode_t *args)
 {
+	type_t	*ftp;
 	tnode_t	*arg;
 	sym_t	*asym;
+	farg_t	farg;
 	tspec_t	at;
 	int	narg, npar, n, i;
 
+	ftp = func->tn_type->t_subt;
+
 	/* get # of args in the prototype */
 	npar = 0;
 	for (asym = ftp->t_args; asym != NULL; asym = asym->s_nxt)
@@ -3117,7 +3174,7 @@
 		 */
 		for (i = narg, arg = args; i > n; i--, arg = arg->tn_right) ;
 
-		/* some things which are always not allowd */
+		/* some things which are never allowed */
 		if ((at = arg->tn_left->tn_type->t_tspec) == VOID) {
 			/* void expressions may not be arguments, arg #%d */
 			error(151, n);
@@ -3135,9 +3192,11 @@
 
 		/* class conversions (arg in value context) */
 		arg->tn_left = cconv(arg->tn_left);
-
+		farg.fa_num = n;
+		farg.fa_sym = asym;
+		farg.fa_func = func;
 		if (asym != NULL) {
-			arg->tn_left = parg(n, asym->s_type, arg->tn_left);
+			arg->tn_left = parg(&farg, arg->tn_left);
 		} else {
 			arg->tn_left = promote(NOOP, 1, arg->tn_left);
 		}
@@ -3155,20 +3214,26 @@
  * prototype parameter. If it is a valid combination, but both types
  * are not the same, insert a conversion to convert the argument into
  * the type of the parameter.
+ *
+ * n:	position of arg
+ * tp:	expected type (from prototype)
+ * tn:	argument
  */
 static tnode_t *
-parg(int n, type_t *tp, tnode_t *tn)
+parg(farg_t *farg, tnode_t *tn)
 {
 	tnode_t	*ln;
+	type_t	*tp;
 	int	warn;
 
+	tp = farg->fa_sym->s_type;
 	ln = xcalloc(1, sizeof (tnode_t));
 	ln->tn_type = tduptyp(tp);
 	ln->tn_type->t_const = 0;
 	ln->tn_lvalue = 1;
-	if (typeok(FARG, n, ln, tn)) {
+	if (typeok(FARG, farg, ln, tn)) {
 		if (!eqtype(tp, tn->tn_type, 1, 0, (warn = 0, &warn)) || warn)
-			tn = convert(FARG, n, tp, tn);
+			tn = convert(FARG, farg, tp, tn);
 	}
 	free(ln);
 	return (tn);
@@ -3248,13 +3313,18 @@
 
 	chkmisc(tn, vctx, tctx, !tctx, 0, 0, 0);
 	if (tn->tn_op == ASSIGN) {
-		if (hflag && tctx)
+		if (hflag && tctx && !tn->tn_parn)
 			/* assignment in conditional context */
 			warning(159);
 	} else if (tn->tn_op == CON) {
-		if (hflag && tctx && !ccflg)
-			/* constant in conditional context */
-			warning(161);
+		if (hflag && tctx && !ccflg) {
+			if (!isityp(tn->tn_type->t_tspec) ||
+			    (tn->tn_val->v_quad != 0 &&
+			    tn->tn_val->v_quad != 1)) {
+				/* constant in conditional context */
+				warning(161);
+			}
+		}
 	}
 	if (!modtab[tn->tn_op].m_sideeff) {
 		/*
@@ -3276,48 +3346,58 @@
 {
 	if (!hflag)
 		return;
-
-	while (!modtab[tn->tn_op].m_sideeff) {
-		if (tn->tn_op == CVT && tn->tn_type->t_tspec == VOID) {
-			tn = tn->tn_left;
-		} else if (tn->tn_op == LOGAND || tn->tn_op == LOGOR) {
-			/*
-			 * && and || have a side effect if the right operand
-			 * has a side effect.
-			 */
-			tn = tn->tn_right;
-		} else if (tn->tn_op == QUEST) {
-			/*
-			 * ? has a side effect if at least one of its right
-			 * operands has a side effect
-			 */
-			tn = tn->tn_right;
-		} else if (tn->tn_op == COLON) {
-			/*
-			 * : has a side effect if at least one of its operands
-			 * has a side effect
-			 */
-			if (modtab[tn->tn_left->tn_op].m_sideeff) {
-				tn = tn->tn_left;
-			} else if (modtab[tn->tn_right->tn_op].m_sideeff) {
-				tn = tn->tn_right;
-			} else {
-				break;
-			}
-		} else {
-			break;
-		}
-	}
-	if (!modtab[tn->tn_op].m_sideeff)
+	if (nulleffexpr(tn)) {
 		/* expression has null effect */
 		warning(129);
+	}
+}
+
+static int
+nulleffexpr(tnode_t *tn)
+{
+	int r1, r2;
+
+	if (modtab[tn->tn_op].m_sideeff)
+		return (0);
+
+	switch (tn->tn_op) {
+	case CVT:
+		if (tn->tn_type->t_tspec == VOID)
+			return (0);
+		else
+			return (nulleffexpr(tn->tn_left));
+	case LOGAND:
+	case LOGOR:
+		/*
+		 * && and || have a null effect if the right operand
+		 * has null effect.
+		 */
+		return (nulleffexpr(tn->tn_right));
+	case QUEST:
+		/*
+		 * ? has null effect if both of its right * operands
+		 * have null effect
+		 */
+		return (nulleffexpr(tn->tn_right));
+	case COLON:
+	case COMMA:
+		/*
+		 * : and , have null effect if both of the operands have
+		 * null effect
+		 */
+		r1 = nulleffexpr(tn->tn_left);
+		r2 = nulleffexpr(tn->tn_right);
+		return (r1 && r2);
+	default:
+		return (1);
+	}
 }
 
 /*
  * Dump an expression to stdout
  * only used for debugging
  */
-static void
+void
 displexpr(tnode_t *tn, int offs)
 {
 	u_quad_t uq;
@@ -3375,7 +3455,7 @@
 /* ARGSUSED */
 void
 chkmisc(tnode_t *tn, int vctx, int tctx, int eqwarn, int fcall, int rvdisc,
-	int szof)
+    int szof)
 {
 	tnode_t	*ln, *rn;
 	mod_t	*mp;
@@ -3425,7 +3505,7 @@
 		if (ln->tn_op == NAME && (reached || rchflg)) {
 			sc = ln->tn_sym->s_scl;
 			/*
-			 * Look if there was a asm statement in one of the
+			 * Look if there was an asm statement in one of the
 			 * compound statements we are in. If not, we don't
 			 * print a warning.
 			 */
@@ -3468,8 +3548,6 @@
 	case STRING:
 		return;
 		/* LINTED (enumeration values not handled in switch) */
-	default:
-		break;
 	}
 
 	cvctx = mp->m_vctx;
@@ -3508,7 +3586,7 @@
 /*
  * Checks the range of array indices, if possible.
  * amper is set if only the address of the element is used. This
- * means that the index is allowd to refere to the first element
+ * means that the index is allowd to refer to the first element
  * after the array.
  */
 static void
@@ -3565,7 +3643,7 @@
 }
 
 /*
- * Check for ordered comparisions of unsigned values with 0.
+ * Check for ordered comparisons of unsigned values with 0.
  */
 static void
 chkcomp(op_t op, tnode_t *ln, tnode_t *rn)
@@ -3586,25 +3664,25 @@
 	if ((hflag || pflag) && lt == CHAR && rn->tn_op == CON &&
 	    (rn->tn_val->v_quad < 0 ||
 	     rn->tn_val->v_quad > ~(~0 << (CHAR_BIT - 1)))) {
-		/* nonportable character comparision, op %s */
+		/* nonportable character comparison, op %s */
 		warning(230, mp->m_name);
 		return;
 	}
 	if ((hflag || pflag) && rt == CHAR && ln->tn_op == CON &&
 	    (ln->tn_val->v_quad < 0 ||
 	     ln->tn_val->v_quad > ~(~0 << (CHAR_BIT - 1)))) {
-		/* nonportable character comparision, op %s */
+		/* nonportable character comparison, op %s */
 		warning(230, mp->m_name);
 		return;
 	}
 	if (isutyp(lt) && !isutyp(rt) &&
 	    rn->tn_op == CON && rn->tn_val->v_quad <= 0) {
 		if (rn->tn_val->v_quad < 0) {
-			/* comparision of %s with %s, op %s */
+			/* comparison of %s with %s, op %s */
 			warning(162, tyname(ln->tn_type), "negative constant",
 				mp->m_name);
 		} else if (op == LT || op == GE || (hflag && op == LE)) {
-			/* comparision of %s with %s, op %s */
+			/* comparison of %s with %s, op %s */
 			warning(162, tyname(ln->tn_type), "0", mp->m_name);
 		}
 		return;
@@ -3612,11 +3690,11 @@
 	if (isutyp(rt) && !isutyp(lt) &&
 	    ln->tn_op == CON && ln->tn_val->v_quad <= 0) {
 		if (ln->tn_val->v_quad < 0) {
-			/* comparision of %s with %s, op %s */
+			/* comparison of %s with %s, op %s */
 			warning(162, "negative constant", tyname(rn->tn_type),
 				mp->m_name);
 		} else if (op == GT || op == LE || (hflag && op == GE)) {
-			/* comparision of %s with %s, op %s */
+			/* comparison of %s with %s, op %s */
 			warning(162, "0", tyname(rn->tn_type), mp->m_name);
 		}
 		return;
@@ -3624,7 +3702,7 @@
 }
 
 /*
- * Takes an expression an returns 0 if this expression can be used
+ * Takes an expression and returns 0 if this expression can be used
  * for static initialisation, otherwise -1.
  *
  * Constant initialisation expressions must be costant or an address
@@ -3722,6 +3800,7 @@
 			     (len2 + 1) * sizeof (wchar_t));
 		free(strg2->st_wcp);
 	}
+	strg1->st_len = len;
 	free(strg2);
 
 	return (strg1);
@@ -3738,7 +3817,7 @@
 precconf(tnode_t *tn)
 {
 	tnode_t	*ln, *rn;
-	op_t	lop, rop;
+	op_t	lop, rop = NOOP;
 	int	lparn, rparn;
 	mod_t	*mp;
 	int	warn;
@@ -3799,8 +3878,6 @@
 		}
 		break;
 		/* LINTED (enumeration values not handled in switch) */
-	default:
-		break;
 	}
 
 	if (warn) {
@@ -3809,3 +3886,26 @@
 	}
 
 }
+
+/*
+ * Return the function name of a function (or of a pointer to a
+ * function).
+ */
+const char *
+funcname(tnode_t *tn)
+{
+	/* dereference function pointer */
+	switch (tn->tn_op) {
+	case AMPER:
+		return funcname(tn->tn_left);
+	case LOAD:
+		/* called as (*fptr)(args) */
+		return funcname(tn->tn_left);
+	case CALL:
+		return funcname(tn->tn_left);
+	case NAME:
+		return tn->tn_sym->s_name;
+	default:
+		return "<unknown>";
+	}
+}
Index: usr.bin/xlint/lint2/chk.c
===================================================================
RCS file: /home/dcvs/src/usr.bin/xlint/lint2/chk.c,v
retrieving revision 1.7
diff -u -r1.7 chk.c
--- usr.bin/xlint/lint2/chk.c	7 Jul 2004 12:24:01 -0000	1.7
+++ usr.bin/xlint/lint2/chk.c	25 Dec 2006 10:32:15 -0000
@@ -1,3 +1,4 @@
+/*	$OpenBSD: chk.c,v 1.15 2006/07/09 19:37:00 miod Exp $	*/
 /*	$NetBSD: chk.c,v 1.2 1995/07/03 21:24:42 cgd Exp $	*/
 
 /*
@@ -30,7 +31,6 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $NetBSD: chk.c,v 1.2 1995/07/03 21:24:42 cgd Exp $
  * $DragonFly: src/usr.bin/xlint/lint2/chk.c,v 1.7 2004/07/07 12:24:01 asmodai Exp $
  */
 
@@ -53,13 +53,11 @@
 static	void	chkvtdi(hte_t *, sym_t *, sym_t *);
 static	void	chkfaui(hte_t *, sym_t *, sym_t *);
 static	void	chkau(hte_t *, int, sym_t *, sym_t *, pos_t *,
-			   fcall_t *, fcall_t *, type_t *, type_t *);
+		   fcall_t *, fcall_t *, type_t *, type_t *);
 static	void	chkrvu(hte_t *, sym_t *);
 static	void	chkadecl(hte_t *, sym_t *, sym_t *);
-static	void	printflike(hte_t *,fcall_t *, int,
-				const char *, type_t **);
-static	void	scanflike(hte_t *, fcall_t *, int,
-			       const char *, type_t **);
+static	void	printflike(hte_t *,fcall_t *, int, const char *, type_t **);
+static	void	scanflike(hte_t *, fcall_t *, int, const char *, type_t **);
 static	void	badfmt(hte_t *, fcall_t *);
 static	void	inconarg(hte_t *, fcall_t *, int);
 static	void	tofewarg(hte_t *, fcall_t *);
@@ -77,73 +75,73 @@
 		tspec_t	it_tspec;
 		ttab_t	it_ttab;
 	} ittab[] = {
-		{ SIGNED,   { 0, 0,
+		{ SIGNED,   { 0, 0, 0,
 				      SIGNED, UNSIGN,
 				      0, 0, 0, 0, 0, "signed" } },
-		{ UNSIGN,   { 0, 0,
+		{ UNSIGN,   { 0, 0, 0,
 				      SIGNED, UNSIGN,
 				      0, 0, 0, 0, 0, "unsigned" } },
-		{ CHAR,	    { CHAR_BIT, CHAR_BIT,
+		{ CHAR,	    { CHAR_BIT, CHAR_BIT, 20,
 				      SCHAR, UCHAR,
 				      1, 0, 0, 1, 1, "char" } },
-		{ SCHAR,    { CHAR_BIT, CHAR_BIT,
+		{ SCHAR,    { CHAR_BIT, CHAR_BIT, 20,
 				      SCHAR, UCHAR,
 				      1, 0, 0, 1, 1, "signed char" } },
-		{ UCHAR,    { CHAR_BIT, CHAR_BIT,
+		{ UCHAR,    { CHAR_BIT, CHAR_BIT, 20,
 				      SCHAR, UCHAR,
 				      1, 1, 0, 1, 1, "unsigned char" } },
-		{ SHORT,    { sizeof (short) * CHAR_BIT, 2 * CHAR_BIT,
+		{ SHORT,    { sizeof (short) * CHAR_BIT, 2 * CHAR_BIT, 30,
 				      SHORT, USHORT,
 				      1, 0, 0, 1, 1, "short" } },
-		{ USHORT,   { sizeof (u_short) * CHAR_BIT, 2 * CHAR_BIT,
+		{ USHORT,   { sizeof (u_short) * CHAR_BIT, 2 * CHAR_BIT, 30,
 				      SHORT, USHORT,
 				      1, 1, 0, 1, 1, "unsigned short" } },
-		{ INT,      { sizeof (int) * CHAR_BIT, 3 * CHAR_BIT,
+		{ INT,      { sizeof (int) * CHAR_BIT, 3 * CHAR_BIT, 40,
 				      INT, UINT,
 				      1, 0, 0, 1, 1, "int" } },
-		{ UINT,     { sizeof (u_int) * CHAR_BIT, 3 * CHAR_BIT,
+		{ UINT,     { sizeof (u_int) * CHAR_BIT, 3 * CHAR_BIT, 40,
 				      INT, UINT,
 				      1, 1, 0, 1, 1, "unsigned int" } },
-		{ LONG,     { sizeof (long) * CHAR_BIT, 4 * CHAR_BIT,
+		{ LONG,     { sizeof (long) * CHAR_BIT, 4 * CHAR_BIT, 50,
 				      LONG, ULONG,
 				      1, 0, 0, 1, 1, "long" } },
-		{ ULONG,    { sizeof (u_long) * CHAR_BIT, 4 * CHAR_BIT,
+		{ ULONG,    { sizeof (u_long) * CHAR_BIT, 4 * CHAR_BIT, 50,
 				      LONG, ULONG,
 				      1, 1, 0, 1, 1, "unsigned long" } },
-		{ QUAD,     { sizeof (quad_t) * CHAR_BIT, 8 * CHAR_BIT,
+		{ QUAD,     { sizeof (quad_t) * CHAR_BIT, 8 * CHAR_BIT, 60,
 				      QUAD, UQUAD,
 				      1, 0, 0, 1, 1, "long long" } },
-		{ UQUAD,    { sizeof (u_quad_t) * CHAR_BIT, 8 * CHAR_BIT,
+		{ UQUAD,    { sizeof (u_quad_t) * CHAR_BIT, 8 * CHAR_BIT, 60,
 				      QUAD, UQUAD,
 				      1, 1, 0, 1, 1, "unsigned long long" } },
-		{ FLOAT,    { sizeof (float) * CHAR_BIT, 4 * CHAR_BIT,
+		{ FLOAT,    { sizeof (float) * CHAR_BIT, 4 * CHAR_BIT, -1,
 				      FLOAT, FLOAT,
 				      0, 0, 1, 1, 1, "float" } },
-		{ DOUBLE,   { sizeof (double) * CHAR_BIT, 8 * CHAR_BIT,
+		{ DOUBLE,   { sizeof (double) * CHAR_BIT, 8 * CHAR_BIT, -1,
 				      DOUBLE, DOUBLE,
 				      0, 0, 1, 1, 1, "double" } },
-		{ LDOUBLE,  { sizeof (ldbl_t) * CHAR_BIT, 10 * CHAR_BIT,
+		{ LDOUBLE,  { sizeof (ldbl_t) * CHAR_BIT, 10 * CHAR_BIT, -1,
 				      LDOUBLE, LDOUBLE,
 				      0, 0, 1, 1, 1, "long double" } },
-		{ VOID,     { -1, -1,
+		{ VOID,     { -1, -1, -1,
 				      VOID, VOID,
 				      0, 0, 0, 0, 0, "void" } },
-		{ STRUCT,   { -1, -1,
+		{ STRUCT,   { -1, -1, -1,
 				      STRUCT, STRUCT,
 				      0, 0, 0, 0, 0, "struct" } },
-		{ UNION,    { -1, -1,
+		{ UNION,    { -1, -1, -1,
 				      UNION, UNION,
 				      0, 0, 0, 0, 0, "union" } },
-		{ ENUM,     { sizeof (int) * CHAR_BIT, 3 * CHAR_BIT,
+		{ ENUM,     { sizeof (int) * CHAR_BIT, 3 * CHAR_BIT, 40,
 				      ENUM, ENUM,
 				      1, 0, 0, 1, 1, "enum" } },
-		{ PTR,      { sizeof (void *) * CHAR_BIT, 4 * CHAR_BIT,
+		{ PTR,      { sizeof (void *) * CHAR_BIT, 4 * CHAR_BIT, -1,
 				      PTR, PTR,
 				      0, 1, 0, 0, 1, "pointer" } },
-		{ ARRAY,    { -1, -1,
+		{ ARRAY,    { -1, -1, -1,
 				      ARRAY, ARRAY,
 				      0, 0, 0, 0, 0, "array" } },
-		{ FUNC,     { -1, -1,
+		{ FUNC,     { -1, -1, -1,
 				      FUNC, FUNC,
 				      0, 0, 0, 0, 0, "function" } },
 	};
@@ -227,11 +225,11 @@
 		return;
 
 	if ((fcall = hte->h_calls) != NULL) {
-		/* %s used( %s ), but not defined */
-		msg(0, hte->h_name, mkpos(&fcall->f_pos));
+		/* %s: %s used, but not defined */
+		msg(0, mkpos(&fcall->f_pos), hte->h_name);
 	} else if ((usym = hte->h_usyms) != NULL) {
-		/* %s used( %s ), but not defined */
-		msg(0, hte->h_name, mkpos(&usym->u_pos));
+		/* %s: %s used, but not defined */
+		msg(0, mkpos(&usym->u_pos), hte->h_name);
 	}
 }
 
@@ -248,8 +246,8 @@
 
 	for (sym = hte->h_syms; sym != NULL; sym = sym->s_nxt) {
 		if (sym->s_def == DEF || sym->s_def == TDEF) {
-			/* %s defined( %s ), but never used */
-			msg(1, hte->h_name, mkpos(&sym->s_pos));
+			/* %s: %s defined, but never used */
+			msg(1, mkpos(&sym->s_pos), hte->h_name);
 			break;
 		}
 	}
@@ -270,13 +268,19 @@
 	if ((sym = hte->h_syms) != NULL) {
 		if (sym->s_def != DECL)
 			errx(1, "internal error: chkdnud() 1");
-		/* %s declared( %s ), but never used or defined */
-		msg(2, hte->h_name, mkpos(&sym->s_pos));
+
+		/* don't warn if the name was declared in a separate header */
+		if (sym->s_pos.p_src != sym->s_pos.p_isrc) {
+			return;
+		}
+
+		/* %s: %s declared, but never used or defined */
+		msg(2, mkpos(&sym->s_pos), hte->h_name);
 	}
 }
 
 /*
- * Print a warning if there is more then one definition for
+ * Print a warning if there is more than one definition for
  * this name.
  */
 static void
@@ -301,8 +305,8 @@
 			continue;
 		}
 		pos1 = xstrdup(mkpos(&def1->s_pos));
-		/* %s multiply defined\t%s  ::  %s */
-		msg(3, hte->h_name, pos1, mkpos(&sym->s_pos));
+		/* %s: %s multiply defined (%s) */
+		msg(3, pos1, hte->h_name, mkpos(&sym->s_pos));
 		free(pos1);
 	}
 }
@@ -356,17 +360,17 @@
 				 * accepted for now.
 				 */
 				pos1 = xstrdup(mkpos(&def->s_pos));
-				/* %s value must be decl. before use %s :: %s */
-				msg(17, hte->h_name,
-				    pos1, mkpos(&call->f_pos));
+				/* %s: %s must be decl. before use (%s) */
+				msg(17, pos1, hte->h_name,
+				    mkpos(&call->f_pos));
 				free(pos1);
 			}
 			continue;
 		}
 		if (!eq || (sflag && warn)) {
 			pos1 = xstrdup(mkpos(&def->s_pos));
-			/* %s value used inconsistenty\t%s  ::  %s */
-			msg(4, hte->h_name, pos1, mkpos(&call->f_pos));
+			/* %s: %s used inconsistently (%s) */
+			msg(4, pos1, hte->h_name, mkpos(&call->f_pos));
 			free(pos1);
 		}
 	}
@@ -404,8 +408,8 @@
 		}
 		if (!eq || (sflag && warn)) {
 			pos1 = xstrdup(mkpos(&def->s_pos));
-			/* %s value declared inconsistently\t%s  ::  %s */
-			msg(5, hte->h_name, pos1, mkpos(&sym->s_pos));
+			/* %s: %s declared inconsistently (%s) */
+			msg(5, pos1, hte->h_name, mkpos(&sym->s_pos));
 			free(pos1);
 		}
 	}
@@ -430,7 +434,7 @@
 		return;
 
 	/*
-	 * If we find a function definition, we use this for comparision,
+	 * If we find a function definition, we use this for comparison,
 	 * otherwise the first prototype we can find. If there is no
 	 * definition or prototype declaration, the first function call
 	 * is used.
@@ -486,8 +490,8 @@
 			 */
 		} else {
 			pos1 = xstrdup(mkpos(pos1p));
-			/* %s: variable # of args\t%s  ::  %s */
-			msg(7, hte->h_name, pos1, mkpos(&call->f_pos));
+			/* %s: %s called with varying # of args (%s) */
+			msg(7, pos1, hte->h_name, mkpos(&call->f_pos));
 			free(pos1);
 			continue;
 		}
@@ -526,7 +530,7 @@
  */
 static void
 chkau(hte_t *hte, int n, sym_t *def, sym_t *decl, pos_t *pos1p,
-      fcall_t *call1, fcall_t *call, type_t *arg1, type_t *arg2)
+    fcall_t *call1, fcall_t *call, type_t *arg1, type_t *arg2)
 {
 	/* LINTED (automatic hides external declaration: warn) */
 	int	promote, asgn, warn;
@@ -589,12 +593,12 @@
 			} else if (t1 == CHAR || t1 == SCHAR) {
 				t1 = INT;
 			} else if (t1 == UCHAR) {
-				t1 = tflag ? UINT : INT;
+				t1 = INT;
 			} else if (t1 == SHORT) {
 				t1 = INT;
 			} else if (t1 == USHORT) {
 				/* CONSTCOND */
-				t1 = INT_MAX < USHRT_MAX || tflag ? UINT : INT;
+				t1 = INT_MAX < USHRT_MAX ? UINT : INT;
 			}
 		}
 
@@ -663,8 +667,8 @@
 	}
 
 	pos1 = xstrdup(mkpos(pos1p));
-	/* %s, arg %d used inconsistently\t%s  ::  %s */
-	msg(6, hte->h_name, n, pos1, mkpos(&call->f_pos));
+	/* %s: %s arg %d used inconsistently (%s) */
+	msg(6, pos1, hte->h_name, n, mkpos(&call->f_pos));
 	free(pos1);
 }
 
@@ -678,7 +682,7 @@
 	const	char *fp;
 	int	fc;
 	int	fwidth, prec, left, sign, space, alt, zero;
-	tspec_t	sz, t1, t2;
+	tspec_t	sz, t1, t2 = NOTSPEC;
 	type_t	*tp;
 
 	fp = fmt;
@@ -836,8 +840,8 @@
 					inconarg(hte, call, n);
 			}
 		} else if (fc == 'D' || fc == 'O' || fc == 'U') {
-			if ((alt && fc != 'O') || sz != NOTSPEC || !tflag)
-				badfmt(hte, call);
+			/* DOU are deprecated */
+			badfmt(hte, call);
 			sz = LONG;
 			if (fc == 'D') {
 				goto int_conv;
@@ -903,7 +907,7 @@
 	const	char *fp;
 	int	fc;
 	int	noasgn, fwidth;
-	tspec_t	sz, t1, t2;
+	tspec_t	sz, t1 = NOTSPEC, t2 = NOTSPEC;
 	type_t	*tp;
 
 	fp = fmt;
@@ -994,13 +998,11 @@
 			}
 			goto conv;
 		} else if (fc == 'D') {
-			if (sz != NOTSPEC || !tflag)
-				badfmt(hte, call);
+			badfmt(hte, call);
 			sz = LONG;
 			goto conv;
 		} else if (fc == 'O') {
-			if (sz != NOTSPEC || !tflag)
-				badfmt(hte, call);
+			badfmt(hte, call);
 			sz = ULONG;
 			goto conv;
 		} else if (fc == 'X') {
@@ -1008,8 +1010,7 @@
 			 * XXX valid in ANSI C, but in NetBSD's libc imple-
 			 * mented as "lx". Thats why it should be avoided.
 			 */
-			if (sz != NOTSPEC || !tflag)
-				badfmt(hte, call);
+			badfmt(hte, call);
 			sz = ULONG;
 			goto conv;
 		} else if (fc == 'E') {
@@ -1017,14 +1018,12 @@
 			 * XXX valid in ANSI C, but in NetBSD's libc imple-
 			 * mented as "lf". Thats why it should be avoided.
 			 */
-			if (sz != NOTSPEC || !tflag)
-				badfmt(hte, call);
+			badfmt(hte, call);
 			sz = DOUBLE;
 			goto conv;
 		} else if (fc == 'F') {
 			/* XXX only for backward compatibility */
-			if (sz != NOTSPEC || !tflag)
-				badfmt(hte, call);
+			badfmt(hte, call);
 			sz = DOUBLE;
 			goto conv;
 		} else if (fc == 'G') {
@@ -1091,29 +1090,29 @@
 static void
 badfmt(hte_t *hte, fcall_t *call)
 {
-	/* %s: malformed format string\t%s */
-	msg(13, hte->h_name, mkpos(&call->f_pos));
+	/* %s: malformed format string argument to %s */
+	msg(13, mkpos(&call->f_pos), hte->h_name);
 }
 
 static void
 inconarg(hte_t *hte, fcall_t *call, int n)
 {
-	/* %s, arg %d inconsistent with format\t%s(%d) */
-	msg(14, hte->h_name, n, mkpos(&call->f_pos));
+	/* %s: arg %d to %s is inconsistent with format */
+	msg(14, mkpos(&call->f_pos), n, hte->h_name);
 }
 
 static void
 tofewarg(hte_t *hte, fcall_t *call)
 {
-	/* %s: too few args for format  \t%s */
-	msg(15, hte->h_name, mkpos(&call->f_pos));
+	/* %s: too few format args to %s */
+	msg(15, mkpos(&call->f_pos), hte->h_name);
 }
 
 static void
 tomanyarg(hte_t *hte, fcall_t *call)
 {
-	/* %s: too many args for format  \t%s */
-	msg(16, hte->h_name, mkpos(&call->f_pos));
+	/* %s: too many format args to %s */
+	msg(16, mkpos(&call->f_pos), hte->h_name);
 }
 
 
@@ -1138,7 +1137,7 @@
 		/* function has return value */
 		used = ignored = 0;
 		for (call = hte->h_calls; call != NULL; call = call->f_nxt) {
-			used |= call->f_rused;
+			used |= call->f_rused || call->f_rdisc;
 			ignored |= !call->f_rused && !call->f_rdisc;
 		}
 		/*
@@ -1160,8 +1159,8 @@
 		/* function has no return value */
 		for (call = hte->h_calls; call != NULL; call = call->f_nxt) {
 			if (call->f_rused)
-				/* %s value is used( %s ), but none ret. */
-				msg(10, hte->h_name, mkpos(&call->f_pos));
+				/* %s: return value of %s is used, but none ret. */
+				msg(10, mkpos(&call->f_pos), hte->h_name);
 		}
 	}
 }
@@ -1208,8 +1207,8 @@
 			if (!eq || warn) {
 				pos1 = xstrdup(mkpos(&sym1->s_pos));
 				pos2 = mkpos(&sym->s_pos);
-				/* %s, arg %d declared inconsistently ... */
-				msg(11, hte->h_name, n + 1, pos1, pos2);
+				/* %s: %s arg %d declared inconsistently ... */
+				msg(11, pos1, hte->h_name, n + 1, pos2);
 				free(pos1);
 			}
 			n++;
@@ -1226,9 +1225,9 @@
 				continue;
 			}
 		}
-		/* %s: variable # of args declared\t%s  ::  %s */
+		/* %s: %s declared with varying # of args (%s) */
 		pos1 = xstrdup(mkpos(&sym1->s_pos));
-		msg(12, hte->h_name, pos1, mkpos(&sym->s_pos));
+		msg(12, pos1, hte->h_name, mkpos(&sym->s_pos));
 		free(pos1);
 	}
 }
@@ -1240,8 +1239,8 @@
  *
  * ignqual	if set, ignore qualifiers of outhermost type; used for
  *		function arguments
- * promote	if set, promote left type before comparision; used for
- *		comparisions of arguments with parameters of old style
+ * promote	if set, promote left type before comparison; used for
+ *		comparisons of arguments with parameters of old style
  *		definitions
  * asgn		left indirected type must have at least the same qualifiers
  *		like right indirected type (for assignments and function
@@ -1267,12 +1266,12 @@
 			} else if (t == CHAR || t == SCHAR) {
 				t = INT;
 			} else if (t == UCHAR) {
-				t = tflag ? UINT : INT;
+				t = INT;
 			} else if (t == SHORT) {
 				t = INT;
 			} else if (t == USHORT) {
 				/* CONSTCOND */
-				t = INT_MAX < USHRT_MAX || tflag ? UINT : INT;
+				t = INT_MAX < USHRT_MAX ? UINT : INT;
 			}
 		}
 
@@ -1312,7 +1311,7 @@
 				return (0);
 			if (!tp1->t_volatile && tp2->t_volatile)
 				return (0);
-		} else if (!ignqual && !tflag) {
+		} else if (!ignqual) {
 			if (tp1->t_const != tp2->t_const)
 				return (0);
 			if (tp1->t_const != tp2->t_const)
Index: usr.bin/xlint/lint2/emit2.c
===================================================================
RCS file: /home/dcvs/src/usr.bin/xlint/lint2/emit2.c,v
retrieving revision 1.5
diff -u -r1.5 emit2.c
--- usr.bin/xlint/lint2/emit2.c	7 Jul 2004 12:13:26 -0000	1.5
+++ usr.bin/xlint/lint2/emit2.c	25 Dec 2006 10:34:34 -0000
@@ -1,3 +1,4 @@
+/*	$OpenBSD: emit2.c,v 1.5 2005/11/20 17:09:55 cloder Exp $	*/
 /*	$NetBSD: emit2.c,v 1.2 1995/07/03 21:24:44 cgd Exp $	*/
 
 /*
@@ -30,7 +31,6 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $NetBSD: emit2.c,v 1.2 1995/07/03 21:24:44 cgd Exp $
  * $DragonFly: src/usr.bin/xlint/lint2/emit2.c,v 1.5 2004/07/07 12:13:26 asmodai Exp $
  */
 
@@ -186,7 +186,7 @@
 
 	/*
 	 * If there is a definition, write it. Otherwise write a tentative
-	 * definition. This is neccessary because more than one tentative
+	 * definition. This is necessary because more than one tentative
 	 * definition is allowed (except with sflag).
 	 */
 	def = NULL;
Index: usr.bin/xlint/lint2/externs2.h
===================================================================
RCS file: /home/dcvs/src/usr.bin/xlint/lint2/externs2.h,v
retrieving revision 1.3
diff -u -r1.3 externs2.h
--- usr.bin/xlint/lint2/externs2.h	3 Nov 2003 19:31:34 -0000	1.3
+++ usr.bin/xlint/lint2/externs2.h	25 Dec 2006 10:35:04 -0000
@@ -1,3 +1,4 @@
+/*	$OpenBSD: externs2.h,v 1.6 2006/05/29 20:47:22 cloder Exp $	*/
 /*	$NetBSD: externs2.h,v 1.2 1995/07/03 21:24:46 cgd Exp $	*/
 
 /*
@@ -42,7 +43,6 @@
 extern	const	char *libname;
 extern	int	pflag;
 extern	int	sflag;
-extern	int	tflag;
 extern	int	Hflag;
 extern	int	hflag;
 extern	int	Fflag;
@@ -60,6 +60,7 @@
  */
 extern	const	char **fnames;
 extern	type_t	**tlst;
+extern	int	csrcfile;
 
 extern	void	readfile(const char *);
 extern	void	mkstatic(hte_t *);
Index: usr.bin/xlint/lint2/hash.c
===================================================================
RCS file: /home/dcvs/src/usr.bin/xlint/lint2/hash.c,v
retrieving revision 1.5
diff -u -r1.5 hash.c
--- usr.bin/xlint/lint2/hash.c	7 Jul 2004 12:13:26 -0000	1.5
+++ usr.bin/xlint/lint2/hash.c	25 Dec 2006 10:35:45 -0000
@@ -1,3 +1,4 @@
+/*	$OpenBSD: hash.c,v 1.5 2005/11/20 17:09:55 cloder Exp $	*/
 /*	$NetBSD: hash.c,v 1.2 1995/07/03 21:24:47 cgd Exp $	*/
 
 /*
@@ -30,7 +31,6 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $NetBSD: hash.c,v 1.2 1995/07/03 21:24:47 cgd Exp $
  * $DragonFly: src/usr.bin/xlint/lint2/hash.c,v 1.5 2004/07/07 12:13:26 asmodai Exp $
  */
 
@@ -92,6 +92,7 @@
 
 	/* create a new hte */
 	hte = xalloc(sizeof (hte_t));
+	memset(hte, 0, sizeof (hte_t));
 	hte->h_name = xstrdup(s);
 	hte->h_lsym = &hte->h_syms;
 	hte->h_lcall = &hte->h_calls;
Index: usr.bin/xlint/lint2/main2.c
===================================================================
RCS file: /home/dcvs/src/usr.bin/xlint/lint2/main2.c,v
retrieving revision 1.6
diff -u -r1.6 main2.c
--- usr.bin/xlint/lint2/main2.c	7 Jul 2004 12:24:01 -0000	1.6
+++ usr.bin/xlint/lint2/main2.c	25 Dec 2006 10:37:56 -0000
@@ -1,3 +1,4 @@
+/*	$OpenBSD: main2.c,v 1.9 2006/05/29 20:47:22 cloder Exp $	*/
 /*	$NetBSD: main2.c,v 1.2 1995/07/03 21:24:53 cgd Exp $	*/
 
 /*
@@ -30,7 +31,6 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $NetBSD: main2.c,v 1.2 1995/07/03 21:24:53 cgd Exp $
  * $DragonFly: src/usr.bin/xlint/lint2/main2.c,v 1.6 2004/07/07 12:24:01 asmodai Exp $
  */
 
@@ -57,13 +57,11 @@
 int	pflag;
 
 /*
- * warnings for (tentative) definitions of the same name in more then
+ * warnings for (tentative) definitions of the same name in more than
  * one translation unit
  */
 int	sflag;
 
-int	tflag;
-
 /*
  * If a complaint stems from a included file, print the name of the included
  * file instead of the name spezified at the command line followed by '?'
@@ -73,7 +71,7 @@
 int	hflag;
 
 /* Print full path names, not only the last component */
-int	Fflag;
+int	Fflag = 1;
 
 /*
  * List of libraries (from -l flag). These libraries are read after all
@@ -100,9 +98,6 @@
 		case 's':
 			sflag = 1;
 			break;
-		case 't':
-			tflag = 1;
-			break;
 		case 'u':
 			uflag = 0;
 			break;
@@ -115,7 +110,7 @@
 		case 'C':
 			len = strlen(optarg);
 			lname = xmalloc(len + 10);
-			(void)sprintf(lname, "llib-l%s.ln", optarg);
+			(void)snprintf(lname, len + 10, "llib-l%s.ln", optarg);
 			libname = lname;
 			Cflag = 1;
 			uflag = 0;
Index: usr.bin/xlint/lint2/mem2.c
===================================================================
RCS file: /home/dcvs/src/usr.bin/xlint/lint2/mem2.c,v
retrieving revision 1.3
diff -u -r1.3 mem2.c
--- usr.bin/xlint/lint2/mem2.c	7 Jul 2004 12:13:26 -0000	1.3
+++ usr.bin/xlint/lint2/mem2.c	25 Dec 2006 10:38:29 -0000
@@ -1,3 +1,4 @@
+/*	$OpenBSD: mem2.c,v 1.4 2005/11/20 17:09:55 cloder Exp $	*/
 /*	$NetBSD: mem2.c,v 1.3 1995/10/02 17:27:11 jpo Exp $	*/
 
 /*
@@ -79,7 +80,7 @@
 		prot = PROT_READ | PROT_WRITE;
 		flags = MAP_ANON | MAP_PRIVATE;
 		mbuf = mmap(NULL, mblklen, prot, flags, -1, (off_t)0);
-		if (mbuf == (void *)MAP_FAILED)
+		if (mbuf == MAP_FAILED)
 			err(1, "can't map memory");
 		if (ALIGN((u_long)mbuf) != (u_long)mbuf)
 			errx(1, "mapped address is not aligned");
Index: usr.bin/xlint/lint2/msg.c
===================================================================
RCS file: /home/dcvs/src/usr.bin/xlint/lint2/msg.c,v
retrieving revision 1.7
diff -u -r1.7 msg.c
--- usr.bin/xlint/lint2/msg.c	7 Jul 2004 12:24:01 -0000	1.7
+++ usr.bin/xlint/lint2/msg.c	25 Dec 2006 10:39:35 -0000
@@ -1,3 +1,4 @@
+/*	$OpenBSD: msg.c,v 1.8 2005/12/10 20:26:10 cloder Exp $	*/
 /*	$NetBSD: msg.c,v 1.2 1995/07/03 21:24:56 cgd Exp $	*/
 
 /*
@@ -30,7 +31,6 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $NetBSD: msg.c,v 1.2 1995/07/03 21:24:56 cgd Exp $
  * $DragonFly: src/usr.bin/xlint/lint2/msg.c,v 1.7 2004/07/07 12:24:01 asmodai Exp $
  */
 
@@ -43,27 +43,27 @@
 
 
 static	const	char *msgs[] = {
-	"%s used( %s ), but not defined",			      /* 0 */
-	"%s defined( %s ), but never used",			      /* 1 */
-	"%s declared( %s ), but never used or defined",		      /* 2 */
-	"%s multiply defined  \t%s  ::  %s",			      /* 3 */
-	"%s value used inconsistently  \t%s  ::  %s",		      /* 4 */
-	"%s value declared inconsistently  \t%s  ::  %s",	      /* 5 */
-	"%s, arg %d used inconsistently  \t%s  ::  %s",		      /* 6 */
-	"%s: variable # of args  \t%s  ::  %s",			      /* 7 */
+	"%s: %s used, but not defined",				      /* 0 */
+	"%s: %s defined, but never used",			      /* 1 */
+	"%s: %s declared, but never used or defined",		      /* 2 */
+	"%s: %s multiply defined (%s)",				      /* 3 */
+	"%s: %s used inconsistently (%s)",			      /* 4 */
+	"%s: %s declared inconsistently (%s)",			      /* 5 */
+	"%s: %s arg %d used inconsistently (%s)",		      /* 6 */
+	"%s: %s called with varying # of args (%s)",		      /* 7 */
 	"%s returns value which is always ignored",		      /* 8 */
 	"%s returns value which is sometimes ignored",		      /* 9 */
-	"%s value is used( %s ), but none returned",		      /* 10 */
-	"%s, arg %d declared inconsistently  \t%s :: %s",	      /* 11 */
-	"%s: variable # of args declared  \t%s  ::  %s",	      /* 12 */
-	"%s: malformed format string  \t%s",			      /* 13 */
-	"%s, arg %d inconsistent with format  \t%s",		      /* 14 */
-	"%s: too few args for format  \t%s",			      /* 15 */
-	"%s: too many args for format  \t%s",			      /* 16 */
-	"%s function value must be declared before use  \t%s  ::  %s",/* 17 */
+	"%s: return value of %s is used, but none returned",	      /* 10 */
+	"%s: %s arg %d declared inconsistently (%s)",		      /* 11 */
+	"%s: %s declared with varying # of args (%s)",		      /* 12 */
+	"%s: malformed format string to %s",			      /* 13 */
+	"%s, arg %d to %s inconsistent with format",		      /* 14 */
+	"%s: too few format args to %s",			      /* 15 */
+	"%s: too many format args to %s",			      /* 16 */
+	"%s: %s must be declared before use (%s)",		      /* 17 */
 };
 
-static	const	char *basename(const char *);
+static	const	char *lbasename(const char *);
 
 void
 msg(int n, ...)
@@ -82,7 +82,7 @@
  * Return a pointer to the last component of a path.
  */
 static const char *
-basename(const char *path)
+lbasename(const char *path)
 {
 	const	char *cp, *cp1, *cp2;
 
@@ -120,16 +120,16 @@
 	}
 	qm = !Hflag && posp->p_src != posp->p_isrc;
 
-	len = strlen(fn = basename(fnames[src]));
+	len = strlen(fn = lbasename(fnames[src]));
 	len += 3 * sizeof (u_short) + 4;
 
 	if (len > blen)
 		buf = xrealloc(buf, blen = len);
 	if (line != 0) {
-		(void)sprintf(buf, "%s%s(%hu)",
+		(void)snprintf(buf, blen, "%s%s:%hu",
 			      fn, qm ? "?" : "", line);
 	} else {
-		(void)sprintf(buf, "%s", fn);
+		(void)snprintf(buf, blen, "%s", fn);
 	}
 
 	return (buf);
Index: usr.bin/xlint/lint2/read.c
===================================================================
RCS file: /home/dcvs/src/usr.bin/xlint/lint2/read.c,v
retrieving revision 1.7
diff -u -r1.7 read.c
--- usr.bin/xlint/lint2/read.c	7 Jul 2004 12:13:26 -0000	1.7
+++ usr.bin/xlint/lint2/read.c	25 Dec 2006 10:40:09 -0000
@@ -1,3 +1,4 @@
+/*	$OpenBSD: read.c,v 1.9 2005/12/01 05:06:40 cloder Exp $	*/
 /*	$NetBSD: read.c,v 1.2 1995/07/03 21:24:59 cgd Exp $	*/
 
 /*
@@ -30,7 +31,6 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $NetBSD: read.c,v 1.2 1995/07/03 21:24:59 cgd Exp $
  * $DragonFly: src/usr.bin/xlint/lint2/read.c,v 1.7 2004/07/07 12:13:26 asmodai Exp $
  */
 
@@ -78,7 +78,7 @@
 static	size_t	tlstlen;		/* length of tlst */
 
 /* index of current C source file (as spezified at the command line) */
-static	int	csrcfile;
+int	csrcfile;
 
 
 static	void	inperr(void);
@@ -130,7 +130,7 @@
 		/* line number in csrcfile */
 		cline = (int)strtol(cp, &eptr, 10);
 		if (cp == eptr) {
-		        cline = -1;
+			cline = -1;
 		} else {
 			cp = eptr;
 		}
@@ -216,7 +216,7 @@
 
 /*
  * setfnid() gets as input an index as used in an input file and the
- * associated file name. If neccessary, it creates a new lint2 file
+ * associated file name. If necessary, it creates a new lint2 file
  * name index for this file name and creates the mapping of the index
  * as used in the input file to the index used in lint2.
  */
@@ -259,7 +259,7 @@
 	rused = rdisc = 0;
 	lai = &fcall->f_args;
 	while ((c = *cp) == 'u' || c == 'i' || c == 'd' ||
-	       c == 'z' || c == 'p' || c == 'n' || c == 's') {
+	    c == 'z' || c == 'p' || c == 'n' || c == 's') {
 		cp++;
 		switch (c) {
 		case 'u':
@@ -334,8 +334,8 @@
 	used = 0;
 
 	while ((c = *cp) == 't' || c == 'd' || c == 'e' || c == 'u' ||
-	       c == 'r' || c == 'o' || c == 's' || c == 'v' ||
-	       c == 'P' || c == 'S') {
+	    c == 'r' || c == 'o' || c == 's' || c == 'v' ||
+	    c == 'P' || c == 'S') {
 		cp++;
 		switch (c) {
 		case 't':
@@ -601,8 +601,6 @@
 		}
 		break;
 		/* LINTED (enumeration value(s) not handled in switch) */
-	default:
-		break;
 	}
 
 	*epp = cp;
@@ -771,8 +769,6 @@
 		}
 		break;
 		/* LINTED (enumeration value(s) not handled in switch) */
-	default:
-		break;
 	}
 
 	*epp = cp;
@@ -1039,6 +1035,7 @@
 	 */
 	for (nhte = hte; nhte->h_link != NULL; nhte = nhte->h_link) ;
 	nhte->h_link = xalloc(sizeof (hte_t));
+	memset(nhte->h_link, 0, sizeof (hte_t));
 	nhte = nhte->h_link;
 	nhte->h_name = hte->h_name;
 	nhte->h_static = 1;
Index: usr.bin/xlint/llib/llib-lstdc
===================================================================
RCS file: /home/dcvs/src/usr.bin/xlint/llib/llib-lstdc,v
retrieving revision 1.1
diff -u -r1.1 llib-lstdc
--- usr.bin/xlint/llib/llib-lstdc	17 Jun 2003 02:56:38 -0000	1.1
+++ usr.bin/xlint/llib/llib-lstdc	28 Dec 2006 16:31:50 -0000
@@ -80,7 +80,7 @@
 /*
  * errno.h
  */
-int	(errno);
+/* int	(errno); */
 
 /*
  * locale.h
Index: usr.bin/xlint/xlint/lint.1
===================================================================
RCS file: /home/dcvs/src/usr.bin/xlint/xlint/lint.1,v
retrieving revision 1.3
diff -u -r1.3 lint.1
--- usr.bin/xlint/xlint/lint.1	7 Jul 2004 07:37:04 -0000	1.3
+++ usr.bin/xlint/xlint/lint.1	25 Dec 2006 10:47:46 -0000
@@ -1,3 +1,4 @@
+.\"	$OpenBSD: lint.1,v 1.22 2006/05/29 20:47:22 cloder Exp $
 .\"	$NetBSD: lint.1,v 1.3 1995/10/23 13:45:31 jpo Exp $
 .\"
 .\" Copyright (c) 1994, 1995 Jochen Pohl
@@ -39,40 +40,32 @@
 .Nm lint
 .Nd a C program verifier
 .Sh SYNOPSIS
-.Bk -words
 .Nm
-.Op Fl abceghprvxzHFSV
-.Op Fl s | t | S
-.Op Fl i | nu
-.Op Fl D Ar name Ns Op = Ns Ar def
-.Op Fl U Ar name
-.Op Fl I Ar directory
-.Op Fl L Ar directory
-.Op Fl l Ar library
-.Op Fl o Ar outputfile
+.Op Fl cefghprsvxzHFV
+.Op Fl i Ns | Ns Fl nu
+.Op Fl D Ns Ar name Ns Op =def
+.Op Fl U Ns Ar name
+.Op Fl I Ns Ar directory
+.Op Fl L Ns Ar directory
+.Op Fl l Ns Ar library
+.Op Fl o Ns Ar outputfile
 .Ar
 .Nm
-.Op Fl abceghprvzHFV
-.Op Fl s | t
-.Fl C Ar library
-.Op Fl D Ar name Ns Op = Ns Ar def
-.Op Fl I Ar directory
-.Op Fl U Ar name
+.Op Fl cefghprsvzHFV
+.Fl C Ns Ar library
+.Op Fl D Ns Ar name Ns Op =def
+.Op Fl I Ns Ar directory
+.Op Fl U Ns Ar name
 .Ar
-.Ek
 .Sh DESCRIPTION
-The
 .Nm
-utility attempts to detect features of the named C program files
-that are likely to be bugs, to be non-portable, or to be
-wasteful.
-It also performs stricter type checking than
-the C compiler.
-The
+attempts to detect features of the named C program files
+that are likely to be bugs, non-portable, or wasteful.
+It also performs stricter type checking than the C compiler.
 .Nm
-utility runs the C preprocessor as its first phase, with the
+runs the C preprocessor as its first phase, with the
 preprocessor symbol
-.Dq Dv lint
+.Sy lint
 defined to allow certain questionable code to be altered
 or skipped by
 .Nm .
@@ -84,67 +77,66 @@
 unreachable statements, loops not entered at the top,
 variables declared and not used, and logical expressions
 with constant values.
-Function calls are checked for
-inconsistencies, such as calls to functions that return
-values in some places and not in others, functions called
-with varying numbers of arguments, function calls that
-pass arguments of a type other than the type the function
-expects to receive, functions whose values are not used,
-and calls to functions not returning values that use
-the non-existent return value of the function.
+Function calls are checked for inconsistencies, such as
+calls to functions that return values in some places and
+not in others, functions called with varying numbers of
+arguments, function calls that pass arguments of a type
+other than the type the function expects to receive,
+functions whose values are not used, and calls to functions
+not returning values that use the non-existent return value
+of the function.
 .Pp
 Filename arguments ending with
-.Pa .c
+.Pa \&.c
 are taken to be C source files.
-Filename arguments with
-names ending with
-.Pa .ln
+Filename arguments with names ending with
+.Pa \&.ln
 are taken to be the result of an earlier invocation of
 .Nm ,
 with either the
-.Fl i , o ,
+.Fl i ,
+.Fl o ,
 or
 .Fl C
 option in effect.
 The
-.Pa .ln
+.Pa \&.ln
 files are analogous to the
-.Pa .o
+.Pa \&.o
 (object) files produced by
 .Xr cc 1
 from
-.Pa .c
+.Pa \&.c
 files.
-The
 .Nm
-utility also accepts special libraries specified with the
+also accepts special libraries specified with the
 .Fl l
 option, which contain definitions of library routines and
 variables.
 .Pp
-The
 .Nm
-utility takes all the
-.Pa .c , .ln ,
+takes all the
+.Pa \&.c , \&.ln ,
 and
-.Pa llib-l Ns Ar library Ns Pa .ln
+.Pa llib-l Ns Ar library Ns Pa \&.ln
 (lint library) files and processes them in command-line order.
 By default,
 .Nm
 appends the standard C lint library
-.Pq Pa llib-lc.ln
+.Pq Pa llib-lc.ln ,
+if it exists,
 to the end of the list of files.
 When the
 .Fl i
 option is used, the
-.Pa .ln
+.Pa \&.ln
 files are ignored.
 Also, when the
 .Fl o
 or
 .Fl i
 options are used, the
-.Pa llib-l Ns Ar library Ns Pa .ln
+.Pa llib-l Ns Ar library Ns Pa \&.ln
 files are ignored.
 When the
 .Fl i
@@ -153,44 +145,24 @@
 the second pass of
 .Nm
 checks this list of files for mutual compatibility.
-At this point,
-if a complaint stems not from a given source file, but from one of
-its included files, the source filename will be printed followed by
-a question mark.
+At this point, if a complaint stems not from a given source
+file, but from one of its included files, the source filename
+will be printed followed by a question mark.
 .Pp
 The options are as follows:
-.Bl -tag -width indent
-.It Fl a
-Report assignments of
-.Vt long
-values to variables that are not
-.Vt long .
-.It Fl aa
-Additional to
-.Fl a ,
-report
-.Em all
-assignments of integer values to other integer values which
-cause implicit narrowing conversion.
-.It Fl b
-Report
-.Ic break
-statements that cannot be reached.
-This is not the default
-because, unfortunately, most
-.Xr lex 1
-and many
-.Xr yacc 1
-outputs produce many such complaints.
+.Bl -tag -width Ds
 .It Fl c
 Complain about casts which have questionable portability.
 .It Fl e
 Complain about unusual operations on
-.Vt enum Ns -Types
+.Sy enum Ns -Types
 and combinations of
-.Vt enum Ns -
+.Sy enum Ns -
 and
-.Vt int Ns eger-Types .
+.Sy integer Ns -Types.
+.It Fl f
+For each warning or error, print the offending line of the
+corresponding source code file.
 .It Fl g
 Don't print warnings for some extensions of
 .Xr gcc 1
@@ -203,25 +175,25 @@
 The
 .Fl g
 flag also turns on the keywords
-.Ic asm
+.Sy asm
 and
-.Ic inline
+.Sy inline
 (alternate keywords with leading underscores for both
-.Ic asm
+.Sy asm
 and
-.Ic inline
+.Sy inline
 are always available).
 .It Fl h
 Apply a number of heuristic tests to attempt to intuit
 bugs, improve style, and reduce waste.
 .It Fl i
 Produce a
-.Pa .ln
+.Pa \&.ln
 file for every
-.Pa .c
+.Pa \&.c
 file on the command line.
 These
-.Pa .ln
+.Pa \&.ln
 files are the product of
 .Nm Ns 's
 first pass only, and are not checked for compatibility
@@ -241,30 +213,8 @@
 With the
 .Fl s
 flag,
-.Dv __STRICT_ANSI__
+.Li __STRICT_ANSI__
 is a predefined preprocessor macro.
-.Fl S
-C9X mode. Currently not fully implemented.
-.It Fl t
-Traditional C mode.
-.Dv __STDC__
-is not predefined in this mode.
-Warnings are printed for constructs
-not allowed in traditional C.
-Warnings for constructs which behave
-differently in traditional C and ANSI C are suppressed.
-Preprocessor
-macros describing the machine type (e.g.,
-.Dv sun3 )
-and machine architecture (e.g.,
-.Dv m68k )
-are defined without leading and trailing underscores.
-The keywords
-.Ic const , volatile
-and
-.Ic signed
-are not available in traditional C mode (although the alternate
-keywords with leading underscores still are).
 .It Fl u
 Do not complain about functions and external variables used
 and not defined, or defined and not used (this is suitable
@@ -275,21 +225,21 @@
 Suppress complaints about unused arguments in functions.
 .It Fl x
 Report variables referred to by
-.Ic extern
+.Sy extern
 declarations, but never used.
 .It Fl z
 Do not complain about structures that are never defined
 (for example, using a structure pointer without knowing
 its contents).
-.It Fl C Ar library
+.It Fl C Ns Ar library
 Create a
 .Nm
 library with the name
 .Pa llib-l Ns Ar library Ns Pa .ln .
 This library is built from all
-.Pa .c
+.Pa \&.c
 and
-.Pa .ln
+.Pa \&.ln
 input files.
 After all global definitions of functions and
 variables in these files are written to the newly created library,
@@ -297,25 +247,25 @@
 checks all input files, including libraries specified with the
 .Fl l
 option, for mutual compatibility.
-.It Fl D Ar name Ns Op = Ns Ar def
+.It Fl D Ns Ar name Ns Op =def
 Define
 .Ar name
 for
 .Xr cpp 1 ,
 as if by a
-.Ic #define
+.Li #define
 directive.
 If no definition is given,
 .Ar name
 is defined as 1.
-.It Fl I Ar directory
+.It Fl I Ns Ar directory
 Add
 .Ar directory
 to the list of directories in which to search for include files.
-.It Fl l Ar library
+.It Fl l Ns Ar library
 Include the lint library
-.Pa llib-l Ns Ar library Ns Pa .ln .
-.It Fl L Ar directory
+.Pa llib-l Ns Ar library Ns Pa \&.ln .
+.It Fl L Ns Ar directory
 Search for lint libraries in
 .Ar directory
 and
@@ -323,15 +273,14 @@
 before searching the standard place.
 .It Fl F
 Print pathnames of files.
-The
 .Nm
-utility normally prints the filename without the path.
+normally prints the filename without the path.
 .It Fl H
 If a complaint stems from an included file
 .Nm
 prints the name of the included file instead of the source file name
 followed by a question mark.
-.It Fl o Ar outputfile
+.It Fl o Ns Ar outputfile
 Name the output file
 .Ar outputfile .
 The output file produced is the input that is given to
@@ -344,7 +293,7 @@
 .Fl i
 option is also used the files are not checked for compatibility.
 To produce a
-.Pa llib-l Ns Ar library Ns Pa .ln
+.Pa llib-l Ns Ar library Ns Pa \&.ln
 without extraneous messages, use of the
 .Fl u
 option is suggested.
@@ -352,7 +301,7 @@
 .Fl v
 option is useful if the source file(s) for the lint library
 are just external interfaces.
-.It Fl U Ar name
+.It Fl U Ns Ar name
 Remove any initial definition of
 .Ar name
 for the preprocessor.
@@ -362,13 +311,14 @@
 .Nm Ns 's
 first and second pass.
 .El
-.Ss Input Grammar
+.Pp
+.Sy Input Grammar
+.Pp
 .Nm Ns 's
 first pass reads standard C source files.
-The
 .Nm
-utility recognizes the following C comments as commands.
-.Bl -tag -width indent
+recognizes the following C comments as commands.
+.Bl -tag -width Fl
 .It Li /* ARGSUSED Ns Ar n Li */
 makes
 .Nm
@@ -379,40 +329,36 @@
 is taken to be 0 (this option acts like the
 .Fl v
 option for the next function).
-.It Xo
-.Li /* CONSTCOND */
-or
-.Li /* CONSTANTCOND */
-or
+.It Li /* CONSTCOND */ No or Xo
+.Li /* CONSTANTCOND */ No or
 .Li /* CONSTANTCONDITION */
 .Xc
 suppress complaints about constant operands for the next expression.
-.It Xo
-.Li /* FALLTHRU */
-or
+.It Li /*\ FALLTHRU\ */ No or Xo
 .Li /* FALLTHROUGH */
 .Xc
 suppress complaints about fall through to a
-.Ic case
+.Sy case
 or
-.Ic default
+.Sy default
 labelled statement.
-This directive should be placed immediately
-preceding the label.
+This directive should be placed immediately preceding the label.
 .It Li /* LINTLIBRARY */
 At the beginning of a file, mark all functions and variables defined
 in this file as
 .Em used .
 Also shut off complaints about unused function arguments.
-.It Xo
-.Li /* LINTED Oo Ar comment Oc Li */
-or
-.Li /* NOSTRICT Oo Ar comment Oc Li */
+.It Li /* LINTED Xo
+.Op Ar comment
+.Li */ No or
+.Li /* NOSTRICT
+.Op Ar comment
+.Li */
 .Xc
 Suppresses any intra-file warning except those dealing with
 unused variables or functions.
-This directive should be placed
-on the line immediately preceding where the
+This directive should be placed on the line immediately
+preceding where the
 .Nm
 warning occurred.
 .It Li /* LONGLONG */
@@ -431,7 +377,7 @@
 The
 .Ar n Ns -th
 argument is interpreted as a
-.Xr printf 3
+.Sy printf
 format string that is used to check the remaining arguments.
 .It Li /* PROTOLIB Ns Ar n Li */
 causes
@@ -440,8 +386,7 @@
 if
 .Ar n
 is non-zero.
-This directive can only be used in conjunction with
-the
+This directive can only be used in conjunction with the
 .Li /* LINTLIBRARY */
 directive.
 If
@@ -456,7 +401,7 @@
 The
 .Ar n Ns -th
 argument is interpreted as a
-.Xr scanf 3
+.Sy scanf
 format string that is used to check the remaining arguments.
 .It Li /* VARARGS Ns Ar n Li */
 Suppress the usual checking for variable numbers of arguments in
@@ -481,24 +426,22 @@
 .Fl i
 option.
 Each of these invocations produces a
-.Pa .ln
+.Pa \&.ln
 file that corresponds to the
-.Pa .c
+.Pa \&.c
 file, and prints all messages that are about just that
 source file.
-After all the source files have been separately
-run through
+After all the source files have been separately run through
 .Nm ,
 it is invoked once more (without the
 .Fl i
 option), listing all the
-.Pa .ln
+.Pa \&.ln
 files with the needed
 .Fl l Ns Ar library
 options.
 This will print all the inter-file inconsistencies.
-This
-scheme works well with
+This scheme works well with
 .Xr make 1 ;
 it allows
 .Xr make 1
@@ -508,15 +451,12 @@
 time the set of source files were
 .Nm Ns ed .
 .Sh ENVIRONMENT
-.Bl -tag -width LIBDIR
+.Bl -tag -width Fl
 .It Ev LIBDIR
 the directory where the lint libraries specified by the
-.Bk -words
-.Fl l Ar library
-.Ek
+.Fl l Ns Ar library
 option must exist.
-If this environment variable is undefined,
-then the default path
+If this environment variable is undefined, then the default path
 .Pa /usr/libdata/lint
 will be used to search for the libraries.
 .It Ev TMPDIR
@@ -524,11 +464,13 @@
 this environment variable.
 .El
 .Sh FILES
-.Bl -tag -width /usr/libdata/lint/llib-lc.ln -compact
-.It Pa /usr/libexec/lint Ns Bq Pa 12
+.Bl -tag -width /usr/libdata/lint/llib-lposix.ln -compact
+.It Pa /usr/libexec/lint Ns Bq 12
 programs
-.It Pa /usr/libdata/lint/llib-l*.ln
-various prebuilt lint libraries
+.It Pa /usr/libdata/lint/llib-lposix.ln
+prebuilt POSIX C lint library
+.It Pa /usr/libdata/lint/llib-lstdc.ln
+prebuilt ANSI/ISO C lint library
 .It Pa /tmp/lint*
 temporaries
 .El
@@ -537,19 +479,17 @@
 .Xr cpp 1 ,
 .Xr make 1
 .Sh AUTHORS
-.An Jochen Pohl
+Jochen Pohl
 .Sh BUGS
-.Bl -item
-.It
 The routines
 .Xr exit 3 ,
 .Xr longjmp 3
 and other functions that do not return are not understood; this
 causes various incorrect diagnostics.
-.It
+.Pp
 Static functions which are used only before their first
 extern declaration are reported as unused.
-.It
+.Pp
 Libraries created by the
 .Fl o
 option will, when used in later
@@ -558,8 +498,6 @@
 were created to be reported again, and cause line numbers and file
 names from the original source used to create those libraries
 to be reported in error messages.
-For these reasons, it is recommended
-to use the
+For these reasons, it is recommended to use the
 .Fl C
 option to create lint libraries.
-.El
Index: usr.bin/xlint/xlint/xlint.c
===================================================================
RCS file: /home/dcvs/src/usr.bin/xlint/xlint/xlint.c,v
retrieving revision 1.12
diff -u -r1.12 xlint.c
--- usr.bin/xlint/xlint/xlint.c	2 Oct 2006 13:26:40 -0000	1.12
+++ usr.bin/xlint/xlint/xlint.c	25 Dec 2006 11:02:58 -0000
@@ -1,3 +1,4 @@
+/*	$OpenBSD: xlint.c,v 1.32 2006/11/10 00:54:59 deraadt Exp $	*/
 /*	$NetBSD: xlint.c,v 1.3 1995/10/23 14:29:30 jpo Exp $	*/
 
 /*
@@ -91,7 +92,7 @@
 static	char	**libsrchpath;
 
 /* flags */
-static	int	iflag, oflag, Cflag, sflag, tflag, Fflag, Sflag;
+static	int	iflag, oflag, Cflag, sflag, tflag, Fflag = 1;
 
 /* print the commands executed to run the stages of compilation */
 static	int	Vflag;
@@ -108,7 +109,6 @@
  */
 static	const	char *currfn;
 
-
 static	void	appstrg(char ***, char *);
 static	void	appcstrg(char ***, const char *);
 static	void	applst(char ***, char *const *);
@@ -116,11 +116,11 @@
 static	char	*concat2(const char *, const char *);
 static	char	*concat3(const char *, const char *, const char *);
 static	void	terminate(int);
-static	const	char *basename(const char *, int);
+static	const	char *lbasename(const char *, int);
 static	void	appdef(char ***, const char *);
 static	void	usage(void);
-static	void	fname(const char *, int);
-static	void	runchild(const char *, char *const *, const char *);
+static	void	fname(const char *);
+static	int	runchild(const char *, char *const *, const char *);
 static	void	findlibs(char *const *);
 static	int	rdok(const char *);
 static	void	lint2(void);
@@ -128,7 +128,7 @@
 
 /*
  * Some functions to deal with lists of strings.
- * Take care that we get no surprises in case of asyncron signals.
+ * Take care that we get no surprises in case of asynchronous signals.
  */
 static void
 appstrg(char ***lstp, char *s)
@@ -187,10 +187,11 @@
 concat2(const char *s1, const char *s2)
 {
 	char	*s;
+	size_t len = strlen(s1) + strlen(s2) + 1;
 
-	s = xmalloc(strlen(s1) + strlen(s2) + 1);
-	strcpy(s, s1);
-	strcat(s, s2);
+	s = xmalloc(len);
+	strlcpy(s, s1, len);
+	strlcat(s, s2, len);
 
 	return (s);
 }
@@ -199,11 +200,12 @@
 concat3(const char *s1, const char *s2, const char *s3)
 {
 	char	*s;
+	size_t len = strlen(s1) + strlen(s2) + strlen(s3) + 1;
 
-	s = xmalloc(strlen(s1) + strlen(s2) + strlen(s3) + 1);
-	strcpy(s, s1);
-	strcat(s, s2);
-	strcat(s, s3);
+	s = xmalloc(len);
+	strlcpy(s, s1, len);
+	strlcat(s, s2, len);
+	strlcat(s, s3, len);
 
 	return (s);
 }
@@ -230,7 +232,7 @@
 	if (currfn != NULL)
 		remove(currfn);
 
-	exit(signo != 0 ? 1 : 0);
+	_exit(signo != 0 ? 1 : 0);
 }
 
 /*
@@ -238,7 +240,7 @@
  * Returns strg if the string does not contain delim.
  */
 static const char *
-basename(const char *strg, int delim)
+lbasename(const char *strg, int delim)
 {
 	const	char *cp, *cp1, *cp2;
 
@@ -260,20 +262,20 @@
 }
 
 static void
-usage(void)
+usage()
 {
-	printf("lint [-abceghprvxzHFS] [-s|-t] [-i|-nu] [-Dname[=def]] [-Uname]\n");
-	printf("     [-Idirectory] [-Ldirectory] [-llibrary] [-ooutputfile] file ...\n");
-	printf("\n");
-	printf("lint [-abceghprvzHFS] [-s|-t] -Clibrary [-Dname[=def]]\n");
-	printf("     [-Idirectory] [-Uname] file ...\n");
+	printf("usage: lint [-abceghprvxzHF] [-s|-t] [-i|-nu] [-Dname[=def]] [-Uname]\n");
+	printf("            [-Idirectory] [-Ldirectory] [-llibrary] [-ooutputfile] file ...\n");
+	printf("       lint [-abceghprvzHF] [-s|-t] -Clibrary [-Dname[=def]]\n");
+	printf("            [-Idirectory] [-Uname] file ...\n");
 	terminate(-1);
 }
 
 int
-main(int argc, char **argv)
+main(int argc, char *argv[])
 {
-	int	c, fd;
+	int	c;
+	int	fd;
 	char	flgbuf[3], *tmp, *s;
 	size_t	len;
 	struct	utsname un;
@@ -282,20 +284,17 @@
 		tmpdir = xstrdup(_PATH_TMP);
 	} else {
 		s = xmalloc(len + 2);
-		sprintf(s, "%s%s", tmp, tmp[len - 1] == '/' ? "" : "/");
+		snprintf(s, len + 2, "%s%s", tmp, tmp[len - 1] == '/' ? "" : "/");
 		tmpdir = s;
 	}
 
-	cppout = xmalloc(strlen(tmpdir) + sizeof ("lint0.XXXXXX"));
-	sprintf(cppout, "%slint0.XXXXXX", tmpdir);
-
-	fd = mkstemp(cppout);
-	if (fd == -1) {
-		err(1, "could not make a temporary file");
-		close(fd);
+	if (asprintf(&cppout, "%slint0.XXXXXXXXXX", tmpdir) == -1)
+		err(1, NULL);
+	if ((fd = mkstemp(cppout)) == -1) {
+		warn("can't make temp");
 		terminate(-1);
 	}
-	close (fd);
+	close(fd);
 
 	p1out = xcalloc(1, sizeof (char *));
 	p2in = xcalloc(1, sizeof (char *));
@@ -322,18 +321,11 @@
 #endif
 #endif
 	appcstrg(&cppflags, "-Wcomment");
-#ifdef __DragonFly__
-	appcstrg(&cppflags, "-D__DragonFly__=" __XSTRING(__DragonFly__));
-#else
-#	error "This ain't NetBSD.  You lose!"
-	appcstrg(&cppflags, "-D__NetBSD__");
-#endif
+	appcstrg(&cppflags, "-D__DragonFly__");
 	appcstrg(&cppflags, "-Dlint");		/* XXX don't def. with -s */
 	appdef(&cppflags, "lint");
 	appdef(&cppflags, "unix");
 
-	appcstrg(&lcppflgs, "-Wtraditional");
-
 	if (uname(&un) == -1)
 		err(1, "uname");
 	appdef(&cppflags, un.machine);
@@ -355,8 +347,7 @@
 	signal(SIGTERM, terminate);
 
 	while (argc > optind) {
-
-		c = getopt(argc, argv, "abceghil:no:prstuvxzC:D:FHI:L:SU:V");
+		c = getopt(argc, argv, "abcefghil:no:prstuvxyzC:D:FHI:L:U:V");
 
 		switch (c) {
 
@@ -364,11 +355,13 @@
 		case 'b':
 		case 'c':
 		case 'e':
+		case 'f':
 		case 'g':
 		case 'r':
 		case 'v':
+		case 'y':
 		case 'z':
-			sprintf(flgbuf, "-%c", c);
+			snprintf(flgbuf, sizeof flgbuf, "-%c", c);
 			appcstrg(&l1flags, flgbuf);
 			break;
 
@@ -377,7 +370,7 @@
 			/* FALLTHROUGH */
 		case 'u':
 		case 'h':
-			sprintf(flgbuf, "-%c", c);
+			snprintf(flgbuf, sizeof flgbuf, "-%c", c);
 			appcstrg(&l1flags, flgbuf);
 			appcstrg(&l2flags, flgbuf);
 			break;
@@ -414,21 +407,13 @@
 			sflag = 1;
 			break;
 
-		case 'S':
-			if (tflag)
-				usage();
-			appcstrg(&l1flags, "-S");
-			Sflag = 1;
-
 		case 't':
 			if (sflag)
 				usage();
 			freelst(&lcppflgs);
 			appcstrg(&lcppflgs, "-traditional");
 			appstrg(&lcppflgs, concat2("-D", MACHINE));
-#ifdef MACHINE_ARCH
 			appstrg(&lcppflgs, concat2("-D", MACHINE_ARCH));
-#endif
 			appcstrg(&l1flags, "-t");
 			appcstrg(&l2flags, "-t");
 			tflag = 1;
@@ -443,15 +428,15 @@
 				usage();
 			Cflag = 1;
 			appstrg(&l2flags, concat2("-C", optarg));
-			p2out = xmalloc(sizeof ("llib-l.ln") + strlen(optarg));
-			sprintf(p2out, "llib-l%s.ln", optarg);
+			if (asprintf(&p2out, "llib-l%s.ln", optarg) == -1)
+				err(1, NULL);
 			freelst(&deflibs);
 			break;
 
 		case 'D':
 		case 'I':
 		case 'U':
-			sprintf(flgbuf, "-%c", c);
+			snprintf(flgbuf, sizeof flgbuf, "-%c", c);
 			appstrg(&cppflags, concat2(flgbuf, optarg));
 			break;
 
@@ -484,14 +469,15 @@
 
 		case -1:
 			/* filename */
-			fname(argv[optind], argc == optind + 1);
+			if (argv[optind] == NULL)
+				break;
+			fname(argv[optind++]);
 			first = 0;
-
-			argc -= optind;
-			argv += optind;
-			optreset = optind = 1;
 		}
+
 	}
+	argc -= optind;
+	argv += optind;
 
 	if (first)
 		usage();
@@ -518,7 +504,6 @@
 
 	terminate(0);
 	/* NOTREACHED */
-	return 0;
 }
 
 /*
@@ -526,15 +511,16 @@
  * and pass it through lint1 if it is a C source.
  */
 static void
-fname(const char *name, int last)
+fname(const char *name)
 {
 	const	char *bn, *suff;
 	char	**args, *ofn, *path;
 	size_t	len;
-	int fd;
+	int	error;
+	int	fd;
 
-	bn = basename(name, '/');
-	suff = basename(bn, '.');
+	bn = lbasename(name, '/');
+	suff = lbasename(bn, '.');
 
 	if (strcmp(suff, "ln") == 0) {
 		/* only for lint2 */
@@ -545,33 +531,29 @@
 
 	if (strcmp(suff, "c") != 0 &&
 	    (strncmp(bn, "llib-l", 6) != 0 || bn != suff)) {
-		warnx("unknown file type: %s\n", name);
+		warnx("unknown file type: %s", name);
 		return;
 	}
 
-	if (!iflag || !first || !last)
-		printf("%s:\n", Fflag ? name : bn);
-
 	/* build the name of the output file of lint1 */
 	if (oflag) {
 		ofn = outputfn;
 		outputfn = NULL;
 		oflag = 0;
 	} else if (iflag) {
-		ofn = xmalloc(strlen(bn) + (bn == suff ? 4 : 2));
-		len = bn == suff ? strlen(bn) : (suff - 1) - bn;
-		sprintf(ofn, "%.*s", (int)len, bn);
-		strcat(ofn, ".ln");
+		len = strlen(bn) + (bn == suff ? 4 : 2);
+		ofn = xmalloc(len);
+		snprintf(ofn, len, "%.*s",
+		    bn == suff ? strlen(bn) : (suff - 1) - bn, bn);
+		strlcat(ofn, ".ln", len);
 	} else {
-		ofn = xmalloc(strlen(tmpdir) + sizeof ("lint1.XXXXXX"));
-		sprintf(ofn, "%slint1.XXXXXX", tmpdir);
-		fd = mkstemp(ofn);
-		if (fd == -1) {
-			err(1, "could not make a temporary file");
-			close(fd);
+		if (asprintf(&ofn, "%slint1.XXXXXXXXXX", tmpdir) == -1)
+			err(1, NULL);
+		if ((fd  = mkstemp(ofn)) == -1) {
+			warn("can't make temp");
 			terminate(-1);
-        	}
-        	close (fd);
+		}
+		close(fd);
 	}
 	if (!iflag)
 		appcstrg(&p1out, ofn);
@@ -580,8 +562,8 @@
 
 	/* run cpp */
 
-	path = xmalloc(strlen(PATH_USRBIN) + sizeof ("/cpp"));
-	sprintf(path, "%s/cpp", PATH_USRBIN);
+	if (asprintf(&path, "%s/cpp", PATH_USRBIN) == -1)
+		err(1, NULL);
 
 	appcstrg(&args, path);
 	applst(&args, cppflags);
@@ -589,23 +571,27 @@
 	appcstrg(&args, name);
 	appcstrg(&args, cppout);
 
-	runchild(path, args, cppout);
+	error = runchild(path, args, cppout);
 	free(path);
 	freelst(&args);
+	if (error)
+		return;
 
 	/* run lint1 */
 
-	path = xmalloc(strlen(PATH_LIBEXEC) + sizeof ("/lint1"));
-	sprintf(path, "%s/lint1", PATH_LIBEXEC);
+	if (asprintf(&path, "%s/lint1", PATH_LIBEXEC) == -1)
+		err(1, NULL);
 
 	appcstrg(&args, path);
 	applst(&args, l1flags);
 	appcstrg(&args, cppout);
 	appcstrg(&args, ofn);
 
-	runchild(path, args, ofn);
+	error = runchild(path, args, ofn);
 	free(path);
 	freelst(&args);
+	if (error)
+		return;
 
 	appcstrg(&p2in, ofn);
 	free(ofn);
@@ -613,10 +599,11 @@
 	free(args);
 }
 
-static void
+static int
 runchild(const char *path, char *const *args, const char *crfn)
 {
-	int	status, rv, signo, i;
+	int	status, signo, i;
+	pid_t	rv;
 
 	if (Vflag) {
 		for (i = 0; args[i] != NULL; i++)
@@ -643,20 +630,21 @@
 		exit(1);
 		/* NOTREACHED */
 	}
+	currfn = NULL;
 
 	while ((rv = wait(&status)) == -1 && errno == EINTR) ;
 	if (rv == -1) {
 		warn("wait");
-		terminate(-1);
+		return(-1);
 	}
 	if (WIFSIGNALED(status)) {
 		signo = WTERMSIG(status);
 		warnx("%s got SIG%s", path, sys_signame[signo]);
-		terminate(-1);
+		return(-1);
 	}
 	if (WEXITSTATUS(status) != 0)
-		terminate(-1);
-	currfn = NULL;
+		return(-1);
+	return(0);
 }
 
 static void
@@ -665,19 +653,21 @@
 	int	i, k;
 	const	char *lib, *path;
 	char	*lfn;
-	size_t	len;
+	size_t	len, l;
 
 	lfn = NULL;
 
 	for (i = 0; (lib = liblst[i]) != NULL; i++) {
 		for (k = 0; (path = libsrchpath[k]) != NULL; k++) {
 			len = strlen(path) + strlen(lib);
-			lfn = xrealloc(lfn, len + sizeof ("/llib-l.ln"));
-			sprintf(lfn, "%s/llib-l%s.ln", path, lib);
+			l = len + sizeof ("/llib-l.ln");
+			lfn = xrealloc(lfn, l);
+			snprintf(lfn, l, "%s/llib-l%s.ln", path, lib);
 			if (rdok(lfn))
 				break;
-			lfn = xrealloc(lfn, len + sizeof ("/lint/llib-l.ln"));
-			sprintf(lfn, "%s/lint/llib-l%s.ln", path, lib);
+			l = len + sizeof ("/lint/llib-l.ln");
+			lfn = xrealloc(lfn, l);
+			snprintf(lfn, l, "%s/lint/llib-l%s.ln", path, lib);
 			if (rdok(lfn))
 				break;
 		}
@@ -706,14 +696,14 @@
 }
 
 static void
-lint2(void)
+lint2()
 {
 	char	*path, **args;
 
 	args = xcalloc(1, sizeof (char *));
 
-	path = xmalloc(strlen(PATH_LIBEXEC) + sizeof ("/lint2"));
-	sprintf(path, "%s/lint2", PATH_LIBEXEC);
+	if (asprintf(&path, "%s/lint2", PATH_LIBEXEC) == -1)
+		err(1, NULL);
 
 	appcstrg(&args, path);
 	applst(&args, l2flags);
