From c0089353cfca084ec49bf69f4bbfc4c4b1cfa2de Mon Sep 17 00:00:00 2001 From: "Pedro F. Giffuni" Date: Mon, 23 Mar 2015 18:45:29 +0000 Subject: [PATCH] xlint: update. Bring some important updates from NetBSD up to about 2008/04/25. The main feature is initial support for C99. This is a very basic update to make it easier to merge new compiler attirbutes but more updates are likely to follow. Obtained from: NetBSD MFC after: 2 weeks --- usr.bin/xlint/arch/sparc64/targparam.h | 4 +- usr.bin/xlint/common/lint.h | 6 +- usr.bin/xlint/common/mem.c | 11 +- usr.bin/xlint/lint1/cgram.y | 176 ++++++++++--- usr.bin/xlint/lint1/decl.c | 86 +++--- usr.bin/xlint/lint1/emit1.c | 10 +- usr.bin/xlint/lint1/err.c | 62 ++++- usr.bin/xlint/lint1/externs1.h | 19 +- usr.bin/xlint/lint1/func.c | 36 +-- usr.bin/xlint/lint1/init.c | 179 +++++++++++-- usr.bin/xlint/lint1/lint1.h | 16 +- usr.bin/xlint/lint1/main1.c | 22 +- usr.bin/xlint/lint1/makeman | 2 +- usr.bin/xlint/lint1/scan.l | 179 ++++++++----- usr.bin/xlint/lint1/tree.c | 345 ++++++++++++++++--------- usr.bin/xlint/lint2/read.c | 29 ++- usr.bin/xlint/xlint/lint.1 | 16 +- usr.bin/xlint/xlint/xlint.c | 26 +- 18 files changed, 868 insertions(+), 356 deletions(-) diff --git a/usr.bin/xlint/arch/sparc64/targparam.h b/usr.bin/xlint/arch/sparc64/targparam.h index 8d57fbd3b65d..df151f2344ec 100644 --- a/usr.bin/xlint/arch/sparc64/targparam.h +++ b/usr.bin/xlint/arch/sparc64/targparam.h @@ -1,4 +1,4 @@ -/* $NetBSD: targparam.h,v 1.2 2002/01/30 06:55:00 thorpej Exp $ */ +/* $NetBSD: targparam.h,v 1.3 2002/01/31 23:31:34 he Exp $ */ /* * Copyright (c) 1994, 1995 Jochen Pohl @@ -29,6 +29,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. + * + * $FreeBSD$ */ /* diff --git a/usr.bin/xlint/common/lint.h b/usr.bin/xlint/common/lint.h index c50d28dd2f84..231d2d6be490 100644 --- a/usr.bin/xlint/common/lint.h +++ b/usr.bin/xlint/common/lint.h @@ -1,4 +1,4 @@ -/* $NetBSD: lint.h,v 1.5 2002/03/07 18:29:56 tv Exp $ */ +/* $NetBSD: lint.h,v 1.7 2003/10/27 00:12:44 lukem Exp $ */ /* * Copyright (c) 1994, 1995 Jochen Pohl @@ -29,6 +29,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. + * + * $FreeBSD$ */ #if HAVE_CONFIG_H @@ -90,7 +92,7 @@ typedef struct { 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 */ + const char *tt_name; /* Bezeichnung des Typs */ } ttab_t; #define size(t) (ttab[t].tt_sz) diff --git a/usr.bin/xlint/common/mem.c b/usr.bin/xlint/common/mem.c index 2621081f1aee..8802da1879b0 100644 --- a/usr.bin/xlint/common/mem.c +++ b/usr.bin/xlint/common/mem.c @@ -1,4 +1,4 @@ -/* $NetBSD: mem.c,v 1.2 2002/01/21 19:49:51 tv Exp $ */ +/* $NetBSD: mem.c,v 1.4 2003/10/16 06:35:26 itojun Exp $ */ /* * Copyright (c) 1994, 1995 Jochen Pohl @@ -33,8 +33,9 @@ #include #if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: mem.c,v 1.2 2002/01/21 19:49:51 tv Exp $"); +__RCSID("$NetBSD: mem.c,v 1.4 2003/10/16 06:35:26 itojun Exp $"); #endif +__FBSDID("$FreeBSD$"); #include #include @@ -64,9 +65,13 @@ xcalloc(size_t n, size_t s) void * xrealloc(void *p, size_t s) { + void *n; - if ((p = realloc(p, s)) == NULL) + if ((n = realloc(p, s)) == NULL) { + free(p); nomem(); + } + p = n; return (p); } diff --git a/usr.bin/xlint/lint1/cgram.y b/usr.bin/xlint/lint1/cgram.y index 8791a2d3b8ed..71d38f4f00bb 100644 --- a/usr.bin/xlint/lint1/cgram.y +++ b/usr.bin/xlint/lint1/cgram.y @@ -1,5 +1,5 @@ %{ -/* $NetBSD: cgram.y,v 1.23 2002/01/31 19:36:53 tv Exp $ */ +/* $NetBSD: cgram.y,v 1.40 2008/04/25 17:18:24 christos Exp $ */ /* * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. @@ -35,7 +35,7 @@ #include #if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: cgram.y,v 1.23 2002/01/31 19:36:53 tv Exp $"); +__RCSID("$NetBSD: cgram.y,v 1.40 2008/04/25 17:18:24 christos Exp $"); #endif __FBSDID("$FreeBSD$"); @@ -65,13 +65,13 @@ int mblklev; */ static int onowarn = -1; -static int toicon(tnode_t *); +static int toicon(tnode_t *, int); static void idecl(sym_t *, int, sbuf_t *); static void ignuptorp(void); #ifdef DEBUG -static __inline void CLRWFLGS(void); -static __inline void CLRWFLGS(void) +static inline void CLRWFLGS(void); +static inline void CLRWFLGS(void) { printf("%s, %d: clear flags %s %d\n", curr_pos.p_file, curr_pos.p_line, __FILE__, __LINE__); @@ -79,8 +79,8 @@ static __inline void CLRWFLGS(void) onowarn = -1; } -static __inline void SAVE(void); -static __inline void SAVE(void) +static inline void SAVE(void); +static inline void SAVE(void) { if (onowarn != -1) abort(); @@ -89,8 +89,8 @@ static __inline void SAVE(void) onowarn = nowarn; } -static __inline void RESTORE(void); -static __inline void RESTORE(void) +static inline void RESTORE(void); +static inline void RESTORE(void) { if (onowarn != -1) { nowarn = onowarn; @@ -107,6 +107,8 @@ static __inline void RESTORE(void) #endif %} +%expect 1 + %union { int y_int; val_t *y_val; @@ -118,6 +120,7 @@ static __inline void RESTORE(void) tqual_t y_tqual; type_t *y_type; tnode_t *y_tnode; + range_t y_range; strg_t *y_strg; pqinf_t *y_pqinf; }; @@ -243,6 +246,8 @@ static __inline void RESTORE(void) %type parameter_type_list %type parameter_declaration %type expr +%type expr_stmnt_val +%type expr_stmnt_list %type term %type func_arg_list %type point_or_arrow @@ -253,6 +258,8 @@ static __inline void RESTORE(void) %type string %type string2 %type opt_asm_or_symbolrename +%type range +%type lorange %% @@ -682,12 +689,12 @@ notype_member_decl: $$ = $1; } | notype_decl T_COLON constant { - $$ = bitfield($1, toicon($3)); + $$ = bitfield($1, toicon($3, 1)); } | { symtyp = FVFT; } T_COLON constant { - $$ = bitfield(NULL, toicon($3)); + $$ = bitfield(NULL, toicon($3, 1)); } ; @@ -696,12 +703,12 @@ type_member_decl: $$ = $1; } | type_decl T_COLON constant { - $$ = bitfield($1, toicon($3)); + $$ = bitfield($1, toicon($3, 1)); } | { symtyp = FVFT; } T_COLON constant { - $$ = bitfield(NULL, toicon($3)); + $$ = bitfield(NULL, toicon($3, 1)); } ; @@ -784,7 +791,7 @@ enumerator: $$ = ename($1, enumval, 1); } | ename T_ASSIGN constant { - $$ = ename($1, toicon($3), 0); + $$ = ename($1, toicon($3, 1), 0); } ; @@ -849,7 +856,7 @@ notype_direct_decl: $$ = addarray($1, 0, 0); } | notype_direct_decl T_LBRACK constant T_RBRACK { - $$ = addarray($1, 1, toicon($3)); + $$ = addarray($1, 1, toicon($3, 0)); } | notype_direct_decl param_list { $$ = addfunc($1, $2); @@ -878,7 +885,7 @@ type_direct_decl: $$ = addarray($1, 0, 0); } | type_direct_decl T_LBRACK constant T_RBRACK { - $$ = addarray($1, 1, toicon($3)); + $$ = addarray($1, 1, toicon($3, 0)); } | type_direct_decl param_list { $$ = addfunc($1, $2); @@ -914,7 +921,7 @@ direct_param_decl: $$ = addarray($1, 0, 0); } | direct_param_decl T_LBRACK constant T_RBRACK { - $$ = addarray($1, 1, toicon($3)); + $$ = addarray($1, 1, toicon($3, 0)); } | direct_param_decl param_list { $$ = addfunc($1, $2); @@ -943,7 +950,7 @@ direct_notype_param_decl: $$ = addarray($1, 0, 0); } | direct_notype_param_decl T_LBRACK constant T_RBRACK { - $$ = addarray($1, 1, toicon($3)); + $$ = addarray($1, 1, toicon($3, 0)); } | direct_notype_param_decl param_list { $$ = addfunc($1, $2); @@ -1121,6 +1128,7 @@ init_expr: expr %prec T_COMMA { mkinit($1); } + | init_by_name init_expr %prec T_COMMA | init_lbrace init_expr_list init_rbrace | init_lbrace init_expr_list T_COMMA init_rbrace | error @@ -1131,6 +1139,38 @@ init_expr_list: | init_expr_list T_COMMA init_expr ; +lorange: + constant T_ELLIPSE { + $$.lo = toicon($1, 1); + } + ; +range: + constant { + $$.lo = toicon($1, 1); + $$.hi = $$.lo + 1; + } + | lorange constant { + $$.lo = $1.lo; + $$.hi = toicon($2, 1); + } + ; + +init_by_name: + T_LBRACK range T_RBRACK T_ASSIGN { + if (!Sflag) + warning(321); + } + | point identifier T_ASSIGN { + if (!Sflag) + warning(313); + memberpush($2); + } + | identifier T_COLON { + gnuism(315); + memberpush($1); + } + ; + init_lbrace: T_LBRACE { initlbr(); @@ -1187,13 +1227,13 @@ direct_abs_decl: $$ = addarray(aname(), 0, 0); } | T_LBRACK constant T_RBRACK { - $$ = addarray(aname(), 1, toicon($2)); + $$ = addarray(aname(), 1, toicon($2, 0)); } | direct_abs_decl T_LBRACK T_RBRACK { $$ = addarray($1, 0, 0); } | direct_abs_decl T_LBRACK constant T_RBRACK { - $$ = addarray($1, 1, toicon($3)); + $$ = addarray($1, 1, toicon($3, 0)); } | abs_decl_param_list { $$ = addfunc(aname(), $1); @@ -1207,9 +1247,8 @@ direct_abs_decl: } ; -stmnt: +non_expr_stmnt: labeled_stmnt - | expr_stmnt | comp_stmnt | selection_stmnt | iteration_stmnt @@ -1217,6 +1256,10 @@ stmnt: ftflg = 0; } | asm_stmnt + +stmnt: + expr_stmnt + | non_expr_stmnt ; labeled_stmnt: @@ -1231,7 +1274,12 @@ label: | T_CASE constant T_COLON { label(T_CASE, NULL, $2); ftflg = 1; - } + } + | T_CASE constant T_ELLIPSE constant T_COLON { + /* XXX: We don't fill all cases */ + label(T_CASE, NULL, $2); + ftflg = 1; + } | T_DEFAULT T_COLON { label(T_DEFAULT, NULL, NULL); ftflg = 1; @@ -1239,11 +1287,11 @@ label: ; comp_stmnt: - compstmnt_lbrace declaration_list opt_stmnt_list compstmnt_rbrace - | compstmnt_lbrace opt_stmnt_list compstmnt_rbrace + comp_stmnt_lbrace declaration_list opt_stmnt_list comp_stmnt_rbrace + | comp_stmnt_lbrace opt_stmnt_list comp_stmnt_rbrace ; -compstmnt_lbrace: +comp_stmnt_lbrace: T_LBRACE { blklev++; mblklev++; @@ -1251,7 +1299,7 @@ compstmnt_lbrace: } ; -compstmnt_rbrace: +comp_stmnt_rbrace: T_RBRACE { popdecl(); freeblk(); @@ -1276,7 +1324,7 @@ stmnt_list: expr_stmnt: expr T_SEMI { - expr($1, 0, 0); + expr($1, 0, 0, 1); ftflg = 0; } | T_SEMI { @@ -1284,6 +1332,34 @@ expr_stmnt: } ; +/* + * The following two productions are used to implement + * ({ [[decl-list] stmt-list] }). + * XXX: This is not well tested. + */ +expr_stmnt_val: + expr T_SEMI { + /* XXX: We should really do that only on the last name */ + if ($1->tn_op == NAME) + $1->tn_sym->s_used = 1; + $$ = $1; + expr($1, 0, 0, 0); + ftflg = 0; + } + | non_expr_stmnt { + $$ = getnode(); + $$->tn_type = gettyp(VOID); + } + ; + +expr_stmnt_list: + expr_stmnt_val + | expr_stmnt_list expr_stmnt_val { + $$ = $2; + } + | expr_stmnt_list expr_stmnt_val + ; + selection_stmnt: if_without_else { SAVE(); @@ -1525,6 +1601,26 @@ term: $2->tn_parn = 1; $$ = $2; } + | T_LPARN comp_stmnt_lbrace declaration_list expr_stmnt_list { + blklev--; + mblklev--; + initsym = mktempsym(duptyp($4->tn_type)); + mblklev++; + blklev++; + gnuism(320); + } comp_stmnt_rbrace T_RPARN { + $$ = getnnode(initsym, 0); + } + | T_LPARN comp_stmnt_lbrace expr_stmnt_list { + blklev--; + mblklev--; + initsym = mktempsym($3->tn_type); + mblklev++; + blklev++; + gnuism(320); + } comp_stmnt_rbrace T_RPARN { + $$ = getnnode(initsym, 0); + } | term T_INCDEC { $$ = build($2 == INC ? INCAFT : DECAFT, $1, NULL); } @@ -1580,6 +1676,14 @@ term: | T_LPARN type_name T_RPARN term %prec T_UNOP { $$ = cast($4, $2); } + | T_LPARN type_name T_RPARN %prec T_UNOP { + sym_t *tmp = mktempsym($2); + idecl(tmp, 1, NULL); + } init_lbrace init_expr_list init_rbrace { + if (!Sflag) + gnuism(319); + $$ = getnnode(initsym, 0); + } ; string: @@ -1620,6 +1724,13 @@ point_or_arrow: } ; +point: + T_STROP { + if ($1 != POINT) + error(249); + } + ; + identifier: T_NAME { $$ = $1; @@ -1635,7 +1746,6 @@ identifier: int yyerror(char *msg) { - error(249); if (++sytxerr >= 5) norecover(); @@ -1670,13 +1780,13 @@ q_gt(int64_t a, int64_t b) * expressions, it frees the memory used for the expression. */ static int -toicon(tnode_t *tn) +toicon(tnode_t *tn, int required) { int i; tspec_t t; val_t *v; - v = constant(tn); + v = constant(tn, required); /* * Abstract declarations are used inside expression. To free @@ -1721,7 +1831,7 @@ idecl(sym_t *decl, int initflg, sbuf_t *rename) case EXTERN: if (rename != NULL) { if (decl->s_rename != NULL) - lerror("idecl() 1"); + LERROR("idecl()"); s = getlblk(1, rename->sb_len + 1); (void)memcpy(s, rename->sb_name, rename->sb_len + 1); @@ -1749,7 +1859,7 @@ idecl(sym_t *decl, int initflg, sbuf_t *rename) decl1loc(decl, initflg); break; default: - lerror("idecl() 2"); + LERROR("idecl()"); } if (initflg && !initerr) diff --git a/usr.bin/xlint/lint1/decl.c b/usr.bin/xlint/lint1/decl.c index e62882ff3a32..ace50b6ed8a0 100644 --- a/usr.bin/xlint/lint1/decl.c +++ b/usr.bin/xlint/lint1/decl.c @@ -1,4 +1,4 @@ -/* $NetBSD: decl.c,v 1.29 2002/01/18 21:01:39 thorpej Exp $ */ +/* $NetBSD: decl.c,v 1.33 2004/06/20 22:20:16 jmc Exp $ */ /* * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. @@ -34,7 +34,7 @@ #include #if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: decl.c,v 1.29 2002/01/18 21:01:39 thorpej Exp $"); +__RCSID("$NetBSD: decl.c,v 1.33 2004/06/20 22:20:16 jmc Exp $"); #endif __FBSDID("$FreeBSD$"); @@ -197,7 +197,7 @@ setcompl(type_t *tp, int ic) tp->t_str->sincompl = ic; } else { if (t != ENUM) - lerror("setcompl() 1"); + LERROR("setcompl()"); tp->t_enum->eincompl = ic; } } @@ -256,7 +256,7 @@ addtype(type_t *tp) * something like "typedef int a; int a b;" * This should not happen with current grammar. */ - lerror("addtype()"); + LERROR("addtype()"); } dcs->d_type = tp; return; @@ -297,7 +297,7 @@ addtype(type_t *tp) dcs->d_lmod = NOTSPEC; if (!quadflg) /* %s C does not support 'long long' */ - (void)gnuism(265, tflag ? "traditional" : "ANSI"); + (void)c99ism(265, tflag ? "traditional" : "c89"); } if (dcs->d_type != NULL && dcs->d_type->t_typedef) { @@ -466,7 +466,7 @@ addqual(tqual_t q) dcs->d_const = 1; } else { if (q != VOLATILE) - lerror("addqual() 1"); + LERROR("addqual()"); if (dcs->d_volatile) { /* duplicate "%s" */ warning(10, "volatile"); @@ -508,13 +508,13 @@ popdecl(void) (void)printf("popdecl(%d)\n", (int)dcs->d_ctx); if (dcs->d_nxt == NULL) - lerror("popdecl() 1"); + LERROR("popdecl()"); di = dcs; dcs = di->d_nxt; switch (di->d_ctx) { case EXTERN: /* there is nothing after external declarations */ - lerror("popdecl() 2"); + LERROR("popdecl()"); /* NOTREACHED */ case MOS: case MOU: @@ -562,7 +562,7 @@ popdecl(void) rmsyms(di->d_dlsyms); break; default: - lerror("popdecl() 3"); + LERROR("popdecl()"); } free(di); } @@ -635,7 +635,7 @@ deftyp(void) if (tp != NULL && (t != NOTSPEC || s != NOTSPEC || l != NOTSPEC)) { /* should never happen */ - lerror("deftyp() 1"); + LERROR("deftyp()"); } if (tp == NULL) { @@ -674,7 +674,7 @@ deftyp(void) case VOID: break; default: - lerror("deftyp() 2"); + LERROR("deftyp()"); } if (t != INT && t != CHAR && (s != NOTSPEC || l != NOTSPEC)) { dcs->d_terr = 1; @@ -712,13 +712,13 @@ deftyp(void) if (dcs->d_const && dcs->d_type->t_const) { if (!dcs->d_type->t_typedef) - lerror("deftyp() 3"); + LERROR("deftyp()"); /* typedef already qualified with "%s" */ warning(68, "const"); } if (dcs->d_volatile && dcs->d_type->t_volatile) { if (!dcs->d_type->t_typedef) - lerror("deftyp() 4"); + LERROR("deftyp()"); /* typedef already qualified with "%s" */ warning(68, "volatile"); } @@ -777,7 +777,7 @@ length(type_t *tp, const char *name) switch (tp->t_tspec) { case FUNC: /* compiler takes size of function */ - lerror("%s", msgs[12]); + LERROR("%s", msgs[12]); /* NOTREACHED */ case STRUCT: case UNION: @@ -796,7 +796,7 @@ length(type_t *tp, const char *name) default: elsz = size(tp->t_tspec); if (elsz <= 0) - lerror("length()"); + LERROR("length()"); break; } return (elem * elsz); @@ -831,7 +831,7 @@ getbound(type_t *tp) } } if (a < CHAR_BIT || a > LINT_ALIGN(1) * CHAR_BIT) - lerror("getbound() 1"); + LERROR("getbound()"); return (a); } @@ -925,7 +925,7 @@ chktyp(sym_t *sym) if (dcs->d_ctx == PARG) { if (sym->s_scl != ABSTRACT) { if (sym->s_name == unnamed) - lerror("chktyp()"); + LERROR("chktyp()"); /* void param cannot have name: %s */ error(61, sym->s_name); *tpp = gettyp(INT); @@ -963,12 +963,12 @@ decl1str(sym_t *dsym) scl_t sc; if ((sc = dsym->s_scl) != MOS && sc != MOU) - lerror("decl1str() 1"); + LERROR("decl1str()"); if (dcs->d_rdcsym != NULL) { if ((sc = dcs->d_rdcsym->s_scl) != MOS && sc != MOU) /* should be ensured by storesym() */ - lerror("decl1str() 2"); + LERROR("decl1str()"); if (dsym->s_styp == dcs->d_rdcsym->s_styp) { /* duplicate member name: %s */ error(33, dsym->s_name); @@ -991,11 +991,13 @@ decl1str(sym_t *dsym) t == SHORT || t == USHORT || t == ENUM) { if (bitfieldtype_ok == 0) { if (sflag) { + char buf[64]; /* * bit-field type '%s' invalid in * ANSI C */ - warning(273, tyname(tp)); + warning(273, + tyname(buf, sizeof(buf), tp)); } else if (pflag) { /* nonportable bit-field type */ warning(34); @@ -1051,7 +1053,7 @@ decl1str(sym_t *dsym) if ((sz = length(dsym->s_type, dsym->s_name)) == 0) { if (t == ARRAY && dsym->s_type->t_dim == 0) { /* illegal zero sized structure member: %s */ - warning(39, dsym->s_name); + c99ism(39, dsym->s_name); } } @@ -1221,12 +1223,12 @@ addarray(sym_t *decl, int dim, int n) tp->t_dim = n; if (n < 0) { - /* zero or negative array dimension */ - error(20); + /* negative array dimension */ + error(20, n); n = 0; } else if (n == 0 && dim) { - /* zero or negative array dimension */ - warning(20); + /* zero array dimension */ + c99ism(322, dim); } else if (n == 0 && !dim) { /* is incomplete type */ setcompl(tp, 1); @@ -1417,7 +1419,7 @@ dname(sym_t *sym) } else if (sc == EXTERN) { sym->s_def = DECL; } else { - lerror("dname() 1"); + LERROR("dname()"); } break; case PARG: @@ -1430,7 +1432,7 @@ dname(sym_t *sym) sym->s_reg = 1; sc = AUTO; } else { - lerror("dname() 2"); + LERROR("dname()"); } sym->s_def = DEF; break; @@ -1453,11 +1455,11 @@ dname(sym_t *sym) } else if (sc == EXTERN) { sym->s_def = DECL; } else { - lerror("dname() 3"); + LERROR("dname()"); } break; default: - lerror("dname() 4"); + LERROR("dname()"); } sym->s_scl = sc; @@ -1481,7 +1483,7 @@ iname(sym_t *sym) /* redeclaration of formal parameter %s */ error(21, sym->s_name); if (!sym->s_defarg) - lerror("iname()"); + LERROR("iname()"); } sym = pushdown(sym); } @@ -1514,7 +1516,7 @@ mktag(sym_t *tag, tspec_t kind, int decl, int semi) } else if (kind == ENUM) { scl = ENUMTAG; } else { - lerror("mktag()"); + LERROR("mktag()"); } if (tag != NULL) { @@ -1636,7 +1638,7 @@ scltoa(scl_t sc) case STRTAG: s = "struct"; break; case UNIONTAG: s = "union"; break; case ENUMTAG: s = "enum"; break; - default: lerror("tagttoa()"); + default: LERROR("tagttoa()"); } return (s); } @@ -1664,7 +1666,7 @@ compltag(type_t *tp, sym_t *fmem) sp->memb = fmem; if (sp->size == 0) { /* zero sized %s */ - (void)gnuism(47, ttab[t].tt_name); + (void)c99ism(47, ttab[t].tt_name); } else { n = 0; for (mem = fmem; mem != NULL; mem = mem->s_nxt) { @@ -2143,7 +2145,7 @@ compltyp(sym_t *dsym, sym_t *ssym) while ((dst = *dstp) != NULL) { if (src == NULL || dst->t_tspec != src->t_tspec) - lerror("compltyp() 1"); + LERROR("compltyp()"); if (dst->t_tspec == ARRAY) { if (dst->t_dim == 0 && src->t_dim != 0) { *dstp = dst = duptyp(dst); @@ -2472,7 +2474,7 @@ decl1loc(sym_t *dsym, int initflg) */ break; default: - lerror("decl1loc() 1"); + LERROR("decl1loc()"); } } else if (dcs->d_rdcsym->s_blklev == blklev) { @@ -2621,7 +2623,7 @@ aname(void) sym_t *sym; if (dcs->d_ctx != ABSTRACT && dcs->d_ctx != PARG) - lerror("aname()"); + LERROR("aname()"); sym = getblk(sizeof (sym_t)); @@ -2791,7 +2793,7 @@ chkausg(int novar, sym_t *arg) { if (!arg->s_set) - lerror("chkausg() 1"); + LERROR("chkausg()"); if (novar) return; @@ -2810,7 +2812,7 @@ chkvusg(int novar, sym_t *sym) sym_t *xsym; if (blklev == 0 || sym->s_blklev == 0) - lerror("chkvusg() 1"); + LERROR("chkvusg()"); /* errors in expressions easily cause lots of these warnings */ if (nerr != 0) @@ -2875,7 +2877,7 @@ chklusg(sym_t *lab) { if (blklev != 1 || lab->s_blklev != 1) - lerror("chklusg() 1"); + LERROR("chklusg()"); if (lab->s_set && !lab->s_used) { STRUCT_ASSIGN(curr_pos, lab->s_spos); @@ -2914,7 +2916,7 @@ chktusg(sym_t *sym) warning(235, sym->s_name); break; default: - lerror("chktusg() 1"); + LERROR("chktusg()"); } } @@ -2946,7 +2948,7 @@ chkglsyms(void) chktusg(sym); } else { if (sym->s_kind != FMOS) - lerror("chkglsyms() 1"); + LERROR("chkglsyms()"); } } @@ -2961,7 +2963,7 @@ chkglvar(sym_t *sym) return; if (sym->s_scl != EXTERN && sym->s_scl != STATIC) - lerror("chkglvar() 1"); + LERROR("chkglvar()"); glchksz(sym); diff --git a/usr.bin/xlint/lint1/emit1.c b/usr.bin/xlint/lint1/emit1.c index 762945feddbc..4d198d626d7b 100644 --- a/usr.bin/xlint/lint1/emit1.c +++ b/usr.bin/xlint/lint1/emit1.c @@ -1,4 +1,4 @@ -/* $NetBSD: emit1.c,v 1.11 2002/01/31 19:36:54 tv Exp $ */ +/* $NetBSD: emit1.c,v 1.14 2004/06/20 22:20:16 jmc Exp $ */ /* * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. @@ -34,7 +34,7 @@ #include #if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: emit1.c,v 1.11 2002/01/31 19:36:54 tv Exp $"); +__RCSID("$NetBSD: emit1.c,v 1.14 2004/06/20 22:20:16 jmc Exp $"); #endif __FBSDID("$FreeBSD$"); @@ -117,7 +117,7 @@ outtype(type_t *tp) case STRUCT: t = 'T'; s = 's'; break; case UNION: t = 'T'; s = 'u'; break; default: - lerror("outtyp() 1"); + LERROR("outtyp()"); } if (tp->t_const) outchar('c'); @@ -257,7 +257,7 @@ outsym(sym_t *sym, scl_t sc, def_t def) outchar('e'); break; default: - lerror("outsym() 2"); + LERROR("outsym()"); } if (llibflg && def != DECL) { /* @@ -485,7 +485,7 @@ outfstrg(strg_t *strg) u_char *cp; if (strg->st_tspec != CHAR) - lerror("outfstrg() 1"); + LERROR("outfstrg()"); cp = strg->st_cp; diff --git a/usr.bin/xlint/lint1/err.c b/usr.bin/xlint/lint1/err.c index 5c56638d0637..e05305e4f8c2 100644 --- a/usr.bin/xlint/lint1/err.c +++ b/usr.bin/xlint/lint1/err.c @@ -1,4 +1,4 @@ -/* $NetBSD: err.c,v 1.17 2002/01/31 19:36:54 tv Exp $ */ +/* $NetBSD: err.c,v 1.40 2009/04/15 01:20:57 christos Exp $ */ /* * Copyright (c) 1994, 1995 Jochen Pohl @@ -33,7 +33,7 @@ #include #if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: err.c,v 1.17 2002/01/31 19:36:54 tv Exp $"); +__RCSID("$NetBSD: err.c,v 1.40 2009/04/15 01:20:57 christos Exp $"); #endif __FBSDID("$FreeBSD$"); @@ -76,7 +76,7 @@ const char *msgs[] = { "null dimension", /* 17 */ "illegal use of 'void'", /* 18 */ "void type for %s", /* 19 */ - "zero or negative array dimension", /* 20 */ + "negative array dimension (%d)", /* 20 */ "redeclaration of formal parameter %s", /* 21 */ "incomplete or misplaced function definition", /* 22 */ "undefined label %s", /* 23 */ @@ -95,7 +95,7 @@ const char *msgs[] = { "illegal bit-field size", /* 36 */ "zero size bit-field", /* 37 */ "function illegal in structure or union", /* 38 */ - "illegal zero sized structure member: %s", /* 39 */ + "zero sized array in struct is a C99 extension: %s", /* 39 */ "unknown size: %s", /* 40 */ "illegal use of bit-field", /* 41 */ "forward reference to enum type", /* 42 */ @@ -103,7 +103,7 @@ const char *msgs[] = { "declaration introduces new type in ANSI C: %s %s", /* 44 */ "base type is really '%s %s'", /* 45 */ "(%s) tag redeclared", /* 46 */ - "zero sized %s", /* 47 */ + "zero sized %s is a C9X feature", /* 47 */ "overflow in enumeration values: %s", /* 48 */ "struct or union member must be named", /* 49 */ "a function is declared as an argument: %s", /* 50 */ @@ -188,7 +188,7 @@ const char *msgs[] = { "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 lose accuracy", /* 132 */ "conversion of pointer to '%s' loses bits", /* 133 */ "conversion of pointer to '%s' may lose bits", /* 134 */ "possible pointer alignment problem", /* 135 */ @@ -232,7 +232,7 @@ const char *msgs[] = { "too many array initializers", /* 173 */ "too many initializers", /* 174 */ "initialisation of an incomplete type", /* 175 */ - "invalid initializer", /* 176 */ + "invalid initializer type %s", /* 176 */ "non-constant initializer", /* 177 */ "initializer does not fit", /* 178 */ "cannot initialize struct/union with no named member", /* 179 */ @@ -354,7 +354,7 @@ const char *msgs[] = { "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 */ + "conversion from '%s' to '%s' may lose accuracy, arg #%d", /* 298 */ "prototype does not match old style definition, arg #%d", /* 299 */ "old style definition", /* 300 */ "array of incomplete type", /* 301 */ @@ -369,6 +369,16 @@ const char *msgs[] = { "symbol renaming can't be used on function arguments", /* 310 */ "symbol renaming can't be used on automatic variables", /* 311 */ "%s C does not support // comments", /* 312 */ + "struct or union member name in initializer is a C9X feature",/* 313 */ + "%s is not a structure or a union", /* 314 */ + "GCC style struct or union member name in initializer", /* 315 */ + "__FUNCTION__ is a GCC extension", /* 316 */ + "__func__ is a C9X feature", /* 317 */ + "variable array dimension is a C99/GCC extension", /* 318 */ + "compound literals are a C9X/GCC extension", /* 319 */ + "({ }) is a GCC extension", /* 320 */ + "array initializer with designators is a C9X feature", /* 321 */ + "zero sized array is a C99 extension", /* 322 */ }; /* @@ -377,10 +387,10 @@ const char *msgs[] = { void msglist(void) { - int i; + size_t i; for (i = 0; i < sizeof(msgs) / sizeof(msgs[0]); i++) - printf("%d\t%s\n", i, msgs[i]); + printf("%zu\t%s\n", i, msgs[i]); } /* @@ -451,14 +461,15 @@ error(int n, ...) } void -lerror(const char *msg, ...) +lerror(const char *file, int line, const char *msg, ...) { va_list ap; const char *fn; va_start(ap, msg); fn = lbasename(curr_pos.p_file); - (void)fprintf(stderr, "%s(%d): lint error: ", fn, curr_pos.p_line); + (void)fprintf(stderr, "%s(%d): lint error: %s, %d", fn, curr_pos.p_line, + file, line); (void)vfprintf(stderr, msg, ap); (void)fprintf(stderr, "\n"); va_end(ap); @@ -492,6 +503,33 @@ message(int n, ...) va_end(ap); } +/* + * XXX I think the logic is possibly somewhat screwed up here. The + * question is, how do we want to interpret the -s and -S flags going + * forward? We need to answer that and then we can fix this to be + * "right"... [perry, 2 Nov 2002] +*/ +int +c99ism(int n, ...) +{ + va_list ap; + int msg; + + va_start(ap, n); + if (sflag && !(Sflag || gflag)) { + verror(n, ap); + msg = 1; + } else if (!sflag && (Sflag || gflag)) { + msg = 0; + } else { + vwarning(n, ap); + msg = 1; + } + va_end(ap); + + return (msg); +} + int gnuism(int n, ...) { diff --git a/usr.bin/xlint/lint1/externs1.h b/usr.bin/xlint/lint1/externs1.h index 765c1efc87d3..cf40a5d9199c 100644 --- a/usr.bin/xlint/lint1/externs1.h +++ b/usr.bin/xlint/lint1/externs1.h @@ -1,4 +1,4 @@ -/* $NetBSD: externs1.h,v 1.13 2002/01/18 21:01:39 thorpej Exp $ */ +/* $NetBSD: externs1.h,v 1.20 2002/11/02 20:09:27 perry Exp $ */ /* * Copyright (c) 1994, 1995 Jochen Pohl @@ -29,6 +29,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. + * + * $FreeBSD$ */ /* @@ -50,6 +52,7 @@ extern int vflag; extern int yflag; extern int wflag; extern int zflag; +extern int Sflag; extern void norecover(void); @@ -80,6 +83,7 @@ extern void clrwflgs(void); extern sym_t *getsym(sbuf_t *); extern void cleanup(void); extern sym_t *pushdown(sym_t *); +extern sym_t *mktempsym(type_t *); extern void rmsym(sym_t *); extern void rmsyms(sym_t *); extern void inssym(int, sym_t *); @@ -118,8 +122,9 @@ extern void error(int, ...); extern void warning(int, ...); extern void message(int, ...); extern int gnuism(int, ...); -extern void lerror(const char *, ...) - __attribute__((__noreturn__,__format__(__printf__, 1, 2))); +extern int c99ism(int, ...); +extern void lerror(const char *, int, const char *, ...) + __attribute__((__noreturn__,__format__(__printf__, 3, 4))); /* * decl.c @@ -194,13 +199,14 @@ extern int typeok(op_t, int, 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 const char *tyname(type_t *); +extern const char *tyname(char *, size_t, type_t *); +extern const char *basictyname(tspec_t); extern tnode_t *bldszof(type_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 *); -extern val_t *constant(tnode_t *); -extern void expr(tnode_t *, int, int); +extern val_t *constant(tnode_t *, int); +extern void expr(tnode_t *, int, int, int); 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 *); @@ -273,6 +279,7 @@ extern void prepinit(void); extern void initrbr(void); extern void initlbr(void); extern void mkinit(tnode_t *); +extern void memberpush(sbuf_t *); /* * emit.c diff --git a/usr.bin/xlint/lint1/func.c b/usr.bin/xlint/lint1/func.c index f34baa1ff2e7..118aa6812e17 100644 --- a/usr.bin/xlint/lint1/func.c +++ b/usr.bin/xlint/lint1/func.c @@ -1,4 +1,4 @@ -/* $NetBSD: func.c,v 1.16 2002/01/03 04:25:15 thorpej Exp $ */ +/* $NetBSD: func.c,v 1.22 2005/09/24 15:30:35 perry Exp $ */ /* * Copyright (c) 1994, 1995 Jochen Pohl @@ -167,7 +167,7 @@ popctrl(int env) clst_t *cl; if (cstk == NULL || cstk->c_env != env) - lerror("popctrl() 1"); + LERROR("popctrl()"); cstk = (ci = cstk)->c_nxt; @@ -220,7 +220,7 @@ funcdef(sym_t *fsym) for (sym = dcs->d_fpsyms; sym != NULL; sym = sym->s_dlnxt) { if (sym->s_blklev != -1) { if (sym->s_blklev != 1) - lerror("funcdef() 1"); + LERROR("funcdef()"); inssym(1, sym); } } @@ -264,12 +264,12 @@ funcdef(sym_t *fsym) for (arg = fsym->s_type->t_args; arg != NULL; arg = arg->s_nxt) { if (arg->s_scl == ABSTRACT) { if (arg->s_name != unnamed) - lerror("funcdef() 2"); + LERROR("funcdef()"); /* formal parameter lacks name: param #%d */ error(59, n); } else { if (arg->s_name == unnamed) - lerror("funcdef() 3"); + LERROR("funcdef()"); } n++; } @@ -389,7 +389,7 @@ funcend(void) * the symbol table */ if (dcs->d_nxt != NULL || dcs->d_ctx != EXTERN) - lerror("funcend() 1"); + LERROR("funcend()"); rmsyms(dcs->d_fpsyms); /* must be set on level 0 */ @@ -446,7 +446,7 @@ label(int typ, sym_t *sym, tnode_t *tn) if (tn != NULL) { if (ci->c_swtype == NULL) - lerror("label() 1"); + LERROR("label()"); if (reached && !ftflg) { if (hflag) @@ -466,7 +466,7 @@ label(int typ, sym_t *sym, tnode_t *tn) * get the value of the expression and convert it * to the type of the switch expression */ - v = constant(tn); + v = constant(tn, 1); (void) memset(&nv, 0, sizeof nv); cvtcon(CASE, 0, ci->c_swtype, &nv, v); free(v); @@ -532,7 +532,7 @@ if1(tnode_t *tn) tn = cconv(tn); if (tn != NULL) tn = promote(NOOP, 0, tn); - expr(tn, 0, 1); + expr(tn, 0, 1, 1); pushctrl(T_IF); } @@ -606,7 +606,7 @@ switch1(tnode_t *tn) tp->t_tspec = INT; } - expr(tn, 1, 0); + expr(tn, 1, 0, 1); pushctrl(T_SWITCH); cstk->c_switch = 1; @@ -627,7 +627,7 @@ switch2(void) clst_t *cl; if (cstk->c_swtype == NULL) - lerror("switch2() 1"); + LERROR("switch2()"); /* * If the switch expression was of type enumeration, count the case @@ -637,7 +637,7 @@ switch2(void) if (cstk->c_swtype->t_isenum) { nenum = nclab = 0; if (cstk->c_swtype->t_enum == NULL) - lerror("switch2() 2"); + LERROR("switch2()"); for (esym = cstk->c_swtype->t_enum->elem; esym != NULL; esym = esym->s_nxt) { nenum++; @@ -704,7 +704,7 @@ while1(tnode_t *tn) } } - expr(tn, 0, 1); + expr(tn, 0, 1, 1); } /* @@ -775,7 +775,7 @@ do2(tnode_t *tn) } } - expr(tn, 0, 1); + expr(tn, 0, 1, 1); /* * The end of the loop is only reached if it is no endless loop @@ -818,7 +818,7 @@ for1(tnode_t *tn1, tnode_t *tn2, tnode_t *tn3) STRUCT_ASSIGN(cstk->c_cfpos, csrc_pos); if (tn1 != NULL) - expr(tn1, 0, 0); + expr(tn1, 0, 0, 1); if (tn2 != NULL) tn2 = cconv(tn2); @@ -830,7 +830,7 @@ for1(tnode_t *tn1, tnode_t *tn2, tnode_t *tn3) tn2 = NULL; } if (tn2 != NULL) - expr(tn2, 0, 1); + expr(tn2, 0, 1, 1); if (tn2 == NULL) { cstk->c_infinite = 1; @@ -877,7 +877,7 @@ for2(void) } if (tn3 != NULL) { - expr(tn3, 0, 0); + expr(tn3, 0, 0, 1); } else { tfreeblk(); } @@ -1014,7 +1014,7 @@ doreturn(tnode_t *tn) } } - expr(tn, 1, 0); + expr(tn, 1, 0, 1); } else { diff --git a/usr.bin/xlint/lint1/init.c b/usr.bin/xlint/lint1/init.c index cf4cbddfa98f..9a10b3357915 100644 --- a/usr.bin/xlint/lint1/init.c +++ b/usr.bin/xlint/lint1/init.c @@ -1,4 +1,4 @@ -/* $NetBSD: init.c,v 1.9 2001/09/18 18:15:54 wiz Exp $ */ +/* $NetBSD: init.c,v 1.10 2002/01/31 19:36:54 tv Exp $ */ /* * Copyright (c) 1994, 1995 Jochen Pohl @@ -33,11 +33,13 @@ #include #if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: init.c,v 1.9 2001/09/18 18:15:54 wiz Exp $"); +__RCSID("$NetBSD: init.c,v 1.10 2002/01/31 19:36:54 tv Exp $"); #endif __FBSDID("$FreeBSD$"); +#include #include +#include #include "lint1.h" @@ -54,6 +56,15 @@ sym_t *initsym; /* Points to the top element of the initialisation stack. */ istk_t *initstk; +typedef struct namlist { + const char *n_name; + struct namlist *n_prev; + struct namlist *n_next; +} namlist_t; + +/* Points to a c9x named member; */ +namlist_t *namedmem = NULL; + static void popi2(void); static void popinit(int); @@ -61,6 +72,53 @@ static void pushinit(void); static void testinit(void); static void nextinit(int); static int strginit(tnode_t *); +static void memberpop(void); + +#ifndef DEBUG +#define DPRINTF(a) +#else +#define DPRINTF(a) printf a +#endif + +void +memberpush(sb) + sbuf_t *sb; +{ + namlist_t *nam = xcalloc(1, sizeof (namlist_t)); + nam->n_name = sb->sb_name; + DPRINTF(("memberpush = %s\n", nam->n_name)); + if (namedmem == NULL) { + nam->n_prev = nam->n_next = nam; + namedmem = nam; + } else { + namedmem->n_prev->n_next = nam; + nam->n_prev = namedmem->n_prev; + nam->n_next = namedmem; + namedmem->n_prev = nam; + } +#if 0 + nam->n_next = namedmem; + namedmem = nam; +#endif +} + +static void +memberpop() +{ + DPRINTF(("memberpop = %s\n", namedmem->n_name)); + if (namedmem->n_next == namedmem) { + free(namedmem); + namedmem = NULL; + } else { + namlist_t *nam = namedmem; + namedmem = namedmem->n_next; + free(nam); + } +#if 0 + namedmem = namedmem->n_next; + free(nam); +#endif +} /* @@ -97,29 +155,53 @@ prepinit(void) static void popi2(void) { +#ifdef DEBUG + char buf[64]; +#endif istk_t *istk; sym_t *m; initstk = (istk = initstk)->i_nxt; if (initstk == NULL) - lerror("popi2() 1"); + LERROR("popi2()"); free(istk); istk = initstk; istk->i_cnt--; if (istk->i_cnt < 0) - lerror("popi2() 3"); + LERROR("popi2()"); + DPRINTF(("popi2(): %d %s\n", istk->i_cnt, + namedmem ? namedmem->n_name : "*null*")); + if (istk->i_cnt >= 0 && namedmem != NULL) { + DPRINTF(("popi2(): %d %s %s\n", istk->i_cnt, + tyname(buf, sizeof(buf), istk->i_type), namedmem->n_name)); + for (m = istk->i_type->t_str->memb; m != NULL; m = m->s_nxt) { + if (m->s_field && m->s_name == unnamed) + continue; + if (strcmp(m->s_name, namedmem->n_name) == 0) { + istk->i_subt = m->s_type; + istk->i_cnt++; + memberpop(); + return; + } + } + error(101, namedmem->n_name); + memberpop(); + istk->i_namedmem = 1; + return; + } /* * If the removed element was a structure member, we must go * to the next structure member. */ - if (istk->i_cnt > 0 && istk->i_type->t_tspec == STRUCT) { + if (istk->i_cnt > 0 && istk->i_type->t_tspec == STRUCT && + !istk->i_namedmem) { do { m = istk->i_mem = istk->i_mem->s_nxt; if (m == NULL) - lerror("popi2() 2"); + LERROR("popi2()"); } while (m->s_field && m->s_name == unnamed); istk->i_subt = m->s_type; } @@ -128,6 +210,7 @@ popi2(void) static void popinit(int brace) { + DPRINTF(("popinit(%d)\n", brace)); if (brace) { /* @@ -154,6 +237,9 @@ popinit(int brace) static void pushinit(void) { +#ifdef DEBUG + char buf[64]; +#endif istk_t *istk; int cnt; sym_t *m; @@ -162,35 +248,45 @@ pushinit(void) /* Extend an incomplete array type by one element */ if (istk->i_cnt == 0) { + DPRINTF(("pushinit(extend) %s\n", tyname(buf, sizeof(buf), + istk->i_type))); /* * Inside of other aggregate types must not be an incomplete * type. */ if (istk->i_nxt->i_nxt != NULL) - lerror("pushinit() 1"); + LERROR("pushinit()"); istk->i_cnt = 1; if (istk->i_type->t_tspec != ARRAY) - lerror("pushinit() 2"); + LERROR("pushinit()"); istk->i_type->t_dim++; /* from now its a complete type */ setcompl(istk->i_type, 0); } if (istk->i_cnt <= 0) - lerror("pushinit() 3"); + LERROR("pushinit()"); if (istk->i_type != NULL && issclt(istk->i_type->t_tspec)) - lerror("pushinit() 4"); + LERROR("pushinit() 4"); initstk = xcalloc(1, sizeof (istk_t)); initstk->i_nxt = istk; initstk->i_type = istk->i_subt; if (initstk->i_type->t_tspec == FUNC) - lerror("pushinit() 5"); + LERROR("pushinit()"); +again: istk = initstk; + DPRINTF(("pushinit(%s)\n", tyname(buf, sizeof(buf), istk->i_type))); switch (istk->i_type->t_tspec) { case ARRAY: + if (namedmem) { + DPRINTF(("pushinit ARRAY %s\n", namedmem->n_name)); + free(istk); + initstk = initstk->i_nxt; + goto again; + } if (incompl(istk->i_type) && istk->i_nxt->i_nxt != NULL) { /* initialisation of an incomplete type */ error(175); @@ -200,6 +296,9 @@ pushinit(void) istk->i_subt = istk->i_type->t_subt; istk->i_nolimit = incompl(istk->i_type); istk->i_cnt = istk->i_type->t_dim; + DPRINTF(("elements array %s[%d] %s\n", + tyname(buf, sizeof(buf), istk->i_subt), istk->i_cnt, + namedmem ? namedmem->n_name : "*none*")); break; case UNION: if (tflag) @@ -214,14 +313,38 @@ pushinit(void) return; } cnt = 0; + DPRINTF(("2. member lookup %s %s\n", + tyname(buf, sizeof(buf), istk->i_type), + namedmem ? namedmem->n_name : "*none*")); for (m = istk->i_type->t_str->memb; m != NULL; m = m->s_nxt) { if (m->s_field && m->s_name == unnamed) continue; + if (namedmem != NULL) { + DPRINTF(("pushinit():[member:%s, looking:%s]\n", + m->s_name, namedmem->n_name)); + if (strcmp(m->s_name, namedmem->n_name) == 0) { + cnt++; + break; + } else + continue; + } if (++cnt == 1) { istk->i_mem = m; istk->i_subt = m->s_type; } } + if (namedmem != NULL) { + istk->i_namedmem = 1; + if (m == NULL) { + error(101, namedmem->n_name); + initerr = 1; + } else { + istk->i_mem = m; + istk->i_subt = m->s_type; + } + memberpop(); + cnt = istk->i_type->t_tspec == STRUCT ? 2 : 1; + } if (cnt == 0) { /* cannot init. struct/union with no named member */ error(179); @@ -231,6 +354,12 @@ pushinit(void) istk->i_cnt = istk->i_type->t_tspec == STRUCT ? cnt : 1; break; default: + if (namedmem) { + DPRINTF(("pushinit(): pop\n")); + free(istk); + initstk = initstk->i_nxt; + goto again; + } istk->i_cnt = 1; break; } @@ -247,7 +376,7 @@ testinit(void) * If a closing brace is expected we have at least one initializer * too much. */ - if (istk->i_cnt == 0 && !istk->i_nolimit) { + if (istk->i_cnt == 0 && !istk->i_nolimit && !istk->i_namedmem) { switch (istk->i_type->t_tspec) { case ARRAY: /* too many array initializers */ @@ -270,7 +399,9 @@ testinit(void) static void nextinit(int brace) { + char buf[64]; + DPRINTF(("nextinit(%d)\n", brace)); if (!brace) { if (initstk->i_type == NULL && !issclt(initstk->i_subt->t_tspec)) { @@ -346,14 +477,18 @@ mkinit(tnode_t *tn) tnode_t *ln; struct mbl *tmem; scl_t sc; +#ifdef DEBUG + char buf[64]; +#endif + DPRINTF(("mkinit(%s)\n", tyname(buf, sizeof(buf), tn->tn_type))); if (initerr || tn == NULL) goto end; sc = initsym->s_scl; /* - * Do not test for automatic aggregat initialisation. If the + * Do not test for automatic aggregate initialisation. If the * initializer starts with a brace we have the warning already. * If not, an error will be printed that the initializer must * be enclosed by braces. @@ -369,7 +504,7 @@ mkinit(tnode_t *tn) ln->tn_type = tduptyp(ln->tn_type); ln->tn_type->t_const = 0; tn = build(ASSIGN, ln, tn); - expr(tn, 0, 0); + expr(tn, 0, 0, 1); goto end; } @@ -388,7 +523,7 @@ mkinit(tnode_t *tn) goto end; initstk->i_cnt--; - + DPRINTF(("mkinit() cnt=%d tn=%p\n", initstk->i_cnt, tn)); /* Create a temporary node for the left side. */ ln = tgetblk(sizeof (tnode_t)); ln->tn_op = NAME; @@ -403,7 +538,7 @@ mkinit(tnode_t *tn) rt = tn->tn_type->t_tspec; if (!issclt(lt)) - lerror("mkinit() 1"); + LERROR("mkinit()"); if (!typeok(INIT, 0, ln, tn)) goto end; @@ -413,7 +548,7 @@ mkinit(tnode_t *tn) * expr() would free it. */ tmem = tsave(); - expr(tn, 1, 0); + expr(tn, 1, 0, 1); trestor(tmem); if (isityp(lt) && ln->tn_type->t_isfield && !isityp(rt)) { @@ -444,7 +579,13 @@ mkinit(tnode_t *tn) } end: - tfreeblk(); + /* + * We only free the block, if we are not a compound declaration + * We know that the only symbols that start with a digit are the + * ones we allocate with mktempsym() for compound declarations + */ + if (!isdigit((unsigned char)initsym->s_name[0])) + tfreeblk(); } @@ -466,7 +607,7 @@ strginit(tnode_t *tn) * 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)) || diff --git a/usr.bin/xlint/lint1/lint1.h b/usr.bin/xlint/lint1/lint1.h index 6cfcbb747d2e..1eb1cc2fcdf0 100644 --- a/usr.bin/xlint/lint1/lint1.h +++ b/usr.bin/xlint/lint1/lint1.h @@ -1,4 +1,4 @@ -/* $NetBSD: lint1.h,v 1.12 2002/01/31 19:33:27 tv Exp $ */ +/* $NetBSD: lint1.h,v 1.16 2002/10/21 22:44:08 christos Exp $ */ /* * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. @@ -106,7 +106,7 @@ typedef struct { * 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 @@ -141,7 +141,7 @@ typedef struct type { u_int t_const : 1; /* const modifier */ u_int t_volatile : 1; /* volatile modifier */ u_int t_proto : 1; /* function prototype (t_args valid) */ - u_int t_vararg : 1; /* protoype with ... */ + u_int t_vararg : 1; /* prototype with ... */ u_int t_typedef : 1; /* type defined with typedef */ u_int t_isfield : 1; /* type is bitfield */ u_int t_isenum : 1; /* type is (or was) enum (t_enum valid) */ @@ -221,7 +221,7 @@ typedef struct sym { 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 an inline function */ struct sym *s_xsym; /* for local declared external symbols pointer @@ -347,6 +347,7 @@ typedef struct istk { type_t *i_subt; /* type of next level */ u_int i_brace : 1; /* need } for pop */ u_int i_nolimit : 1; /* incomplete array type */ + u_int i_namedmem : 1; /* has c9x named members */ sym_t *i_mem; /* next structure member */ int i_cnt; /* # of remaining elements */ struct istk *i_nxt; /* previous level */ @@ -396,6 +397,11 @@ typedef struct cstk { struct cstk *c_nxt; /* outer control statement */ } cstk_t; +typedef struct { + size_t lo; + size_t hi; +} range_t; + #include "externs1.h" #define ERR_SETSIZE 1024 @@ -413,4 +419,6 @@ typedef struct err_set { ((p)->errs_bits[(n)/__NERRBITS] & (1 << ((n) % __NERRBITS))) #define ERR_ZERO(p) (void)memset((p), 0, sizeof(*(p))) +#define LERROR(fmt, args...) lerror(__FILE__, __LINE__, fmt, ##args) + extern err_set msgset; diff --git a/usr.bin/xlint/lint1/main1.c b/usr.bin/xlint/lint1/main1.c index 29c872f4ef88..59f6c7f99b40 100644 --- a/usr.bin/xlint/lint1/main1.c +++ b/usr.bin/xlint/lint1/main1.c @@ -1,4 +1,4 @@ -/* $NetBSD: main1.c,v 1.11 2002/01/29 02:43:38 tv Exp $ */ +/* $NetBSD: main1.c,v 1.17 2006/11/08 18:31:15 christos Exp $ */ /* * Copyright (c) 1994, 1995 Jochen Pohl @@ -33,7 +33,7 @@ #include #if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: main1.c,v 1.11 2002/01/29 02:43:38 tv Exp $"); +__RCSID("$NetBSD: main1.c,v 1.17 2006/11/08 18:31:15 christos Exp $"); #endif __FBSDID("$FreeBSD$"); @@ -53,7 +53,7 @@ int yflag; /* * Print warnings if an assignment of an integertype to another integertype - * causes an implizit narrowing conversion. If aflag is 1, these warnings + * causes an implicit 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 greater than 1, they are always printed. */ @@ -101,6 +101,8 @@ int sflag; /* Traditional C mode. */ int tflag; +/* Enable C9X extensions */ +int Sflag; /* * Complain about functions and external variables used and not defined, * or defined and not used. @@ -126,7 +128,7 @@ main(int argc, char *argv[]) char *ptr; ERR_ZERO(&msgset); - while ((c = getopt(argc, argv, "abcdeghmprstuvwyzFX:")) != -1) { + while ((c = getopt(argc, argv, "abcdeghmprstuvwyzFSX:")) != -1) { switch (c) { case 'a': aflag++; break; case 'b': bflag = 1; break; @@ -139,6 +141,7 @@ main(int argc, char *argv[]) case 'p': pflag = 1; break; case 'r': rflag = 1; break; case 's': sflag = 1; break; + case 'S': Sflag = 1; break; case 't': tflag = 1; break; case 'u': uflag = 0; break; case 'w': wflag = 1; break; @@ -154,7 +157,10 @@ main(int argc, char *argv[]) for (ptr = strtok(optarg, ","); ptr; ptr = strtok(NULL, ",")) { char *eptr; - long msg = strtol(ptr, &eptr, 0); + long msg; + + errno = 0; + msg = strtol(ptr, &eptr, 0); if ((msg == LONG_MIN || msg == LONG_MAX) && errno == ERANGE) err(1, "invalid error message id '%s'", @@ -197,7 +203,9 @@ main(int argc, char *argv[]) /* Following warnings cannot be suppressed by LINTED */ nowarn = 0; - +#ifdef DEBUG + printf("%s, %d: nowarn = 0\n", curr_pos.p_file, curr_pos.p_line); +#endif chkglsyms(); outclose(); @@ -209,7 +217,7 @@ static void usage(void) { (void)fprintf(stderr, - "usage: lint1 [-abcdeghmprstuvwyzF] [-X [,]... src dest\n"); + "usage: lint1 [-abcdeghmprstuvwyzFS] [-X [,]... src dest\n"); exit(1); } diff --git a/usr.bin/xlint/lint1/makeman b/usr.bin/xlint/lint1/makeman index 7aa060cb3faf..922fe5a13ea0 100644 --- a/usr.bin/xlint/lint1/makeman +++ b/usr.bin/xlint/lint1/makeman @@ -74,7 +74,7 @@ It is intended to be used with .Fl X flag of .Xr lint 1 . -.Bl -column -offset indent "Id#" "Message" +.Bl -column -offset indent "XXXX" __EOF "$@" | sed -e 's/\\/\\e/g' -e "s/'/\\'/" echo ".El" diff --git a/usr.bin/xlint/lint1/scan.l b/usr.bin/xlint/lint1/scan.l index 013a79520b00..5b715177a5f7 100644 --- a/usr.bin/xlint/lint1/scan.l +++ b/usr.bin/xlint/lint1/scan.l @@ -1,5 +1,5 @@ %{ -/* $NetBSD: scan.l,v 1.26 2002/01/31 22:30:21 tv Exp $ */ +/* $NetBSD: scan.l,v 1.37 2007/02/06 00:08:31 he Exp $ */ /* * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. @@ -35,7 +35,7 @@ #include #if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: scan.l,v 1.26 2002/01/31 22:30:21 tv Exp $"); +__RCSID("$NetBSD: scan.l,v 1.37 2007/02/06 00:08:31 he Exp $"); #endif __FBSDID("$FreeBSD$"); @@ -96,12 +96,13 @@ EX ([eE][+-]?[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]? | +0[xX]{HD}+p{HD}+[fFlL]? | \.{D}+{EX}?[fFlL]? return (fcon()); "=" return (operator(T_ASSIGN, ASSIGN)); "*=" return (operator(T_OPASS, MULASS)); @@ -191,55 +192,56 @@ static struct kwtab { 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 */ - u_int kw_stdc : 1; /* STDC keyword */ - u_int kw_gcc : 1; /* GCC keyword */ + u_int kw_c89; /* c89 keyword */ + u_int kw_c99; /* c99 keyword */ + u_int kw_gcc; /* 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 }, - { "__symbolrename", T_SYMBOLRENAME, 0, 0, 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, 0, 0, 0, 1 }, + { "__asm", T_ASM, 0, 0, 0, 0, 0, 0 }, + { "__asm__", T_ASM, 0, 0, 0, 0, 0, 0 }, + { "auto", T_SCLASS, AUTO, 0, 0, 0, 0, 0 }, + { "break", T_BREAK, 0, 0, 0, 0, 0, 0 }, + { "case", T_CASE, 0, 0, 0, 0, 0, 0 }, + { "char", T_TYPE, 0, CHAR, 0, 0, 0, 0 }, + { "const", T_QUAL, 0, 0, CONST, 1, 0, 0 }, + { "__const__", T_QUAL, 0, 0, CONST, 0, 0, 0 }, + { "__const", T_QUAL, 0, 0, CONST, 0, 0, 0 }, + { "continue", T_CONTINUE, 0, 0, 0, 0, 0, 0 }, + { "default", T_DEFAULT, 0, 0, 0, 0, 0, 0 }, + { "do", T_DO, 0, 0, 0, 0, 0, 0 }, + { "double", T_TYPE, 0, DOUBLE, 0, 0, 0, 0 }, + { "else", T_ELSE, 0, 0, 0, 0, 0, 0 }, + { "enum", T_ENUM, 0, 0, 0, 0, 0, 0 }, + { "extern", T_SCLASS, EXTERN, 0, 0, 0, 0, 0 }, + { "float", T_TYPE, 0, FLOAT, 0, 0, 0, 0 }, + { "for", T_FOR, 0, 0, 0, 0, 0, 0 }, + { "goto", T_GOTO, 0, 0, 0, 0, 0, 0 }, + { "if", T_IF, 0, 0, 0, 0, 0, 0 }, + { "inline", T_SCLASS, INLINE, 0, 0, 0, 1, 0 }, + { "__inline__", T_SCLASS, INLINE, 0, 0, 0, 0, 0 }, + { "__inline", T_SCLASS, INLINE, 0, 0, 0, 0, 0 }, + { "int", T_TYPE, 0, INT, 0, 0, 0, 0 }, + { "__symbolrename", T_SYMBOLRENAME, 0, 0, 0, 0, 0, 0 }, + { "long", T_TYPE, 0, LONG, 0, 0, 0, 0 }, + { "register", T_SCLASS, REG, 0, 0, 0, 0, 0 }, + { "return", T_RETURN, 0, 0, 0, 0, 0, 0 }, + { "short", T_TYPE, 0, SHORT, 0, 0, 0, 0 }, + { "signed", T_TYPE, 0, SIGNED, 0, 1, 0, 0 }, + { "__signed__", T_TYPE, 0, SIGNED, 0, 0, 0, 0 }, + { "__signed", T_TYPE, 0, SIGNED, 0, 0, 0, 0 }, + { "sizeof", T_SIZEOF, 0, 0, 0, 0, 0, 0 }, + { "static", T_SCLASS, STATIC, 0, 0, 0, 0, 0 }, + { "struct", T_SOU, 0, STRUCT, 0, 0, 0, 0 }, + { "switch", T_SWITCH, 0, 0, 0, 0, 0, 0 }, + { "typedef", T_SCLASS, TYPEDEF, 0, 0, 0, 0, 0 }, + { "union", T_SOU, 0, UNION, 0, 0, 0, 0 }, + { "unsigned", T_TYPE, 0, UNSIGN, 0, 0, 0, 0 }, + { "void", T_TYPE, 0, VOID, 0, 0, 0, 0 }, + { "volatile", T_QUAL, 0, 0, VOLATILE, 1, 0, 0 }, + { "__volatile__", T_QUAL, 0, 0, VOLATILE, 0, 0, 0 }, + { "__volatile", T_QUAL, 0, 0, VOLATILE, 0, 0, 0 }, + { "while", T_WHILE, 0, 0, 0, 0, 0, 0 }, + { NULL, 0, 0, 0, 0, 0, 0, 0 } }; /* Symbol table */ @@ -274,7 +276,9 @@ initscan(void) uint64_t uq; for (kw = kwtab; kw->kw_name != NULL; kw++) { - if (kw->kw_stdc && tflag) + if ((kw->kw_c89 || kw->kw_c99) && tflag) + continue; + if (kw->kw_c99 && !(Sflag || gflag)) continue; if (kw->kw_gcc && !gflag) continue; @@ -400,7 +404,7 @@ name(void) if (sym != NULL) { if (blklev < sym->s_blklev) - lerror("name() 1"); + LERROR("name()"); sb->sb_name = sym->s_name; sb->sb_len = strlen(sym->s_name); tok = sym->s_scl == TYPEDEF ? T_TYPENAME : T_NAME; @@ -508,7 +512,7 @@ icon(int base) uq = strtouq(cp, &eptr, base); } if (eptr != cp + len) - lerror("icon() 1"); + LERROR("icon()"); if (errno != 0) /* integer constant out of range */ warning(252); @@ -524,8 +528,10 @@ icon(int base) /* ok */ } else if (ul <= (unsigned)UINT_MAX && base != 10) { typ = UINT; +#if INT_MAX != LONG_MAX } else if (ul <= LONG_MAX) { typ = LONG; +#endif } else { typ = ULONG; } @@ -681,8 +687,24 @@ fcon(void) errno = 0; d = strtod(cp, &eptr); - if (eptr != cp + len) - lerror("fcon() 1"); + if (eptr != cp + len) { + switch (*eptr) { + /* + * XXX: non-native non-current strtod() may not handle hex + * floats, ignore the rest if we find traces of hex float + * syntax... + */ + case 'p': + case 'P': + case 'x': + case 'X': + d = 0; + errno = 0; + break; + default: + LERROR("fcon()"); + } + } if (errno != 0) /* floating-point constant out of range */ warning(248); @@ -1140,7 +1162,7 @@ slashslashcomment(void) { int c; - if (sflag < 2 && !gflag) + if (!Sflag && !gflag) /* // comments only supported in C99 */ (void)gnuism(312, tflag ? "traditional" : "ANSI"); @@ -1299,7 +1321,7 @@ getsym(sbuf_t *sb) if (sym != NULL) { if (sym->s_kind != symtyp) - lerror("storesym() 1"); + LERROR("storesym()"); symtyp = FVFT; freesb(sb); return (sym); @@ -1318,7 +1340,7 @@ getsym(sbuf_t *sb) while (di->d_nxt != NULL && di->d_nxt->d_nxt != NULL) di = di->d_nxt; if (di->d_ctx != AUTO) - lerror("storesym() 2"); + LERROR("storesym()"); } else { sym = getblk(sizeof (sym_t)); sym->s_name = sb->sb_name; @@ -1343,6 +1365,39 @@ getsym(sbuf_t *sb) return (sym); } +/* + * Construct a temporary symbol. The symbol starts with a digit, so that + * it is illegal. + */ +sym_t * +mktempsym(type_t *t) +{ + static int n = 0; + int h; + char *s = getlblk(blklev, 64); + sym_t *sym = getblk(sizeof (sym_t)); + + (void)snprintf(s, 64, "%.8d_tmp", n++); + h = hash(s); + + sym->s_name = s; + sym->s_type = t; + sym->s_blklev = blklev; + sym->s_scl = AUTO; + sym->s_kind = FVFT; + sym->s_used = 1; + sym->s_set = 1; + + if ((sym->s_link = symtab[h]) != NULL) + symtab[h]->s_rlink = &sym->s_link; + (symtab[h] = sym)->s_rlink = &symtab[h]; + + *dcs->d_ldlsym = sym; + dcs->d_ldlsym = &sym->s_dlnxt; + + return sym; +} + /* * Remove a symbol forever from the symbol table. s_blklev * is set to -1 to avoid that the symbol will later be put @@ -1391,7 +1446,7 @@ inssym(int bl, sym_t *sym) (symtab[h] = sym)->s_rlink = &symtab[h]; sym->s_blklev = bl; if (sym->s_link != NULL && sym->s_blklev < sym->s_link->s_blklev) - lerror("inssym()"); + LERROR("inssym()"); } /* @@ -1432,7 +1487,7 @@ pushdown(sym_t *sym) h = hash(sym->s_name); nsym = getblk(sizeof (sym_t)); if (sym->s_blklev > blklev) - lerror("pushdown()"); + LERROR("pushdown()"); nsym->s_name = sym->s_name; UNIQUE_CURR_POS(nsym->s_dpos); nsym->s_kind = sym->s_kind; @@ -1469,7 +1524,7 @@ freeyyv(void *sp, int tok) } else if (strg->st_tspec == WCHAR) { free(strg->st_wcp); } else { - lerror("fryylv() 1"); + LERROR("fryylv()"); } free(strg); } diff --git a/usr.bin/xlint/lint1/tree.c b/usr.bin/xlint/lint1/tree.c index 12417bad3c2b..4989322cb49b 100644 --- a/usr.bin/xlint/lint1/tree.c +++ b/usr.bin/xlint/lint1/tree.c @@ -1,4 +1,4 @@ -/* $NetBSD: tree.c,v 1.24 2002/01/31 22:30:20 tv Exp $ */ +/* $NetBSD: tree.c,v 1.45 2008/03/04 02:41:46 christos Exp $ */ /* * Copyright (c) 1994, 1995 Jochen Pohl @@ -33,7 +33,7 @@ #include #if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: tree.c,v 1.24 2002/01/31 22:30:20 tv Exp $"); +__RCSID("$NetBSD: tree.c,v 1.45 2008/03/04 02:41:46 christos Exp $"); #endif __FBSDID("$FreeBSD$"); @@ -302,13 +302,32 @@ getnnode(sym_t *sym, int ntok) */ sym->s_type = incref(sym->s_type, FUNC); } else { - /* %s undefined */ - error(99, sym->s_name); + if (!blklev) { + /* %s undefined */ + error(99, sym->s_name); + } else { + int fixtype; + if (strcmp(sym->s_name, "__FUNCTION__") == 0) { + gnuism(316); + fixtype = 1; + } else if (strcmp(sym->s_name, "__func__") == 0) { + if (!Sflag) + warning(317); + fixtype = 1; + } else { + error(99, sym->s_name); + fixtype = 0; + } + if (fixtype) { + sym->s_type = incref(gettyp(CHAR), PTR); + sym->s_type->t_const = 1; + } + } } } if (sym->s_kind != FVFT && sym->s_kind != FMOS) - lerror("getnnode() 1"); + LERROR("getnnode()"); n = getnode(); n->tn_type = sym->s_type; @@ -382,6 +401,7 @@ strmemb(tnode_t *tn, op_t op, sym_t *msym) */ if (msym->s_scl == NOSCL) { /* undefined struct/union member: %s */ + fprintf(stderr, "3. %s\n", msym->s_name); error(101, msym->s_name); rmsym(msym); msym->s_kind = FMOS; @@ -651,7 +671,7 @@ build(op_t op, tnode_t *ln, tnode_t *rn) default: rtp = mp->m_logop ? gettyp(INT) : ln->tn_type; if (!mp->m_binary && rn != NULL) - lerror("build() 1"); + LERROR("build()"); ntn = mktnode(op, rtp, ln, rn); break; } @@ -757,10 +777,15 @@ typeok(op_t op, int arg, tnode_t *ln, tnode_t *rn) mp = &modtab[op]; - if ((lt = (ltp = ln->tn_type)->t_tspec) == PTR) + if ((ltp = ln->tn_type) == NULL) + LERROR("typeok()"); + + if ((lt = ltp->t_tspec) == PTR) lst = (lstp = ltp->t_subt)->t_tspec; if (mp->m_binary) { - if ((rt = (rtp = rn->tn_type)->t_tspec) == PTR) + if ((rtp = rn->tn_type) == NULL) + LERROR("typeok()"); + if ((rt = rtp->t_tspec) == PTR) rst = (rstp = rtp->t_subt)->t_tspec; } @@ -1009,8 +1034,10 @@ typeok(op_t op, int arg, tnode_t *ln, tnode_t *rn) error(170); return (0); } + while (rn->tn_op == CVT) + rn = rn->tn_left; if (rn->tn_op != COLON) - lerror("typeok() 2"); + LERROR("typeok()"); break; case COLON: @@ -1149,9 +1176,9 @@ typeok(op_t op, int arg, tnode_t *ln, tnode_t *rn) 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)) { + } else if (mp->m_enumop && (ltp->t_isenum && rtp && rtp->t_isenum)) { chkeop2(op, arg, ln, rn); - } else if (mp->m_enumop && (ltp->t_isenum || rtp->t_isenum)) { + } else if (mp->m_enumop && (ltp->t_isenum || (rtp &&rtp->t_isenum))) { chkeop1(op, arg, ln, rn); } @@ -1409,6 +1436,7 @@ chkeop2(op_t op, int arg, tnode_t *ln, tnode_t *rn) static void chkeop1(op_t op, int arg, tnode_t *ln, tnode_t *rn) { + char lbuf[64], rbuf[64]; if (!eflag) return; @@ -1425,20 +1453,24 @@ chkeop1(op_t op, int arg, tnode_t *ln, tnode_t *rn) return; } /* initialisation of '%s' with '%s' */ - warning(277, tyname(ln->tn_type), tyname(rn->tn_type)); + warning(277, tyname(lbuf, sizeof(lbuf), ln->tn_type), + tyname(rbuf, sizeof(rbuf), rn->tn_type)); break; case FARG: /* combination of '%s' and '%s', arg #%d */ - warning(278, tyname(ln->tn_type), tyname(rn->tn_type), arg); + warning(278, tyname(lbuf, sizeof(lbuf), ln->tn_type), + tyname(rbuf, sizeof(rbuf), rn->tn_type), arg); break; case RETURN: /* combination of '%s' and '%s' in return */ - warning(279, tyname(ln->tn_type), tyname(rn->tn_type)); + warning(279, tyname(lbuf, sizeof(lbuf), ln->tn_type), + tyname(rbuf, sizeof(rbuf), rn->tn_type)); break; default: /* combination of '%s' and %s, op %s */ - warning(242, tyname(ln->tn_type), tyname(rn->tn_type), - modtab[op].m_name); + warning(242, tyname(lbuf, sizeof(lbuf), ln->tn_type), + tyname(rbuf, sizeof(rbuf), rn->tn_type), + modtab[op].m_name); break; } } @@ -1465,7 +1497,7 @@ mktnode(op_t op, type_t *type, tnode_t *ln, tnode_t *rn) if (t != FUNC && t != VOID) ntn->tn_lvalue = 1; } else { - lerror("mktnode() 2"); + LERROR("mktnode()"); } } @@ -1503,7 +1535,7 @@ promote(op_t op, int farg, tnode_t *tn) t = INT; } else { if (size(INT) != len) - lerror("promote() 1"); + LERROR("promote()"); if (isutyp(t)) { t = UINT; } else { @@ -1636,7 +1668,7 @@ convert(op_t op, int arg, type_t *tp, tnode_t *tn) tspec_t nt, ot, ost = NOTSPEC; if (tn->tn_lvalue) - lerror("convert() 1"); + LERROR("convert()"); nt = tp->t_tspec; if ((ot = tn->tn_type->t_tspec) == PTR) @@ -1682,6 +1714,7 @@ static void ptconv(int arg, tspec_t nt, tspec_t ot, type_t *tp, tnode_t *tn) { tnode_t *ptn; + char buf[64]; if (!isatyp(nt) || !isatyp(ot)) return; @@ -1704,9 +1737,10 @@ ptconv(int arg, tspec_t nt, tspec_t ot, type_t *tp, tnode_t *tn) if (isftyp(nt) != isftyp(ot) || psize(nt) != psize(ot)) { /* representation and/or width change */ - if (styp(nt) != SHORT || !isityp(ot) || psize(ot) > psize(INT)) + if (!isityp(ot) || psize(ot) > psize(INT)) { /* conversion to '%s' due to prototype, arg #%d */ - warning(259, tyname(tp), arg); + warning(259, tyname(buf, sizeof(buf), tp), arg); + } } else if (hflag) { /* * they differ in sign or base type (char, short, int, @@ -1720,7 +1754,7 @@ ptconv(int arg, tspec_t nt, tspec_t ot, type_t *tp, tnode_t *tn) /* ok */ } else { /* conversion to '%s' due to prototype, arg #%d */ - warning(259, tyname(tp), arg); + warning(259, tyname(buf, sizeof(buf), tp), arg); } } } @@ -1733,6 +1767,7 @@ ptconv(int arg, tspec_t nt, tspec_t ot, type_t *tp, tnode_t *tn) static void iiconv(op_t op, int arg, tspec_t nt, tspec_t ot, type_t *tp, tnode_t *tn) { + char lbuf[64], rbuf[64]; if (tn->tn_op == CON) return; @@ -1744,9 +1779,10 @@ iiconv(op_t op, int arg, tspec_t nt, tspec_t ot, type_t *tp, tnode_t *tn) /* conversion to %s may sign-extend incorrectly (, arg #%d) */ if (aflag && pflag) { if (op == FARG) { - warning(297, tyname(tp), arg); + warning(297, tyname(lbuf, sizeof(lbuf), tp), + arg); } else { - warning(131, tyname(tp)); + warning(131, tyname(lbuf, sizeof(lbuf), tp)); } } } @@ -1758,9 +1794,14 @@ iiconv(op_t op, int arg, tspec_t nt, tspec_t ot, type_t *tp, tnode_t *tn) /* conversion from '%s' may lose accuracy */ if (aflag) { if (op == FARG) { - warning(298, tyname(tn->tn_type), arg); + warning(298, + tyname(rbuf, sizeof(rbuf), tn->tn_type), + tyname(lbuf, sizeof(lbuf), tp), + arg); } else { - warning(132, tyname(tn->tn_type)); + warning(132, + tyname(rbuf, sizeof(rbuf), tn->tn_type), + tyname(lbuf, sizeof(lbuf), tp)); } } } @@ -1772,6 +1813,7 @@ iiconv(op_t op, int arg, tspec_t nt, tspec_t ot, type_t *tp, tnode_t *tn) static void piconv(op_t op, tspec_t nt, type_t *tp, tnode_t *tn) { + char buf[64]; if (tn->tn_op == CON) return; @@ -1784,10 +1826,10 @@ piconv(op_t op, tspec_t nt, type_t *tp, tnode_t *tn) if (psize(nt) < psize(PTR)) { if (pflag && size(nt) >= size(PTR)) { /* conv. of pointer to %s may lose bits */ - warning(134, tyname(tp)); + warning(134, tyname(buf, sizeof(buf), tp)); } else { /* conv. of pointer to %s loses bits */ - warning(133, tyname(tp)); + warning(133, tyname(buf, sizeof(buf), tp)); } } } @@ -1855,6 +1897,7 @@ ppconv(op_t op, tnode_t *tn, type_t *tp) void cvtcon(op_t op, int arg, type_t *tp, val_t *nv, val_t *v) { + char lbuf[64], rbuf[64]; tspec_t ot, nt; ldbl_t max = 0.0, min = 0.0; int sz, rchk; @@ -1899,18 +1942,21 @@ cvtcon(op_t op, int arg, type_t *tp, val_t *nv, val_t *v) case LDOUBLE: max = LDBL_MAX; min = -LDBL_MAX; break; default: - lerror("cvtcon() 1"); + LERROR("cvtcon()"); } if (v->v_ldbl > max || v->v_ldbl < min) { if (nt == LDOUBLE) - lerror("cvtcon() 2"); + LERROR("cvtcon()"); if (op == FARG) { /* conv. of %s to %s is out of rng., arg #%d */ - warning(295, tyname(gettyp(ot)), tyname(tp), - arg); + warning(295, tyname(lbuf, sizeof(lbuf), + gettyp(ot)), tyname(rbuf, sizeof(rbuf), tp), + arg); } else { /* conversion of %s to %s is out of range */ - warning(119, tyname(gettyp(ot)), tyname(tp)); + warning(119, tyname(lbuf, sizeof(lbuf), + gettyp(ot)), + tyname(rbuf, sizeof(rbuf), tp)); } v->v_ldbl = v->v_ldbl > 0 ? max : min; } @@ -1988,8 +2034,9 @@ cvtcon(op_t op, int arg, type_t *tp, val_t *nv, val_t *v) * extra bits set to 0 in conversion * of '%s' to '%s', op %s */ - warning(309, tyname(gettyp(ot)), - tyname(tp), modtab[op].m_name); + warning(309, tyname(lbuf, sizeof(lbuf), + gettyp(ot)), tyname(rbuf, sizeof(rbuf), tp), + modtab[op].m_name); } else if (nsz < osz && (v->v_quad & xmask) != xmask && (v->v_quad & xmask) != 0) { @@ -2049,11 +2096,14 @@ cvtcon(op_t op, int arg, type_t *tp, val_t *nv, val_t *v) 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); + warning(295, tyname(lbuf, sizeof(lbuf), + gettyp(ot)), tyname(rbuf, sizeof(rbuf), tp), + arg); } else { /* conversion of %s to %s is out of range */ - warning(119, tyname(gettyp(ot)), tyname(tp)); + warning(119, tyname(lbuf, sizeof(lbuf), + gettyp(ot)), + tyname(rbuf, sizeof(rbuf), tp)); } } else if (nv->v_quad != v->v_quad) { if (op == ASSIGN && tp->t_isfield) { @@ -2067,11 +2117,14 @@ cvtcon(op_t op, int arg, type_t *tp, val_t *nv, val_t *v) 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); + warning(295, tyname(lbuf, sizeof(lbuf), + gettyp(ot)), tyname(rbuf, sizeof(rbuf), tp), + arg); } else { /* conversion of %s to %s is out of range */ - warning(119, tyname(gettyp(ot)), tyname(tp)); + warning(119, tyname(lbuf, sizeof(lbuf), + gettyp(ot)), + tyname(rbuf, sizeof(rbuf), tp)); } } } @@ -2119,7 +2172,7 @@ illptrc(mod_t *mp, type_t *ltp, type_t *rtp) tspec_t lt, rt; if (ltp->t_tspec != PTR || rtp->t_tspec != PTR) - lerror("illptrc() 1"); + LERROR("illptrc()"); lt = ltp->t_subt->t_tspec; rt = rtp->t_subt->t_tspec; @@ -2153,7 +2206,7 @@ mrgqual(type_t **tpp, type_t *tp1, type_t *tp2) if ((*tpp)->t_tspec != PTR || tp1->t_tspec != PTR || tp2->t_tspec != PTR) { - lerror("mrgqual()"); + LERROR("mrgqual()"); } if ((*tpp)->t_subt->t_const == @@ -2182,7 +2235,7 @@ conmemb(type_t *tp) tspec_t t; if ((t = tp->t_tspec) != STRUCT && t != UNION) - lerror("conmemb()"); + LERROR("conmemb()"); for (m = tp->t_str->memb; m != NULL; m = m->s_nxt) { tp = m->s_type; if (tp->t_const) @@ -2196,39 +2249,87 @@ conmemb(type_t *tp) } const char * -tyname(type_t *tp) +basictyname(tspec_t t) +{ + switch (t) { + case CHAR: return "char"; + case UCHAR: return "unsigned char"; + case SCHAR: return "signed char"; + case SHORT: return "short"; + case USHORT: return "unsigned short"; + case INT: return "int"; + case UINT: return "unsigned int"; + case LONG: return "long"; + case ULONG: return "unsigned long"; + case QUAD: return "long long"; + case UQUAD: return "unsigned long long"; + case FLOAT: return "float"; + case DOUBLE: return "double"; + case LDOUBLE: return "long double"; + case PTR: return "pointer"; + case ENUM: return "enum"; + case STRUCT: return "struct"; + case UNION: return "union"; + case FUNC: return "function"; + case ARRAY: return "array"; + default: + LERROR("basictyname()"); + return NULL; + } +} + +const char * +tyname(char *buf, size_t bufsiz, type_t *tp) { tspec_t t; const char *s; + char lbuf[64]; if ((t = tp->t_tspec) == INT && tp->t_isenum) t = ENUM; + s = basictyname(t); + + switch (t) { - case CHAR: s = "char"; break; - case UCHAR: s = "unsigned char"; break; - case SCHAR: s = "signed char"; break; - case SHORT: s = "short"; break; - case USHORT: s = "unsigned short"; break; - case INT: s = "int"; break; - case UINT: s = "unsigned int"; break; - case LONG: s = "long"; break; - case ULONG: s = "unsigned long"; break; - case QUAD: s = "long long"; break; - case UQUAD: s = "unsigned long long"; break; - case FLOAT: s = "float"; break; - case DOUBLE: s = "double"; break; - case LDOUBLE: s = "long double"; break; - case PTR: s = "pointer"; break; - case ENUM: s = "enum"; break; - case STRUCT: s = "struct"; break; - case UNION: s = "union"; break; - case FUNC: s = "function"; break; - case ARRAY: s = "array"; break; + case CHAR: + case UCHAR: + case SCHAR: + case SHORT: + case USHORT: + case INT: + case UINT: + case LONG: + case ULONG: + case QUAD: + case UQUAD: + case FLOAT: + case DOUBLE: + case LDOUBLE: + case FUNC: + (void)snprintf(buf, bufsiz, "%s", s); + break; + case PTR: + (void)snprintf(buf, bufsiz, "%s to %s", s, + tyname(lbuf, sizeof(lbuf), tp->t_subt)); + break; + case ENUM: + (void)snprintf(buf, bufsiz, "%s %s", s, + tp->t_enum->etag->s_name); + break; + case STRUCT: + case UNION: + (void)snprintf(buf, bufsiz, "%s %s", s, + tp->t_str->stag->s_name); + break; + case ARRAY: + (void)snprintf(buf, bufsiz, "%s of %s[%d]", s, + tyname(lbuf, sizeof(lbuf), tp->t_subt), tp->t_dim); + break; default: - lerror("tyname()"); + LERROR("tyname()"); } - return (s); + return (buf); } /* @@ -2241,11 +2342,11 @@ bldstr(op_t op, tnode_t *ln, tnode_t *rn) int nolval; if (rn->tn_op != NAME) - lerror("bldstr() 1"); + LERROR("bldstr()"); if (rn->tn_sym->s_value.v_tspec != INT) - lerror("bldstr() 2"); + LERROR("bldstr()"); if (rn->tn_sym->s_scl != MOS && rn->tn_sym->s_scl != MOU) - lerror("bldstr() 3"); + LERROR("bldstr()"); /* * Remember if the left operand is an lvalue (structure members @@ -2257,7 +2358,7 @@ bldstr(op_t op, tnode_t *ln, tnode_t *rn) ln = bldamper(ln, 1); } else if (ln->tn_type->t_tspec != PTR) { if (!tflag || !isityp(ln->tn_type->t_tspec)) - lerror("bldstr() 4"); + LERROR("bldstr()"); ln = convert(NOOP, 0, tincref(gettyp(VOID), PTR), ln); } @@ -2292,7 +2393,7 @@ bldincdec(op_t op, tnode_t *ln) tnode_t *cn, *ntn; if (ln == NULL) - lerror("bldincdec() 1"); + LERROR("bldincdec()"); if (ln->tn_type->t_tspec == PTR) { cn = plength(ln->tn_type); @@ -2351,7 +2452,7 @@ bldplmi(op_t op, tnode_t *ln, tnode_t *rn) if (ln->tn_type->t_tspec == PTR && rn->tn_type->t_tspec != PTR) { if (!isityp(rn->tn_type->t_tspec)) - lerror("bldplmi() 1"); + LERROR("bldplmi()"); ctn = plength(ln->tn_type); if (rn->tn_type->t_tspec != ctn->tn_type->t_tspec) @@ -2364,7 +2465,7 @@ bldplmi(op_t op, tnode_t *ln, tnode_t *rn) } else if (rn->tn_type->t_tspec == PTR) { if (ln->tn_type->t_tspec != PTR || op != MINUS) - lerror("bldplmi() 2"); + LERROR("bldplmi()"); #if PTRDIFF_IS_LONG tp = gettyp(LONG); #else @@ -2429,9 +2530,9 @@ bldcol(tnode_t *ln, tnode_t *rn) } else if (lt == STRUCT || lt == UNION) { /* Both types must be identical. */ if (rt != STRUCT && rt != UNION) - lerror("bldcol() 1"); + LERROR("bldcol()"); if (ln->tn_type->t_str != rn->tn_type->t_str) - lerror("bldcol() 2"); + LERROR("bldcol()"); if (incompl(ln->tn_type)) { /* unknown operand size, op %s */ error(138, modtab[COLON].m_name); @@ -2452,17 +2553,17 @@ bldcol(tnode_t *ln, tnode_t *rn) rtp = rn->tn_type; } else if (lt == PTR && ln->tn_type->t_subt->t_tspec == VOID) { if (rt != PTR) - lerror("bldcol() 4"); + LERROR("bldcol()"); rtp = ln->tn_type; mrgqual(&rtp, ln->tn_type, rn->tn_type); } else if (rt == PTR && rn->tn_type->t_subt->t_tspec == VOID) { if (lt != PTR) - lerror("bldcol() 5"); + LERROR("bldcol()"); rtp = rn->tn_type; mrgqual(&rtp, ln->tn_type, rn->tn_type); } else { if (lt != PTR || rt != PTR) - lerror("bldcol() 6"); + LERROR("bldcol()"); /* * XXX For now we simply take the left type. This is * probably wrong, if one type contains a functionprototype @@ -2488,14 +2589,14 @@ bldasgn(op_t op, tnode_t *ln, tnode_t *rn) tnode_t *ntn, *ctn; if (ln == NULL || rn == NULL) - lerror("bldasgn() 1"); + LERROR("bldasgn()"); lt = ln->tn_type->t_tspec; rt = rn->tn_type->t_tspec; if ((op == ADDASS || op == SUBASS) && lt == PTR) { if (!isityp(rt)) - lerror("bldasgn() 2"); + LERROR("bldasgn()"); ctn = plength(ln->tn_type); if (rn->tn_type->t_tspec != ctn->tn_type->t_tspec) rn = convert(NOOP, 0, ctn->tn_type, rn); @@ -2506,7 +2607,7 @@ bldasgn(op_t op, tnode_t *ln, tnode_t *rn) if ((op == ASSIGN || op == RETURN) && (lt == STRUCT || rt == STRUCT)) { if (rt != lt || ln->tn_type->t_str != rn->tn_type->t_str) - lerror("bldasgn() 3"); + LERROR("bldasgn()"); if (incompl(ln->tn_type)) { if (op == RETURN) { /* cannot return incomplete type */ @@ -2519,12 +2620,13 @@ bldasgn(op_t op, tnode_t *ln, tnode_t *rn) } } - if (op == SHLASS || op == SHRASS) { - if (rt != INT) { - rn = convert(NOOP, 0, gettyp(INT), rn); - rt = INT; + if (op == SHLASS) { + if (psize(lt) < psize(rt)) { + if (hflag) + /* semantics of %s change in ANSI C; use ... */ + warning(118, "<<="); } - } else { + } else if (op != SHRASS) { if (op == ASSIGN || lt != PTR) { if (lt != rt || (ln->tn_type->t_isfield && rn->tn_op == CON)) { @@ -2549,7 +2651,7 @@ plength(type_t *tp) tspec_t st; if (tp->t_tspec != PTR) - lerror("plength() 1"); + LERROR("plength()"); tp = tp->t_subt; elem = 1; @@ -2586,7 +2688,7 @@ plength(type_t *tp) /* cannot do pointer arithmetic on operand of ... */ error(136); } else if (elsz == -1) { - lerror("plength() 2"); + LERROR("plength()"); } break; } @@ -2743,7 +2845,7 @@ fold(tnode_t *tn) q = utyp ? ul | ur : sl | sr; break; default: - lerror("fold() 5"); + LERROR("fold()"); } /* XXX does not work for quads. */ @@ -2773,7 +2875,7 @@ foldtst(tnode_t *tn) nomem(); v->v_tspec = tn->tn_type->t_tspec; if (tn->tn_type->t_tspec != INT) - lerror("foldtst() 1"); + LERROR("foldtst()"); if (isftyp(tn->tn_left->tn_type->t_tspec)) { l = tn->tn_left->tn_val->v_ldbl != 0.0; @@ -2803,7 +2905,7 @@ foldtst(tnode_t *tn) v->v_quad = l || r; break; default: - lerror("foldtst() 1"); + LERROR("foldtst()"); } return (getcnode(tn->tn_type, v)); @@ -2824,12 +2926,12 @@ foldflt(tnode_t *tn) v->v_tspec = t = tn->tn_type->t_tspec; if (!isftyp(t)) - lerror("foldflt() 1"); + LERROR("foldflt()"); if (t != tn->tn_left->tn_type->t_tspec) - lerror("foldflt() 2"); + LERROR("foldflt()"); if (modtab[tn->tn_op].m_binary && t != tn->tn_right->tn_type->t_tspec) - lerror("foldflt() 3"); + LERROR("foldflt()"); l = tn->tn_left->tn_val->v_ldbl; if (modtab[tn->tn_op].m_binary) @@ -2885,11 +2987,11 @@ foldflt(tnode_t *tn) v->v_quad = l != r; break; default: - lerror("foldflt() 4"); + LERROR("foldflt()"); } if (isnan((double)v->v_ldbl)) - lerror("foldflt() 5"); + LERROR("foldflt()"); if (!finite((double)v->v_ldbl) || (t == FLOAT && (v->v_ldbl > FLT_MAX || v->v_ldbl < -FLT_MAX)) || @@ -2962,7 +3064,7 @@ bldszof(type_t *tp) } else { elsz = size(tp->t_tspec); if (elsz <= 0) - lerror("bldszof() 1"); + LERROR("bldszof()"); } break; } @@ -3199,7 +3301,7 @@ parg( int n, /* pos of arg */ * type, an error message is printed. */ val_t * -constant(tnode_t *tn) +constant(tnode_t *tn, int required) { val_t *v; @@ -3213,7 +3315,7 @@ constant(tnode_t *tn) if (tn == NULL) { if (nerr == 0) - lerror("constant() 1"); + LERROR("constant()"); v->v_tspec = INT; v->v_quad = 1; return (v); @@ -3223,7 +3325,7 @@ constant(tnode_t *tn) if (tn->tn_op == CON) { if (tn->tn_type->t_tspec != tn->tn_val->v_tspec) - lerror("constant() 2"); + LERROR("constant()"); if (isityp(tn->tn_val->v_tspec)) { v->v_ansiu = tn->tn_val->v_ansiu; v->v_quad = tn->tn_val->v_quad; @@ -3235,7 +3337,10 @@ constant(tnode_t *tn) } /* integral constant expression expected */ - error(55); + if (required) + error(55); + else + c99ism(318); if (!isityp(v->v_tspec)) v->v_tspec = INT; @@ -3252,11 +3357,11 @@ constant(tnode_t *tn) * for the expression. */ void -expr(tnode_t *tn, int vctx, int tctx) +expr(tnode_t *tn, int vctx, int tctx, int freeblk) { if (tn == NULL && nerr == 0) - lerror("expr() 1"); + LERROR("expr()"); if (tn == NULL) { tfreeblk(); @@ -3289,7 +3394,8 @@ expr(tnode_t *tn, int vctx, int tctx) displexpr(tn, 0); /* free the tree memory */ - tfreeblk(); + if (freeblk) + tfreeblk(); } static void @@ -3361,7 +3467,7 @@ displexpr(tnode_t *tn, int offs) (long)uq & 0xffffffffl); } else if (tn->tn_op == CON) { if (tn->tn_type->t_tspec != PTR) - lerror("displexpr() 1"); + LERROR("displexpr()"); (void)printf("0x%0*lx ", (int)(sizeof (void *) * CHAR_BIT / 4), (u_long)tn->tn_val->v_quad); } else if (tn->tn_op == STRING) { @@ -3477,7 +3583,7 @@ chkmisc(tnode_t *tn, int vctx, int tctx, int eqwarn, int fcall, int rvdisc, break; case CALL: if (ln->tn_op != AMPER || ln->tn_left->tn_op != NAME) - lerror("chkmisc() 1"); + LERROR("chkmisc()"); if (!szof) outcall(tn, vctx || tctx, rvdisc); break; @@ -3632,6 +3738,7 @@ chkaidx(tnode_t *tn, int amper) static void chkcomp(op_t op, tnode_t *ln, tnode_t *rn) { + char buf[64]; tspec_t lt, rt; mod_t *mp; @@ -3663,11 +3770,12 @@ chkcomp(op_t op, tnode_t *ln, tnode_t *rn) rn->tn_op == CON && rn->tn_val->v_quad <= 0) { if (rn->tn_val->v_quad < 0) { /* comparison of %s with %s, op %s */ - warning(162, tyname(ln->tn_type), "negative constant", - mp->m_name); + warning(162, tyname(buf, sizeof(buf), ln->tn_type), + "negative constant", mp->m_name); } else if (op == LT || op == GE || (hflag && op == LE)) { /* comparison of %s with %s, op %s */ - warning(162, tyname(ln->tn_type), "0", mp->m_name); + warning(162, tyname(buf, sizeof(buf), ln->tn_type), + "0", mp->m_name); } return; } @@ -3675,11 +3783,12 @@ chkcomp(op_t op, tnode_t *ln, tnode_t *rn) ln->tn_op == CON && ln->tn_val->v_quad <= 0) { if (ln->tn_val->v_quad < 0) { /* comparison of %s with %s, op %s */ - warning(162, "negative constant", tyname(rn->tn_type), - mp->m_name); + warning(162, "negative constant", + tyname(buf, sizeof(buf), rn->tn_type), mp->m_name); } else if (op == GT || op == LE || (hflag && op == GE)) { /* comparison of %s with %s, op %s */ - warning(162, "0", tyname(rn->tn_type), mp->m_name); + warning(162, "0", tyname(buf, sizeof(buf), rn->tn_type), + mp->m_name); } return; } @@ -3689,7 +3798,7 @@ chkcomp(op_t op, tnode_t *ln, tnode_t *rn) * Takes an expression an returns 0 if this expression can be used * for static initialisation, otherwise -1. * - * Constant initialisation expressions must be costant or an address + * Constant initialisation expressions must be constant or an address * of a static object with an optional offset. In the first case, * the result is returned in *offsp. In the second case, the static * object is returned in *symp and the offset in *offsp. @@ -3707,7 +3816,9 @@ conaddr(tnode_t *tn, sym_t **symp, ptrdiff_t *offsp) switch (tn->tn_op) { case MINUS: - if (tn->tn_right->tn_op != CON) + if (tn->tn_right->tn_op == CVT) + return conaddr(tn->tn_right, symp, offsp); + else if (tn->tn_right->tn_op != CON) return (-1); /* FALLTHROUGH */ case PLUS: @@ -3743,9 +3854,9 @@ conaddr(tnode_t *tn, sym_t **symp, ptrdiff_t *offsp) case CVT: t = tn->tn_type->t_tspec; ot = tn->tn_left->tn_type->t_tspec; - if ((!isityp(t) && t != PTR) || (!isityp(ot) && ot != PTR)) { + if ((!isityp(t) && t != PTR) || (!isityp(ot) && ot != PTR)) return (-1); - } else if (psize(t) != psize(ot)) { + else if (psize(t) != psize(ot)) { return (-1); } if (conaddr(tn->tn_left, symp, offsp) == -1) diff --git a/usr.bin/xlint/lint2/read.c b/usr.bin/xlint/lint2/read.c index 0ffd611a3a6b..c6e68477ea89 100644 --- a/usr.bin/xlint/lint2/read.c +++ b/usr.bin/xlint/lint2/read.c @@ -1,4 +1,4 @@ -/* $NetBSD: read.c,v 1.12 2002/01/21 19:49:52 tv Exp $ */ +/* $NetBSD: read.c,v 1.19 2007/09/28 21:53:50 uwe Exp $ */ /* * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. @@ -34,7 +34,7 @@ #include #if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: read.c,v 1.12 2002/01/21 19:49:52 tv Exp $"); +__RCSID("$NetBSD: read.c,v 1.19 2007/09/28 21:53:50 uwe Exp $"); #endif __FBSDID("$FreeBSD$"); @@ -87,7 +87,8 @@ static hte_t **renametab; static int csrcfile; -static void inperr(void); +#define inperr() inperror(__FILE__, __LINE__) +static void inperror(const char *, size_t); static void setsrc(const char *); static void setfnid(int, const char *); static void funccall(pos_t *, const char *); @@ -213,10 +214,10 @@ readfile(const char *name) static void -inperr(void) +inperror(const char *file, size_t line) { - errx(1, "input file error: %s", fnames[srcfile]); + errx(1, "%s,%zd: input file error: %s", file, line, fnames[srcfile]); } /* @@ -361,9 +362,7 @@ decldef(pos_t *posp, const char *cp) used = 0; - while ((c = *cp) == 't' || c == 'd' || c == 'e' || c == 'u' || - c == 'r' || c == 'o' || c == 's' || c == 'v' || - c == 'P' || c == 'S') { + while (strchr("tdeurosvPS", (c = *cp)) != NULL) { cp++; switch (c) { case 't': @@ -545,7 +544,7 @@ inptype(const char *cp, const char **epp) type_t *tp; int narg, i, osdef = 0; size_t tlen; - u_short tidx; + u_short tidx, sidx; int h; /* If we have this type already, return it's index. */ @@ -621,10 +620,12 @@ inptype(const char *cp, const char **epp) case ARRAY: tp->t_dim = (int)strtol(cp, &eptr, 10); cp = eptr; - tp->t_subt = TP(inptype(cp, &cp)); + sidx = inptype(cp, &cp); /* force seq. point! (ditto below) */ + tp->t_subt = TP(sidx); break; case PTR: - tp->t_subt = TP(inptype(cp, &cp)); + sidx = inptype(cp, &cp); + tp->t_subt = TP(sidx); break; case FUNC: c = *cp; @@ -641,11 +642,13 @@ inptype(const char *cp, const char **epp) tp->t_vararg = 1; cp++; } else { - tp->t_args[i] = TP(inptype(cp, &cp)); + sidx = inptype(cp, &cp); + tp->t_args[i] = TP(sidx); } } } - tp->t_subt = TP(inptype(cp, &cp)); + sidx = inptype(cp, &cp); + tp->t_subt = TP(sidx); break; case ENUM: tp->t_tspec = INT; diff --git a/usr.bin/xlint/xlint/lint.1 b/usr.bin/xlint/xlint/lint.1 index 13ffce10dbc8..30731d2df3a3 100644 --- a/usr.bin/xlint/xlint/lint.1 +++ b/usr.bin/xlint/xlint/lint.1 @@ -1,4 +1,4 @@ -.\" $NetBSD: lint.1,v 1.21 2002/01/03 04:25:18 thorpej Exp $ +.\" $NetBSD: lint.1,v 1.29 2004/01/26 21:59:42 wiz Exp $ .\" .\" Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. .\" Copyright (c) 1994, 1995 Jochen Pohl @@ -32,7 +32,7 @@ .\" .\" $FreeBSD$ .\" -.Dd May 24, 2001 +.Dd Mar 23, 2015 .Dt LINT 1 .Os .Sh NAME @@ -49,6 +49,7 @@ .Op Fl I Ar directory .Op Fl d Ar directory .Op Fl L Ar directory +.Op Fl MD .Op Fl l Ar library .Op Fl o Ar outputfile .Op Fl B Ar directory @@ -269,6 +270,8 @@ With the flag, .Dv __STRICT_ANSI__ is a predefined preprocessor macro. +.It Fl S +C9X mode. Currently not fully implemented. .It Fl t Traditional C mode. .Dv __STDC__ @@ -369,6 +372,13 @@ 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 MD +Pass +.Fl MD +to +.Xr cpp 1 +causing cpp to create files containing dependency information for +each source file. .It Fl o Ar outputfile Name the output file .Ar outputfile . @@ -415,7 +425,7 @@ The utility recognizes the following C comments as commands. .Bl -tag -width indent .It Li /* ARGSUSED Ns Ar n Li */ -makes +Makes .Nm check only the first .Ar n diff --git a/usr.bin/xlint/xlint/xlint.c b/usr.bin/xlint/xlint/xlint.c index 7980d6cc1ccb..7c9994d5cc3a 100644 --- a/usr.bin/xlint/xlint/xlint.c +++ b/usr.bin/xlint/xlint/xlint.c @@ -1,4 +1,4 @@ -/* $NetBSD: xlint.c,v 1.27 2002/01/31 19:09:33 tv Exp $ */ +/* $NetBSD: xlint.c,v 1.36 2005/02/09 21:24:48 dsl Exp $ */ /* * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. @@ -34,7 +34,7 @@ #include #if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: xlint.c,v 1.27 2002/01/31 19:09:33 tv Exp $"); +__RCSID("$NetBSD: xlint.c,v 1.36 2005/02/09 21:24:48 dsl Exp $"); #endif __FBSDID("$FreeBSD$"); @@ -104,7 +104,7 @@ static char **libsrchpath; static char *libexec_path; /* flags */ -static int iflag, oflag, Cflag, sflag, tflag, Fflag, dflag, Bflag; +static int iflag, oflag, Cflag, sflag, tflag, Fflag, dflag, Bflag, Sflag; /* print the commands executed to run the stages of compilation */ static int Vflag; @@ -145,7 +145,7 @@ static void cat(char *const *, const char *); /* * 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) @@ -286,13 +286,13 @@ usage(void) { (void)fprintf(stderr, - "usage: lint [-abceghprvwxzHF] [-s|-t] [-i|-nu] [-Dname[=def]]" + "usage: lint [-abceghprvwxzHFS] [-s|-t] [-i|-nu] [-Dname[=def]]" " [-Uname] [-X [,]...\n"); (void)fprintf(stderr, "\t[-Idirectory] [-Ldirectory] [-llibrary] [-ooutputfile]" " file...\n"); (void)fprintf(stderr, - " lint [-abceghprvwzHF] [-s|-t] -Clibrary [-Dname[=def]]\n" + " lint [-abceghprvwzHFS] [-s|-t] -Clibrary [-Dname[=def]]\n" " [-X [,]...\n"); (void)fprintf(stderr, "\t[-Idirectory] [-Uname] [-Bpath] file" " ...\n"); @@ -344,6 +344,9 @@ main(int argc, char *argv[]) #else appcstrg(&cflags, "-U__GNUC__"); appcstrg(&cflags, "-undef"); +#endif +#if 0 + appcstrg(&cflags, "-Wp,-$"); #endif appcstrg(&cflags, "-Wp,-C"); appcstrg(&cflags, "-Wcomment"); @@ -359,8 +362,7 @@ main(int argc, char *argv[]) (void)signal(SIGINT, terminate); (void)signal(SIGQUIT, terminate); (void)signal(SIGTERM, terminate); - - while ((c = getopt(argc, argv, "abcd:eghil:no:prstuvwxzB:C:D:FHI:L:U:VX:")) != -1) { + while ((c = getopt(argc, argv, "abcd:eghil:no:prstuvwxzB:C:D:FHI:L:M:SU:VX:")) != -1) { switch (c) { case 'a': @@ -426,6 +428,13 @@ main(int argc, char *argv[]) sflag = 1; break; + case 'S': + if (tflag) + usage(); + appcstrg(&l1flags, "-S"); + Sflag = 1; + break; + #if !HAVE_CONFIG_H case 't': if (sflag) @@ -465,6 +474,7 @@ main(int argc, char *argv[]) case 'D': case 'I': + case 'M': case 'U': (void)sprintf(flgbuf, "-%c", c); appstrg(&cflags, concat2(flgbuf, optarg));