Fri Jun 9 13:03:49 2023 UTC ()
lint: indent local variables consistently

No binary change.


(rillig)
diff -r1.18 -r1.19 src/usr.bin/xlint/common/emit.c
diff -r1.34 -r1.35 src/usr.bin/xlint/common/inittyp.c
diff -r1.315 -r1.316 src/usr.bin/xlint/lint1/decl.c
diff -r1.66 -r1.67 src/usr.bin/xlint/lint1/emit1.c
diff -r1.197 -r1.198 src/usr.bin/xlint/lint1/err.c
diff -r1.154 -r1.155 src/usr.bin/xlint/lint1/func.c
diff -r1.158 -r1.159 src/usr.bin/xlint/lint1/lex.c
diff -r1.525 -r1.526 src/usr.bin/xlint/lint1/tree.c
diff -r1.54 -r1.55 src/usr.bin/xlint/lint2/chk.c
diff -r1.30 -r1.31 src/usr.bin/xlint/lint2/emit2.c
diff -r1.24 -r1.25 src/usr.bin/xlint/lint2/hash.c
diff -r1.28 -r1.29 src/usr.bin/xlint/lint2/main2.c
diff -r1.19 -r1.20 src/usr.bin/xlint/lint2/msg.c
diff -r1.80 -r1.81 src/usr.bin/xlint/lint2/read.c
diff -r1.109 -r1.110 src/usr.bin/xlint/xlint/xlint.c

cvs diff -r1.18 -r1.19 src/usr.bin/xlint/common/emit.c (expand / switch to unified diff)

--- src/usr.bin/xlint/common/emit.c 2023/01/14 09:30:07 1.18
+++ src/usr.bin/xlint/common/emit.c 2023/06/09 13:03:49 1.19
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: emit.c,v 1.18 2023/01/14 09:30:07 rillig Exp $ */ 1/* $NetBSD: emit.c,v 1.19 2023/06/09 13:03:49 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1994, 1995 Jochen Pohl 4 * Copyright (c) 1994, 1995 Jochen Pohl
5 * All Rights Reserved. 5 * All Rights Reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -27,27 +27,27 @@ @@ -27,27 +27,27 @@
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34#if HAVE_NBTOOL_CONFIG_H 34#if HAVE_NBTOOL_CONFIG_H
35#include "nbtool_config.h" 35#include "nbtool_config.h"
36#endif 36#endif
37 37
38#include <sys/cdefs.h> 38#include <sys/cdefs.h>
39#if defined(__RCSID) 39#if defined(__RCSID)
40__RCSID("$NetBSD: emit.c,v 1.18 2023/01/14 09:30:07 rillig Exp $"); 40__RCSID("$NetBSD: emit.c,v 1.19 2023/06/09 13:03:49 rillig Exp $");
41#endif 41#endif
42 42
43#include <stdio.h> 43#include <stdio.h>
44#include <string.h> 44#include <string.h>
45 45
46#include "lint.h" 46#include "lint.h"
47 47
48/* name and handle of output file */ 48/* name and handle of output file */
49static const char *loname; 49static const char *loname;
50static FILE *lout; 50static FILE *lout;
51 51
52/* output buffer data */ 52/* output buffer data */
53static ob_t ob; 53static ob_t ob;
@@ -96,27 +96,27 @@ outxbuf(void) @@ -96,27 +96,27 @@ outxbuf(void)
96 coffs = ob.o_next - ob.o_buf; 96 coffs = ob.o_next - ob.o_buf;
97 ob.o_len *= 2; 97 ob.o_len *= 2;
98 ob.o_end = (ob.o_buf = xrealloc(ob.o_buf, ob.o_len)) + ob.o_len; 98 ob.o_end = (ob.o_buf = xrealloc(ob.o_buf, ob.o_len)) + ob.o_len;
99 ob.o_next = ob.o_buf + coffs; 99 ob.o_next = ob.o_buf + coffs;
100} 100}
101 101
102/* 102/*
103 * reset output buffer 103 * reset output buffer
104 * if it is not empty, it is flushed 104 * if it is not empty, it is flushed
105 */ 105 */
106void 106void
107outclr(void) 107outclr(void)
108{ 108{
109 size_t sz; 109 size_t sz;
110 110
111 if (ob.o_buf != ob.o_next) { 111 if (ob.o_buf != ob.o_next) {
112 outchar('\n'); 112 outchar('\n');
113 sz = ob.o_next - ob.o_buf; 113 sz = ob.o_next - ob.o_buf;
114 if (sz > ob.o_len) 114 if (sz > ob.o_len)
115 errx(1, "internal error: outclr"); 115 errx(1, "internal error: outclr");
116 if (fwrite(ob.o_buf, sz, 1, lout) != 1) 116 if (fwrite(ob.o_buf, sz, 1, lout) != 1)
117 err(1, "cannot write to %s", loname); 117 err(1, "cannot write to %s", loname);
118 ob.o_next = ob.o_buf; 118 ob.o_next = ob.o_buf;
119 } 119 }
120} 120}
121 121
122/* 122/*

cvs diff -r1.34 -r1.35 src/usr.bin/xlint/common/inittyp.c (expand / switch to unified diff)

--- src/usr.bin/xlint/common/inittyp.c 2023/05/22 12:55:04 1.34
+++ src/usr.bin/xlint/common/inittyp.c 2023/06/09 13:03:49 1.35
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: inittyp.c,v 1.34 2023/05/22 12:55:04 rillig Exp $ */ 1/* $NetBSD: inittyp.c,v 1.35 2023/06/09 13:03:49 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1994, 1995 Jochen Pohl 4 * Copyright (c) 1994, 1995 Jochen Pohl
5 * All Rights Reserved. 5 * All Rights Reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -27,27 +27,27 @@ @@ -27,27 +27,27 @@
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34#if HAVE_NBTOOL_CONFIG_H 34#if HAVE_NBTOOL_CONFIG_H
35#include "nbtool_config.h" 35#include "nbtool_config.h"
36#endif 36#endif
37 37
38#include <sys/cdefs.h> 38#include <sys/cdefs.h>
39#if defined(__RCSID) 39#if defined(__RCSID)
40__RCSID("$NetBSD: inittyp.c,v 1.34 2023/05/22 12:55:04 rillig Exp $"); 40__RCSID("$NetBSD: inittyp.c,v 1.35 2023/06/09 13:03:49 rillig Exp $");
41#endif 41#endif
42 42
43#if defined(IS_LINT1) 43#if defined(IS_LINT1)
44#include "lint1.h" 44#include "lint1.h"
45#else 45#else
46#include "lint2.h" 46#include "lint2.h"
47#endif 47#endif
48 48
49#define INT_RSIZE (/*CONSTCOND*/INTPTR_TSPEC == LONG ? 3 : 4) 49#define INT_RSIZE (/*CONSTCOND*/INTPTR_TSPEC == LONG ? 3 : 4)
50 50
51#ifdef IS_LINT1 51#ifdef IS_LINT1
52#define typeinfo( \ 52#define typeinfo( \
53 name, signed_type, unsigned_type, \ 53 name, signed_type, unsigned_type, \
@@ -118,27 +118,27 @@ ttab_t ttab[NTSPEC] = { @@ -118,27 +118,27 @@ ttab_t ttab[NTSPEC] = {
118 typeinfo("float _Complex", FCOMPLEX, FCOMPLEX, 118 typeinfo("float _Complex", FCOMPLEX, FCOMPLEX,
119 FLOAT_SIZE * 2, 32 * 2, 'c'), 119 FLOAT_SIZE * 2, 32 * 2, 'c'),
120 typeinfo("double _Complex", DCOMPLEX, DCOMPLEX, 120 typeinfo("double _Complex", DCOMPLEX, DCOMPLEX,
121 DOUBLE_SIZE * 2, 64 * 2, 'c'), 121 DOUBLE_SIZE * 2, 64 * 2, 'c'),
122 typeinfo("long double _Complex", LCOMPLEX, LCOMPLEX, 122 typeinfo("long double _Complex", LCOMPLEX, LCOMPLEX,
123 LDOUBLE_SIZE * 2, 80 * 2, 'c'), 123 LDOUBLE_SIZE * 2, 80 * 2, 'c'),
124}; 124};
125#undef typeinfo 125#undef typeinfo
126 126
127#ifdef IS_LINT1 127#ifdef IS_LINT1
128void 128void
129inittyp(void) 129inittyp(void)
130{ 130{
131 size_t i; 131 size_t i;
132 132
133 if (!pflag) { 133 if (!pflag) {
134 for (i = 0; i < NTSPEC; i++) 134 for (i = 0; i < NTSPEC; i++)
135 ttab[i].tt_portable_size_in_bits = 135 ttab[i].tt_portable_size_in_bits =
136 ttab[i].tt_size_in_bits; 136 ttab[i].tt_size_in_bits;
137 } 137 }
138 138
139 if (Tflag) { 139 if (Tflag) {
140 ttab[BOOL].tt_is_integer = false; 140 ttab[BOOL].tt_is_integer = false;
141 ttab[BOOL].tt_is_uinteger = false; 141 ttab[BOOL].tt_is_uinteger = false;
142 ttab[BOOL].tt_is_arithmetic = false; 142 ttab[BOOL].tt_is_arithmetic = false;
143 } 143 }
144} 144}

cvs diff -r1.315 -r1.316 src/usr.bin/xlint/lint1/decl.c (expand / switch to unified diff)

--- src/usr.bin/xlint/lint1/decl.c 2023/06/03 21:08:06 1.315
+++ src/usr.bin/xlint/lint1/decl.c 2023/06/09 13:03:49 1.316
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: decl.c,v 1.315 2023/06/03 21:08:06 rillig Exp $ */ 1/* $NetBSD: decl.c,v 1.316 2023/06/09 13:03:49 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. 4 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
5 * Copyright (c) 1994, 1995 Jochen Pohl 5 * Copyright (c) 1994, 1995 Jochen Pohl
6 * All Rights Reserved. 6 * All Rights Reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
@@ -28,27 +28,27 @@ @@ -28,27 +28,27 @@
28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */ 33 */
34 34
35#if HAVE_NBTOOL_CONFIG_H 35#if HAVE_NBTOOL_CONFIG_H
36#include "nbtool_config.h" 36#include "nbtool_config.h"
37#endif 37#endif
38 38
39#include <sys/cdefs.h> 39#include <sys/cdefs.h>
40#if defined(__RCSID) 40#if defined(__RCSID)
41__RCSID("$NetBSD: decl.c,v 1.315 2023/06/03 21:08:06 rillig Exp $"); 41__RCSID("$NetBSD: decl.c,v 1.316 2023/06/09 13:03:49 rillig Exp $");
42#endif 42#endif
43 43
44#include <sys/param.h> 44#include <sys/param.h>
45#include <limits.h> 45#include <limits.h>
46#include <stdlib.h> 46#include <stdlib.h>
47#include <string.h> 47#include <string.h>
48 48
49#include "lint1.h" 49#include "lint1.h"
50 50
51const char unnamed[] = "<unnamed>"; 51const char unnamed[] = "<unnamed>";
52 52
53/* shared type structures for arithmetic types and void */ 53/* shared type structures for arithmetic types and void */
54static type_t typetab[NTSPEC]; 54static type_t typetab[NTSPEC];
@@ -142,38 +142,38 @@ initdecl(void) @@ -142,38 +142,38 @@ initdecl(void)
142 * else). 142 * else).
143 */ 143 */
144type_t * 144type_t *
145gettyp(tspec_t t) 145gettyp(tspec_t t)
146{ 146{
147 147
148 /* TODO: make the return type 'const' */ 148 /* TODO: make the return type 'const' */
149 return &typetab[t]; 149 return &typetab[t];
150} 150}
151 151
152type_t * 152type_t *
153block_dup_type(const type_t *tp) 153block_dup_type(const type_t *tp)
154{ 154{
155 type_t *ntp; 155 type_t *ntp;
156 156
157 ntp = block_zero_alloc(sizeof(*ntp)); 157 ntp = block_zero_alloc(sizeof(*ntp));
158 *ntp = *tp; 158 *ntp = *tp;
159 return ntp; 159 return ntp;
160} 160}
161 161
162/* Duplicate a type, free the allocated memory after the expression. */ 162/* Duplicate a type, free the allocated memory after the expression. */
163type_t * 163type_t *
164expr_dup_type(const type_t *tp) 164expr_dup_type(const type_t *tp)
165{ 165{
166 type_t *ntp; 166 type_t *ntp;
167 167
168 ntp = expr_zero_alloc(sizeof(*ntp)); 168 ntp = expr_zero_alloc(sizeof(*ntp));
169 *ntp = *tp; 169 *ntp = *tp;
170 return ntp; 170 return ntp;
171} 171}
172 172
173/* 173/*
174 * Return the unqualified version of the type. The returned type is freed at 174 * Return the unqualified version of the type. The returned type is freed at
175 * the end of the current expression. 175 * the end of the current expression.
176 * 176 *
177 * See C99 6.2.5p25. 177 * See C99 6.2.5p25.
178 */ 178 */
179type_t * 179type_t *
@@ -194,27 +194,27 @@ expr_unqualified_type(const type_t *tp) @@ -194,27 +194,27 @@ expr_unqualified_type(const type_t *tp)
194 * tp1->t_sou == tp2->t_sou. 194 * tp1->t_sou == tp2->t_sou.
195 */ 195 */
196 196
197 return ntp; 197 return ntp;
198} 198}
199 199
200/* 200/*
201 * Returns whether the argument is void or an incomplete array, 201 * Returns whether the argument is void or an incomplete array,
202 * struct, union or enum type. 202 * struct, union or enum type.
203 */ 203 */
204bool 204bool
205is_incomplete(const type_t *tp) 205is_incomplete(const type_t *tp)
206{ 206{
207 tspec_t t; 207 tspec_t t;
208 208
209 if ((t = tp->t_tspec) == VOID) 209 if ((t = tp->t_tspec) == VOID)
210 return true; 210 return true;
211 if (t == ARRAY) 211 if (t == ARRAY)
212 return tp->t_incomplete_array; 212 return tp->t_incomplete_array;
213 if (is_struct_or_union(t)) 213 if (is_struct_or_union(t))
214 return tp->t_sou->sou_incomplete; 214 return tp->t_sou->sou_incomplete;
215 if (t == ENUM) 215 if (t == ENUM)
216 return tp->t_enum->en_incomplete; 216 return tp->t_enum->en_incomplete;
217 217
218 return false; 218 return false;
219} 219}
220 220
@@ -249,27 +249,27 @@ dcs_add_storage_class(scl_t sc) @@ -249,27 +249,27 @@ dcs_add_storage_class(scl_t sc)
249/* 249/*
250 * Remember the type, modifier or typedef name returned by the parser 250 * Remember the type, modifier or typedef name returned by the parser
251 * in *dcs (top element of decl stack). This information is used in 251 * in *dcs (top element of decl stack). This information is used in
252 * dcs_end_type to build the type used for all declarators in this 252 * dcs_end_type to build the type used for all declarators in this
253 * declaration. 253 * declaration.
254 * 254 *
255 * If tp->t_typedef is true, the type comes from a previously defined 255 * If tp->t_typedef is true, the type comes from a previously defined
256 * typename. Otherwise, it comes from a type specifier (int, long, ...) or a 256 * typename. Otherwise, it comes from a type specifier (int, long, ...) or a
257 * struct/union/enum tag. 257 * struct/union/enum tag.
258 */ 258 */
259void 259void
260dcs_add_type(type_t *tp) 260dcs_add_type(type_t *tp)
261{ 261{
262 tspec_t t; 262 tspec_t t;
263 263
264 debug_step("%s: %s", __func__, type_name(tp)); 264 debug_step("%s: %s", __func__, type_name(tp));
265 if (tp->t_typedef) { 265 if (tp->t_typedef) {
266 /* 266 /*
267 * something like "typedef int a; int a b;" 267 * something like "typedef int a; int a b;"
268 * This should not happen with current grammar. 268 * This should not happen with current grammar.
269 */ 269 */
270 lint_assert(dcs->d_type == NULL); 270 lint_assert(dcs->d_type == NULL);
271 lint_assert(dcs->d_abstract_type == NO_TSPEC); 271 lint_assert(dcs->d_abstract_type == NO_TSPEC);
272 lint_assert(dcs->d_sign_mod == NO_TSPEC); 272 lint_assert(dcs->d_sign_mod == NO_TSPEC);
273 lint_assert(dcs->d_rank_mod == NO_TSPEC); 273 lint_assert(dcs->d_rank_mod == NO_TSPEC);
274 274
275 dcs->d_type = tp; 275 dcs->d_type = tp;
@@ -387,27 +387,27 @@ merge_signedness(tspec_t t, tspec_t s) @@ -387,27 +387,27 @@ merge_signedness(tspec_t t, tspec_t s)
387 : t == INT ? UINT 387 : t == INT ? UINT
388 : t == LONG ? ULONG 388 : t == LONG ? ULONG
389 : t == QUAD ? UQUAD 389 : t == QUAD ? UQUAD
390 : t; 390 : t;
391} 391}
392 392
393/* 393/*
394 * called if a list of declaration specifiers contains a typedef name 394 * called if a list of declaration specifiers contains a typedef name
395 * and other specifiers (except struct, union, enum, typedef name) 395 * and other specifiers (except struct, union, enum, typedef name)
396 */ 396 */
397static type_t * 397static type_t *
398typedef_error(type_t *td, tspec_t t) 398typedef_error(type_t *td, tspec_t t)
399{ 399{
400 tspec_t t2; 400 tspec_t t2;
401 401
402 t2 = td->t_tspec; 402 t2 = td->t_tspec;
403 403
404 if ((t == SIGNED || t == UNSIGN) && 404 if ((t == SIGNED || t == UNSIGN) &&
405 (t2 == CHAR || t2 == SHORT || t2 == INT || 405 (t2 == CHAR || t2 == SHORT || t2 == INT ||
406 t2 == LONG || t2 == QUAD)) { 406 t2 == LONG || t2 == QUAD)) {
407 if (allow_c90) 407 if (allow_c90)
408 /* modifying typedef with '%s'; only qualifiers... */ 408 /* modifying typedef with '%s'; only qualifiers... */
409 warning(5, tspec_name(t)); 409 warning(5, tspec_name(t));
410 td = block_dup_type(gettyp(merge_signedness(t2, t))); 410 td = block_dup_type(gettyp(merge_signedness(t2, t)));
411 td->t_typedef = true; 411 td->t_typedef = true;
412 return td; 412 return td;
413 } 413 }
@@ -454,27 +454,27 @@ invalid: @@ -454,27 +454,27 @@ invalid:
454 454
455/* 455/*
456 * Remember the symbol of a typedef name (2nd arg) in a struct, union 456 * Remember the symbol of a typedef name (2nd arg) in a struct, union
457 * or enum tag if the typedef name is the first defined for this tag. 457 * or enum tag if the typedef name is the first defined for this tag.
458 * 458 *
459 * If the tag is unnamed, the typedef name is used for identification 459 * If the tag is unnamed, the typedef name is used for identification
460 * of this tag in lint2. Although it's possible that more than one typedef 460 * of this tag in lint2. Although it's possible that more than one typedef
461 * name is defined for one tag, the first name defined should be unique 461 * name is defined for one tag, the first name defined should be unique
462 * if the tag is unnamed. 462 * if the tag is unnamed.
463 */ 463 */
464static void 464static void
465set_first_typedef(type_t *tp, sym_t *sym) 465set_first_typedef(type_t *tp, sym_t *sym)
466{ 466{
467 tspec_t t; 467 tspec_t t;
468 468
469 if (is_struct_or_union(t = tp->t_tspec)) { 469 if (is_struct_or_union(t = tp->t_tspec)) {
470 if (tp->t_sou->sou_first_typedef == NULL) 470 if (tp->t_sou->sou_first_typedef == NULL)
471 tp->t_sou->sou_first_typedef = sym; 471 tp->t_sou->sou_first_typedef = sym;
472 } else if (t == ENUM) { 472 } else if (t == ENUM) {
473 if (tp->t_enum->en_first_typedef == NULL) 473 if (tp->t_enum->en_first_typedef == NULL)
474 tp->t_enum->en_first_typedef = sym; 474 tp->t_enum->en_first_typedef = sym;
475 } 475 }
476} 476}
477 477
478static unsigned int 478static unsigned int
479bit_field_size(sym_t **mem) 479bit_field_size(sym_t **mem)
480{ 480{
@@ -562,44 +562,44 @@ dcs_add_qualifier(tqual_t q) @@ -562,44 +562,44 @@ dcs_add_qualifier(tqual_t q)
562 } else { 562 } else {
563 lint_assert(q == RESTRICT || q == THREAD || q == ATOMIC); 563 lint_assert(q == RESTRICT || q == THREAD || q == ATOMIC);
564 /* Silently ignore these qualifiers. */ 564 /* Silently ignore these qualifiers. */
565 } 565 }
566} 566}
567 567
568/* 568/*
569 * Go to the next declaration level (structs, nested structs, blocks, 569 * Go to the next declaration level (structs, nested structs, blocks,
570 * argument declaration lists ...) 570 * argument declaration lists ...)
571 */ 571 */
572void 572void
573begin_declaration_level(declaration_kind dk) 573begin_declaration_level(declaration_kind dk)
574{ 574{
575 dinfo_t *di; 575 dinfo_t *di;
576 576
577 /* put a new element on the declaration stack */ 577 /* put a new element on the declaration stack */
578 di = xcalloc(1, sizeof(*di)); 578 di = xcalloc(1, sizeof(*di));
579 di->d_enclosing = dcs; 579 di->d_enclosing = dcs;
580 dcs = di; 580 dcs = di;
581 di->d_kind = dk; 581 di->d_kind = dk;
582 di->d_ldlsym = &di->d_dlsyms; 582 di->d_ldlsym = &di->d_dlsyms;
583 debug_step("%s(%s)", __func__, declaration_kind_name(dk)); 583 debug_step("%s(%s)", __func__, declaration_kind_name(dk));
584} 584}
585 585
586/* 586/*
587 * Go back to previous declaration level 587 * Go back to previous declaration level
588 */ 588 */
589void 589void
590end_declaration_level(void) 590end_declaration_level(void)
591{ 591{
592 dinfo_t *di; 592 dinfo_t *di;
593 593
594 debug_step("%s(%s)", __func__, declaration_kind_name(dcs->d_kind)); 594 debug_step("%s(%s)", __func__, declaration_kind_name(dcs->d_kind));
595 595
596 lint_assert(dcs->d_enclosing != NULL); 596 lint_assert(dcs->d_enclosing != NULL);
597 di = dcs; 597 di = dcs;
598 dcs = di->d_enclosing; 598 dcs = di->d_enclosing;
599 599
600 switch (di->d_kind) { 600 switch (di->d_kind) {
601 case DK_STRUCT_MEMBER: 601 case DK_STRUCT_MEMBER:
602 case DK_UNION_MEMBER: 602 case DK_UNION_MEMBER:
603 case DK_ENUM_CONSTANT: 603 case DK_ENUM_CONSTANT:
604 /* 604 /*
605 * Symbols declared in (nested) structs or enums are 605 * Symbols declared in (nested) structs or enums are
@@ -716,28 +716,28 @@ dcs_adjust_storage_class(void) @@ -716,28 +716,28 @@ dcs_adjust_storage_class(void)
716 dcs->d_scl = NOSCL; 716 dcs->d_scl = NOSCL;
717 } 717 }
718 } 718 }
719} 719}
720 720
721/* 721/*
722 * Merge the declaration specifiers from dcs into dcs->d_type. 722 * Merge the declaration specifiers from dcs into dcs->d_type.
723 * 723 *
724 * See C99 6.7.2 "Type specifiers". 724 * See C99 6.7.2 "Type specifiers".
725 */ 725 */
726static void 726static void
727dcs_merge_declaration_specifiers(void) 727dcs_merge_declaration_specifiers(void)
728{ 728{
729 tspec_t t, s, l, c; 729 tspec_t t, s, l, c;
730 type_t *tp; 730 type_t *tp;
731 731
732 t = dcs->d_abstract_type; /* VOID, BOOL, CHAR, INT or COMPLEX */ 732 t = dcs->d_abstract_type; /* VOID, BOOL, CHAR, INT or COMPLEX */
733 c = dcs->d_complex_mod; /* FLOAT or DOUBLE */ 733 c = dcs->d_complex_mod; /* FLOAT or DOUBLE */
734 s = dcs->d_sign_mod; /* SIGNED or UNSIGN */ 734 s = dcs->d_sign_mod; /* SIGNED or UNSIGN */
735 l = dcs->d_rank_mod; /* SHORT, LONG or QUAD */ 735 l = dcs->d_rank_mod; /* SHORT, LONG or QUAD */
736 tp = dcs->d_type; 736 tp = dcs->d_type;
737 737
738 debug_step("%s: %s", __func__, type_name(tp)); 738 debug_step("%s: %s", __func__, type_name(tp));
739 if (t == NO_TSPEC && s == NO_TSPEC && l == NO_TSPEC && c == NO_TSPEC && 739 if (t == NO_TSPEC && s == NO_TSPEC && l == NO_TSPEC && c == NO_TSPEC &&
740 tp == NULL) 740 tp == NULL)
741 dcs->d_notyp = true; 741 dcs->d_notyp = true;
742 if (t == NO_TSPEC && s == NO_TSPEC && (l == NO_TSPEC || l == LONG) && 742 if (t == NO_TSPEC && s == NO_TSPEC && (l == NO_TSPEC || l == LONG) &&
743 tp == NULL) 743 tp == NULL)
@@ -907,50 +907,50 @@ alignment_in_bits(const type_t *tp) @@ -907,50 +907,50 @@ alignment_in_bits(const type_t *tp)
907 } 907 }
908 lint_assert(a >= CHAR_SIZE); 908 lint_assert(a >= CHAR_SIZE);
909 lint_assert(a <= worst_align_in_bits); 909 lint_assert(a <= worst_align_in_bits);
910 return a; 910 return a;
911} 911}
912 912
913/* 913/*
914 * Concatenate two lists of symbols by s_next. Used by declarations of 914 * Concatenate two lists of symbols by s_next. Used by declarations of
915 * struct/union/enum elements and parameters. 915 * struct/union/enum elements and parameters.
916 */ 916 */
917sym_t * 917sym_t *
918concat_lists(sym_t *l1, sym_t *l2) 918concat_lists(sym_t *l1, sym_t *l2)
919{ 919{
920 sym_t *l; 920 sym_t *l;
921 921
922 if ((l = l1) == NULL) 922 if ((l = l1) == NULL)
923 return l2; 923 return l2;
924 while (l1->s_next != NULL) 924 while (l1->s_next != NULL)
925 l1 = l1->s_next; 925 l1 = l1->s_next;
926 l1->s_next = l2; 926 l1->s_next = l2;
927 return l; 927 return l;
928} 928}
929 929
930/* 930/*
931 * Check if the type of the given symbol is valid and print an error 931 * Check if the type of the given symbol is valid and print an error
932 * message if it is not. 932 * message if it is not.
933 * 933 *
934 * Invalid types are: 934 * Invalid types are:
935 * - arrays of incomplete types or functions 935 * - arrays of incomplete types or functions
936 * - functions returning arrays or functions 936 * - functions returning arrays or functions
937 * - void types other than type of function or pointer 937 * - void types other than type of function or pointer
938 */ 938 */
939void 939void
940check_type(sym_t *sym) 940check_type(sym_t *sym)
941{ 941{
942 tspec_t to, t; 942 tspec_t to, t;
943 type_t **tpp, *tp; 943 type_t **tpp, *tp;
944 944
945 tpp = &sym->s_type; 945 tpp = &sym->s_type;
946 to = NO_TSPEC; 946 to = NO_TSPEC;
947 while ((tp = *tpp) != NULL) { 947 while ((tp = *tpp) != NULL) {
948 t = tp->t_tspec; 948 t = tp->t_tspec;
949 /* 949 /*
950 * If this is the type of an old-style function definition, 950 * If this is the type of an old-style function definition,
951 * a better warning is printed in begin_function(). 951 * a better warning is printed in begin_function().
952 */ 952 */
953 if (t == FUNC && !tp->t_proto && 953 if (t == FUNC && !tp->t_proto &&
954 !(to == NO_TSPEC && sym->s_osdef)) { 954 !(to == NO_TSPEC && sym->s_osdef)) {
955 /* TODO: Make this an error in C99 mode as well. */ 955 /* TODO: Make this an error in C99 mode as well. */
956 if ((!allow_trad && !allow_c99) && hflag) 956 if ((!allow_trad && !allow_c99) && hflag)
@@ -1099,29 +1099,29 @@ declare_bit_field(sym_t *dsym, tspec_t * @@ -1099,29 +1099,29 @@ declare_bit_field(sym_t *dsym, tspec_t *
1099 /* bit-field in union is very unusual */ 1099 /* bit-field in union is very unusual */
1100 warning(41); 1100 warning(41);
1101 dsym->s_type->t_bitfield = false; 1101 dsym->s_type->t_bitfield = false;
1102 dsym->s_bitfield = false; 1102 dsym->s_bitfield = false;
1103 } 1103 }
1104} 1104}
1105 1105
1106/* 1106/*
1107 * Process the declarator of a struct/union element. 1107 * Process the declarator of a struct/union element.
1108 */ 1108 */
1109sym_t * 1109sym_t *
1110declarator_1_struct_union(sym_t *dsym) 1110declarator_1_struct_union(sym_t *dsym)
1111{ 1111{
1112 type_t *tp; 1112 type_t *tp;
1113 tspec_t t; 1113 tspec_t t;
1114 int sz; 1114 int sz;
1115 unsigned int o = 0; /* Appease GCC */ 1115 unsigned int o = 0; /* Appease GCC */
1116 1116
1117 lint_assert(is_member(dsym)); 1117 lint_assert(is_member(dsym));
1118 1118
1119 if (dcs->d_redeclared_symbol != NULL) { 1119 if (dcs->d_redeclared_symbol != NULL) {
1120 lint_assert(is_member(dcs->d_redeclared_symbol)); 1120 lint_assert(is_member(dcs->d_redeclared_symbol));
1121 1121
1122 if (dsym->u.s_member.sm_sou_type == 1122 if (dsym->u.s_member.sm_sou_type ==
1123 dcs->d_redeclared_symbol->u.s_member.sm_sou_type) { 1123 dcs->d_redeclared_symbol->u.s_member.sm_sou_type) {
1124 /* duplicate member name '%s' */ 1124 /* duplicate member name '%s' */
1125 error(33, dsym->s_name); 1125 error(33, dsym->s_name);
1126 rmsym(dcs->d_redeclared_symbol); 1126 rmsym(dcs->d_redeclared_symbol);
1127 } 1127 }
@@ -1447,28 +1447,28 @@ add_function(sym_t *decl, sym_t *args) @@ -1447,28 +1447,28 @@ add_function(sym_t *decl, sym_t *args)
1447 } 1447 }
1448 1448
1449 *tpp = block_derive_function(dcs->d_enclosing->d_type, 1449 *tpp = block_derive_function(dcs->d_enclosing->d_type,
1450 dcs->d_proto, args, dcs->d_vararg); 1450 dcs->d_proto, args, dcs->d_vararg);
1451 1451
1452 debug_step("add_function: '%s'", type_name(decl->s_type)); 1452 debug_step("add_function: '%s'", type_name(decl->s_type));
1453 debug_leave(); 1453 debug_leave();
1454 return decl; 1454 return decl;
1455} 1455}
1456 1456
1457static sym_t * 1457static sym_t *
1458new_style_function(sym_t *args) 1458new_style_function(sym_t *args)
1459{ 1459{
1460 sym_t *arg, *sym; 1460 sym_t *arg, *sym;
1461 scl_t sc; 1461 scl_t sc;
1462 1462
1463 /* 1463 /*
1464 * Declarations of structs/unions/enums in param lists are legal, 1464 * Declarations of structs/unions/enums in param lists are legal,
1465 * but senseless. 1465 * but senseless.
1466 */ 1466 */
1467 for (sym = dcs->d_dlsyms; sym != NULL; sym = sym->s_level_next) { 1467 for (sym = dcs->d_dlsyms; sym != NULL; sym = sym->s_level_next) {
1468 sc = sym->s_scl; 1468 sc = sym->s_scl;
1469 if (sc == STRUCT_TAG || sc == UNION_TAG || sc == ENUM_TAG) { 1469 if (sc == STRUCT_TAG || sc == UNION_TAG || sc == ENUM_TAG) {
1470 /* dubious tag declaration '%s %s' */ 1470 /* dubious tag declaration '%s %s' */
1471 warning(85, storage_class_name(sc), sym->s_name); 1471 warning(85, storage_class_name(sc), sym->s_name);
1472 } 1472 }
1473 } 1473 }
1474 1474
@@ -1531,27 +1531,27 @@ check_function_definition(sym_t *sym, bo @@ -1531,27 +1531,27 @@ check_function_definition(sym_t *sym, bo
1531 sym->u.s_old_style_args = NULL; 1531 sym->u.s_old_style_args = NULL;
1532 } 1532 }
1533} 1533}
1534 1534
1535/* 1535/*
1536 * Process the name in a declarator. 1536 * Process the name in a declarator.
1537 * The symbol gets one of the storage classes EXTERN, STATIC, AUTO or 1537 * The symbol gets one of the storage classes EXTERN, STATIC, AUTO or
1538 * TYPEDEF. 1538 * TYPEDEF.
1539 * s_def and s_register are valid after declarator_name(). 1539 * s_def and s_register are valid after declarator_name().
1540 */ 1540 */
1541sym_t * 1541sym_t *
1542declarator_name(sym_t *sym) 1542declarator_name(sym_t *sym)
1543{ 1543{
1544 scl_t sc = NOSCL; 1544 scl_t sc = NOSCL;
1545 1545
1546 if (sym->s_scl == NOSCL) 1546 if (sym->s_scl == NOSCL)
1547 dcs->d_redeclared_symbol = NULL; 1547 dcs->d_redeclared_symbol = NULL;
1548 else if (sym->s_defarg) { 1548 else if (sym->s_defarg) {
1549 sym->s_defarg = false; 1549 sym->s_defarg = false;
1550 dcs->d_redeclared_symbol = NULL; 1550 dcs->d_redeclared_symbol = NULL;
1551 } else { 1551 } else {
1552 dcs->d_redeclared_symbol = sym; 1552 dcs->d_redeclared_symbol = sym;
1553 sym = pushdown(sym); 1553 sym = pushdown(sym);
1554 } 1554 }
1555 1555
1556 switch (dcs->d_kind) { 1556 switch (dcs->d_kind) {
1557 case DK_STRUCT_MEMBER: 1557 case DK_STRUCT_MEMBER:
@@ -1659,28 +1659,28 @@ old_style_function_name(sym_t *sym) @@ -1659,28 +1659,28 @@ old_style_function_name(sym_t *sym)
1659 1659
1660/* 1660/*
1661 * Create the type of a tag. 1661 * Create the type of a tag.
1662 * 1662 *
1663 * tag points to the symbol table entry of the tag 1663 * tag points to the symbol table entry of the tag
1664 * kind is the kind of the tag (STRUCT/UNION/ENUM) 1664 * kind is the kind of the tag (STRUCT/UNION/ENUM)
1665 * decl is true if the type of the tag will be completed in this declaration 1665 * decl is true if the type of the tag will be completed in this declaration
1666 * (the following token is T_LBRACE) 1666 * (the following token is T_LBRACE)
1667 * semi is true if the following token is T_SEMI 1667 * semi is true if the following token is T_SEMI
1668 */ 1668 */
1669type_t * 1669type_t *
1670make_tag_type(sym_t *tag, tspec_t kind, bool decl, bool semi) 1670make_tag_type(sym_t *tag, tspec_t kind, bool decl, bool semi)
1671{ 1671{
1672 scl_t scl; 1672 scl_t scl;
1673 type_t *tp; 1673 type_t *tp;
1674 1674
1675 if (kind == STRUCT) 1675 if (kind == STRUCT)
1676 scl = STRUCT_TAG; 1676 scl = STRUCT_TAG;
1677 else if (kind == UNION) 1677 else if (kind == UNION)
1678 scl = UNION_TAG; 1678 scl = UNION_TAG;
1679 else { 1679 else {
1680 lint_assert(kind == ENUM); 1680 lint_assert(kind == ENUM);
1681 scl = ENUM_TAG; 1681 scl = ENUM_TAG;
1682 } 1682 }
1683 1683
1684 if (tag != NULL) { 1684 if (tag != NULL) {
1685 if (tag->s_scl != NOSCL) 1685 if (tag->s_scl != NOSCL)
1686 tag = new_tag(tag, scl, decl, semi); 1686 tag = new_tag(tag, scl, decl, semi);
@@ -2284,53 +2284,53 @@ prototypes_compatible(const type_t *tp1, @@ -2284,53 +2284,53 @@ prototypes_compatible(const type_t *tp1,
2284/* 2284/*
2285 * Returns whether all parameters of a prototype are compatible with an 2285 * Returns whether all parameters of a prototype are compatible with an
2286 * old-style function declaration. 2286 * old-style function declaration.
2287 * 2287 *
2288 * This is the case if the following conditions are met: 2288 * This is the case if the following conditions are met:
2289 * 1. the prototype has a fixed number of parameters 2289 * 1. the prototype has a fixed number of parameters
2290 * 2. no parameter is of type float 2290 * 2. no parameter is of type float
2291 * 3. no parameter is converted to another type if integer promotion 2291 * 3. no parameter is converted to another type if integer promotion
2292 * is applied on it 2292 * is applied on it
2293 */ 2293 */
2294static bool 2294static bool
2295matches_no_arg_function(const type_t *tp, bool *dowarn) 2295matches_no_arg_function(const type_t *tp, bool *dowarn)
2296{ 2296{
2297 sym_t *arg; 2297 sym_t *arg;
2298 tspec_t t; 2298 tspec_t t;
2299 2299
2300 if (tp->t_vararg && dowarn != NULL) 2300 if (tp->t_vararg && dowarn != NULL)
2301 *dowarn = true; 2301 *dowarn = true;
2302 for (arg = tp->t_args; arg != NULL; arg = arg->s_next) { 2302 for (arg = tp->t_args; arg != NULL; arg = arg->s_next) {
2303 if ((t = arg->s_type->t_tspec) == FLOAT || 2303 if ((t = arg->s_type->t_tspec) == FLOAT ||
2304 t == CHAR || t == SCHAR || t == UCHAR || 2304 t == CHAR || t == SCHAR || t == UCHAR ||
2305 t == SHORT || t == USHORT) { 2305 t == SHORT || t == USHORT) {
2306 if (dowarn != NULL) 2306 if (dowarn != NULL)
2307 *dowarn = true; 2307 *dowarn = true;
2308 } 2308 }
2309 } 2309 }
2310 /* FIXME: Always returning true cannot be correct. */ 2310 /* FIXME: Always returning true cannot be correct. */
2311 return true; 2311 return true;
2312} 2312}
2313 2313
2314/* 2314/*
2315 * Compares a prototype declaration with the remembered arguments of 2315 * Compares a prototype declaration with the remembered arguments of
2316 * a previous old-style function definition. 2316 * a previous old-style function definition.
2317 */ 2317 */
2318static bool 2318static bool
2319check_old_style_definition(sym_t *rdsym, sym_t *dsym) 2319check_old_style_definition(sym_t *rdsym, sym_t *dsym)
2320{ 2320{
2321 sym_t *args, *pargs, *arg, *parg; 2321 sym_t *args, *pargs, *arg, *parg;
2322 int narg, nparg, n; 2322 int narg, nparg, n;
2323 bool dowarn, msg; 2323 bool dowarn, msg;
2324 2324
2325 args = rdsym->u.s_old_style_args; 2325 args = rdsym->u.s_old_style_args;
2326 pargs = dsym->s_type->t_args; 2326 pargs = dsym->s_type->t_args;
2327 2327
2328 msg = false; 2328 msg = false;
2329 2329
2330 narg = nparg = 0; 2330 narg = nparg = 0;
2331 for (arg = args; arg != NULL; arg = arg->s_next) 2331 for (arg = args; arg != NULL; arg = arg->s_next)
2332 narg++; 2332 narg++;
2333 for (parg = pargs; parg != NULL; parg = parg->s_next) 2333 for (parg = pargs; parg != NULL; parg = parg->s_next)
2334 nparg++; 2334 nparg++;
2335 if (narg != nparg) { 2335 if (narg != nparg) {
2336 /* prototype does not match old-style definition */ 2336 /* prototype does not match old-style definition */
@@ -2613,28 +2613,28 @@ check_func_old_style_arguments(void) @@ -2613,28 +2613,28 @@ check_func_old_style_arguments(void)
2613 funcsym->s_osdef = false; 2613 funcsym->s_osdef = false;
2614 funcsym->u.s_old_style_args = NULL; 2614 funcsym->u.s_old_style_args = NULL;
2615 } 2615 }
2616} 2616}
2617 2617
2618/* 2618/*
2619 * Checks compatibility of an old-style function definition with a previous 2619 * Checks compatibility of an old-style function definition with a previous
2620 * prototype declaration. 2620 * prototype declaration.
2621 * Returns true if the position of the previous declaration should be reported. 2621 * Returns true if the position of the previous declaration should be reported.
2622 */ 2622 */
2623static bool 2623static bool
2624check_prototype_declaration(sym_t *arg, sym_t *parg) 2624check_prototype_declaration(sym_t *arg, sym_t *parg)
2625{ 2625{
2626 type_t *tp, *ptp; 2626 type_t *tp, *ptp;
2627 bool dowarn; 2627 bool dowarn;
2628 2628
2629 tp = arg->s_type; 2629 tp = arg->s_type;
2630 ptp = parg->s_type; 2630 ptp = parg->s_type;
2631 2631
2632 dowarn = false; 2632 dowarn = false;
2633 2633
2634 if (!types_compatible(tp, ptp, true, true, &dowarn)) { 2634 if (!types_compatible(tp, ptp, true, true, &dowarn)) {
2635 if (types_compatible(tp, ptp, true, false, &dowarn)) { 2635 if (types_compatible(tp, ptp, true, false, &dowarn)) {
2636 /* type of '%s' does not match prototype */ 2636 /* type of '%s' does not match prototype */
2637 return gnuism(58, arg->s_name); 2637 return gnuism(58, arg->s_name);
2638 } else { 2638 } else {
2639 /* type of '%s' does not match prototype */ 2639 /* type of '%s' does not match prototype */
2640 error(58, arg->s_name); 2640 error(58, arg->s_name);
@@ -2849,27 +2849,27 @@ declare_external_in_block(sym_t *dsym) @@ -2849,27 +2849,27 @@ declare_external_in_block(sym_t *dsym)
2849 * information at the end of the block. 2849 * information at the end of the block.
2850 */ 2850 */
2851 dsym->s_ext_sym = esym; 2851 dsym->s_ext_sym = esym;
2852 } 2852 }
2853} 2853}
2854 2854
2855/* 2855/*
2856 * Print an error or a warning if the symbol cannot be initialized due 2856 * Print an error or a warning if the symbol cannot be initialized due
2857 * to type/storage class. Return whether an error has been detected. 2857 * to type/storage class. Return whether an error has been detected.
2858 */ 2858 */
2859static bool 2859static bool
2860check_init(sym_t *sym) 2860check_init(sym_t *sym)
2861{ 2861{
2862 bool erred; 2862 bool erred;
2863 2863
2864 erred = false; 2864 erred = false;
2865 2865
2866 if (sym->s_type->t_tspec == FUNC) { 2866 if (sym->s_type->t_tspec == FUNC) {
2867 /* cannot initialize function '%s' */ 2867 /* cannot initialize function '%s' */
2868 error(24, sym->s_name); 2868 error(24, sym->s_name);
2869 erred = true; 2869 erred = true;
2870 } else if (sym->s_scl == TYPEDEF) { 2870 } else if (sym->s_scl == TYPEDEF) {
2871 /* cannot initialize typedef '%s' */ 2871 /* cannot initialize typedef '%s' */
2872 error(25, sym->s_name); 2872 error(25, sym->s_name);
2873 erred = true; 2873 erred = true;
2874 } else if (sym->s_scl == EXTERN && sym->s_def == DECL) { 2874 } else if (sym->s_scl == EXTERN && sym->s_def == DECL) {
2875 if (dcs->d_kind == DK_EXTERN) { 2875 if (dcs->d_kind == DK_EXTERN) {
@@ -2881,27 +2881,27 @@ check_init(sym_t *sym) @@ -2881,27 +2881,27 @@ check_init(sym_t *sym)
2881 erred = true; 2881 erred = true;
2882 } 2882 }
2883 } 2883 }
2884 2884
2885 return erred; 2885 return erred;
2886} 2886}
2887 2887
2888/* 2888/*
2889 * Create a symbol for an abstract declaration. 2889 * Create a symbol for an abstract declaration.
2890 */ 2890 */
2891sym_t * 2891sym_t *
2892abstract_name(void) 2892abstract_name(void)
2893{ 2893{
2894 sym_t *sym; 2894 sym_t *sym;
2895 2895
2896 lint_assert(dcs->d_kind == DK_ABSTRACT || 2896 lint_assert(dcs->d_kind == DK_ABSTRACT ||
2897 dcs->d_kind == DK_PROTO_ARG); 2897 dcs->d_kind == DK_PROTO_ARG);
2898 2898
2899 sym = block_zero_alloc(sizeof(*sym)); 2899 sym = block_zero_alloc(sizeof(*sym));
2900 2900
2901 sym->s_name = unnamed; 2901 sym->s_name = unnamed;
2902 sym->s_def = DEF; 2902 sym->s_def = DEF;
2903 sym->s_scl = ABSTRACT; 2903 sym->s_scl = ABSTRACT;
2904 sym->s_block_level = -1; 2904 sym->s_block_level = -1;
2905 2905
2906 if (dcs->d_kind == DK_PROTO_ARG) 2906 if (dcs->d_kind == DK_PROTO_ARG)
2907 sym->s_arg = true; 2907 sym->s_arg = true;
@@ -3061,28 +3061,28 @@ check_argument_usage(bool novar, sym_t * @@ -3061,28 +3061,28 @@ check_argument_usage(bool novar, sym_t *
3061 3061
3062 if (novar) 3062 if (novar)
3063 return; 3063 return;
3064 3064
3065 if (!arg->s_used && vflag) { 3065 if (!arg->s_used && vflag) {
3066 /* argument '%s' unused in function '%s' */ 3066 /* argument '%s' unused in function '%s' */
3067 warning_at(231, &arg->s_def_pos, arg->s_name, funcsym->s_name); 3067 warning_at(231, &arg->s_def_pos, arg->s_name, funcsym->s_name);
3068 } 3068 }
3069} 3069}
3070 3070
3071static void 3071static void
3072check_variable_usage(bool novar, sym_t *sym) 3072check_variable_usage(bool novar, sym_t *sym)
3073{ 3073{
3074 scl_t sc; 3074 scl_t sc;
3075 sym_t *xsym; 3075 sym_t *xsym;
3076 3076
3077 lint_assert(block_level != 0); 3077 lint_assert(block_level != 0);
3078 3078
3079 /* example at file scope: int c = ({ return 3; }); */ 3079 /* example at file scope: int c = ({ return 3; }); */
3080 if (sym->s_block_level == 0 && ch_isdigit(sym->s_name[0])) 3080 if (sym->s_block_level == 0 && ch_isdigit(sym->s_name[0]))
3081 return; 3081 return;
3082 3082
3083 /* errors in expressions easily cause lots of these warnings */ 3083 /* errors in expressions easily cause lots of these warnings */
3084 if (nerr != 0) 3084 if (nerr != 0)
3085 return; 3085 return;
3086 3086
3087 /* 3087 /*
3088 * XXX Only variables are checked, although types should 3088 * XXX Only variables are checked, although types should
@@ -3186,27 +3186,27 @@ check_tag_usage(sym_t *sym) @@ -3186,27 +3186,27 @@ check_tag_usage(sym_t *sym)
3186} 3186}
3187 3187
3188/* 3188/*
3189 * Called after the entire translation unit has been parsed. 3189 * Called after the entire translation unit has been parsed.
3190 * Changes tentative definitions into definitions. 3190 * Changes tentative definitions into definitions.
3191 * Performs some tests on global symbols. Detected problems are: 3191 * Performs some tests on global symbols. Detected problems are:
3192 * - defined variables of incomplete type 3192 * - defined variables of incomplete type
3193 * - constant variables which are not initialized 3193 * - constant variables which are not initialized
3194 * - static symbols which are never used 3194 * - static symbols which are never used
3195 */ 3195 */
3196void 3196void
3197check_global_symbols(void) 3197check_global_symbols(void)
3198{ 3198{
3199 sym_t *sym; 3199 sym_t *sym;
3200 3200
3201 if (block_level != 0 || dcs->d_enclosing != NULL) 3201 if (block_level != 0 || dcs->d_enclosing != NULL)
3202 norecover(); 3202 norecover();
3203 3203
3204 for (sym = dcs->d_dlsyms; sym != NULL; sym = sym->s_level_next) { 3204 for (sym = dcs->d_dlsyms; sym != NULL; sym = sym->s_level_next) {
3205 if (sym->s_block_level == -1) 3205 if (sym->s_block_level == -1)
3206 continue; 3206 continue;
3207 if (sym->s_kind == FVFT) 3207 if (sym->s_kind == FVFT)
3208 check_global_variable(sym); 3208 check_global_variable(sym);
3209 else if (sym->s_kind == FTAG) 3209 else if (sym->s_kind == FTAG)
3210 check_tag_usage(sym); 3210 check_tag_usage(sym);
3211 else 3211 else
3212 lint_assert(sym->s_kind == FMEMBER); 3212 lint_assert(sym->s_kind == FMEMBER);
@@ -3328,28 +3328,28 @@ print_previous_declaration(const sym_t * @@ -3328,28 +3328,28 @@ print_previous_declaration(const sym_t *
3328/* 3328/*
3329 * Gets a node for a constant and returns the value of this constant 3329 * Gets a node for a constant and returns the value of this constant
3330 * as integer. 3330 * as integer.
3331 * 3331 *
3332 * If the node is not constant or too large for int or of type float, 3332 * If the node is not constant or too large for int or of type float,
3333 * a warning will be printed. 3333 * a warning will be printed.
3334 * 3334 *
3335 * to_int_constant() should be used only inside declarations. If it is used in 3335 * to_int_constant() should be used only inside declarations. If it is used in
3336 * expressions, it frees the memory used for the expression. 3336 * expressions, it frees the memory used for the expression.
3337 */ 3337 */
3338int 3338int
3339to_int_constant(tnode_t *tn, bool required) 3339to_int_constant(tnode_t *tn, bool required)
3340{ 3340{
3341 int i; 3341 int i;
3342 tspec_t t; 3342 tspec_t t;
3343 3343
3344 if (tn == NULL) 3344 if (tn == NULL)
3345 return 1; 3345 return 1;
3346 3346
3347 val_t *v = constant(tn, required); 3347 val_t *v = constant(tn, required);
3348 3348
3349 /* 3349 /*
3350 * Abstract declarations are used inside expression. To free 3350 * Abstract declarations are used inside expression. To free
3351 * the memory would be a fatal error. 3351 * the memory would be a fatal error.
3352 * We don't free blocks that are inside casts because these 3352 * We don't free blocks that are inside casts because these
3353 * will be used later to match types. 3353 * will be used later to match types.
3354 */ 3354 */
3355 if (tn->tn_op != CON && dcs->d_kind != DK_ABSTRACT) 3355 if (tn->tn_op != CON && dcs->d_kind != DK_ABSTRACT)

cvs diff -r1.66 -r1.67 src/usr.bin/xlint/lint1/emit1.c (expand / switch to unified diff)

--- src/usr.bin/xlint/lint1/emit1.c 2023/04/22 17:49:15 1.66
+++ src/usr.bin/xlint/lint1/emit1.c 2023/06/09 13:03:49 1.67
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: emit1.c,v 1.66 2023/04/22 17:49:15 rillig Exp $ */ 1/* $NetBSD: emit1.c,v 1.67 2023/06/09 13:03:49 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. 4 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
5 * Copyright (c) 1994, 1995 Jochen Pohl 5 * Copyright (c) 1994, 1995 Jochen Pohl
6 * All Rights Reserved. 6 * All Rights Reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
@@ -28,27 +28,27 @@ @@ -28,27 +28,27 @@
28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */ 33 */
34 34
35#if HAVE_NBTOOL_CONFIG_H 35#if HAVE_NBTOOL_CONFIG_H
36#include "nbtool_config.h" 36#include "nbtool_config.h"
37#endif 37#endif
38 38
39#include <sys/cdefs.h> 39#include <sys/cdefs.h>
40#if defined(__RCSID) 40#if defined(__RCSID)
41__RCSID("$NetBSD: emit1.c,v 1.66 2023/04/22 17:49:15 rillig Exp $"); 41__RCSID("$NetBSD: emit1.c,v 1.67 2023/06/09 13:03:49 rillig Exp $");
42#endif 42#endif
43 43
44#include "lint1.h" 44#include "lint1.h"
45 45
46static void outtt(sym_t *, sym_t *); 46static void outtt(sym_t *, sym_t *);
47static void outfstrg(strg_t *); 47static void outfstrg(strg_t *);
48 48
49/* 49/*
50 * Write type into the output buffer. 50 * Write type into the output buffer.
51 * The type is written as a sequence of substrings, each of which describes a 51 * The type is written as a sequence of substrings, each of which describes a
52 * node of type type_t 52 * node of type type_t
53 * a node is encoded as follows: 53 * a node is encoded as follows:
54 * _Bool B 54 * _Bool B
@@ -90,29 +90,29 @@ static void outfstrg(strg_t *); @@ -90,29 +90,29 @@ static void outfstrg(strg_t *);
90 * and 'v' (for volatile) 90 * and 'v' (for volatile)
91 */ 91 */
92void 92void
93outtype(const type_t *tp) 93outtype(const type_t *tp)
94{ 94{
95 /* Available letters: ------GH--K-MNO--R--U-W-YZ */ 95 /* Available letters: ------GH--K-MNO--R--U-W-YZ */
96#ifdef INT128_SIZE 96#ifdef INT128_SIZE
97 static const char tt[NTSPEC] = "???BCCCSSIILLQQJJDDDVTTTPAF?XXX"; 97 static const char tt[NTSPEC] = "???BCCCSSIILLQQJJDDDVTTTPAF?XXX";
98 static const char ss[NTSPEC] = "??? su u u u u us l sue ?s l"; 98 static const char ss[NTSPEC] = "??? su u u u u us l sue ?s l";
99#else 99#else
100 static const char tt[NTSPEC] = "???BCCCSSIILLQQDDDVTTTPAF?XXX"; 100 static const char tt[NTSPEC] = "???BCCCSSIILLQQDDDVTTTPAF?XXX";
101 static const char ss[NTSPEC] = "??? su u u u us l sue ?s l"; 101 static const char ss[NTSPEC] = "??? su u u u us l sue ?s l";
102#endif 102#endif
103 int na; 103 int na;
104 sym_t *arg; 104 sym_t *arg;
105 tspec_t ts; 105 tspec_t ts;
106 106
107 while (tp != NULL) { 107 while (tp != NULL) {
108 if ((ts = tp->t_tspec) == INT && tp->t_is_enum) 108 if ((ts = tp->t_tspec) == INT && tp->t_is_enum)
109 ts = ENUM; 109 ts = ENUM;
110 lint_assert(tt[ts] != '?' && ss[ts] != '?'); 110 lint_assert(tt[ts] != '?' && ss[ts] != '?');
111 if (tp->t_const) 111 if (tp->t_const)
112 outchar('c'); 112 outchar('c');
113 if (tp->t_volatile) 113 if (tp->t_volatile)
114 outchar('v'); 114 outchar('v');
115 if (ss[ts] != ' ') 115 if (ss[ts] != ' ')
116 outchar(ss[ts]); 116 outchar(ss[ts]);
117 outchar(tt[ts]); 117 outchar(tt[ts]);
118 118
@@ -341,30 +341,30 @@ outfdef(const sym_t *fsym, const pos_t * @@ -341,30 +341,30 @@ outfdef(const sym_t *fsym, const pos_t *
341} 341}
342 342
343/* 343/*
344 * write out all information necessary for lint2 to check function 344 * write out all information necessary for lint2 to check function
345 * calls 345 * calls
346 * 346 *
347 * retval_used is set if the return value is used (assigned to a variable) 347 * retval_used is set if the return value is used (assigned to a variable)
348 * retval_discarded is set if the return value is neither used nor ignored 348 * retval_discarded is set if the return value is neither used nor ignored
349 * (that is, cast to void) 349 * (that is, cast to void)
350 */ 350 */
351void 351void
352outcall(const tnode_t *tn, bool retval_used, bool retval_discarded) 352outcall(const tnode_t *tn, bool retval_used, bool retval_discarded)
353{ 353{
354 tnode_t *args, *arg; 354 tnode_t *args, *arg;
355 int narg, n, i; 355 int narg, n, i;
356 int64_t q; 356 int64_t q;
357 tspec_t t; 357 tspec_t t;
358 358
359 /* reset buffer */ 359 /* reset buffer */
360 outclr(); 360 outclr();
361 361
362 /* 362 /*
363 * line number of .c source, 'c' for function call, Id of current 363 * line number of .c source, 'c' for function call, Id of current
364 * source (.c or .h), and line in current source 364 * source (.c or .h), and line in current source
365 */ 365 */
366 outint(csrc_pos.p_line); 366 outint(csrc_pos.p_line);
367 outchar('c'); 367 outchar('c');
368 outint(get_filename_id(curr_pos.p_file)); 368 outint(get_filename_id(curr_pos.p_file));
369 outchar('.'); 369 outchar('.');
370 outint(curr_pos.p_line); 370 outint(curr_pos.p_line);
@@ -479,27 +479,27 @@ outqchar(char c) @@ -479,27 +479,27 @@ outqchar(char c)
479 outchar((char)((c & 07) + '0')); 479 outchar((char)((c & 07) + '0'));
480 break; 480 break;
481 } 481 }
482} 482}
483 483
484/* 484/*
485 * extracts potential format specifiers for printf() and scanf() and 485 * extracts potential format specifiers for printf() and scanf() and
486 * writes them, enclosed in "" and quoted if necessary, to the output buffer 486 * writes them, enclosed in "" and quoted if necessary, to the output buffer
487 */ 487 */
488static void 488static void
489outfstrg(strg_t *strg) 489outfstrg(strg_t *strg)
490{ 490{
491 char c, oc; 491 char c, oc;
492 bool first; 492 bool first;
493 const char *cp; 493 const char *cp;
494 494
495 lint_assert(strg->st_char); 495 lint_assert(strg->st_char);
496 cp = strg->st_mem; 496 cp = strg->st_mem;
497 497
498 outchar('"'); 498 outchar('"');
499 499
500 c = *cp++; 500 c = *cp++;
501 501
502 while (c != '\0') { 502 while (c != '\0') {
503 503
504 if (c != '%') { 504 if (c != '%') {
505 c = *cp++; 505 c = *cp++;

cvs diff -r1.197 -r1.198 src/usr.bin/xlint/lint1/err.c (expand / switch to unified diff)

--- src/usr.bin/xlint/lint1/err.c 2023/06/03 21:08:06 1.197
+++ src/usr.bin/xlint/lint1/err.c 2023/06/09 13:03:49 1.198
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: err.c,v 1.197 2023/06/03 21:08:06 rillig Exp $ */ 1/* $NetBSD: err.c,v 1.198 2023/06/09 13:03:49 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1994, 1995 Jochen Pohl 4 * Copyright (c) 1994, 1995 Jochen Pohl
5 * All Rights Reserved. 5 * All Rights Reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -27,27 +27,27 @@ @@ -27,27 +27,27 @@
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34#if HAVE_NBTOOL_CONFIG_H 34#if HAVE_NBTOOL_CONFIG_H
35#include "nbtool_config.h" 35#include "nbtool_config.h"
36#endif 36#endif
37 37
38#include <sys/cdefs.h> 38#include <sys/cdefs.h>
39#if defined(__RCSID) 39#if defined(__RCSID)
40__RCSID("$NetBSD: err.c,v 1.197 2023/06/03 21:08:06 rillig Exp $"); 40__RCSID("$NetBSD: err.c,v 1.198 2023/06/09 13:03:49 rillig Exp $");
41#endif 41#endif
42 42
43#include <limits.h> 43#include <limits.h>
44#include <stdarg.h> 44#include <stdarg.h>
45#include <stdlib.h> 45#include <stdlib.h>
46#include <string.h> 46#include <string.h>
47 47
48#include "lint1.h" 48#include "lint1.h"
49 49
50/* number of errors found */ 50/* number of errors found */
51int nerr; 51int nerr;
52 52
53/* number of syntax errors */ 53/* number of syntax errors */
@@ -509,43 +509,43 @@ lbasename(const char *path) @@ -509,43 +509,43 @@ lbasename(const char *path)
509 if (Fflag) 509 if (Fflag)
510 return path; 510 return path;
511 511
512 const char *base = path; 512 const char *base = path;
513 for (const char *p = path; *p != '\0'; p++) 513 for (const char *p = path; *p != '\0'; p++)
514 if (*p == '/') 514 if (*p == '/')
515 base = p + 1; 515 base = p + 1;
516 return base; 516 return base;
517} 517}
518 518
519static void 519static void
520verror_at(int msgid, const pos_t *pos, va_list ap) 520verror_at(int msgid, const pos_t *pos, va_list ap)
521{ 521{
522 const char *fn; 522 const char *fn;
523 523
524 if (is_suppressed[msgid]) 524 if (is_suppressed[msgid])
525 return; 525 return;
526 526
527 fn = lbasename(pos->p_file); 527 fn = lbasename(pos->p_file);
528 (void)printf("%s(%d): error: ", fn, pos->p_line); 528 (void)printf("%s(%d): error: ", fn, pos->p_line);
529 (void)vprintf(msgs[msgid], ap); 529 (void)vprintf(msgs[msgid], ap);
530 (void)printf(" [%d]\n", msgid); 530 (void)printf(" [%d]\n", msgid);
531 nerr++; 531 nerr++;
532 print_stack_trace(); 532 print_stack_trace();
533} 533}
534 534
535static void 535static void
536vwarning_at(int msgid, const pos_t *pos, va_list ap) 536vwarning_at(int msgid, const pos_t *pos, va_list ap)
537{ 537{
538 const char *fn; 538 const char *fn;
539 539
540 if (is_suppressed[msgid]) 540 if (is_suppressed[msgid])
541 return; 541 return;
542 542
543 debug_step("%s: lwarn=%d msgid=%d", __func__, lwarn, msgid); 543 debug_step("%s: lwarn=%d msgid=%d", __func__, lwarn, msgid);
544 if (lwarn == LWARN_NONE || lwarn == msgid) 544 if (lwarn == LWARN_NONE || lwarn == msgid)
545 /* this warning is suppressed by a LINTED comment */ 545 /* this warning is suppressed by a LINTED comment */
546 return; 546 return;
547 547
548 fn = lbasename(pos->p_file); 548 fn = lbasename(pos->p_file);
549 (void)printf("%s(%d): warning: ", fn, pos->p_line); 549 (void)printf("%s(%d): warning: ", fn, pos->p_line);
550 (void)vprintf(msgs[msgid], ap); 550 (void)vprintf(msgs[msgid], ap);
551 (void)printf(" [%d]\n", msgid); 551 (void)printf(" [%d]\n", msgid);
@@ -562,47 +562,47 @@ vmessage_at(int msgid, const pos_t *pos, @@ -562,47 +562,47 @@ vmessage_at(int msgid, const pos_t *pos,
562 if (is_suppressed[msgid]) 562 if (is_suppressed[msgid])
563 return; 563 return;
564 564
565 fn = lbasename(pos->p_file); 565 fn = lbasename(pos->p_file);
566 (void)printf("%s(%d): ", fn, pos->p_line); 566 (void)printf("%s(%d): ", fn, pos->p_line);
567 (void)vprintf(msgs[msgid], ap); 567 (void)vprintf(msgs[msgid], ap);
568 (void)printf(" [%d]\n", msgid); 568 (void)printf(" [%d]\n", msgid);
569 print_stack_trace(); 569 print_stack_trace();
570} 570}
571 571
572void 572void
573(error_at)(int msgid, const pos_t *pos, ...) 573(error_at)(int msgid, const pos_t *pos, ...)
574{ 574{
575 va_list ap; 575 va_list ap;
576 576
577 va_start(ap, pos); 577 va_start(ap, pos);
578 verror_at(msgid, pos, ap); 578 verror_at(msgid, pos, ap);
579 va_end(ap); 579 va_end(ap);
580} 580}
581 581
582void 582void
583(error)(int msgid, ...) 583(error)(int msgid, ...)
584{ 584{
585 va_list ap; 585 va_list ap;
586 586
587 va_start(ap, msgid); 587 va_start(ap, msgid);
588 verror_at(msgid, &curr_pos, ap); 588 verror_at(msgid, &curr_pos, ap);
589 va_end(ap); 589 va_end(ap);
590} 590}
591 591
592void 592void
593assert_failed(const char *file, int line, const char *func, const char *cond) 593assert_failed(const char *file, int line, const char *func, const char *cond)
594{ 594{
595 const char *fn; 595 const char *fn;
596 596
597 /* 597 /*
598 * After encountering a parse error in the grammar, lint often does 598 * After encountering a parse error in the grammar, lint often does
599 * not properly clean up its data structures, especially in 'dcs', 599 * not properly clean up its data structures, especially in 'dcs',
600 * the stack of declaration levels. This often leads to assertion 600 * the stack of declaration levels. This often leads to assertion
601 * failures. These cases are not interesting though, as the purpose 601 * failures. These cases are not interesting though, as the purpose
602 * of lint is to check syntactically valid code. In such a case, 602 * of lint is to check syntactically valid code. In such a case,
603 * exit gracefully. This allows a fuzzer like afl to focus on more 603 * exit gracefully. This allows a fuzzer like afl to focus on more
604 * interesting cases instead of reporting nonsense translation units 604 * interesting cases instead of reporting nonsense translation units
605 * like 'f=({e:;}' or 'v(const(char););e(v){'. 605 * like 'f=({e:;}' or 'v(const(char););e(v){'.
606 */ 606 */
607 if (sytxerr > 0) 607 if (sytxerr > 0)
608 norecover(); 608 norecover();
@@ -610,87 +610,87 @@ assert_failed(const char *file, int line @@ -610,87 +610,87 @@ assert_failed(const char *file, int line
610 fn = lbasename(curr_pos.p_file); 610 fn = lbasename(curr_pos.p_file);
611 (void)fflush(stdout); 611 (void)fflush(stdout);
612 (void)fprintf(stderr, 612 (void)fprintf(stderr,
613 "lint: assertion \"%s\" failed in %s at %s:%d near %s:%d\n", 613 "lint: assertion \"%s\" failed in %s at %s:%d near %s:%d\n",
614 cond, func, file, line, fn, curr_pos.p_line); 614 cond, func, file, line, fn, curr_pos.p_line);
615 print_stack_trace(); 615 print_stack_trace();
616 (void)fflush(stdout); 616 (void)fflush(stdout);
617 abort(); 617 abort();
618} 618}
619 619
620void 620void
621(warning_at)(int msgid, const pos_t *pos, ...) 621(warning_at)(int msgid, const pos_t *pos, ...)
622{ 622{
623 va_list ap; 623 va_list ap;
624 624
625 va_start(ap, pos); 625 va_start(ap, pos);
626 vwarning_at(msgid, pos, ap); 626 vwarning_at(msgid, pos, ap);
627 va_end(ap); 627 va_end(ap);
628} 628}
629 629
630void 630void
631(warning)(int msgid, ...) 631(warning)(int msgid, ...)
632{ 632{
633 va_list ap; 633 va_list ap;
634 634
635 va_start(ap, msgid); 635 va_start(ap, msgid);
636 vwarning_at(msgid, &curr_pos, ap); 636 vwarning_at(msgid, &curr_pos, ap);
637 va_end(ap); 637 va_end(ap);
638} 638}
639 639
640void 640void
641(message_at)(int msgid, const pos_t *pos, ...) 641(message_at)(int msgid, const pos_t *pos, ...)
642{ 642{
643 va_list ap; 643 va_list ap;
644 644
645 va_start(ap, pos); 645 va_start(ap, pos);
646 vmessage_at(msgid, pos, ap); 646 vmessage_at(msgid, pos, ap);
647 va_end(ap); 647 va_end(ap);
648} 648}
649 649
650void 650void
651(c99ism)(int msgid, ...) 651(c99ism)(int msgid, ...)
652{ 652{
653 va_list ap; 653 va_list ap;
654 654
655 if (allow_c99) 655 if (allow_c99)
656 return; 656 return;
657 657
658 va_start(ap, msgid); 658 va_start(ap, msgid);
659 int severity = (!allow_gcc ? 1 : 0) + (!allow_trad ? 1 : 0); 659 int severity = (!allow_gcc ? 1 : 0) + (!allow_trad ? 1 : 0);
660 if (severity == 2) 660 if (severity == 2)
661 verror_at(msgid, &curr_pos, ap); 661 verror_at(msgid, &curr_pos, ap);
662 if (severity == 1) 662 if (severity == 1)
663 vwarning_at(msgid, &curr_pos, ap); 663 vwarning_at(msgid, &curr_pos, ap);
664 va_end(ap); 664 va_end(ap);
665} 665}
666 666
667void 667void
668(c11ism)(int msgid, ...) 668(c11ism)(int msgid, ...)
669{ 669{
670 va_list ap; 670 va_list ap;
671 671
672 /* FIXME: C11 mode has nothing to do with GCC mode. */ 672 /* FIXME: C11 mode has nothing to do with GCC mode. */
673 if (allow_c11 || allow_gcc) 673 if (allow_c11 || allow_gcc)
674 return; 674 return;
675 va_start(ap, msgid); 675 va_start(ap, msgid);
676 verror_at(msgid, &curr_pos, ap); 676 verror_at(msgid, &curr_pos, ap);
677 va_end(ap); 677 va_end(ap);
678} 678}
679 679
680bool 680bool
681(gnuism)(int msgid, ...) 681(gnuism)(int msgid, ...)
682{ 682{
683 va_list ap; 683 va_list ap;
684 int severity = (!allow_gcc ? 1 : 0) + 684 int severity = (!allow_gcc ? 1 : 0) +
685 (!allow_trad && !allow_c99 ? 1 : 0); 685 (!allow_trad && !allow_c99 ? 1 : 0);
686 686
687 va_start(ap, msgid); 687 va_start(ap, msgid);
688 if (severity == 2) 688 if (severity == 2)
689 verror_at(msgid, &curr_pos, ap); 689 verror_at(msgid, &curr_pos, ap);
690 if (severity == 1) 690 if (severity == 1)
691 vwarning_at(msgid, &curr_pos, ap); 691 vwarning_at(msgid, &curr_pos, ap);
692 va_end(ap); 692 va_end(ap);
693 return severity > 0; 693 return severity > 0;
694} 694}
695 695
696 696

cvs diff -r1.154 -r1.155 src/usr.bin/xlint/lint1/func.c (expand / switch to unified diff)

--- src/usr.bin/xlint/lint1/func.c 2023/05/11 08:01:36 1.154
+++ src/usr.bin/xlint/lint1/func.c 2023/06/09 13:03:49 1.155
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: func.c,v 1.154 2023/05/11 08:01:36 rillig Exp $ */ 1/* $NetBSD: func.c,v 1.155 2023/06/09 13:03:49 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1994, 1995 Jochen Pohl 4 * Copyright (c) 1994, 1995 Jochen Pohl
5 * All Rights Reserved. 5 * All Rights Reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -27,27 +27,27 @@ @@ -27,27 +27,27 @@
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34#if HAVE_NBTOOL_CONFIG_H 34#if HAVE_NBTOOL_CONFIG_H
35#include "nbtool_config.h" 35#include "nbtool_config.h"
36#endif 36#endif
37 37
38#include <sys/cdefs.h> 38#include <sys/cdefs.h>
39#if defined(__RCSID) 39#if defined(__RCSID)
40__RCSID("$NetBSD: func.c,v 1.154 2023/05/11 08:01:36 rillig Exp $"); 40__RCSID("$NetBSD: func.c,v 1.155 2023/06/09 13:03:49 rillig Exp $");
41#endif 41#endif
42 42
43#include <stdlib.h> 43#include <stdlib.h>
44#include <string.h> 44#include <string.h>
45 45
46#include "lint1.h" 46#include "lint1.h"
47#include "cgram.h" 47#include "cgram.h"
48 48
49/* 49/*
50 * Contains a pointer to the symbol table entry of the current function 50 * Contains a pointer to the symbol table entry of the current function
51 * definition. 51 * definition.
52 */ 52 */
53sym_t *funcsym; 53sym_t *funcsym;
@@ -210,29 +210,29 @@ check_statement_reachable(void) @@ -210,29 +210,29 @@ check_statement_reachable(void)
210/* 210/*
211 * Called after a function declaration which introduces a function definition 211 * Called after a function declaration which introduces a function definition
212 * and before an (optional) old-style argument declaration list. 212 * and before an (optional) old-style argument declaration list.
213 * 213 *
214 * Puts all symbols declared in the prototype or in an old-style argument 214 * Puts all symbols declared in the prototype or in an old-style argument
215 * list back to the symbol table. 215 * list back to the symbol table.
216 * 216 *
217 * Does the usual checking of storage class, type (return value), 217 * Does the usual checking of storage class, type (return value),
218 * redeclaration, etc. 218 * redeclaration, etc.
219 */ 219 */
220void 220void
221begin_function(sym_t *fsym) 221begin_function(sym_t *fsym)
222{ 222{
223 int n; 223 int n;
224 bool dowarn; 224 bool dowarn;
225 sym_t *arg, *sym, *rdsym; 225 sym_t *arg, *sym, *rdsym;
226 226
227 funcsym = fsym; 227 funcsym = fsym;
228 228
229 /* 229 /*
230 * Put all symbols declared in the argument list back to the 230 * Put all symbols declared in the argument list back to the
231 * symbol table. 231 * symbol table.
232 */ 232 */
233 for (sym = dcs->d_func_proto_syms; sym != NULL; 233 for (sym = dcs->d_func_proto_syms; sym != NULL;
234 sym = sym->s_level_next) { 234 sym = sym->s_level_next) {
235 if (sym->s_block_level != -1) { 235 if (sym->s_block_level != -1) {
236 lint_assert(sym->s_block_level == 1); 236 lint_assert(sym->s_block_level == 1);
237 inssym(1, sym); 237 inssym(1, sym);
238 } 238 }
@@ -360,28 +360,28 @@ check_missing_return_value(void) @@ -360,28 +360,28 @@ check_missing_return_value(void)
360 if (allow_c99 && strcmp(funcsym->s_name, "main") == 0) 360 if (allow_c99 && strcmp(funcsym->s_name, "main") == 0)
361 return; 361 return;
362 362
363 /* function '%s' falls off bottom without returning value */ 363 /* function '%s' falls off bottom without returning value */
364 warning(217, funcsym->s_name); 364 warning(217, funcsym->s_name);
365} 365}
366 366
367/* 367/*
368 * Called at the end of a function definition. 368 * Called at the end of a function definition.
369 */ 369 */
370void 370void
371end_function(void) 371end_function(void)
372{ 372{
373 sym_t *arg; 373 sym_t *arg;
374 int n; 374 int n;
375 375
376 if (reached) { 376 if (reached) {
377 cstmt->c_had_return_noval = true; 377 cstmt->c_had_return_noval = true;
378 check_missing_return_value(); 378 check_missing_return_value();
379 } 379 }
380 380
381 /* 381 /*
382 * This warning is printed only if the return value was implicitly 382 * This warning is printed only if the return value was implicitly
383 * declared to be int. Otherwise the wrong return statement 383 * declared to be int. Otherwise the wrong return statement
384 * has already printed a warning. 384 * has already printed a warning.
385 */ 385 */
386 if (cstmt->c_had_return_noval && cstmt->c_had_return_value && 386 if (cstmt->c_had_return_noval && cstmt->c_had_return_value &&
387 funcsym->s_return_type_implicit_int) 387 funcsym->s_return_type_implicit_int)
@@ -476,29 +476,29 @@ check_case_label_enum(const tnode_t *tn, @@ -476,29 +476,29 @@ check_case_label_enum(const tnode_t *tn,
476 return; 476 return;
477 477
478#if 0 /* not yet ready, see msg_130.c */ 478#if 0 /* not yet ready, see msg_130.c */
479 /* enum type mismatch: '%s' '%s' '%s' */ 479 /* enum type mismatch: '%s' '%s' '%s' */
480 warning(130, type_name(cs->c_switch_type), op_name(EQ), 480 warning(130, type_name(cs->c_switch_type), op_name(EQ),
481 type_name(tn->tn_type)); 481 type_name(tn->tn_type));
482#endif 482#endif
483} 483}
484 484
485static void 485static void
486check_case_label(tnode_t *tn, control_statement *cs) 486check_case_label(tnode_t *tn, control_statement *cs)
487{ 487{
488 case_label_t *cl; 488 case_label_t *cl;
489 val_t *v; 489 val_t *v;
490 val_t nv; 490 val_t nv;
491 tspec_t t; 491 tspec_t t;
492 492
493 if (cs == NULL) { 493 if (cs == NULL) {
494 /* case not in switch */ 494 /* case not in switch */
495 error(195); 495 error(195);
496 return; 496 return;
497 } 497 }
498 498
499 if (tn == NULL) 499 if (tn == NULL)
500 return; 500 return;
501 501
502 if (tn->tn_op != CON) { 502 if (tn->tn_op != CON) {
503 /* non-constant case expression */ 503 /* non-constant case expression */
504 error(197); 504 error(197);
@@ -677,28 +677,28 @@ if3(bool els) @@ -677,28 +677,28 @@ if3(bool els)
677 set_reached(false); 677 set_reached(false);
678 else if (!els) 678 else if (!els)
679 set_reached(true); 679 set_reached(true);
680 680
681 end_control_statement(CS_IF); 681 end_control_statement(CS_IF);
682} 682}
683 683
684/* 684/*
685 * T_SWITCH T_LPAREN expr T_RPAREN 685 * T_SWITCH T_LPAREN expr T_RPAREN
686 */ 686 */
687void 687void
688switch1(tnode_t *tn) 688switch1(tnode_t *tn)
689{ 689{
690 tspec_t t; 690 tspec_t t;
691 type_t *tp; 691 type_t *tp;
692 692
693 if (tn != NULL) 693 if (tn != NULL)
694 tn = cconv(tn); 694 tn = cconv(tn);
695 if (tn != NULL) 695 if (tn != NULL)
696 tn = promote(NOOP, false, tn); 696 tn = promote(NOOP, false, tn);
697 if (tn != NULL && !is_integer(tn->tn_type->t_tspec)) { 697 if (tn != NULL && !is_integer(tn->tn_type->t_tspec)) {
698 /* switch expression must have integral type */ 698 /* switch expression must have integral type */
699 error(205); 699 error(205);
700 tn = NULL; 700 tn = NULL;
701 } 701 }
702 if (tn != NULL && !allow_c90) { 702 if (tn != NULL && !allow_c90) {
703 t = tn->tn_type->t_tspec; 703 t = tn->tn_type->t_tspec;
704 if (t == LONG || t == ULONG || t == QUAD || t == UQUAD) { 704 if (t == LONG || t == ULONG || t == QUAD || t == UQUAD) {
@@ -733,28 +733,28 @@ switch1(tnode_t *tn) @@ -733,28 +733,28 @@ switch1(tnode_t *tn)
733 cstmt->c_switch_type = tp; 733 cstmt->c_switch_type = tp;
734 cstmt->c_switch_expr = tn; 734 cstmt->c_switch_expr = tn;
735 735
736 set_reached(false); 736 set_reached(false);
737 seen_fallthrough = true; 737 seen_fallthrough = true;
738} 738}
739 739
740/* 740/*
741 * switch_expr statement 741 * switch_expr statement
742 */ 742 */
743void 743void
744switch2(void) 744switch2(void)
745{ 745{
746 int nenum = 0, nclab = 0; 746 int nenum = 0, nclab = 0;
747 sym_t *esym; 747 sym_t *esym;
748 case_label_t *cl; 748 case_label_t *cl;
749 749
750 lint_assert(cstmt->c_switch_type != NULL); 750 lint_assert(cstmt->c_switch_type != NULL);
751 751
752 if (cstmt->c_switch_type->t_is_enum) { 752 if (cstmt->c_switch_type->t_is_enum) {
753 /* 753 /*
754 * Warn if the number of case labels is different from the 754 * Warn if the number of case labels is different from the
755 * number of enumerators. 755 * number of enumerators.
756 */ 756 */
757 nenum = nclab = 0; 757 nenum = nclab = 0;
758 lint_assert(cstmt->c_switch_type->t_enum != NULL); 758 lint_assert(cstmt->c_switch_type->t_enum != NULL);
759 for (esym = cstmt->c_switch_type->t_enum->en_first_enumerator; 759 for (esym = cstmt->c_switch_type->t_enum->en_first_enumerator;
760 esym != NULL; esym = esym->s_next) { 760 esym != NULL; esym = esym->s_next) {
@@ -936,28 +936,28 @@ for1(tnode_t *tn1, tnode_t *tn2, tnode_t @@ -936,28 +936,28 @@ for1(tnode_t *tn1, tnode_t *tn2, tnode_t
936 936
937 /* Checking the reinitialization expression is done in for2() */ 937 /* Checking the reinitialization expression is done in for2() */
938 938
939 set_reached(!is_zero(tn2)); 939 set_reached(!is_zero(tn2));
940} 940}
941 941
942/* 942/*
943 * for_exprs statement 943 * for_exprs statement
944 * for_exprs error 944 * for_exprs error
945 */ 945 */
946void 946void
947for2(void) 947for2(void)
948{ 948{
949 pos_t cpos, cspos; 949 pos_t cpos, cspos;
950 tnode_t *tn3; 950 tnode_t *tn3;
951 951
952 if (cstmt->c_continue) 952 if (cstmt->c_continue)
953 set_reached(true); 953 set_reached(true);
954 954
955 cpos = curr_pos; 955 cpos = curr_pos;
956 cspos = csrc_pos; 956 cspos = csrc_pos;
957 957
958 /* Restore the tree memory for the reinitialization expression */ 958 /* Restore the tree memory for the reinitialization expression */
959 expr_restore_memory(cstmt->c_for_expr3_mem); 959 expr_restore_memory(cstmt->c_for_expr3_mem);
960 tn3 = cstmt->c_for_expr3; 960 tn3 = cstmt->c_for_expr3;
961 curr_pos = cstmt->c_for_expr3_pos; 961 curr_pos = cstmt->c_for_expr3_pos;
962 csrc_pos = cstmt->c_for_expr3_csrc_pos; 962 csrc_pos = cstmt->c_for_expr3_csrc_pos;
963 963

cvs diff -r1.158 -r1.159 src/usr.bin/xlint/lint1/lex.c (expand / switch to unified diff)

--- src/usr.bin/xlint/lint1/lex.c 2023/04/11 00:03:42 1.158
+++ src/usr.bin/xlint/lint1/lex.c 2023/06/09 13:03:49 1.159
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: lex.c,v 1.158 2023/04/11 00:03:42 rillig Exp $ */ 1/* $NetBSD: lex.c,v 1.159 2023/06/09 13:03:49 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. 4 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
5 * Copyright (c) 1994, 1995 Jochen Pohl 5 * Copyright (c) 1994, 1995 Jochen Pohl
6 * All Rights Reserved. 6 * All Rights Reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
@@ -28,27 +28,27 @@ @@ -28,27 +28,27 @@
28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */ 33 */
34 34
35#if HAVE_NBTOOL_CONFIG_H 35#if HAVE_NBTOOL_CONFIG_H
36#include "nbtool_config.h" 36#include "nbtool_config.h"
37#endif 37#endif
38 38
39#include <sys/cdefs.h> 39#include <sys/cdefs.h>
40#if defined(__RCSID) 40#if defined(__RCSID)
41__RCSID("$NetBSD: lex.c,v 1.158 2023/04/11 00:03:42 rillig Exp $"); 41__RCSID("$NetBSD: lex.c,v 1.159 2023/06/09 13:03:49 rillig Exp $");
42#endif 42#endif
43 43
44#include <ctype.h> 44#include <ctype.h>
45#include <errno.h> 45#include <errno.h>
46#include <float.h> 46#include <float.h>
47#include <limits.h> 47#include <limits.h>
48#include <math.h> 48#include <math.h>
49#include <stdlib.h> 49#include <stdlib.h>
50#include <string.h> 50#include <string.h>
51 51
52#include "lint1.h" 52#include "lint1.h"
53#include "cgram.h" 53#include "cgram.h"
54 54
@@ -395,27 +395,27 @@ initscan(void) @@ -395,27 +395,27 @@ initscan(void)
395 add_keyword(kw, true, true); 395 add_keyword(kw, true, true);
396 } 396 }
397} 397}
398 398
399/* 399/*
400 * When scanning the remainder of a long token (see lex_input), read a byte 400 * When scanning the remainder of a long token (see lex_input), read a byte
401 * and return it as an unsigned char or as EOF. 401 * and return it as an unsigned char or as EOF.
402 * 402 *
403 * Increment the line counts if necessary. 403 * Increment the line counts if necessary.
404 */ 404 */
405static int 405static int
406read_byte(void) 406read_byte(void)
407{ 407{
408 int c; 408 int c;
409 409
410 if ((c = lex_input()) == EOF) 410 if ((c = lex_input()) == EOF)
411 return c; 411 return c;
412 if (c == '\0') 412 if (c == '\0')
413 return EOF; /* lex returns 0 on EOF. */ 413 return EOF; /* lex returns 0 on EOF. */
414 if (c == '\n') 414 if (c == '\n')
415 lex_next_line(); 415 lex_next_line();
416 return c; 416 return c;
417} 417}
418 418
419static int 419static int
420lex_keyword(sym_t *sym) 420lex_keyword(sym_t *sym)
421{ 421{
@@ -837,27 +837,27 @@ get_escaped_char(int delim) @@ -837,27 +837,27 @@ get_escaped_char(int delim)
837 return -2; 837 return -2;
838 case '\\': 838 case '\\':
839 c = read_escaped_backslash(delim); 839 c = read_escaped_backslash(delim);
840 if (c == -3) 840 if (c == -3)
841 return get_escaped_char(delim); 841 return get_escaped_char(delim);
842 } 842 }
843 return c; 843 return c;
844} 844}
845 845
846/* Called if lex found a leading "'". */ 846/* Called if lex found a leading "'". */
847int 847int
848lex_character_constant(void) 848lex_character_constant(void)
849{ 849{
850 size_t n; 850 size_t n;
851 int val, c; 851 int val, c;
852 852
853 n = 0; 853 n = 0;
854 val = 0; 854 val = 0;
855 while ((c = get_escaped_char('\'')) >= 0) { 855 while ((c = get_escaped_char('\'')) >= 0) {
856 val = (int)((unsigned int)val << CHAR_SIZE) + c; 856 val = (int)((unsigned int)val << CHAR_SIZE) + c;
857 n++; 857 n++;
858 } 858 }
859 if (c == -2) { 859 if (c == -2) {
860 /* unterminated character constant */ 860 /* unterminated character constant */
861 error(253); 861 error(253);
862 } else if (n > sizeof(int) || (n > 1 && (pflag || hflag))) { 862 } else if (n > sizeof(int) || (n > 1 && (pflag || hflag))) {
863 /* 863 /*
@@ -879,30 +879,30 @@ lex_character_constant(void) @@ -879,30 +879,30 @@ lex_character_constant(void)
879 yylval.y_val = xcalloc(1, sizeof(*yylval.y_val)); 879 yylval.y_val = xcalloc(1, sizeof(*yylval.y_val));
880 yylval.y_val->v_tspec = INT; 880 yylval.y_val->v_tspec = INT;
881 yylval.y_val->v_quad = val; 881 yylval.y_val->v_quad = val;
882 882
883 return T_CON; 883 return T_CON;
884} 884}
885 885
886/* 886/*
887 * Called if lex found a leading L\' 887 * Called if lex found a leading L\'
888 */ 888 */
889int 889int
890lex_wide_character_constant(void) 890lex_wide_character_constant(void)
891{ 891{
892 static char buf[MB_LEN_MAX + 1]; 892 static char buf[MB_LEN_MAX + 1];
893 size_t n, nmax; 893 size_t n, nmax;
894 int c; 894 int c;
895 wchar_t wc; 895 wchar_t wc;
896 896
897 nmax = MB_CUR_MAX; 897 nmax = MB_CUR_MAX;
898 898
899 n = 0; 899 n = 0;
900 while ((c = get_escaped_char('\'')) >= 0) { 900 while ((c = get_escaped_char('\'')) >= 0) {
901 if (n < nmax) 901 if (n < nmax)
902 buf[n] = (char)c; 902 buf[n] = (char)c;
903 n++; 903 n++;
904 } 904 }
905 905
906 wc = 0; 906 wc = 0;
907 907
908 if (c == -2) { 908 if (c == -2) {
@@ -959,33 +959,33 @@ parse_line_directive_flags(const char *p @@ -959,33 +959,33 @@ parse_line_directive_flags(const char *p
959 } 959 }
960} 960}
961 961
962/* 962/*
963 * Called for preprocessor directives. Currently implemented are: 963 * Called for preprocessor directives. Currently implemented are:
964 * # pragma [argument...] 964 * # pragma [argument...]
965 * # lineno 965 * # lineno
966 * # lineno "filename" 966 * # lineno "filename"
967 * # lineno "filename" GCC-flag... 967 * # lineno "filename" GCC-flag...
968 */ 968 */
969void 969void
970lex_directive(const char *yytext) 970lex_directive(const char *yytext)
971{ 971{
972 const char *cp, *fn; 972 const char *cp, *fn;
973 char c, *eptr; 973 char c, *eptr;
974 size_t fnl; 974 size_t fnl;
975 long ln; 975 long ln;
976 bool is_begin, is_end, is_system; 976 bool is_begin, is_end, is_system;
977 977
978 static bool first = true; 978 static bool first = true;
979 979
980 /* Go to first non-whitespace after # */ 980 /* Go to first non-whitespace after # */
981 for (cp = yytext + 1; (c = *cp) == ' ' || c == '\t'; cp++) 981 for (cp = yytext + 1; (c = *cp) == ' ' || c == '\t'; cp++)
982 continue; 982 continue;
983 983
984 if (!ch_isdigit(c)) { 984 if (!ch_isdigit(c)) {
985 if (strncmp(cp, "pragma", 6) == 0 && ch_isspace(cp[6])) 985 if (strncmp(cp, "pragma", 6) == 0 && ch_isspace(cp[6]))
986 return; 986 return;
987 error: 987 error:
988 /* undefined or invalid # directive */ 988 /* undefined or invalid # directive */
989 warning(255); 989 warning(255);
990 return; 990 return;
991 } 991 }
@@ -1060,30 +1060,30 @@ lex_comment(void) @@ -1060,30 +1060,30 @@ lex_comment(void)
1060 { "FALLTHROUGH", false, fallthru }, 1060 { "FALLTHROUGH", false, fallthru },
1061 { "FALL THROUGH", false, fallthru }, 1061 { "FALL THROUGH", false, fallthru },
1062 { "fallthrough", false, fallthru }, 1062 { "fallthrough", false, fallthru },
1063 { "LINTLIBRARY", false, lintlib }, 1063 { "LINTLIBRARY", false, lintlib },
1064 { "LINTED", true, linted }, 1064 { "LINTED", true, linted },
1065 { "LONGLONG", false, longlong }, 1065 { "LONGLONG", false, longlong },
1066 { "NOSTRICT", true, linted }, 1066 { "NOSTRICT", true, linted },
1067 { "NOTREACHED", false, not_reached }, 1067 { "NOTREACHED", false, not_reached },
1068 { "PRINTFLIKE", true, printflike }, 1068 { "PRINTFLIKE", true, printflike },
1069 { "PROTOLIB", true, protolib }, 1069 { "PROTOLIB", true, protolib },
1070 { "SCANFLIKE", true, scanflike }, 1070 { "SCANFLIKE", true, scanflike },
1071 { "VARARGS", true, varargs }, 1071 { "VARARGS", true, varargs },
1072 }; 1072 };
1073 char keywd[32]; 1073 char keywd[32];
1074 char arg[32]; 1074 char arg[32];
1075 size_t l, i; 1075 size_t l, i;
1076 int a; 1076 int a;
1077 1077
1078 bool seen_end_of_comment = false; 1078 bool seen_end_of_comment = false;
1079 1079
1080 /* Skip whitespace after the start of the comment */ 1080 /* Skip whitespace after the start of the comment */
1081 while (c = read_byte(), isspace(c)) 1081 while (c = read_byte(), isspace(c))
1082 continue; 1082 continue;
1083 1083
1084 /* Read the potential keyword to keywd */ 1084 /* Read the potential keyword to keywd */
1085 l = 0; 1085 l = 0;
1086 while (c != EOF && l < sizeof(keywd) - 1 && 1086 while (c != EOF && l < sizeof(keywd) - 1 &&
1087 (isalpha(c) || isspace(c))) { 1087 (isalpha(c) || isspace(c))) {
1088 if (islower(c) && l > 0 && ch_isupper(keywd[0])) 1088 if (islower(c) && l > 0 && ch_isupper(keywd[0]))
1089 break; 1089 break;
@@ -1165,28 +1165,28 @@ lex_slash_slash_comment(void) @@ -1165,28 +1165,28 @@ lex_slash_slash_comment(void)
1165void 1165void
1166clear_warn_flags(void) 1166clear_warn_flags(void)
1167{ 1167{
1168 1168
1169 lwarn = LWARN_ALL; 1169 lwarn = LWARN_ALL;
1170 quadflg = false; 1170 quadflg = false;
1171 constcond_flag = false; 1171 constcond_flag = false;
1172} 1172}
1173 1173
1174int 1174int
1175lex_string(void) 1175lex_string(void)
1176{ 1176{
1177 unsigned char *s; 1177 unsigned char *s;
1178 int c; 1178 int c;
1179 size_t len, max; 1179 size_t len, max;
1180 1180
1181 s = xmalloc(max = 64); 1181 s = xmalloc(max = 64);
1182 1182
1183 len = 0; 1183 len = 0;
1184 while ((c = get_escaped_char('"')) >= 0) { 1184 while ((c = get_escaped_char('"')) >= 0) {
1185 /* +1 to reserve space for a trailing NUL character */ 1185 /* +1 to reserve space for a trailing NUL character */
1186 if (len + 1 == max) 1186 if (len + 1 == max)
1187 s = xrealloc(s, max *= 2); 1187 s = xrealloc(s, max *= 2);
1188 s[len++] = (char)c; 1188 s[len++] = (char)c;
1189 } 1189 }
1190 s[len] = '\0'; 1190 s[len] = '\0';
1191 if (c == -2) 1191 if (c == -2)
1192 /* unterminated string constant */ 1192 /* unterminated string constant */
@@ -1194,27 +1194,27 @@ lex_string(void) @@ -1194,27 +1194,27 @@ lex_string(void)
1194 1194
1195 strg_t *strg = xcalloc(1, sizeof(*strg)); 1195 strg_t *strg = xcalloc(1, sizeof(*strg));
1196 strg->st_char = true; 1196 strg->st_char = true;
1197 strg->st_len = len; 1197 strg->st_len = len;
1198 strg->st_mem = s; 1198 strg->st_mem = s;
1199 1199
1200 yylval.y_string = strg; 1200 yylval.y_string = strg;
1201 return T_STRING; 1201 return T_STRING;
1202} 1202}
1203 1203
1204int 1204int
1205lex_wide_string(void) 1205lex_wide_string(void)
1206{ 1206{
1207 int c, n; 1207 int c, n;
1208 1208
1209 size_t len = 0, max = 64; 1209 size_t len = 0, max = 64;
1210 char *s = xmalloc(max); 1210 char *s = xmalloc(max);
1211 while ((c = get_escaped_char('"')) >= 0) { 1211 while ((c = get_escaped_char('"')) >= 0) {
1212 /* +1 to save space for a trailing NUL character */ 1212 /* +1 to save space for a trailing NUL character */
1213 if (len + 1 >= max) 1213 if (len + 1 >= max)
1214 s = xrealloc(s, max *= 2); 1214 s = xrealloc(s, max *= 2);
1215 s[len++] = (char)c; 1215 s[len++] = (char)c;
1216 } 1216 }
1217 s[len] = '\0'; 1217 s[len] = '\0';
1218 if (c == -2) 1218 if (c == -2)
1219 /* unterminated string constant */ 1219 /* unterminated string constant */
1220 error(258); 1220 error(258);
@@ -1222,27 +1222,27 @@ lex_wide_string(void) @@ -1222,27 +1222,27 @@ lex_wide_string(void)
1222 /* get length of wide-character string */ 1222 /* get length of wide-character string */
1223 (void)mblen(NULL, 0); 1223 (void)mblen(NULL, 0);
1224 size_t wlen = 0; 1224 size_t wlen = 0;
1225 for (size_t i = 0; i < len; i += n, wlen++) { 1225 for (size_t i = 0; i < len; i += n, wlen++) {
1226 if ((n = mblen(&s[i], MB_CUR_MAX)) == -1) { 1226 if ((n = mblen(&s[i], MB_CUR_MAX)) == -1) {
1227 /* invalid multibyte character */ 1227 /* invalid multibyte character */
1228 error(291); 1228 error(291);
1229 break; 1229 break;
1230 } 1230 }
1231 if (n == 0) 1231 if (n == 0)
1232 n = 1; 1232 n = 1;
1233 } 1233 }
1234 1234
1235 wchar_t *ws = xmalloc((wlen + 1) * sizeof(*ws)); 1235 wchar_t *ws = xmalloc((wlen + 1) * sizeof(*ws));
1236 size_t wi = 0; 1236 size_t wi = 0;
1237 /* convert from multibyte to wide char */ 1237 /* convert from multibyte to wide char */
1238 (void)mbtowc(NULL, NULL, 0); 1238 (void)mbtowc(NULL, NULL, 0);
1239 for (size_t i = 0; i < len; i += n, wi++) { 1239 for (size_t i = 0; i < len; i += n, wi++) {
1240 if ((n = mbtowc(&ws[wi], &s[i], MB_CUR_MAX)) == -1) 1240 if ((n = mbtowc(&ws[wi], &s[i], MB_CUR_MAX)) == -1)
1241 break; 1241 break;
1242 if (n == 0) 1242 if (n == 0)
1243 n = 1; 1243 n = 1;
1244 } 1244 }
1245 ws[wi] = 0; 1245 ws[wi] = 0;
1246 free(s); 1246 free(s);
1247 1247
1248 strg_t *strg = xcalloc(1, sizeof(*strg)); 1248 strg_t *strg = xcalloc(1, sizeof(*strg));
@@ -1303,27 +1303,27 @@ getsym(sbuf_t *sb) @@ -1303,27 +1303,27 @@ getsym(sbuf_t *sb)
1303 sym = symtab_search(sb->sb_name); 1303 sym = symtab_search(sb->sb_name);
1304 } 1304 }
1305 1305
1306 if (sym != NULL) { 1306 if (sym != NULL) {
1307 lint_assert(sym->s_kind == symtyp); 1307 lint_assert(sym->s_kind == symtyp);
1308 symtyp = FVFT; 1308 symtyp = FVFT;
1309 free(sb); 1309 free(sb);
1310 return sym; 1310 return sym;
1311 } 1311 }
1312 1312
1313 /* create a new symbol table entry */ 1313 /* create a new symbol table entry */
1314 1314
1315 /* labels must always be allocated at level 1 (outermost block) */ 1315 /* labels must always be allocated at level 1 (outermost block) */
1316 dinfo_t *di; 1316 dinfo_t *di;
1317 if (symtyp == FLABEL) { 1317 if (symtyp == FLABEL) {
1318 sym = level_zero_alloc(1, sizeof(*sym)); 1318 sym = level_zero_alloc(1, sizeof(*sym));
1319 char *s = level_zero_alloc(1, sb->sb_len + 1); 1319 char *s = level_zero_alloc(1, sb->sb_len + 1);
1320 (void)memcpy(s, sb->sb_name, sb->sb_len + 1); 1320 (void)memcpy(s, sb->sb_name, sb->sb_len + 1);
1321 sym->s_name = s; 1321 sym->s_name = s;
1322 sym->s_block_level = 1; 1322 sym->s_block_level = 1;
1323 di = dcs; 1323 di = dcs;
1324 while (di->d_enclosing != NULL && 1324 while (di->d_enclosing != NULL &&
1325 di->d_enclosing->d_enclosing != NULL) 1325 di->d_enclosing->d_enclosing != NULL)
1326 di = di->d_enclosing; 1326 di = di->d_enclosing;
1327 lint_assert(di->d_kind == DK_AUTO); 1327 lint_assert(di->d_kind == DK_AUTO);
1328 } else { 1328 } else {
1329 sym = block_zero_alloc(sizeof(*sym)); 1329 sym = block_zero_alloc(sizeof(*sym));
@@ -1393,27 +1393,27 @@ rmsym(sym_t *sym) @@ -1393,27 +1393,27 @@ rmsym(sym_t *sym)
1393 symtab_remove(sym); 1393 symtab_remove(sym);
1394 1394
1395 /* avoid that the symbol will later be put back to the symbol table */ 1395 /* avoid that the symbol will later be put back to the symbol table */
1396 sym->s_block_level = -1; 1396 sym->s_block_level = -1;
1397} 1397}
1398 1398
1399/* 1399/*
1400 * Remove all symbols from the symbol table that have the same level as the 1400 * Remove all symbols from the symbol table that have the same level as the
1401 * given symbol. 1401 * given symbol.
1402 */ 1402 */
1403void 1403void
1404rmsyms(sym_t *syms) 1404rmsyms(sym_t *syms)
1405{ 1405{
1406 sym_t *sym; 1406 sym_t *sym;
1407 1407
1408 /* Note the use of s_level_next instead of s_symtab_next. */ 1408 /* Note the use of s_level_next instead of s_symtab_next. */
1409 for (sym = syms; sym != NULL; sym = sym->s_level_next) { 1409 for (sym = syms; sym != NULL; sym = sym->s_level_next) {
1410 if (sym->s_block_level != -1) { 1410 if (sym->s_block_level != -1) {
1411 debug_step("rmsyms '%s' %s '%s'", 1411 debug_step("rmsyms '%s' %s '%s'",
1412 sym->s_name, symt_name(sym->s_kind), 1412 sym->s_name, symt_name(sym->s_kind),
1413 type_name(sym->s_type)); 1413 type_name(sym->s_type));
1414 symtab_remove(sym); 1414 symtab_remove(sym);
1415 sym->s_symtab_ref = NULL; 1415 sym->s_symtab_ref = NULL;
1416 } 1416 }
1417 } 1417 }
1418} 1418}
1419 1419
@@ -1442,27 +1442,27 @@ void @@ -1442,27 +1442,27 @@ void
1442clean_up_after_error(void) 1442clean_up_after_error(void)
1443{ 1443{
1444 1444
1445 symtab_remove_locals(); 1445 symtab_remove_locals();
1446 1446
1447 while (mem_block_level > 0) 1447 while (mem_block_level > 0)
1448 level_free_all(mem_block_level--); 1448 level_free_all(mem_block_level--);
1449} 1449}
1450 1450
1451/* Create a new symbol with the same name as an existing symbol. */ 1451/* Create a new symbol with the same name as an existing symbol. */
1452sym_t * 1452sym_t *
1453pushdown(const sym_t *sym) 1453pushdown(const sym_t *sym)
1454{ 1454{
1455 sym_t *nsym; 1455 sym_t *nsym;
1456 1456
1457 debug_step("pushdown '%s' %s '%s'", 1457 debug_step("pushdown '%s' %s '%s'",
1458 sym->s_name, symt_name(sym->s_kind), type_name(sym->s_type)); 1458 sym->s_name, symt_name(sym->s_kind), type_name(sym->s_type));
1459 nsym = block_zero_alloc(sizeof(*nsym)); 1459 nsym = block_zero_alloc(sizeof(*nsym));
1460 lint_assert(sym->s_block_level <= block_level); 1460 lint_assert(sym->s_block_level <= block_level);
1461 nsym->s_name = sym->s_name; 1461 nsym->s_name = sym->s_name;
1462 UNIQUE_CURR_POS(nsym->s_def_pos); 1462 UNIQUE_CURR_POS(nsym->s_def_pos);
1463 nsym->s_kind = sym->s_kind; 1463 nsym->s_kind = sym->s_kind;
1464 nsym->s_block_level = block_level; 1464 nsym->s_block_level = block_level;
1465 1465
1466 symtab_add(nsym); 1466 symtab_add(nsym);
1467 1467
1468 *dcs->d_ldlsym = nsym; 1468 *dcs->d_ldlsym = nsym;

cvs diff -r1.525 -r1.526 src/usr.bin/xlint/lint1/tree.c (expand / switch to unified diff)

--- src/usr.bin/xlint/lint1/tree.c 2023/06/03 20:28:54 1.525
+++ src/usr.bin/xlint/lint1/tree.c 2023/06/09 13:03:49 1.526
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: tree.c,v 1.525 2023/06/03 20:28:54 rillig Exp $ */ 1/* $NetBSD: tree.c,v 1.526 2023/06/09 13:03:49 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1994, 1995 Jochen Pohl 4 * Copyright (c) 1994, 1995 Jochen Pohl
5 * All Rights Reserved. 5 * All Rights Reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -27,27 +27,27 @@ @@ -27,27 +27,27 @@
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34#if HAVE_NBTOOL_CONFIG_H 34#if HAVE_NBTOOL_CONFIG_H
35#include "nbtool_config.h" 35#include "nbtool_config.h"
36#endif 36#endif
37 37
38#include <sys/cdefs.h> 38#include <sys/cdefs.h>
39#if defined(__RCSID) 39#if defined(__RCSID)
40__RCSID("$NetBSD: tree.c,v 1.525 2023/06/03 20:28:54 rillig Exp $"); 40__RCSID("$NetBSD: tree.c,v 1.526 2023/06/09 13:03:49 rillig Exp $");
41#endif 41#endif
42 42
43#include <float.h> 43#include <float.h>
44#include <limits.h> 44#include <limits.h>
45#include <math.h> 45#include <math.h>
46#include <signal.h> 46#include <signal.h>
47#include <stdlib.h> 47#include <stdlib.h>
48#include <string.h> 48#include <string.h>
49 49
50#include "lint1.h" 50#include "lint1.h"
51 51
52 52
53typedef struct integer_constraints { 53typedef struct integer_constraints {
@@ -305,42 +305,42 @@ ic_expr(const tnode_t *tn) @@ -305,42 +305,42 @@ ic_expr(const tnode_t *tn)
305 case QUEST: 305 case QUEST:
306 lc = ic_expr(tn->tn_right->tn_left); 306 lc = ic_expr(tn->tn_right->tn_left);
307 rc = ic_expr(tn->tn_right->tn_right); 307 rc = ic_expr(tn->tn_right->tn_right);
308 return ic_cond(lc, rc); 308 return ic_cond(lc, rc);
309 default: 309 default:
310 return ic_any(tn->tn_type); 310 return ic_any(tn->tn_type);
311 } 311 }
312} 312}
313 313
314/* Build 'pointer to tp', 'array of tp' or 'function returning tp'. */ 314/* Build 'pointer to tp', 'array of tp' or 'function returning tp'. */
315type_t * 315type_t *
316block_derive_type(type_t *tp, tspec_t t) 316block_derive_type(type_t *tp, tspec_t t)
317{ 317{
318 type_t *tp2; 318 type_t *tp2;
319 319
320 tp2 = block_zero_alloc(sizeof(*tp2)); 320 tp2 = block_zero_alloc(sizeof(*tp2));
321 tp2->t_tspec = t; 321 tp2->t_tspec = t;
322 tp2->t_subt = tp; 322 tp2->t_subt = tp;
323 return tp2; 323 return tp2;
324} 324}
325 325
326/* 326/*
327 * Derive 'pointer to tp' or 'function returning tp'. 327 * Derive 'pointer to tp' or 'function returning tp'.
328 * The memory is freed at the end of the current expression. 328 * The memory is freed at the end of the current expression.
329 */ 329 */
330type_t * 330type_t *
331expr_derive_type(type_t *tp, tspec_t t) 331expr_derive_type(type_t *tp, tspec_t t)
332{ 332{
333 type_t *tp2; 333 type_t *tp2;
334 334
335 tp2 = expr_zero_alloc(sizeof(*tp2)); 335 tp2 = expr_zero_alloc(sizeof(*tp2));
336 tp2->t_tspec = t; 336 tp2->t_tspec = t;
337 tp2->t_subt = tp; 337 tp2->t_subt = tp;
338 return tp2; 338 return tp2;
339} 339}
340 340
341/* 341/*
342 * Build and initialize a new node. 342 * Build and initialize a new node.
343 */ 343 */
344static tnode_t * 344static tnode_t *
345new_tnode(op_t op, bool sys, type_t *type, tnode_t *ln, tnode_t *rn) 345new_tnode(op_t op, bool sys, type_t *type, tnode_t *ln, tnode_t *rn)
346{ 346{
@@ -358,43 +358,43 @@ new_tnode(op_t op, bool sys, type_t *typ @@ -358,43 +358,43 @@ new_tnode(op_t op, bool sys, type_t *typ
358 if (t != FUNC && t != VOID) 358 if (t != FUNC && t != VOID)
359 ntn->tn_lvalue = true; 359 ntn->tn_lvalue = true;
360 } 360 }
361 361
362 return ntn; 362 return ntn;
363} 363}
364 364
365/* 365/*
366 * Create a node for a constant. 366 * Create a node for a constant.
367 */ 367 */
368tnode_t * 368tnode_t *
369build_constant(type_t *tp, val_t *v) 369build_constant(type_t *tp, val_t *v)
370{ 370{
371 tnode_t *n; 371 tnode_t *n;
372 372
373 n = expr_alloc_tnode(); 373 n = expr_alloc_tnode();
374 n->tn_op = CON; 374 n->tn_op = CON;
375 n->tn_type = tp; 375 n->tn_type = tp;
376 n->tn_val = expr_zero_alloc(sizeof(*n->tn_val)); 376 n->tn_val = expr_zero_alloc(sizeof(*n->tn_val));
377 n->tn_val->v_tspec = tp->t_tspec; 377 n->tn_val->v_tspec = tp->t_tspec;
378 n->tn_val->v_unsigned_since_c90 = v->v_unsigned_since_c90; 378 n->tn_val->v_unsigned_since_c90 = v->v_unsigned_since_c90;
379 n->tn_val->v_u = v->v_u; 379 n->tn_val->v_u = v->v_u;
380 free(v); 380 free(v);
381 return n; 381 return n;
382} 382}
383 383
384static tnode_t * 384static tnode_t *
385build_integer_constant(tspec_t t, int64_t q) 385build_integer_constant(tspec_t t, int64_t q)
386{ 386{
387 tnode_t *n; 387 tnode_t *n;
388 388
389 n = expr_alloc_tnode(); 389 n = expr_alloc_tnode();
390 n->tn_op = CON; 390 n->tn_op = CON;
391 n->tn_type = gettyp(t); 391 n->tn_type = gettyp(t);
392 n->tn_val = expr_zero_alloc(sizeof(*n->tn_val)); 392 n->tn_val = expr_zero_alloc(sizeof(*n->tn_val));
393 n->tn_val->v_tspec = t; 393 n->tn_val->v_tspec = t;
394 n->tn_val->v_quad = q; 394 n->tn_val->v_quad = q;
395 return n; 395 return n;
396} 396}
397 397
398static void 398static void
399fallback_symbol(sym_t *sym) 399fallback_symbol(sym_t *sym)
400{ 400{
@@ -479,27 +479,27 @@ build_name_call(sym_t *sym) @@ -479,27 +479,27 @@ build_name_call(sym_t *sym)
479 } else if (!allow_trad) { 479 } else if (!allow_trad) {
480 /* function '%s' implicitly declared to return int */ 480 /* function '%s' implicitly declared to return int */
481 warning(215, sym->s_name); 481 warning(215, sym->s_name);
482 } 482 }
483 483
484 /* XXX if !allow_c90, the symbol should be exported to level 0 */ 484 /* XXX if !allow_c90, the symbol should be exported to level 0 */
485 sym->s_type = block_derive_type(sym->s_type, FUNC); 485 sym->s_type = block_derive_type(sym->s_type, FUNC);
486} 486}
487 487
488/* Create a node for a name (symbol table entry). */ 488/* Create a node for a name (symbol table entry). */
489tnode_t * 489tnode_t *
490build_name(sym_t *sym, bool is_funcname) 490build_name(sym_t *sym, bool is_funcname)
491{ 491{
492 tnode_t *n; 492 tnode_t *n;
493 493
494 if (sym->s_scl == NOSCL && !in_gcc_attribute) { 494 if (sym->s_scl == NOSCL && !in_gcc_attribute) {
495 sym->s_scl = EXTERN; 495 sym->s_scl = EXTERN;
496 sym->s_def = DECL; 496 sym->s_def = DECL;
497 if (is_funcname) 497 if (is_funcname)
498 build_name_call(sym); 498 build_name_call(sym);
499 else 499 else
500 fallback_symbol(sym); 500 fallback_symbol(sym);
501 } 501 }
502 502
503 lint_assert(sym->s_kind == FVFT || sym->s_kind == FMEMBER); 503 lint_assert(sym->s_kind == FVFT || sym->s_kind == FMEMBER);
504 504
505 n = expr_alloc_tnode(); 505 n = expr_alloc_tnode();
@@ -517,28 +517,28 @@ build_name(sym_t *sym, bool is_funcname) @@ -517,28 +517,28 @@ build_name(sym_t *sym, bool is_funcname)
517 } else { 517 } else {
518 n->tn_op = NAME; 518 n->tn_op = NAME;
519 n->tn_sym = sym; 519 n->tn_sym = sym;
520 if (sym->s_kind == FVFT && sym->s_type->t_tspec != FUNC) 520 if (sym->s_kind == FVFT && sym->s_type->t_tspec != FUNC)
521 n->tn_lvalue = true; 521 n->tn_lvalue = true;
522 } 522 }
523 523
524 return n; 524 return n;
525} 525}
526 526
527tnode_t * 527tnode_t *
528build_string(strg_t *strg) 528build_string(strg_t *strg)
529{ 529{
530 size_t len; 530 size_t len;
531 tnode_t *n; 531 tnode_t *n;
532 type_t *tp; 532 type_t *tp;
533 533
534 len = strg->st_len; 534 len = strg->st_len;
535 535
536 n = expr_alloc_tnode(); 536 n = expr_alloc_tnode();
537 537
538 tp = expr_zero_alloc(sizeof(*tp)); 538 tp = expr_zero_alloc(sizeof(*tp));
539 tp->t_tspec = ARRAY; 539 tp->t_tspec = ARRAY;
540 tp->t_subt = gettyp(strg->st_char ? CHAR : WCHAR); 540 tp->t_subt = gettyp(strg->st_char ? CHAR : WCHAR);
541 tp->t_dim = (int)(len + 1); 541 tp->t_dim = (int)(len + 1);
542 542
543 n->tn_op = STRING; 543 n->tn_op = STRING;
544 n->tn_type = tp; 544 n->tn_type = tp;
@@ -579,27 +579,27 @@ static bool @@ -579,27 +579,27 @@ static bool
579is_out_of_char_range(const tnode_t *tn) 579is_out_of_char_range(const tnode_t *tn)
580{ 580{
581 return tn->tn_op == CON && 581 return tn->tn_op == CON &&
582 !(0 <= tn->tn_val->v_quad && 582 !(0 <= tn->tn_val->v_quad &&
583 tn->tn_val->v_quad < 1 << (CHAR_SIZE - 1)); 583 tn->tn_val->v_quad < 1 << (CHAR_SIZE - 1));
584} 584}
585 585
586/* 586/*
587 * Check for ordered comparisons of unsigned values with 0. 587 * Check for ordered comparisons of unsigned values with 0.
588 */ 588 */
589static void 589static void
590check_integer_comparison(op_t op, tnode_t *ln, tnode_t *rn) 590check_integer_comparison(op_t op, tnode_t *ln, tnode_t *rn)
591{ 591{
592 tspec_t lt, rt; 592 tspec_t lt, rt;
593 593
594 lt = ln->tn_type->t_tspec; 594 lt = ln->tn_type->t_tspec;
595 rt = rn->tn_type->t_tspec; 595 rt = rn->tn_type->t_tspec;
596 596
597 if (ln->tn_op != CON && rn->tn_op != CON) 597 if (ln->tn_op != CON && rn->tn_op != CON)
598 return; 598 return;
599 599
600 if (!is_integer(lt) || !is_integer(rt)) 600 if (!is_integer(lt) || !is_integer(rt))
601 return; 601 return;
602 602
603 if (hflag || pflag) { 603 if (hflag || pflag) {
604 if (lt == CHAR && is_out_of_char_range(rn)) { 604 if (lt == CHAR && is_out_of_char_range(rn)) {
605 char buf[128]; 605 char buf[128];
@@ -743,27 +743,27 @@ balance(op_t op, tnode_t **lnp, tnode_t  @@ -743,27 +743,27 @@ balance(op_t op, tnode_t **lnp, tnode_t
743 743
744 if (t != lt) 744 if (t != lt)
745 *lnp = apply_usual_arithmetic_conversions(op, *lnp, t); 745 *lnp = apply_usual_arithmetic_conversions(op, *lnp, t);
746 if (t != rt) 746 if (t != rt)
747 *rnp = apply_usual_arithmetic_conversions(op, *rnp, t); 747 *rnp = apply_usual_arithmetic_conversions(op, *rnp, t);
748} 748}
749 749
750/* 750/*
751 * Create a tree node for the unary & operator 751 * Create a tree node for the unary & operator
752 */ 752 */
753static tnode_t * 753static tnode_t *
754build_address(bool sys, tnode_t *tn, bool noign) 754build_address(bool sys, tnode_t *tn, bool noign)
755{ 755{
756 tspec_t t; 756 tspec_t t;
757 757
758 if (!noign && ((t = tn->tn_type->t_tspec) == ARRAY || t == FUNC)) { 758 if (!noign && ((t = tn->tn_type->t_tspec) == ARRAY || t == FUNC)) {
759 if (!allow_c90) 759 if (!allow_c90)
760 /* '&' before array or function: ignored */ 760 /* '&' before array or function: ignored */
761 warning(127); 761 warning(127);
762 return tn; 762 return tn;
763 } 763 }
764 764
765 /* eliminate &* */ 765 /* eliminate &* */
766 if (tn->tn_op == INDIR && 766 if (tn->tn_op == INDIR &&
767 tn->tn_left->tn_type->t_tspec == PTR && 767 tn->tn_left->tn_type->t_tspec == PTR &&
768 tn->tn_left->tn_type->t_subt == tn->tn_type) { 768 tn->tn_left->tn_type->t_subt == tn->tn_type) {
769 return tn->tn_left; 769 return tn->tn_left;
@@ -922,28 +922,28 @@ fold(tnode_t *tn) @@ -922,28 +922,28 @@ fold(tnode_t *tn)
922 cn->tn_system_dependent = true; 922 cn->tn_system_dependent = true;
923 if (is_binary(tn) && tn->tn_right->tn_system_dependent) 923 if (is_binary(tn) && tn->tn_right->tn_system_dependent)
924 cn->tn_system_dependent = true; 924 cn->tn_system_dependent = true;
925 925
926 return cn; 926 return cn;
927} 927}
928 928
929/* 929/*
930 * Create a new node for one of the operators POINT and ARROW. 930 * Create a new node for one of the operators POINT and ARROW.
931 */ 931 */
932static tnode_t * 932static tnode_t *
933build_struct_access(op_t op, bool sys, tnode_t *ln, tnode_t *rn) 933build_struct_access(op_t op, bool sys, tnode_t *ln, tnode_t *rn)
934{ 934{
935 tnode_t *ntn, *ctn; 935 tnode_t *ntn, *ctn;
936 bool nolval; 936 bool nolval;
937 937
938 lint_assert(rn->tn_op == NAME); 938 lint_assert(rn->tn_op == NAME);
939 lint_assert(is_member(rn->tn_sym)); 939 lint_assert(is_member(rn->tn_sym));
940 940
941 /* 941 /*
942 * Remember if the left operand is an lvalue (structure members 942 * Remember if the left operand is an lvalue (structure members
943 * are lvalues if and only if the structure itself is an lvalue). 943 * are lvalues if and only if the structure itself is an lvalue).
944 */ 944 */
945 nolval = op == POINT && !ln->tn_lvalue; 945 nolval = op == POINT && !ln->tn_lvalue;
946 946
947 if (op == POINT) { 947 if (op == POINT) {
948 ln = build_address(sys, ln, true); 948 ln = build_address(sys, ln, true);
949 } else if (ln->tn_type->t_tspec != PTR) { 949 } else if (ln->tn_type->t_tspec != PTR) {
@@ -1031,27 +1031,27 @@ subt_size_in_bytes(type_t *tp) @@ -1031,27 +1031,27 @@ subt_size_in_bytes(type_t *tp)
1031 if (elsz_in_bits == 0) 1031 if (elsz_in_bits == 0)
1032 elsz_in_bits = CHAR_SIZE; 1032 elsz_in_bits = CHAR_SIZE;
1033 1033
1034 return build_integer_constant(PTRDIFF_TSPEC, 1034 return build_integer_constant(PTRDIFF_TSPEC,
1035 (int64_t)(elem * elsz_in_bits / CHAR_SIZE)); 1035 (int64_t)(elem * elsz_in_bits / CHAR_SIZE));
1036} 1036}
1037 1037
1038/* 1038/*
1039 * Create a node for INCAFT, INCBEF, DECAFT and DECBEF. 1039 * Create a node for INCAFT, INCBEF, DECAFT and DECBEF.
1040 */ 1040 */
1041static tnode_t * 1041static tnode_t *
1042build_prepost_incdec(op_t op, bool sys, tnode_t *ln) 1042build_prepost_incdec(op_t op, bool sys, tnode_t *ln)
1043{ 1043{
1044 tnode_t *cn, *ntn; 1044 tnode_t *cn, *ntn;
1045 1045
1046 lint_assert(ln != NULL); 1046 lint_assert(ln != NULL);
1047 1047
1048 if (ln->tn_type->t_tspec == PTR) { 1048 if (ln->tn_type->t_tspec == PTR) {
1049 cn = subt_size_in_bytes(ln->tn_type); 1049 cn = subt_size_in_bytes(ln->tn_type);
1050 } else { 1050 } else {
1051 cn = build_integer_constant(INT, (int64_t)1); 1051 cn = build_integer_constant(INT, (int64_t)1);
1052 } 1052 }
1053 ntn = new_tnode(op, sys, ln->tn_type, ln, cn); 1053 ntn = new_tnode(op, sys, ln->tn_type, ln, cn);
1054 1054
1055 return ntn; 1055 return ntn;
1056} 1056}
1057 1057
@@ -1203,28 +1203,28 @@ merge_qualifiers(type_t *tp1, const type @@ -1203,28 +1203,28 @@ merge_qualifiers(type_t *tp1, const type
1203 nstp = expr_dup_type(tp1->t_subt); 1203 nstp = expr_dup_type(tp1->t_subt);
1204 nstp->t_const |= c2; 1204 nstp->t_const |= c2;
1205 nstp->t_volatile |= v2; 1205 nstp->t_volatile |= v2;
1206 1206
1207 ntp = expr_dup_type(tp1); 1207 ntp = expr_dup_type(tp1);
1208 ntp->t_subt = nstp; 1208 ntp->t_subt = nstp;
1209 return ntp; 1209 return ntp;
1210} 1210}
1211 1211
1212/* See C99 6.5.15 "Conditional operator". */ 1212/* See C99 6.5.15 "Conditional operator". */
1213static tnode_t * 1213static tnode_t *
1214build_colon(bool sys, tnode_t *ln, tnode_t *rn) 1214build_colon(bool sys, tnode_t *ln, tnode_t *rn)
1215{ 1215{
1216 tspec_t lt, rt; 1216 tspec_t lt, rt;
1217 type_t *tp; 1217 type_t *tp;
1218 1218
1219 lt = ln->tn_type->t_tspec; 1219 lt = ln->tn_type->t_tspec;
1220 rt = rn->tn_type->t_tspec; 1220 rt = rn->tn_type->t_tspec;
1221 1221
1222 if (is_arithmetic(lt) && is_arithmetic(rt)) { 1222 if (is_arithmetic(lt) && is_arithmetic(rt)) {
1223 /* The operands were already balanced in build_binary. */ 1223 /* The operands were already balanced in build_binary. */
1224 tp = ln->tn_type; 1224 tp = ln->tn_type;
1225 } else if (lt == BOOL && rt == BOOL) { 1225 } else if (lt == BOOL && rt == BOOL) {
1226 tp = ln->tn_type; 1226 tp = ln->tn_type;
1227 } else if (lt == VOID || rt == VOID) { 1227 } else if (lt == VOID || rt == VOID) {
1228 tp = gettyp(VOID); 1228 tp = gettyp(VOID);
1229 } else if (is_struct_or_union(lt)) { 1229 } else if (is_struct_or_union(lt)) {
1230 /* Both types must be identical. */ 1230 /* Both types must be identical. */
@@ -1318,28 +1318,28 @@ is_assignment(op_t op) @@ -1318,28 +1318,28 @@ is_assignment(op_t op)
1318 op == SHLASS || 1318 op == SHLASS ||
1319 op == SHRASS || 1319 op == SHRASS ||
1320 op == ANDASS || 1320 op == ANDASS ||
1321 op == XORASS || 1321 op == XORASS ||
1322 op == ORASS || 1322 op == ORASS ||
1323 op == RETURN || 1323 op == RETURN ||
1324 op == INIT; 1324 op == INIT;
1325} 1325}
1326 1326
1327/* Create a node for an assignment operator (both '=' and 'op='). */ 1327/* Create a node for an assignment operator (both '=' and 'op='). */
1328static tnode_t * 1328static tnode_t *
1329build_assignment(op_t op, bool sys, tnode_t *ln, tnode_t *rn) 1329build_assignment(op_t op, bool sys, tnode_t *ln, tnode_t *rn)
1330{ 1330{
1331 tspec_t lt, rt; 1331 tspec_t lt, rt;
1332 tnode_t *ntn, *ctn; 1332 tnode_t *ntn, *ctn;
1333 1333
1334 lt = ln->tn_type->t_tspec; 1334 lt = ln->tn_type->t_tspec;
1335 rt = rn->tn_type->t_tspec; 1335 rt = rn->tn_type->t_tspec;
1336 1336
1337 if (any_query_enabled && is_assignment(rn->tn_op)) { 1337 if (any_query_enabled && is_assignment(rn->tn_op)) {
1338 /* chained assignment with '%s' and '%s' */ 1338 /* chained assignment with '%s' and '%s' */
1339 query_message(10, op_name(op), op_name(rn->tn_op)); 1339 query_message(10, op_name(op), op_name(rn->tn_op));
1340 } 1340 }
1341 1341
1342 if ((op == ADDASS || op == SUBASS) && lt == PTR) { 1342 if ((op == ADDASS || op == SUBASS) && lt == PTR) {
1343 lint_assert(is_integer(rt)); 1343 lint_assert(is_integer(rt));
1344 ctn = subt_size_in_bytes(ln->tn_type); 1344 ctn = subt_size_in_bytes(ln->tn_type);
1345 if (rn->tn_type->t_tspec != ctn->tn_type->t_tspec) 1345 if (rn->tn_type->t_tspec != ctn->tn_type->t_tspec)
@@ -1390,27 +1390,27 @@ build_assignment(op_t op, bool sys, tnod @@ -1390,27 +1390,27 @@ build_assignment(op_t op, bool sys, tnod
1390 } 1390 }
1391 1391
1392 ntn = new_tnode(op, sys, ln->tn_type, ln, rn); 1392 ntn = new_tnode(op, sys, ln->tn_type, ln, rn);
1393 1393
1394 return ntn; 1394 return ntn;
1395} 1395}
1396 1396
1397/* 1397/*
1398 * Create a node for REAL, IMAG 1398 * Create a node for REAL, IMAG
1399 */ 1399 */
1400static tnode_t * 1400static tnode_t *
1401build_real_imag(op_t op, bool sys, tnode_t *ln) 1401build_real_imag(op_t op, bool sys, tnode_t *ln)
1402{ 1402{
1403 tnode_t *cn, *ntn; 1403 tnode_t *cn, *ntn;
1404 1404
1405 lint_assert(ln != NULL); 1405 lint_assert(ln != NULL);
1406 1406
1407 if (ln->tn_op == NAME) { 1407 if (ln->tn_op == NAME) {
1408 /* 1408 /*
1409 * This may be too much, but it avoids wrong warnings. 1409 * This may be too much, but it avoids wrong warnings.
1410 * See d_c99_complex_split.c. 1410 * See d_c99_complex_split.c.
1411 */ 1411 */
1412 mark_as_used(ln->tn_sym, false, false); 1412 mark_as_used(ln->tn_sym, false, false);
1413 mark_as_set(ln->tn_sym); 1413 mark_as_set(ln->tn_sym);
1414 } 1414 }
1415 1415
1416 switch (ln->tn_type->t_tspec) { 1416 switch (ln->tn_type->t_tspec) {
@@ -1501,28 +1501,28 @@ check_precedence_confusion(tnode_t *tn) @@ -1501,28 +1501,28 @@ check_precedence_confusion(tnode_t *tn)
1501 ln->tn_op, ln->tn_parenthesized, 1501 ln->tn_op, ln->tn_parenthesized,
1502 rn->tn_op, rn->tn_parenthesized)) { 1502 rn->tn_op, rn->tn_parenthesized)) {
1503 /* precedence confusion possible: parenthesize! */ 1503 /* precedence confusion possible: parenthesize! */
1504 warning(169); 1504 warning(169);
1505 } 1505 }
1506} 1506}
1507 1507
1508/* 1508/*
1509 * Fold constant nodes, as much as is needed for comparing the value with 0. 1509 * Fold constant nodes, as much as is needed for comparing the value with 0.
1510 */ 1510 */
1511static tnode_t * 1511static tnode_t *
1512fold_bool(tnode_t *tn) 1512fold_bool(tnode_t *tn)
1513{ 1513{
1514 bool l, r; 1514 bool l, r;
1515 val_t *v; 1515 val_t *v;
1516 1516
1517 v = xcalloc(1, sizeof(*v)); 1517 v = xcalloc(1, sizeof(*v));
1518 v->v_tspec = tn->tn_type->t_tspec; 1518 v->v_tspec = tn->tn_type->t_tspec;
1519 lint_assert(v->v_tspec == INT || (Tflag && v->v_tspec == BOOL)); 1519 lint_assert(v->v_tspec == INT || (Tflag && v->v_tspec == BOOL));
1520 1520
1521 l = constant_is_nonzero(tn->tn_left); 1521 l = constant_is_nonzero(tn->tn_left);
1522 r = is_binary(tn) && constant_is_nonzero(tn->tn_right); 1522 r = is_binary(tn) && constant_is_nonzero(tn->tn_right);
1523 1523
1524 switch (tn->tn_op) { 1524 switch (tn->tn_op) {
1525 case NOT: 1525 case NOT:
1526 if (hflag && !constcond_flag) 1526 if (hflag && !constcond_flag)
1527 /* constant argument to '!' */ 1527 /* constant argument to '!' */
1528 warning(239); 1528 warning(239);
@@ -1566,29 +1566,29 @@ floating_error_value(tspec_t t, ldbl_t l @@ -1566,29 +1566,29 @@ floating_error_value(tspec_t t, ldbl_t l
1566 * few programs practically use 'long double'. 1566 * few programs practically use 'long double'.
1567 */ 1567 */
1568 /* LINTED 248: floating-point constant out of range */ 1568 /* LINTED 248: floating-point constant out of range */
1569 ldbl_t max = LDBL_MAX; 1569 ldbl_t max = LDBL_MAX;
1570 return lv < 0 ? -max : max; 1570 return lv < 0 ? -max : max;
1571} 1571}
1572 1572
1573/* 1573/*
1574 * Fold constant nodes having operands with floating point type. 1574 * Fold constant nodes having operands with floating point type.
1575 */ 1575 */
1576static tnode_t * 1576static tnode_t *
1577fold_float(tnode_t *tn) 1577fold_float(tnode_t *tn)
1578{ 1578{
1579 val_t *v; 1579 val_t *v;
1580 tspec_t t; 1580 tspec_t t;
1581 ldbl_t lv, rv = 0; 1581 ldbl_t lv, rv = 0;
1582 1582
1583 fpe = 0; 1583 fpe = 0;
1584 v = xcalloc(1, sizeof(*v)); 1584 v = xcalloc(1, sizeof(*v));
1585 v->v_tspec = t = tn->tn_type->t_tspec; 1585 v->v_tspec = t = tn->tn_type->t_tspec;
1586 1586
1587 lint_assert(is_floating(t)); 1587 lint_assert(is_floating(t));
1588 lint_assert(t == tn->tn_left->tn_type->t_tspec); 1588 lint_assert(t == tn->tn_left->tn_type->t_tspec);
1589 lint_assert(!is_binary(tn) || t == tn->tn_right->tn_type->t_tspec); 1589 lint_assert(!is_binary(tn) || t == tn->tn_right->tn_type->t_tspec);
1590 1590
1591 lv = tn->tn_left->tn_val->v_ldbl; 1591 lv = tn->tn_left->tn_val->v_ldbl;
1592 if (is_binary(tn)) 1592 if (is_binary(tn))
1593 rv = tn->tn_right->tn_val->v_ldbl; 1593 rv = tn->tn_right->tn_val->v_ldbl;
1594 1594
@@ -1660,28 +1660,28 @@ fold_float(tnode_t *tn) @@ -1660,28 +1660,28 @@ fold_float(tnode_t *tn)
1660 return build_constant(tn->tn_type, v); 1660 return build_constant(tn->tn_type, v);
1661} 1661}
1662 1662
1663/* 1663/*
1664 * Create a tree node for a binary operator and its two operands. Also called 1664 * Create a tree node for a binary operator and its two operands. Also called
1665 * for unary operators; in that case rn is NULL. 1665 * for unary operators; in that case rn is NULL.
1666 * 1666 *
1667 * Function calls, sizeof and casts are handled elsewhere. 1667 * Function calls, sizeof and casts are handled elsewhere.
1668 */ 1668 */
1669tnode_t * 1669tnode_t *
1670build_binary(tnode_t *ln, op_t op, bool sys, tnode_t *rn) 1670build_binary(tnode_t *ln, op_t op, bool sys, tnode_t *rn)
1671{ 1671{
1672 const mod_t *mp; 1672 const mod_t *mp;
1673 tnode_t *ntn; 1673 tnode_t *ntn;
1674 type_t *rettp; 1674 type_t *rettp;
1675 1675
1676 mp = &modtab[op]; 1676 mp = &modtab[op];
1677 1677
1678 /* If there was an error in one of the operands, return. */ 1678 /* If there was an error in one of the operands, return. */
1679 if (ln == NULL || (mp->m_binary && rn == NULL)) 1679 if (ln == NULL || (mp->m_binary && rn == NULL))
1680 return NULL; 1680 return NULL;
1681 1681
1682 /* 1682 /*
1683 * Apply class conversions to the left operand, but only if its 1683 * Apply class conversions to the left operand, but only if its
1684 * value is needed or it is compared with zero. 1684 * value is needed or it is compared with zero.
1685 */ 1685 */
1686 if (mp->m_value_context || mp->m_compares_with_zero) 1686 if (mp->m_value_context || mp->m_compares_with_zero)
1687 ln = cconv(ln); 1687 ln = cconv(ln);
@@ -1886,29 +1886,29 @@ all_members_compatible(const sym_t *msym @@ -1886,29 +1886,29 @@ all_members_compatible(const sym_t *msym
1886 } 1886 }
1887 } 1887 }
1888 } 1888 }
1889 return true; 1889 return true;
1890} 1890}
1891 1891
1892/* 1892/*
1893 * Returns a symbol which has the same name as the msym argument and is a 1893 * Returns a symbol which has the same name as the msym argument and is a
1894 * member of the struct or union specified by the tn argument. 1894 * member of the struct or union specified by the tn argument.
1895 */ 1895 */
1896static sym_t * 1896static sym_t *
1897struct_or_union_member(tnode_t *tn, op_t op, sym_t *msym) 1897struct_or_union_member(tnode_t *tn, op_t op, sym_t *msym)
1898{ 1898{
1899 struct_or_union *str; 1899 struct_or_union *str;
1900 type_t *tp; 1900 type_t *tp;
1901 tspec_t t; 1901 tspec_t t;
1902 1902
1903 /* 1903 /*
1904 * Remove the member if it was unknown until now, which means 1904 * Remove the member if it was unknown until now, which means
1905 * that no defined struct or union has a member with the same name. 1905 * that no defined struct or union has a member with the same name.
1906 */ 1906 */
1907 if (msym->s_scl == NOSCL) { 1907 if (msym->s_scl == NOSCL) {
1908 /* type '%s' does not have member '%s' */ 1908 /* type '%s' does not have member '%s' */
1909 error(101, type_name(tn->tn_type), msym->s_name); 1909 error(101, type_name(tn->tn_type), msym->s_name);
1910 rmsym(msym); 1910 rmsym(msym);
1911 msym->s_kind = FMEMBER; 1911 msym->s_kind = FMEMBER;
1912 msym->s_scl = STRUCT_MEMBER; 1912 msym->s_scl = STRUCT_MEMBER;
1913 1913
1914 struct_or_union *sou = expr_zero_alloc(sizeof(*sou)); 1914 struct_or_union *sou = expr_zero_alloc(sizeof(*sou));
@@ -1993,27 +1993,27 @@ struct_or_union_member(tnode_t *tn, op_t @@ -1993,27 +1993,27 @@ struct_or_union_member(tnode_t *tn, op_t
1993 error(105, op == POINT ? "object" : "pointer"); 1993 error(105, op == POINT ? "object" : "pointer");
1994 } else { 1994 } else {
1995 /* unacceptable operand of '%s' */ 1995 /* unacceptable operand of '%s' */
1996 error(111, op_name(op)); 1996 error(111, op_name(op));
1997 } 1997 }
1998 } 1998 }
1999 1999
2000 return msym; 2000 return msym;
2001} 2001}
2002 2002
2003tnode_t * 2003tnode_t *
2004build_member_access(tnode_t *ln, op_t op, bool sys, sbuf_t *member) 2004build_member_access(tnode_t *ln, op_t op, bool sys, sbuf_t *member)
2005{ 2005{
2006 sym_t *msym; 2006 sym_t *msym;
2007 2007
2008 if (ln == NULL) 2008 if (ln == NULL)
2009 return NULL; 2009 return NULL;
2010 2010
2011 if (op == ARROW) { 2011 if (op == ARROW) {
2012 /* must do this before struct_or_union_member is called */ 2012 /* must do this before struct_or_union_member is called */
2013 ln = cconv(ln); 2013 ln = cconv(ln);
2014 } 2014 }
2015 msym = struct_or_union_member(ln, op, getsym(member)); 2015 msym = struct_or_union_member(ln, op, getsym(member));
2016 return build_binary(ln, op, sys, build_name(msym, false)); 2016 return build_binary(ln, op, sys, build_name(msym, false));
2017} 2017}
2018 2018
2019/* 2019/*
@@ -2859,28 +2859,28 @@ warn_assign(op_t op, int arg, @@ -2859,28 +2859,28 @@ warn_assign(op_t op, int arg,
2859 break; 2859 break;
2860 } 2860 }
2861} 2861}
2862 2862
2863/* 2863/*
2864 * Checks type compatibility for ASSIGN, INIT, FARG and RETURN 2864 * Checks type compatibility for ASSIGN, INIT, FARG and RETURN
2865 * and prints warnings/errors if necessary. 2865 * and prints warnings/errors if necessary.
2866 * Returns whether the types are (almost) compatible. 2866 * Returns whether the types are (almost) compatible.
2867 */ 2867 */
2868static bool 2868static bool
2869check_assign_types_compatible(op_t op, int arg, 2869check_assign_types_compatible(op_t op, int arg,
2870 const tnode_t *ln, const tnode_t *rn) 2870 const tnode_t *ln, const tnode_t *rn)
2871{ 2871{
2872 tspec_t lt, rt, lst = NO_TSPEC, rst = NO_TSPEC; 2872 tspec_t lt, rt, lst = NO_TSPEC, rst = NO_TSPEC;
2873 type_t *ltp, *rtp, *lstp = NULL, *rstp = NULL; 2873 type_t *ltp, *rtp, *lstp = NULL, *rstp = NULL;
2874 2874
2875 if ((lt = (ltp = ln->tn_type)->t_tspec) == PTR) 2875 if ((lt = (ltp = ln->tn_type)->t_tspec) == PTR)
2876 lst = (lstp = ltp->t_subt)->t_tspec; 2876 lst = (lstp = ltp->t_subt)->t_tspec;
2877 if ((rt = (rtp = rn->tn_type)->t_tspec) == PTR) 2877 if ((rt = (rtp = rn->tn_type)->t_tspec) == PTR)
2878 rst = (rstp = rtp->t_subt)->t_tspec; 2878 rst = (rstp = rtp->t_subt)->t_tspec;
2879 2879
2880 if (lt == BOOL && is_scalar(rt)) /* C99 6.3.1.2 */ 2880 if (lt == BOOL && is_scalar(rt)) /* C99 6.3.1.2 */
2881 return true; 2881 return true;
2882 2882
2883 if (is_arithmetic(lt) && (is_arithmetic(rt) || rt == BOOL)) 2883 if (is_arithmetic(lt) && (is_arithmetic(rt) || rt == BOOL))
2884 return true; 2884 return true;
2885 2885
2886 if (is_struct_or_union(lt) && is_struct_or_union(rt)) 2886 if (is_struct_or_union(lt) && is_struct_or_union(rt))
@@ -3178,28 +3178,28 @@ typeok_enum(op_t op, const mod_t *mp, in @@ -3178,28 +3178,28 @@ typeok_enum(op_t op, const mod_t *mp, in
3178 } else if (mp->m_valid_on_enum && 3178 } else if (mp->m_valid_on_enum &&
3179 (ltp->t_is_enum && rtp != NULL && rtp->t_is_enum)) { 3179 (ltp->t_is_enum && rtp != NULL && rtp->t_is_enum)) {
3180 check_enum_type_mismatch(op, arg, ln, rn); 3180 check_enum_type_mismatch(op, arg, ln, rn);
3181 } else if (mp->m_valid_on_enum && 3181 } else if (mp->m_valid_on_enum &&
3182 (ltp->t_is_enum || (rtp != NULL && rtp->t_is_enum))) { 3182 (ltp->t_is_enum || (rtp != NULL && rtp->t_is_enum))) {
3183 check_enum_int_mismatch(op, arg, ln, rn); 3183 check_enum_int_mismatch(op, arg, ln, rn);
3184 } 3184 }
3185} 3185}
3186 3186
3187/* Perform most type checks. Return whether the types are ok. */ 3187/* Perform most type checks. Return whether the types are ok. */
3188bool 3188bool
3189typeok(op_t op, int arg, const tnode_t *ln, const tnode_t *rn) 3189typeok(op_t op, int arg, const tnode_t *ln, const tnode_t *rn)
3190{ 3190{
3191 tspec_t lt, rt; 3191 tspec_t lt, rt;
3192 type_t *ltp, *rtp; 3192 type_t *ltp, *rtp;
3193 3193
3194 const mod_t *mp = &modtab[op]; 3194 const mod_t *mp = &modtab[op];
3195 3195
3196 lint_assert((ltp = ln->tn_type) != NULL); 3196 lint_assert((ltp = ln->tn_type) != NULL);
3197 lt = ltp->t_tspec; 3197 lt = ltp->t_tspec;
3198 3198
3199 if (mp->m_binary) { 3199 if (mp->m_binary) {
3200 lint_assert((rtp = rn->tn_type) != NULL); 3200 lint_assert((rtp = rn->tn_type) != NULL);
3201 rt = rtp->t_tspec; 3201 rt = rtp->t_tspec;
3202 } else { 3202 } else {
3203 rtp = NULL; 3203 rtp = NULL;
3204 rt = NO_TSPEC; 3204 rt = NO_TSPEC;
3205 } 3205 }
@@ -4128,27 +4128,27 @@ cast_to_union(tnode_t *otn, type_t *ntp) @@ -4128,27 +4128,27 @@ cast_to_union(tnode_t *otn, type_t *ntp)
4128 } 4128 }
4129 4129
4130 /* type '%s' is not a member of '%s' */ 4130 /* type '%s' is not a member of '%s' */
4131 error(329, type_name(otn->tn_type), type_name(ntp)); 4131 error(329, type_name(otn->tn_type), type_name(ntp));
4132 return NULL; 4132 return NULL;
4133} 4133}
4134 4134
4135/* 4135/*
4136 * Type casts. 4136 * Type casts.
4137 */ 4137 */
4138tnode_t * 4138tnode_t *
4139cast(tnode_t *tn, type_t *tp) 4139cast(tnode_t *tn, type_t *tp)
4140{ 4140{
4141 tspec_t nt, ot; 4141 tspec_t nt, ot;
4142 4142
4143 if (tn == NULL) 4143 if (tn == NULL)
4144 return NULL; 4144 return NULL;
4145 4145
4146 tn = cconv(tn); 4146 tn = cconv(tn);
4147 4147
4148 lint_assert(tp != NULL); 4148 lint_assert(tp != NULL);
4149 nt = tp->t_tspec; 4149 nt = tp->t_tspec;
4150 ot = tn->tn_type->t_tspec; 4150 ot = tn->tn_type->t_tspec;
4151 4151
4152 if (nt == VOID) { 4152 if (nt == VOID) {
4153 /* 4153 /*
4154 * C90 6.3.4, C99 6.5.4p2 and C11 6.5.4p2 allow any type to 4154 * C90 6.3.4, C99 6.5.4p2 and C11 6.5.4p2 allow any type to
@@ -4221,50 +4221,50 @@ build_function_argument(tnode_t *args, t @@ -4221,50 +4221,50 @@ build_function_argument(tnode_t *args, t
4221 4221
4222/* 4222/*
4223 * Compare the type of an argument with the corresponding type of a 4223 * Compare the type of an argument with the corresponding type of a
4224 * prototype parameter. If it is a valid combination, but both types 4224 * prototype parameter. If it is a valid combination, but both types
4225 * are not the same, insert a conversion to convert the argument into 4225 * are not the same, insert a conversion to convert the argument into
4226 * the type of the parameter. 4226 * the type of the parameter.
4227 */ 4227 */
4228static tnode_t * 4228static tnode_t *
4229check_prototype_argument( 4229check_prototype_argument(
4230 int n, /* pos of arg */ 4230 int n, /* pos of arg */
4231 type_t *tp, /* expected type (from prototype) */ 4231 type_t *tp, /* expected type (from prototype) */
4232 tnode_t *tn) /* argument */ 4232 tnode_t *tn) /* argument */
4233{ 4233{
4234 tnode_t *ln = xcalloc(1, sizeof(*ln)); 4234 tnode_t *ln = xcalloc(1, sizeof(*ln));
4235 ln->tn_type = expr_unqualified_type(tp); 4235 ln->tn_type = expr_unqualified_type(tp);
4236 ln->tn_lvalue = true; 4236 ln->tn_lvalue = true;
4237 if (typeok(FARG, n, ln, tn)) { 4237 if (typeok(FARG, n, ln, tn)) {
4238 bool dowarn; 4238 bool dowarn;
4239 if (!types_compatible(tp, tn->tn_type, 4239 if (!types_compatible(tp, tn->tn_type,
4240 true, false, (dowarn = false, &dowarn)) || dowarn) 4240 true, false, (dowarn = false, &dowarn)) || dowarn)
4241 tn = convert(FARG, n, tp, tn); 4241 tn = convert(FARG, n, tp, tn);
4242 } 4242 }
4243 free(ln); 4243 free(ln);
4244 return tn; 4244 return tn;
4245} 4245}
4246 4246
4247/* 4247/*
4248 * Check types of all function arguments and insert conversions, 4248 * Check types of all function arguments and insert conversions,
4249 * if necessary. 4249 * if necessary.
4250 */ 4250 */
4251static tnode_t * 4251static tnode_t *
4252check_function_arguments(type_t *ftp, tnode_t *args) 4252check_function_arguments(type_t *ftp, tnode_t *args)
4253{ 4253{
4254 tnode_t *arg; 4254 tnode_t *arg;
4255 sym_t *asym; 4255 sym_t *asym;
4256 tspec_t at; 4256 tspec_t at;
4257 int narg, npar, n, i; 4257 int narg, npar, n, i;
4258 4258
4259 /* get # of args in the prototype */ 4259 /* get # of args in the prototype */
4260 npar = 0; 4260 npar = 0;
4261 for (asym = ftp->t_args; asym != NULL; asym = asym->s_next) 4261 for (asym = ftp->t_args; asym != NULL; asym = asym->s_next)
4262 npar++; 4262 npar++;
4263 4263
4264 /* get # of args in function call */ 4264 /* get # of args in function call */
4265 narg = 0; 4265 narg = 0;
4266 for (arg = args; arg != NULL; arg = arg->tn_right) 4266 for (arg = args; arg != NULL; arg = arg->tn_right)
4267 narg++; 4267 narg++;
4268 4268
4269 asym = ftp->t_args; 4269 asym = ftp->t_args;
4270 if (ftp->t_proto && npar != narg && !(ftp->t_vararg && npar < narg)) { 4270 if (ftp->t_proto && npar != narg && !(ftp->t_vararg && npar < narg)) {
@@ -4314,28 +4314,28 @@ check_function_arguments(type_t *ftp, tn @@ -4314,28 +4314,28 @@ check_function_arguments(type_t *ftp, tn
4314 asym = asym->s_next; 4314 asym = asym->s_next;
4315 } 4315 }
4316 4316
4317 return args; 4317 return args;
4318} 4318}
4319 4319
4320/* 4320/*
4321 * Create the node for a function call. Also check types of 4321 * Create the node for a function call. Also check types of
4322 * function arguments and insert conversions, if necessary. 4322 * function arguments and insert conversions, if necessary.
4323 */ 4323 */
4324tnode_t * 4324tnode_t *
4325build_function_call(tnode_t *func, bool sys, tnode_t *args) 4325build_function_call(tnode_t *func, bool sys, tnode_t *args)
4326{ 4326{
4327 tnode_t *ntn; 4327 tnode_t *ntn;
4328 op_t fcop; 4328 op_t fcop;
4329 4329
4330 if (func == NULL) 4330 if (func == NULL)
4331 return NULL; 4331 return NULL;
4332 4332
4333 if (func->tn_op == NAME && func->tn_type->t_tspec == FUNC) { 4333 if (func->tn_op == NAME && func->tn_type->t_tspec == FUNC) {
4334 fcop = CALL; 4334 fcop = CALL;
4335 } else { 4335 } else {
4336 fcop = ICALL; 4336 fcop = ICALL;
4337 } 4337 }
4338 4338
4339 check_ctype_function_call(func, args); 4339 check_ctype_function_call(func, args);
4340 4340
4341 /* 4341 /*
@@ -4730,27 +4730,27 @@ check_expr_misc(const tnode_t *tn, bool  @@ -4730,27 +4730,27 @@ check_expr_misc(const tnode_t *tn, bool
4730 * 4730 *
4731 * The expression can consist of PLUS, MINUS, ADDR, NAME, STRING and 4731 * The expression can consist of PLUS, MINUS, ADDR, NAME, STRING and
4732 * CON. Type conversions are allowed if they do not change binary 4732 * CON. Type conversions are allowed if they do not change binary
4733 * representation (including width). 4733 * representation (including width).
4734 * 4734 *
4735 * C99 6.6 "Constant expressions" 4735 * C99 6.6 "Constant expressions"
4736 * C99 6.7.8p4 restricts initializers for static storage duration 4736 * C99 6.7.8p4 restricts initializers for static storage duration
4737 */ 4737 */
4738bool 4738bool
4739constant_addr(const tnode_t *tn, const sym_t **symp, ptrdiff_t *offsp) 4739constant_addr(const tnode_t *tn, const sym_t **symp, ptrdiff_t *offsp)
4740{ 4740{
4741 const sym_t *sym; 4741 const sym_t *sym;
4742 ptrdiff_t offs1, offs2; 4742 ptrdiff_t offs1, offs2;
4743 tspec_t t, ot; 4743 tspec_t t, ot;
4744 4744
4745 switch (tn->tn_op) { 4745 switch (tn->tn_op) {
4746 case MINUS: 4746 case MINUS:
4747 if (tn->tn_right->tn_op == CVT) 4747 if (tn->tn_right->tn_op == CVT)
4748 return constant_addr(tn->tn_right, symp, offsp); 4748 return constant_addr(tn->tn_right, symp, offsp);
4749 else if (tn->tn_right->tn_op != CON) 4749 else if (tn->tn_right->tn_op != CON)
4750 return false; 4750 return false;
4751 /* FALLTHROUGH */ 4751 /* FALLTHROUGH */
4752 case PLUS: 4752 case PLUS:
4753 offs1 = offs2 = 0; 4753 offs1 = offs2 = 0;
4754 if (tn->tn_left->tn_op == CON) { 4754 if (tn->tn_left->tn_op == CON) {
4755 offs1 = (ptrdiff_t)tn->tn_left->tn_val->v_quad; 4755 offs1 = (ptrdiff_t)tn->tn_left->tn_val->v_quad;
4756 if (!constant_addr(tn->tn_right, &sym, &offs2)) 4756 if (!constant_addr(tn->tn_right, &sym, &offs2))

cvs diff -r1.54 -r1.55 src/usr.bin/xlint/lint2/chk.c (expand / switch to unified diff)

--- src/usr.bin/xlint/lint2/chk.c 2023/05/22 12:55:04 1.54
+++ src/usr.bin/xlint/lint2/chk.c 2023/06/09 13:03:49 1.55
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: chk.c,v 1.54 2023/05/22 12:55:04 rillig Exp $ */ 1/* $NetBSD: chk.c,v 1.55 2023/06/09 13:03:49 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. 4 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
5 * Copyright (c) 1994, 1995 Jochen Pohl 5 * Copyright (c) 1994, 1995 Jochen Pohl
6 * All Rights Reserved. 6 * All Rights Reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
@@ -28,27 +28,27 @@ @@ -28,27 +28,27 @@
28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */ 33 */
34 34
35#if HAVE_NBTOOL_CONFIG_H 35#if HAVE_NBTOOL_CONFIG_H
36#include "nbtool_config.h" 36#include "nbtool_config.h"
37#endif 37#endif
38 38
39#include <sys/cdefs.h> 39#include <sys/cdefs.h>
40#if defined(__RCSID) 40#if defined(__RCSID)
41__RCSID("$NetBSD: chk.c,v 1.54 2023/05/22 12:55:04 rillig Exp $"); 41__RCSID("$NetBSD: chk.c,v 1.55 2023/06/09 13:03:49 rillig Exp $");
42#endif 42#endif
43 43
44#include <ctype.h> 44#include <ctype.h>
45#include <limits.h> 45#include <limits.h>
46#include <stdlib.h> 46#include <stdlib.h>
47#include <string.h> 47#include <string.h>
48 48
49#include "lint2.h" 49#include "lint2.h"
50 50
51static void check_used_not_defined(const hte_t *); 51static void check_used_not_defined(const hte_t *);
52static void check_defined_not_used(const hte_t *); 52static void check_defined_not_used(const hte_t *);
53static void check_declared_not_used_or_defined(const hte_t *); 53static void check_declared_not_used_or_defined(const hte_t *);
54static void check_multiple_definitions(const hte_t *); 54static void check_multiple_definitions(const hte_t *);
@@ -66,39 +66,39 @@ static void inconsistent_arguments(const @@ -66,39 +66,39 @@ static void inconsistent_arguments(const
66static void too_few_arguments(const hte_t *, fcall_t *); 66static void too_few_arguments(const hte_t *, fcall_t *);
67static void too_many_arguments(const hte_t *, fcall_t *); 67static void too_many_arguments(const hte_t *, fcall_t *);
68static bool types_compatible(type_t *, type_t *, bool, bool, bool, bool *); 68static bool types_compatible(type_t *, type_t *, bool, bool, bool, bool *);
69static bool prototypes_compatible(type_t *, type_t *, bool *); 69static bool prototypes_compatible(type_t *, type_t *, bool *);
70static bool matches_no_arg_function(type_t *, bool *); 70static bool matches_no_arg_function(type_t *, bool *);
71 71
72 72
73/* 73/*
74 * If there is a symbol named "main", mark it as used. 74 * If there is a symbol named "main", mark it as used.
75 */ 75 */
76void 76void
77mark_main_as_used(void) 77mark_main_as_used(void)
78{ 78{
79 hte_t *hte; 79 hte_t *hte;
80 80
81 if ((hte = hsearch("main", false)) != NULL) 81 if ((hte = hsearch("main", false)) != NULL)
82 hte->h_used = true; 82 hte->h_used = true;
83} 83}
84 84
85/* 85/*
86 * Performs all tests for a single name 86 * Performs all tests for a single name
87 */ 87 */
88void 88void
89check_name(const hte_t *hte) 89check_name(const hte_t *hte)
90{ 90{
91 sym_t *sym, *def, *pdecl, *decl; 91 sym_t *sym, *def, *pdecl, *decl;
92 92
93 if (uflag) { 93 if (uflag) {
94 check_used_not_defined(hte); 94 check_used_not_defined(hte);
95 check_defined_not_used(hte); 95 check_defined_not_used(hte);
96 if (xflag) 96 if (xflag)
97 check_declared_not_used_or_defined(hte); 97 check_declared_not_used_or_defined(hte);
98 } 98 }
99 check_multiple_definitions(hte); 99 check_multiple_definitions(hte);
100 100
101 /* Get definition, prototype declaration and declaration */ 101 /* Get definition, prototype declaration and declaration */
102 def = pdecl = decl = NULL; 102 def = pdecl = decl = NULL;
103 for (sym = hte->h_syms; sym != NULL; sym = sym->s_next) { 103 for (sym = hte->h_syms; sym != NULL; sym = sym->s_next) {
104 if (def == NULL && (sym->s_def == DEF || sym->s_def == TDEF)) 104 if (def == NULL && (sym->s_def == DEF || sym->s_def == TDEF))
@@ -123,92 +123,92 @@ check_name(const hte_t *hte) @@ -123,92 +123,92 @@ check_name(const hte_t *hte)
123 chkfaui(hte, def, decl); 123 chkfaui(hte, def, decl);
124 124
125 check_return_values(hte, def); 125 check_return_values(hte, def);
126 126
127 check_argument_declarations(hte, def, decl); 127 check_argument_declarations(hte, def, decl);
128} 128}
129 129
130/* 130/*
131 * Print a warning if the name has been used, but not defined. 131 * Print a warning if the name has been used, but not defined.
132 */ 132 */
133static void 133static void
134check_used_not_defined(const hte_t *hte) 134check_used_not_defined(const hte_t *hte)
135{ 135{
136 fcall_t *fcall; 136 fcall_t *fcall;
137 usym_t *usym; 137 usym_t *usym;
138 138
139 if (!hte->h_used || hte->h_def) 139 if (!hte->h_used || hte->h_def)
140 return; 140 return;
141 141
142 if ((fcall = hte->h_calls) != NULL) { 142 if ((fcall = hte->h_calls) != NULL) {
143 /* %s used( %s ), but not defined */ 143 /* %s used( %s ), but not defined */
144 msg(0, hte->h_name, mkpos(&fcall->f_pos)); 144 msg(0, hte->h_name, mkpos(&fcall->f_pos));
145 } else if ((usym = hte->h_usyms) != NULL) { 145 } else if ((usym = hte->h_usyms) != NULL) {
146 /* %s used( %s ), but not defined */ 146 /* %s used( %s ), but not defined */
147 msg(0, hte->h_name, mkpos(&usym->u_pos)); 147 msg(0, hte->h_name, mkpos(&usym->u_pos));
148 } 148 }
149} 149}
150 150
151/* 151/*
152 * Print a warning if the name has been defined, but never used. 152 * Print a warning if the name has been defined, but never used.
153 */ 153 */
154static void 154static void
155check_defined_not_used(const hte_t *hte) 155check_defined_not_used(const hte_t *hte)
156{ 156{
157 sym_t *sym; 157 sym_t *sym;
158 158
159 if (!hte->h_def || hte->h_used) 159 if (!hte->h_def || hte->h_used)
160 return; 160 return;
161 161
162 for (sym = hte->h_syms; sym != NULL; sym = sym->s_next) { 162 for (sym = hte->h_syms; sym != NULL; sym = sym->s_next) {
163 if (sym->s_def == DEF || sym->s_def == TDEF) { 163 if (sym->s_def == DEF || sym->s_def == TDEF) {
164 /* %s defined( %s ), but never used */ 164 /* %s defined( %s ), but never used */
165 msg(1, hte->h_name, mkpos(&sym->s_pos)); 165 msg(1, hte->h_name, mkpos(&sym->s_pos));
166 break; 166 break;
167 } 167 }
168 } 168 }
169} 169}
170 170
171/* 171/*
172 * Print a warning if the variable has been declared, but is not used 172 * Print a warning if the variable has been declared, but is not used
173 * or defined. 173 * or defined.
174 */ 174 */
175static void 175static void
176check_declared_not_used_or_defined(const hte_t *hte) 176check_declared_not_used_or_defined(const hte_t *hte)
177{ 177{
178 sym_t *sym; 178 sym_t *sym;
179 179
180 if (hte->h_syms == NULL || hte->h_used || hte->h_def) 180 if (hte->h_syms == NULL || hte->h_used || hte->h_def)
181 return; 181 return;
182 182
183 sym = hte->h_syms; 183 sym = hte->h_syms;
184 if (TP(sym->s_type)->t_tspec == FUNC) 184 if (TP(sym->s_type)->t_tspec == FUNC)
185 return; 185 return;
186 186
187 if (sym->s_def != DECL) 187 if (sym->s_def != DECL)
188 errx(1, "internal error: check_declared_not_used_or_defined"); 188 errx(1, "internal error: check_declared_not_used_or_defined");
189 /* %s declared( %s ), but never used or defined */ 189 /* %s declared( %s ), but never used or defined */
190 msg(2, hte->h_name, mkpos(&sym->s_pos)); 190 msg(2, hte->h_name, mkpos(&sym->s_pos));
191} 191}
192 192
193/* 193/*
194 * Print a warning if there is more than one definition for 194 * Print a warning if there is more than one definition for
195 * this name. 195 * this name.
196 */ 196 */
197static void 197static void
198check_multiple_definitions(const hte_t *hte) 198check_multiple_definitions(const hte_t *hte)
199{ 199{
200 sym_t *sym, *def1; 200 sym_t *sym, *def1;
201 char *pos1; 201 char *pos1;
202 202
203 if (!hte->h_def) 203 if (!hte->h_def)
204 return; 204 return;
205 205
206 def1 = NULL; 206 def1 = NULL;
207 for (sym = hte->h_syms; sym != NULL; sym = sym->s_next) { 207 for (sym = hte->h_syms; sym != NULL; sym = sym->s_next) {
208 /* 208 /*
209 * ANSI C allows tentative definitions of the same name in 209 * ANSI C allows tentative definitions of the same name in
210 * only one compilation unit. 210 * only one compilation unit.
211 */ 211 */
212 if (sym->s_def != DEF && (!sflag || sym->s_def != TDEF)) 212 if (sym->s_def != DEF && (!sflag || sym->s_def != TDEF))
213 continue; 213 continue;
214 if (sym->s_inline) 214 if (sym->s_inline)
@@ -226,31 +226,31 @@ check_multiple_definitions(const hte_t * @@ -226,31 +226,31 @@ check_multiple_definitions(const hte_t *
226 226
227/* 227/*
228 * Print a warning if the return value assumed for a function call 228 * Print a warning if the return value assumed for a function call
229 * differs from the return value of the function definition or 229 * differs from the return value of the function definition or
230 * function declaration. 230 * function declaration.
231 * 231 *
232 * If no definition/declaration can be found, the assumed return values 232 * If no definition/declaration can be found, the assumed return values
233 * are always int. So there is no need to compare with another function 233 * are always int. So there is no need to compare with another function
234 * call as it's done for function arguments. 234 * call as it's done for function arguments.
235 */ 235 */
236static void 236static void
237chkvtui(const hte_t *hte, sym_t *def, sym_t *decl) 237chkvtui(const hte_t *hte, sym_t *def, sym_t *decl)
238{ 238{
239 fcall_t *call; 239 fcall_t *call;
240 char *pos1; 240 char *pos1;
241 type_t *tp1, *tp2; 241 type_t *tp1, *tp2;
242 bool dowarn, eq; 242 bool dowarn, eq;
243 tspec_t t1; 243 tspec_t t1;
244 244
245 if (hte->h_calls == NULL) 245 if (hte->h_calls == NULL)
246 return; 246 return;
247 247
248 if (def == NULL) 248 if (def == NULL)
249 def = decl; 249 def = decl;
250 if (def == NULL) 250 if (def == NULL)
251 return; 251 return;
252 252
253 t1 = (tp1 = TP(def->s_type)->t_subt)->t_tspec; 253 t1 = (tp1 = TP(def->s_type)->t_subt)->t_tspec;
254 for (call = hte->h_calls; call != NULL; call = call->f_next) { 254 for (call = hte->h_calls; call != NULL; call = call->f_next) {
255 tp2 = TP(call->f_type)->t_subt; 255 tp2 = TP(call->f_type)->t_subt;
256 eq = types_compatible(tp1, tp2, 256 eq = types_compatible(tp1, tp2,
@@ -288,30 +288,30 @@ chkvtui(const hte_t *hte, sym_t *def, sy @@ -288,30 +288,30 @@ chkvtui(const hte_t *hte, sym_t *def, sy
288 free(pos1); 288 free(pos1);
289 } 289 }
290 } 290 }
291} 291}
292 292
293/* 293/*
294 * Print a warning if a definition/declaration does not match another 294 * Print a warning if a definition/declaration does not match another
295 * definition/declaration of the same name. For functions, only the 295 * definition/declaration of the same name. For functions, only the
296 * types of return values are tested. 296 * types of return values are tested.
297 */ 297 */
298static void 298static void
299chkvtdi(const hte_t *hte, sym_t *def, sym_t *decl) 299chkvtdi(const hte_t *hte, sym_t *def, sym_t *decl)
300{ 300{
301 sym_t *sym; 301 sym_t *sym;
302 type_t *tp1, *tp2; 302 type_t *tp1, *tp2;
303 bool eq, dowarn; 303 bool eq, dowarn;
304 char *pos1; 304 char *pos1;
305 305
306 if (def == NULL) 306 if (def == NULL)
307 def = decl; 307 def = decl;
308 if (def == NULL) 308 if (def == NULL)
309 return; 309 return;
310 310
311 tp1 = TP(def->s_type); 311 tp1 = TP(def->s_type);
312 for (sym = hte->h_syms; sym != NULL; sym = sym->s_next) { 312 for (sym = hte->h_syms; sym != NULL; sym = sym->s_next) {
313 type_t *xt1, *xt2; 313 type_t *xt1, *xt2;
314 if (sym == def) 314 if (sym == def)
315 continue; 315 continue;
316 tp2 = TP(sym->s_type); 316 tp2 = TP(sym->s_type);
317 dowarn = false; 317 dowarn = false;
@@ -330,31 +330,31 @@ chkvtdi(const hte_t *hte, sym_t *def, sy @@ -330,31 +330,31 @@ chkvtdi(const hte_t *hte, sym_t *def, sy
330 free(pos1); 330 free(pos1);
331 } 331 }
332 } 332 }
333} 333}
334 334
335/* 335/*
336 * Print a warning if a function is called with arguments which does 336 * Print a warning if a function is called with arguments which does
337 * not match the function definition, declaration or another call 337 * not match the function definition, declaration or another call
338 * of the same function. 338 * of the same function.
339 */ 339 */
340static void 340static void
341chkfaui(const hte_t *hte, sym_t *def, sym_t *decl) 341chkfaui(const hte_t *hte, sym_t *def, sym_t *decl)
342{ 342{
343 type_t *tp1, *tp2, **ap1, **ap2; 343 type_t *tp1, *tp2, **ap1, **ap2;
344 pos_t *pos1p = NULL; 344 pos_t *pos1p = NULL;
345 fcall_t *calls, *call, *call1; 345 fcall_t *calls, *call, *call1;
346 int n, as; 346 int n, as;
347 char *pos1; 347 char *pos1;
348 arginf_t *ai; 348 arginf_t *ai;
349 349
350 if ((calls = hte->h_calls) == NULL) 350 if ((calls = hte->h_calls) == NULL)
351 return; 351 return;
352 352
353 /* 353 /*
354 * If we find a function definition, we use this for comparison, 354 * If we find a function definition, we use this for comparison,
355 * otherwise the first prototype we can find. If there is no 355 * otherwise the first prototype we can find. If there is no
356 * definition or prototype declaration, the first function call 356 * definition or prototype declaration, the first function call
357 * is used. 357 * is used.
358 */ 358 */
359 tp1 = NULL; 359 tp1 = NULL;
360 call1 = NULL; 360 call1 = NULL;
@@ -443,30 +443,30 @@ chkfaui(const hte_t *hte, sym_t *def, sy @@ -443,30 +443,30 @@ chkfaui(const hte_t *hte, sym_t *def, sy
443 * def the function definition or NULL 443 * def the function definition or NULL
444 * decl prototype declaration, old-style declaration or NULL 444 * decl prototype declaration, old-style declaration or NULL
445 * pos1p position of definition, declaration of first call 445 * pos1p position of definition, declaration of first call
446 * call1 first call, if both def and decl are old-style def/decl 446 * call1 first call, if both def and decl are old-style def/decl
447 * call checked call 447 * call checked call
448 * arg1 currently checked argument of def/decl/call1 448 * arg1 currently checked argument of def/decl/call1
449 * arg2 currently checked argument of call 449 * arg2 currently checked argument of call
450 * 450 *
451 */ 451 */
452static void 452static void
453chkau(const hte_t *hte, int n, sym_t *def, sym_t *decl, pos_t *pos1p, 453chkau(const hte_t *hte, int n, sym_t *def, sym_t *decl, pos_t *pos1p,
454 fcall_t *call1, fcall_t *call, type_t *arg1, type_t *arg2) 454 fcall_t *call1, fcall_t *call, type_t *arg1, type_t *arg2)
455{ 455{
456 bool promote, asgn, dowarn; 456 bool promote, asgn, dowarn;
457 tspec_t t1, t2; 457 tspec_t t1, t2;
458 arginf_t *ai, *ai1; 458 arginf_t *ai, *ai1;
459 char *pos1; 459 char *pos1;
460 460
461 /* 461 /*
462 * If a function definition is available (def != NULL), we compare the 462 * If a function definition is available (def != NULL), we compare the
463 * function call (call) with the definition. Otherwise, if a function 463 * function call (call) with the definition. Otherwise, if a function
464 * definition is available and it is not an old-style definition 464 * definition is available and it is not an old-style definition
465 * (decl != NULL && TP(decl->s_type)->t_proto), we compare the call 465 * (decl != NULL && TP(decl->s_type)->t_proto), we compare the call
466 * with this declaration. Otherwise we compare it with the first 466 * with this declaration. Otherwise we compare it with the first
467 * call we have found (call1). 467 * call we have found (call1).
468 */ 468 */
469 469
470 /* arg1 must be promoted if it stems from an old-style definition */ 470 /* arg1 must be promoted if it stems from an old-style definition */
471 promote = def != NULL && def->s_old_style_function; 471 promote = def != NULL && def->s_old_style_function;
472 472
@@ -597,31 +597,31 @@ chkau(const hte_t *hte, int n, sym_t *de @@ -597,31 +597,31 @@ chkau(const hte_t *hte, int n, sym_t *de
597 /* %s, arg %d used inconsistently \t%s[%s] :: %s[%s] */ 597 /* %s, arg %d used inconsistently \t%s[%s] :: %s[%s] */
598 msg(6, hte->h_name, n, pos1, type_name(arg1), 598 msg(6, hte->h_name, n, pos1, type_name(arg1),
599 mkpos(&call->f_pos), type_name(arg2)); 599 mkpos(&call->f_pos), type_name(arg2));
600 free(pos1); 600 free(pos1);
601} 601}
602 602
603/* 603/*
604 * Compare the types in the NULL-terminated array ap with the format 604 * Compare the types in the NULL-terminated array ap with the format
605 * string fmt. 605 * string fmt.
606 */ 606 */
607static void 607static void
608printflike(const hte_t *hte, fcall_t *call, int n, const char *fmt, type_t **ap) 608printflike(const hte_t *hte, fcall_t *call, int n, const char *fmt, type_t **ap)
609{ 609{
610 const char *fp; 610 const char *fp;
611 char fc; 611 char fc;
612 bool fwidth, prec, left, sign, space, alt, zero; 612 bool fwidth, prec, left, sign, space, alt, zero;
613 tspec_t sz, t1, t2 = NO_TSPEC; 613 tspec_t sz, t1, t2 = NO_TSPEC;
614 type_t *tp; 614 type_t *tp;
615 615
616 fp = fmt; 616 fp = fmt;
617 fc = *fp++; 617 fc = *fp++;
618 618
619 for (;;) { 619 for (;;) {
620 if (fc == '\0') { 620 if (fc == '\0') {
621 if (*ap != NULL) 621 if (*ap != NULL)
622 too_many_arguments(hte, call); 622 too_many_arguments(hte, call);
623 break; 623 break;
624 } 624 }
625 if (fc != '%') { 625 if (fc != '%') {
626 bad_format_string(hte, call); 626 bad_format_string(hte, call);
627 break; 627 break;
@@ -822,31 +822,31 @@ printflike(const hte_t *hte, fcall_t *ca @@ -822,31 +822,31 @@ printflike(const hte_t *hte, fcall_t *ca
822 } 822 }
823 823
824 fc = *fp++; 824 fc = *fp++;
825 } 825 }
826} 826}
827 827
828/* 828/*
829 * Compare the types in the NULL-terminated array ap with the format 829 * Compare the types in the NULL-terminated array ap with the format
830 * string fmt. 830 * string fmt.
831 */ 831 */
832static void 832static void
833scanflike(const hte_t *hte, fcall_t *call, int n, const char *fmt, type_t **ap) 833scanflike(const hte_t *hte, fcall_t *call, int n, const char *fmt, type_t **ap)
834{ 834{
835 const char *fp; 835 const char *fp;
836 char fc; 836 char fc;
837 bool noasgn, fwidth; 837 bool noasgn, fwidth;
838 tspec_t sz, t1 = NO_TSPEC, t2 = NO_TSPEC; 838 tspec_t sz, t1 = NO_TSPEC, t2 = NO_TSPEC;
839 type_t *tp = NULL; 839 type_t *tp = NULL;
840 840
841 fp = fmt; 841 fp = fmt;
842 fc = *fp++; 842 fc = *fp++;
843 843
844 for (;;) { 844 for (;;) {
845 if (fc == '\0') { 845 if (fc == '\0') {
846 if (*ap != NULL) 846 if (*ap != NULL)
847 too_many_arguments(hte, call); 847 too_many_arguments(hte, call);
848 break; 848 break;
849 } 849 }
850 if (fc != '%') { 850 if (fc != '%') {
851 bad_format_string(hte, call); 851 bad_format_string(hte, call);
852 break; 852 break;
@@ -1063,28 +1063,28 @@ static const char ignorelist[][8] = { @@ -1063,28 +1063,28 @@ static const char ignorelist[][8] = {
1063 "printf", 1063 "printf",
1064 "strcat", 1064 "strcat",
1065 "strcpy", 1065 "strcpy",
1066 "vprintf", 1066 "vprintf",
1067}; 1067};
1068 1068
1069/* 1069/*
1070 * Print warnings for return values which are used but not returned, 1070 * Print warnings for return values which are used but not returned,
1071 * or return values which are always or sometimes ignored. 1071 * or return values which are always or sometimes ignored.
1072 */ 1072 */
1073static void 1073static void
1074check_return_values(const hte_t *hte, sym_t *def) 1074check_return_values(const hte_t *hte, sym_t *def)
1075{ 1075{
1076 fcall_t *call; 1076 fcall_t *call;
1077 bool used, ignored; 1077 bool used, ignored;
1078 1078
1079 if (def == NULL) 1079 if (def == NULL)
1080 /* don't know whether or not the functions returns a value */ 1080 /* don't know whether or not the functions returns a value */
1081 return; 1081 return;
1082 1082
1083 if (hte->h_calls == NULL) 1083 if (hte->h_calls == NULL)
1084 return; 1084 return;
1085 1085
1086 if (def->s_function_has_return_value) { 1086 if (def->s_function_has_return_value) {
1087 /* 1087 /*
1088 * XXX as soon as we are able to disable single warnings, 1088 * XXX as soon as we are able to disable single warnings,
1089 * the following dependencies from hflag should be removed. 1089 * the following dependencies from hflag should be removed.
1090 * But for now I don't want to be bothered by these warnings 1090 * But for now I don't want to be bothered by these warnings
@@ -1117,32 +1117,32 @@ check_return_values(const hte_t *hte, sy @@ -1117,32 +1117,32 @@ check_return_values(const hte_t *hte, sy
1117 if (call->f_rused) 1117 if (call->f_rused)
1118 /* %s value is used( %s ), but none returned */ 1118 /* %s value is used( %s ), but none returned */
1119 msg(10, hte->h_name, mkpos(&call->f_pos)); 1119 msg(10, hte->h_name, mkpos(&call->f_pos));
1120 } 1120 }
1121 } 1121 }
1122} 1122}
1123 1123
1124/* 1124/*
1125 * Print warnings for inconsistent argument declarations. 1125 * Print warnings for inconsistent argument declarations.
1126 */ 1126 */
1127static void 1127static void
1128check_argument_declarations(const hte_t *hte, sym_t *def, sym_t *decl) 1128check_argument_declarations(const hte_t *hte, sym_t *def, sym_t *decl)
1129{ 1129{
1130 bool osdef, eq, dowarn; 1130 bool osdef, eq, dowarn;
1131 int n; 1131 int n;
1132 sym_t *sym1, *sym; 1132 sym_t *sym1, *sym;
1133 type_t **ap1, **ap2, *tp1, *tp2; 1133 type_t **ap1, **ap2, *tp1, *tp2;
1134 char *pos1; 1134 char *pos1;
1135 const char *pos2; 1135 const char *pos2;
1136 1136
1137 osdef = false; 1137 osdef = false;
1138 if (def != NULL) { 1138 if (def != NULL) {
1139 osdef = def->s_old_style_function; 1139 osdef = def->s_old_style_function;
1140 sym1 = def; 1140 sym1 = def;
1141 } else if (decl != NULL && TP(decl->s_type)->t_proto) { 1141 } else if (decl != NULL && TP(decl->s_type)->t_proto) {
1142 sym1 = decl; 1142 sym1 = decl;
1143 } else { 1143 } else {
1144 return; 1144 return;
1145 } 1145 }
1146 if (TP(sym1->s_type)->t_tspec != FUNC) 1146 if (TP(sym1->s_type)->t_tspec != FUNC)
1147 return; 1147 return;
1148 1148
@@ -1200,28 +1200,28 @@ check_argument_declarations(const hte_t  @@ -1200,28 +1200,28 @@ check_argument_declarations(const hte_t
1200 * promote if set, promote left type before comparison; used for 1200 * promote if set, promote left type before comparison; used for
1201 * comparisons of arguments with parameters of old-style 1201 * comparisons of arguments with parameters of old-style
1202 * definitions 1202 * definitions
1203 * asgn left indirected type must have at least the same qualifiers 1203 * asgn left indirected type must have at least the same qualifiers
1204 * like right indirected type (for assignments and function 1204 * like right indirected type (for assignments and function
1205 * arguments) 1205 * arguments)
1206 * *dowarn set to true if an old-style declaration was compared with 1206 * *dowarn set to true if an old-style declaration was compared with
1207 * an incompatible prototype declaration 1207 * an incompatible prototype declaration
1208 */ 1208 */
1209static bool 1209static bool
1210types_compatible(type_t *tp1, type_t *tp2, 1210types_compatible(type_t *tp1, type_t *tp2,
1211 bool ignqual, bool promot, bool asgn, bool *dowarn) 1211 bool ignqual, bool promot, bool asgn, bool *dowarn)
1212{ 1212{
1213 tspec_t t, to; 1213 tspec_t t, to;
1214 int indir; 1214 int indir;
1215 1215
1216 to = NO_TSPEC; 1216 to = NO_TSPEC;
1217 indir = 0; 1217 indir = 0;
1218 1218
1219 while (tp1 != NULL && tp2 != NULL) { 1219 while (tp1 != NULL && tp2 != NULL) {
1220 1220
1221 t = tp1->t_tspec; 1221 t = tp1->t_tspec;
1222 if (promot) { 1222 if (promot) {
1223 if (t == FLOAT) { 1223 if (t == FLOAT) {
1224 t = DOUBLE; 1224 t = DOUBLE;
1225 } else if (t == CHAR || t == SCHAR) { 1225 } else if (t == CHAR || t == SCHAR) {
1226 t = INT; 1226 t = INT;
1227 } else if (t == UCHAR) { 1227 } else if (t == UCHAR) {
@@ -1326,27 +1326,27 @@ types_compatible(type_t *tp1, type_t *tp @@ -1326,27 +1326,27 @@ types_compatible(type_t *tp1, type_t *tp
1326 indir++; 1326 indir++;
1327 1327
1328 } 1328 }
1329 1329
1330 return tp1 == tp2; 1330 return tp1 == tp2;
1331} 1331}
1332 1332
1333/* 1333/*
1334 * Compares arguments of two prototypes 1334 * Compares arguments of two prototypes
1335 */ 1335 */
1336static bool 1336static bool
1337prototypes_compatible(type_t *tp1, type_t *tp2, bool *dowarn) 1337prototypes_compatible(type_t *tp1, type_t *tp2, bool *dowarn)
1338{ 1338{
1339 type_t **a1, **a2; 1339 type_t **a1, **a2;
1340 1340
1341 if (tp1->t_vararg != tp2->t_vararg) 1341 if (tp1->t_vararg != tp2->t_vararg)
1342 return false; 1342 return false;
1343 1343
1344 a1 = tp1->t_args; 1344 a1 = tp1->t_args;
1345 a2 = tp2->t_args; 1345 a2 = tp2->t_args;
1346 1346
1347 while (*a1 != NULL && *a2 != NULL) { 1347 while (*a1 != NULL && *a2 != NULL) {
1348 1348
1349 if (!types_compatible(*a1, *a2, true, false, false, dowarn)) 1349 if (!types_compatible(*a1, *a2, true, false, false, dowarn))
1350 return false; 1350 return false;
1351 1351
1352 a1++; 1352 a1++;
@@ -1360,28 +1360,28 @@ prototypes_compatible(type_t *tp1, type_ @@ -1360,28 +1360,28 @@ prototypes_compatible(type_t *tp1, type_
1360/* 1360/*
1361 * Returns whether all parameters of a prototype are compatible with an 1361 * Returns whether all parameters of a prototype are compatible with an
1362 * old-style function declaration. 1362 * old-style function declaration.
1363 * 1363 *
1364 * This is the case if the following conditions are met: 1364 * This is the case if the following conditions are met:
1365 * 1. the prototype must have a fixed number of parameters 1365 * 1. the prototype must have a fixed number of parameters
1366 * 2. no parameter is of type float 1366 * 2. no parameter is of type float
1367 * 3. no parameter is converted to another type if integer promotion 1367 * 3. no parameter is converted to another type if integer promotion
1368 * is applied on it 1368 * is applied on it
1369 */ 1369 */
1370static bool 1370static bool
1371matches_no_arg_function(type_t *tp, bool *dowarn) 1371matches_no_arg_function(type_t *tp, bool *dowarn)
1372{ 1372{
1373 type_t **arg; 1373 type_t **arg;
1374 tspec_t t; 1374 tspec_t t;
1375 1375
1376 if (tp->t_vararg && dowarn != NULL) 1376 if (tp->t_vararg && dowarn != NULL)
1377 *dowarn = true; 1377 *dowarn = true;
1378 for (arg = tp->t_args; *arg != NULL; arg++) { 1378 for (arg = tp->t_args; *arg != NULL; arg++) {
1379 if ((t = (*arg)->t_tspec) == FLOAT) 1379 if ((t = (*arg)->t_tspec) == FLOAT)
1380 return false; 1380 return false;
1381 if (t == CHAR || t == SCHAR || t == UCHAR) 1381 if (t == CHAR || t == SCHAR || t == UCHAR)
1382 return false; 1382 return false;
1383 if (t == SHORT || t == USHORT) 1383 if (t == SHORT || t == USHORT)
1384 return false; 1384 return false;
1385 } 1385 }
1386 return true; 1386 return true;
1387} 1387}

cvs diff -r1.30 -r1.31 src/usr.bin/xlint/lint2/emit2.c (expand / switch to unified diff)

--- src/usr.bin/xlint/lint2/emit2.c 2023/02/02 22:23:30 1.30
+++ src/usr.bin/xlint/lint2/emit2.c 2023/06/09 13:03:49 1.31
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: emit2.c,v 1.30 2023/02/02 22:23:30 rillig Exp $ */ 1/* $NetBSD: emit2.c,v 1.31 2023/06/09 13:03:49 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. 4 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
5 * Copyright (c) 1994, 1995 Jochen Pohl 5 * Copyright (c) 1994, 1995 Jochen Pohl
6 * All Rights Reserved. 6 * All Rights Reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
@@ -24,52 +24,52 @@ @@ -24,52 +24,52 @@
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */ 33 */
34 34
35#include <sys/cdefs.h> 35#include <sys/cdefs.h>
36#if defined(__RCSID) 36#if defined(__RCSID)
37__RCSID("$NetBSD: emit2.c,v 1.30 2023/02/02 22:23:30 rillig Exp $"); 37__RCSID("$NetBSD: emit2.c,v 1.31 2023/06/09 13:03:49 rillig Exp $");
38#endif 38#endif
39 39
40#include "lint2.h" 40#include "lint2.h"
41 41
42static void outtype(type_t *); 42static void outtype(type_t *);
43static void outdef(hte_t *, sym_t *); 43static void outdef(hte_t *, sym_t *);
44static void dumpname(hte_t *); 44static void dumpname(hte_t *);
45static void outfiles(void); 45static void outfiles(void);
46 46
47/* 47/*
48 * Write type into the output buffer. 48 * Write type into the output buffer.
49 */ 49 */
50static void 50static void
51outtype(type_t *tp) 51outtype(type_t *tp)
52{ 52{
53#ifdef INT128_SIZE 53#ifdef INT128_SIZE
54 static const char tt[NTSPEC] = "???BCCCSSIILLQQJJDDDVTTTPAF?XXX"; 54 static const char tt[NTSPEC] = "???BCCCSSIILLQQJJDDDVTTTPAF?XXX";
55 static const char ss[NTSPEC] = "??? su u u u u us l sue ?s l"; 55 static const char ss[NTSPEC] = "??? su u u u u us l sue ?s l";
56#else 56#else
57 static const char tt[NTSPEC] = "???BCCCSSIILLQQDDDVTTTPAF?XXX"; 57 static const char tt[NTSPEC] = "???BCCCSSIILLQQDDDVTTTPAF?XXX";
58 static const char ss[NTSPEC] = "??? su u u u us l sue ?s l"; 58 static const char ss[NTSPEC] = "??? su u u u us l sue ?s l";
59#endif 59#endif
60 60
61 while (tp != NULL) { 61 while (tp != NULL) {
62 tspec_t ts = tp->t_tspec; 62 tspec_t ts = tp->t_tspec;
63 if (ts == INT && tp->t_is_enum) 63 if (ts == INT && tp->t_is_enum)
64 ts = ENUM; 64 ts = ENUM;
65 if (!ch_isupper(tt[ts])) 65 if (!ch_isupper(tt[ts]))
66 errx(1, "internal error: outtype(%d)", ts); 66 errx(1, "internal error: outtype(%d)", ts);
67 if (tp->t_const) 67 if (tp->t_const)
68 outchar('c'); 68 outchar('c');
69 if (tp->t_volatile) 69 if (tp->t_volatile)
70 outchar('v'); 70 outchar('v');
71 if (ss[ts] != ' ') 71 if (ss[ts] != ' ')
72 outchar(ss[ts]); 72 outchar(ss[ts]);
73 if (ts == FUNC && tp->t_args != NULL && !tp->t_proto) 73 if (ts == FUNC && tp->t_args != NULL && !tp->t_proto)
74 outchar('f'); 74 outchar('f');
75 else 75 else
@@ -156,27 +156,27 @@ outdef(hte_t *hte, sym_t *sym) @@ -156,27 +156,27 @@ outdef(hte_t *hte, sym_t *sym)
156 /* name */ 156 /* name */
157 outname(hte->h_name); 157 outname(hte->h_name);
158 158
159 /* type */ 159 /* type */
160 outtype(TP(sym->s_type)); 160 outtype(TP(sym->s_type));
161} 161}
162 162
163/* 163/*
164 * Write the first definition of a name into the lint library. 164 * Write the first definition of a name into the lint library.
165 */ 165 */
166static void 166static void
167dumpname(hte_t *hte) 167dumpname(hte_t *hte)
168{ 168{
169 sym_t *sym, *def; 169 sym_t *sym, *def;
170 170
171 /* static and undefined symbols are not written */ 171 /* static and undefined symbols are not written */
172 if (hte->h_static || !hte->h_def) 172 if (hte->h_static || !hte->h_def)
173 return; 173 return;
174 174
175 /* 175 /*
176 * If there is a definition, write it. Otherwise, write a tentative 176 * If there is a definition, write it. Otherwise, write a tentative
177 * definition. This is necessary because more than one tentative 177 * definition. This is necessary because more than one tentative
178 * definition is allowed (except with sflag). 178 * definition is allowed (except with sflag).
179 */ 179 */
180 def = NULL; 180 def = NULL;
181 for (sym = hte->h_syms; sym != NULL; sym = sym->s_next) { 181 for (sym = hte->h_syms; sym != NULL; sym = sym->s_next) {
182 if (sym->s_def == DEF) { 182 if (sym->s_def == DEF) {

cvs diff -r1.24 -r1.25 src/usr.bin/xlint/lint2/hash.c (expand / switch to unified diff)

--- src/usr.bin/xlint/lint2/hash.c 2022/05/20 21:18:55 1.24
+++ src/usr.bin/xlint/lint2/hash.c 2023/06/09 13:03:49 1.25
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: hash.c,v 1.24 2022/05/20 21:18:55 rillig Exp $ */ 1/* $NetBSD: hash.c,v 1.25 2023/06/09 13:03:49 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1994, 1995 Jochen Pohl 4 * Copyright (c) 1994, 1995 Jochen Pohl
5 * All Rights Reserved. 5 * All Rights Reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -27,27 +27,27 @@ @@ -27,27 +27,27 @@
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34#if HAVE_NBTOOL_CONFIG_H 34#if HAVE_NBTOOL_CONFIG_H
35#include "nbtool_config.h" 35#include "nbtool_config.h"
36#endif 36#endif
37 37
38#include <sys/cdefs.h> 38#include <sys/cdefs.h>
39#if defined(__RCSID) 39#if defined(__RCSID)
40__RCSID("$NetBSD: hash.c,v 1.24 2022/05/20 21:18:55 rillig Exp $"); 40__RCSID("$NetBSD: hash.c,v 1.25 2023/06/09 13:03:49 rillig Exp $");
41#endif 41#endif
42 42
43/* 43/*
44 * XXX Really need a generalized hash table package 44 * XXX Really need a generalized hash table package
45 */ 45 */
46 46
47#include <limits.h> 47#include <limits.h>
48#include <stddef.h> 48#include <stddef.h>
49#include <stdlib.h> 49#include <stdlib.h>
50#include <string.h> 50#include <string.h>
51 51
52#include "lint2.h" 52#include "lint2.h"
53 53
@@ -78,27 +78,27 @@ hash(const char *s) @@ -78,27 +78,27 @@ hash(const char *s)
78 v ^= v >> 28; 78 v ^= v >> 28;
79 } 79 }
80 return v % HSHSIZ2; 80 return v % HSHSIZ2;
81} 81}
82 82
83/* 83/*
84 * Look for a hash table entry. If no hash table entry for the 84 * Look for a hash table entry. If no hash table entry for the
85 * given name exists and mknew is set, create a new one. 85 * given name exists and mknew is set, create a new one.
86 */ 86 */
87hte_t * 87hte_t *
88_hsearch(hte_t **table, const char *s, bool mknew) 88_hsearch(hte_t **table, const char *s, bool mknew)
89{ 89{
90 unsigned int h; 90 unsigned int h;
91 hte_t *hte; 91 hte_t *hte;
92 92
93 if (table == NULL) 93 if (table == NULL)
94 table = htab; 94 table = htab;
95 95
96 h = hash(s); 96 h = hash(s);
97 for (hte = table[h]; hte != NULL; hte = hte->h_link) { 97 for (hte = table[h]; hte != NULL; hte = hte->h_link) {
98 if (strcmp(hte->h_name, s) == 0) 98 if (strcmp(hte->h_name, s) == 0)
99 break; 99 break;
100 } 100 }
101 101
102 if (hte != NULL || !mknew) 102 if (hte != NULL || !mknew)
103 return hte; 103 return hte;
104 104
@@ -149,29 +149,29 @@ hte_by_name(const void *va, const void * @@ -149,29 +149,29 @@ hte_by_name(const void *va, const void *
149 149
150void 150void
151symtab_init(void) 151symtab_init(void)
152{ 152{
153 htab = htab_new(); 153 htab = htab_new();
154} 154}
155 155
156/* 156/*
157 * Call the action for each name in the hash table. 157 * Call the action for each name in the hash table.
158 */ 158 */
159void 159void
160symtab_forall(void (*action)(hte_t *)) 160symtab_forall(void (*action)(hte_t *))
161{ 161{
162 int i; 162 int i;
163 hte_t *hte; 163 hte_t *hte;
164 hte_t **table = htab; 164 hte_t **table = htab;
165 165
166 for (i = 0; i < HSHSIZ2; i++) { 166 for (i = 0; i < HSHSIZ2; i++) {
167 for (hte = table[i]; hte != NULL; hte = hte->h_link) 167 for (hte = table[i]; hte != NULL; hte = hte->h_link)
168 action(hte); 168 action(hte);
169 } 169 }
170} 170}
171 171
172/* Run the action for each name in the symbol table, in alphabetic order. */ 172/* Run the action for each name in the symbol table, in alphabetic order. */
173void 173void
174symtab_forall_sorted(void (*action)(hte_t *)) 174symtab_forall_sorted(void (*action)(hte_t *))
175{ 175{
176 hte_t *hte; 176 hte_t *hte;
177 struct hte_list sorted = { NULL, 0, 0 }; 177 struct hte_list sorted = { NULL, 0, 0 };
@@ -186,28 +186,28 @@ symtab_forall_sorted(void (*action)(hte_ @@ -186,28 +186,28 @@ symtab_forall_sorted(void (*action)(hte_
186 186
187 for (i = 0; i < sorted.len; i++) 187 for (i = 0; i < sorted.len; i++)
188 action(sorted.items[i]); 188 action(sorted.items[i]);
189 189
190 free(sorted.items); 190 free(sorted.items);
191} 191}
192 192
193/* 193/*
194 * Free all contents of the hash table that this module allocated. 194 * Free all contents of the hash table that this module allocated.
195 */ 195 */
196void 196void
197_destroyhash(hte_t **table) 197_destroyhash(hte_t **table)
198{ 198{
199 int i; 199 int i;
200 hte_t *hte, *nexthte; 200 hte_t *hte, *nexthte;
201 201
202 if (table == NULL) 202 if (table == NULL)
203 err(1, "_destroyhash called on main hash table"); 203 err(1, "_destroyhash called on main hash table");
204 204
205 for (i = 0; i < HSHSIZ2; i++) { 205 for (i = 0; i < HSHSIZ2; i++) {
206 for (hte = table[i]; hte != NULL; hte = nexthte) { 206 for (hte = table[i]; hte != NULL; hte = nexthte) {
207 free(__UNCONST(hte->h_name)); 207 free(__UNCONST(hte->h_name));
208 nexthte = hte->h_link; 208 nexthte = hte->h_link;
209 free(hte); 209 free(hte);
210 } 210 }
211 } 211 }
212 free(table); 212 free(table);
213} 213}

cvs diff -r1.28 -r1.29 src/usr.bin/xlint/lint2/main2.c (expand / switch to unified diff)

--- src/usr.bin/xlint/lint2/main2.c 2023/03/28 14:44:35 1.28
+++ src/usr.bin/xlint/lint2/main2.c 2023/06/09 13:03:49 1.29
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: main2.c,v 1.28 2023/03/28 14:44:35 rillig Exp $ */ 1/* $NetBSD: main2.c,v 1.29 2023/06/09 13:03:49 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1994, 1995 Jochen Pohl 4 * Copyright (c) 1994, 1995 Jochen Pohl
5 * All Rights Reserved. 5 * All Rights Reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -27,27 +27,27 @@ @@ -27,27 +27,27 @@
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34#if HAVE_NBTOOL_CONFIG_H 34#if HAVE_NBTOOL_CONFIG_H
35#include "nbtool_config.h" 35#include "nbtool_config.h"
36#endif 36#endif
37 37
38#include <sys/cdefs.h> 38#include <sys/cdefs.h>
39#if defined(__RCSID) 39#if defined(__RCSID)
40__RCSID("$NetBSD: main2.c,v 1.28 2023/03/28 14:44:35 rillig Exp $"); 40__RCSID("$NetBSD: main2.c,v 1.29 2023/06/09 13:03:49 rillig Exp $");
41#endif 41#endif
42 42
43#include <stdio.h> 43#include <stdio.h>
44#include <stdlib.h> 44#include <stdlib.h>
45#include <string.h> 45#include <string.h>
46#include <unistd.h> 46#include <unistd.h>
47 47
48#include "lint2.h" 48#include "lint2.h"
49 49
50/* warnings for symbols which are declared but not defined or used */ 50/* warnings for symbols which are declared but not defined or used */
51bool xflag; 51bool xflag;
52 52
53/* 53/*
@@ -87,29 +87,29 @@ bool Fflag; @@ -87,29 +87,29 @@ bool Fflag;
87static const char **libs; 87static const char **libs;
88 88
89static void usage(void) __attribute__((noreturn)); 89static void usage(void) __attribute__((noreturn));
90 90
91static void 91static void
92check_name_non_const(hte_t *hte) 92check_name_non_const(hte_t *hte)
93{ 93{
94 check_name(hte); 94 check_name(hte);
95} 95}
96 96
97int 97int
98main(int argc, char *argv[]) 98main(int argc, char *argv[])
99{ 99{
100 int c, i; 100 int c, i;
101 size_t len; 101 size_t len;
102 char *lname; 102 char *lname;
103 103
104 libs = xcalloc(1, sizeof(*libs)); 104 libs = xcalloc(1, sizeof(*libs));
105 105
106 opterr = 0; 106 opterr = 0;
107 while ((c = getopt(argc, argv, "hstxuC:HFl:")) != -1) { 107 while ((c = getopt(argc, argv, "hstxuC:HFl:")) != -1) {
108 switch (c) { 108 switch (c) {
109 case 's': 109 case 's':
110 sflag = true; 110 sflag = true;
111 break; 111 break;
112 case 't': 112 case 't':
113 tflag = true; 113 tflag = true;
114 break; 114 break;
115 case 'u': 115 case 'u':

cvs diff -r1.19 -r1.20 src/usr.bin/xlint/lint2/msg.c (expand / switch to unified diff)

--- src/usr.bin/xlint/lint2/msg.c 2023/02/19 19:27:01 1.19
+++ src/usr.bin/xlint/lint2/msg.c 2023/06/09 13:03:49 1.20
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: msg.c,v 1.19 2023/02/19 19:27:01 rillig Exp $ */ 1/* $NetBSD: msg.c,v 1.20 2023/06/09 13:03:49 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1994, 1995 Jochen Pohl 4 * Copyright (c) 1994, 1995 Jochen Pohl
5 * All Rights Reserved. 5 * All Rights Reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -27,27 +27,27 @@ @@ -27,27 +27,27 @@
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34#if HAVE_NBTOOL_CONFIG_H 34#if HAVE_NBTOOL_CONFIG_H
35#include "nbtool_config.h" 35#include "nbtool_config.h"
36#endif 36#endif
37 37
38#include <sys/cdefs.h> 38#include <sys/cdefs.h>
39#if defined(__RCSID) 39#if defined(__RCSID)
40__RCSID("$NetBSD: msg.c,v 1.19 2023/02/19 19:27:01 rillig Exp $"); 40__RCSID("$NetBSD: msg.c,v 1.20 2023/06/09 13:03:49 rillig Exp $");
41#endif 41#endif
42 42
43#include <stdarg.h> 43#include <stdarg.h>
44#include <stdio.h> 44#include <stdio.h>
45#include <string.h> 45#include <string.h>
46 46
47#include "lint2.h" 47#include "lint2.h"
48 48
49static const char *msgs[] = { 49static const char *msgs[] = {
50 "%s used( %s ), but not defined", /* 0 */ 50 "%s used( %s ), but not defined", /* 0 */
51 "%s defined( %s ), but never used", /* 1 */ 51 "%s defined( %s ), but never used", /* 1 */
52 "%s declared( %s ), but never used or defined", /* 2 */ 52 "%s declared( %s ), but never used or defined", /* 2 */
53 "%s multiply defined \t%s :: %s", /* 3 */ 53 "%s multiply defined \t%s :: %s", /* 3 */
@@ -61,27 +61,27 @@ static const char *msgs[] = { @@ -61,27 +61,27 @@ static const char *msgs[] = {
61 "%s, arg %d declared inconsistently (%s != %s)\t%s :: %s", /* 11 */ 61 "%s, arg %d declared inconsistently (%s != %s)\t%s :: %s", /* 11 */
62 "%s: variable # of args declared \t%s :: %s", /* 12 */ 62 "%s: variable # of args declared \t%s :: %s", /* 12 */
63 "%s: malformed format string \t%s", /* 13 */ 63 "%s: malformed format string \t%s", /* 13 */
64 "%s, arg %d inconsistent with format \t%s", /* 14 */ 64 "%s, arg %d inconsistent with format \t%s", /* 14 */
65 "%s: too few args for format \t%s", /* 15 */ 65 "%s: too few args for format \t%s", /* 15 */
66 "%s: too many args for format \t%s", /* 16 */ 66 "%s: too many args for format \t%s", /* 16 */
67 "%s function value must be declared before use \t%s :: %s",/* 17 */ 67 "%s function value must be declared before use \t%s :: %s",/* 17 */
68 "%s renamed multiple times \t%s :: %s", /* 18 */ 68 "%s renamed multiple times \t%s :: %s", /* 18 */
69}; 69};
70 70
71void 71void
72msg(int n, ...) 72msg(int n, ...)
73{ 73{
74 va_list ap; 74 va_list ap;
75 75
76 va_start(ap, n); 76 va_start(ap, n);
77 77
78 (void)vprintf(msgs[n], ap); 78 (void)vprintf(msgs[n], ap);
79 (void)printf("\n"); 79 (void)printf("\n");
80 80
81 va_end(ap); 81 va_end(ap);
82} 82}
83 83
84/* 84/*
85 * Return a pointer to the last component of a path. 85 * Return a pointer to the last component of a path.
86 */ 86 */
87static const char * 87static const char *
@@ -94,32 +94,32 @@ lbasename(const char *path) @@ -94,32 +94,32 @@ lbasename(const char *path)
94 const char *base = path; 94 const char *base = path;
95 for (const char *p = path; *p != '\0'; p++) 95 for (const char *p = path; *p != '\0'; p++)
96 if (*p == '/') 96 if (*p == '/')
97 base = p + 1; 97 base = p + 1;
98 return base; 98 return base;
99} 99}
100 100
101/* 101/*
102 * Create a string which describes a position in a source file. 102 * Create a string which describes a position in a source file.
103 */ 103 */
104const char * 104const char *
105mkpos(pos_t *posp) 105mkpos(pos_t *posp)
106{ 106{
107 size_t len; 107 size_t len;
108 const char *fn; 108 const char *fn;
109 static char *buf; 109 static char *buf;
110 static size_t blen = 0; 110 static size_t blen = 0;
111 bool qm; 111 bool qm;
112 int src, line; 112 int src, line;
113 113
114 if (Hflag && posp->p_src != posp->p_isrc) { 114 if (Hflag && posp->p_src != posp->p_isrc) {
115 src = posp->p_isrc; 115 src = posp->p_isrc;
116 line = posp->p_iline; 116 line = posp->p_iline;
117 } else { 117 } else {
118 src = posp->p_src; 118 src = posp->p_src;
119 line = posp->p_line; 119 line = posp->p_line;
120 } 120 }
121 qm = !Hflag && posp->p_src != posp->p_isrc; 121 qm = !Hflag && posp->p_src != posp->p_isrc;
122 122
123 len = strlen(fn = lbasename(fnames[src])); 123 len = strlen(fn = lbasename(fnames[src]));
124 len += 3 * sizeof(unsigned short) + 4; 124 len += 3 * sizeof(unsigned short) + 4;
125 125

cvs diff -r1.80 -r1.81 src/usr.bin/xlint/lint2/read.c (expand / switch to unified diff)

--- src/usr.bin/xlint/lint2/read.c 2023/05/22 12:55:04 1.80
+++ src/usr.bin/xlint/lint2/read.c 2023/06/09 13:03:49 1.81
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: read.c,v 1.80 2023/05/22 12:55:04 rillig Exp $ */ 1/* $NetBSD: read.c,v 1.81 2023/06/09 13:03:49 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. 4 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
5 * Copyright (c) 1994, 1995 Jochen Pohl 5 * Copyright (c) 1994, 1995 Jochen Pohl
6 * All Rights Reserved. 6 * All Rights Reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
@@ -28,27 +28,27 @@ @@ -28,27 +28,27 @@
28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */ 33 */
34 34
35#if HAVE_NBTOOL_CONFIG_H 35#if HAVE_NBTOOL_CONFIG_H
36#include "nbtool_config.h" 36#include "nbtool_config.h"
37#endif 37#endif
38 38
39#include <sys/cdefs.h> 39#include <sys/cdefs.h>
40#if defined(__RCSID) 40#if defined(__RCSID)
41__RCSID("$NetBSD: read.c,v 1.80 2023/05/22 12:55:04 rillig Exp $"); 41__RCSID("$NetBSD: read.c,v 1.81 2023/06/09 13:03:49 rillig Exp $");
42#endif 42#endif
43 43
44#include <ctype.h> 44#include <ctype.h>
45#include <limits.h> 45#include <limits.h>
46#include <stdarg.h> 46#include <stdarg.h>
47#include <stdio.h> 47#include <stdio.h>
48#include <stdlib.h> 48#include <stdlib.h>
49#include <string.h> 49#include <string.h>
50 50
51#include "lint2.h" 51#include "lint2.h"
52 52
53 53
54/* index of current (included) source file */ 54/* index of current (included) source file */
@@ -204,29 +204,29 @@ read_ln_line(const char *line) @@ -204,29 +204,29 @@ read_ln_line(const char *line)
204 decldef(pos, cp); 204 decldef(pos, cp);
205 break; 205 break;
206 case 'u': 206 case 'u':
207 usedsym(pos, cp); 207 usedsym(pos, cp);
208 break; 208 break;
209 default: 209 default:
210 inperr("bad record type %c", rt); 210 inperr("bad record type %c", rt);
211 } 211 }
212} 212}
213 213
214void 214void
215readfile(const char *name) 215readfile(const char *name)
216{ 216{
217 FILE *inp; 217 FILE *inp;
218 size_t len; 218 size_t len;
219 char *line; 219 char *line;
220 220
221 if (inpfns == NULL) 221 if (inpfns == NULL)
222 inpfns = xcalloc(ninpfns = 128, sizeof(*inpfns)); 222 inpfns = xcalloc(ninpfns = 128, sizeof(*inpfns));
223 if (fnames == NULL) 223 if (fnames == NULL)
224 fnames = xcalloc(nfnames = 256, sizeof(*fnames)); 224 fnames = xcalloc(nfnames = 256, sizeof(*fnames));
225 if (flines == NULL) 225 if (flines == NULL)
226 flines = xcalloc(nfnames, sizeof(*flines)); 226 flines = xcalloc(nfnames, sizeof(*flines));
227 if (tlstlen == 0) 227 if (tlstlen == 0)
228 tlst = xcalloc(tlstlen = 256, sizeof(*tlst)); 228 tlst = xcalloc(tlstlen = 256, sizeof(*tlst));
229 if (thtab == NULL) 229 if (thtab == NULL)
230 thtab = xcalloc(THSHSIZ2, sizeof(*thtab)); 230 thtab = xcalloc(THSHSIZ2, sizeof(*thtab));
231 231
232 renametab = htab_new(); 232 renametab = htab_new();
@@ -306,30 +306,30 @@ setfnid(int fid, const char *cp) @@ -306,30 +306,30 @@ setfnid(int fid, const char *cp)
306 */ 306 */
307 if ((size_t)fid >= ninpfns) 307 if ((size_t)fid >= ninpfns)
308 errx(1, "internal error: setfnid"); 308 errx(1, "internal error: setfnid");
309 inpfns[fid] = (unsigned short)getfnidx(cp); 309 inpfns[fid] = (unsigned short)getfnidx(cp);
310} 310}
311 311
312/* 312/*
313 * Process a function call record (c-record). 313 * Process a function call record (c-record).
314 */ 314 */
315static void 315static void
316funccall(pos_t pos, const char *cp) 316funccall(pos_t pos, const char *cp)
317{ 317{
318 arginf_t *ai, **lai; 318 arginf_t *ai, **lai;
319 char c; 319 char c;
320 bool rused, rdisc; 320 bool rused, rdisc;
321 hte_t *hte; 321 hte_t *hte;
322 fcall_t *fcall; 322 fcall_t *fcall;
323 const char *name; 323 const char *name;
324 324
325 fcall = xalloc(sizeof(*fcall)); 325 fcall = xalloc(sizeof(*fcall));
326 fcall->f_pos = pos; 326 fcall->f_pos = pos;
327 327
328 /* read flags */ 328 /* read flags */
329 rused = rdisc = false; 329 rused = rdisc = false;
330 lai = &fcall->f_args; 330 lai = &fcall->f_args;
331 331
332again: 332again:
333 c = *cp++; 333 c = *cp++;
334 switch (c) { 334 switch (c) {
335 case 'u': 335 case 'u':
@@ -458,30 +458,30 @@ parse_function_attribute(const char **pp @@ -458,30 +458,30 @@ parse_function_attribute(const char **pp
458 default: 458 default:
459 (*pp)--; 459 (*pp)--;
460 return false; 460 return false;
461 } 461 }
462 return true; 462 return true;
463} 463}
464 464
465/* 465/*
466 * Process a declaration or definition (d-record). 466 * Process a declaration or definition (d-record).
467 */ 467 */
468static void 468static void
469decldef(pos_t pos, const char *cp) 469decldef(pos_t pos, const char *cp)
470{ 470{
471 sym_t *symp, sym; 471 sym_t *symp, sym;
472 char *pos1, *tname; 472 char *pos1, *tname;
473 bool used, renamed; 473 bool used, renamed;
474 hte_t *hte, *renamehte = NULL; 474 hte_t *hte, *renamehte = NULL;
475 const char *name, *newname; 475 const char *name, *newname;
476 476
477 (void)memset(&sym, 0, sizeof(sym)); 477 (void)memset(&sym, 0, sizeof(sym));
478 sym.s_pos = pos; 478 sym.s_pos = pos;
479 sym.s_def = NODECL; 479 sym.s_def = NODECL;
480 480
481 used = false; 481 used = false;
482 482
483 while (parse_function_attribute(&cp, &sym, &used)) 483 while (parse_function_attribute(&cp, &sym, &used))
484 continue; 484 continue;
485 485
486 /* read symbol name, doing renaming if necessary */ 486 /* read symbol name, doing renaming if necessary */
487 name = inpname(cp, &cp); 487 name = inpname(cp, &cp);
@@ -554,28 +554,28 @@ decldef(pos_t pos, const char *cp) @@ -554,28 +554,28 @@ decldef(pos_t pos, const char *cp)
554 renamehte->h_syms = symp; 554 renamehte->h_syms = symp;
555 } 555 }
556 556
557 if (*cp != '\0') 557 if (*cp != '\0')
558 inperr("trailing line: %s", cp); 558 inperr("trailing line: %s", cp);
559} 559}
560 560
561/* 561/*
562 * Read an u-record (emitted by lint1 if a symbol was used). 562 * Read an u-record (emitted by lint1 if a symbol was used).
563 */ 563 */
564static void 564static void
565usedsym(pos_t pos, const char *cp) 565usedsym(pos_t pos, const char *cp)
566{ 566{
567 usym_t *usym; 567 usym_t *usym;
568 hte_t *hte; 568 hte_t *hte;
569 const char *name; 569 const char *name;
570 570
571 usym = xalloc(sizeof(*usym)); 571 usym = xalloc(sizeof(*usym));
572 usym->u_pos = pos; 572 usym->u_pos = pos;
573 573
574 /* needed as delimiter between two numbers */ 574 /* needed as delimiter between two numbers */
575 if (*cp++ != 'x') 575 if (*cp++ != 'x')
576 inperr("bad delim %c", cp[-1]); 576 inperr("bad delim %c", cp[-1]);
577 577
578 name = inpname(cp, &cp); 578 name = inpname(cp, &cp);
579 hte = _hsearch(renametab, name, false); 579 hte = _hsearch(renametab, name, false);
580 if (hte != NULL) 580 if (hte != NULL)
581 hte = hte->h_hte; 581 hte = hte->h_hte;
@@ -641,34 +641,34 @@ parse_tspec(const char **pp, char c, boo @@ -641,34 +641,34 @@ parse_tspec(const char **pp, char c, boo
641 : (s == 'l' ? LCOMPLEX : DCOMPLEX); 641 : (s == 'l' ? LCOMPLEX : DCOMPLEX);
642 default: 642 default:
643 inperr("tspec '%c'", c); 643 inperr("tspec '%c'", c);
644 /* NOTREACHED */ 644 /* NOTREACHED */
645 } 645 }
646} 646}
647 647
648/* 648/*
649 * Read a type and return the index of this type. 649 * Read a type and return the index of this type.
650 */ 650 */
651static unsigned short 651static unsigned short
652inptype(const char *cp, const char **epp) 652inptype(const char *cp, const char **epp)
653{ 653{
654 char c; 654 char c;
655 const char *ep; 655 const char *ep;
656 type_t *tp; 656 type_t *tp;
657 int narg, i; 657 int narg, i;
658 bool osdef = false; 658 bool osdef = false;
659 size_t tlen; 659 size_t tlen;
660 unsigned short tidx; 660 unsigned short tidx;
661 int h; 661 int h;
662 662
663 /* If we have this type already, return its index. */ 663 /* If we have this type already, return its index. */
664 tlen = gettlen(cp, &ep); 664 tlen = gettlen(cp, &ep);
665 h = thash(cp, tlen); 665 h = thash(cp, tlen);
666 if ((tidx = findtype(cp, tlen, h)) != 0) { 666 if ((tidx = findtype(cp, tlen, h)) != 0) {
667 *epp = ep; 667 *epp = ep;
668 return tidx; 668 return tidx;
669 } 669 }
670 670
671 /* No, we must create a new type. */ 671 /* No, we must create a new type. */
672 tp = xalloc(sizeof(*tp)); 672 tp = xalloc(sizeof(*tp));
673 673
674 tidx = storetyp(tp, cp, tlen, h); 674 tidx = storetyp(tp, cp, tlen, h);
@@ -743,30 +743,30 @@ inptype(const char *cp, const char **epp @@ -743,30 +743,30 @@ inptype(const char *cp, const char **epp
743 break; 743 break;
744 } 744 }
745 745
746 *epp = cp; 746 *epp = cp;
747 return tidx; 747 return tidx;
748} 748}
749 749
750/* 750/*
751 * Get the length of a type string. 751 * Get the length of a type string.
752 */ 752 */
753static size_t 753static size_t
754gettlen(const char *cp, const char **epp) 754gettlen(const char *cp, const char **epp)
755{ 755{
756 const char *cp1; 756 const char *cp1;
757 char c, s; 757 char c, s;
758 tspec_t t; 758 tspec_t t;
759 int narg, i; 759 int narg, i;
760 760
761 cp1 = cp; 761 cp1 = cp;
762 762
763 c = *cp++; 763 c = *cp++;
764 764
765 if (c == 'c') 765 if (c == 'c')
766 c = *cp++; 766 c = *cp++;
767 if (c == 'v') 767 if (c == 'v')
768 c = *cp++; 768 c = *cp++;
769 769
770 switch (c) { 770 switch (c) {
771 case 's': 771 case 's':
772 case 'u': 772 case 'u':
@@ -922,48 +922,48 @@ gettlen(const char *cp, const char **epp @@ -922,48 +922,48 @@ gettlen(const char *cp, const char **epp
922 break; 922 break;
923 } 923 }
924 924
925 *epp = cp; 925 *epp = cp;
926 return (size_t)(cp - cp1); 926 return (size_t)(cp - cp1);
927} 927}
928 928
929/* 929/*
930 * Search a type by its type string. 930 * Search a type by its type string.
931 */ 931 */
932static unsigned short 932static unsigned short
933findtype(const char *cp, size_t len, int h) 933findtype(const char *cp, size_t len, int h)
934{ 934{
935 thtab_t *thte; 935 thtab_t *thte;
936 936
937 for (thte = thtab[h]; thte != NULL; thte = thte->th_next) { 937 for (thte = thtab[h]; thte != NULL; thte = thte->th_next) {
938 if (strncmp(thte->th_name, cp, len) != 0) 938 if (strncmp(thte->th_name, cp, len) != 0)
939 continue; 939 continue;
940 if (thte->th_name[len] == '\0') 940 if (thte->th_name[len] == '\0')
941 return thte->th_idx; 941 return thte->th_idx;
942 } 942 }
943 943
944 return 0; 944 return 0;
945} 945}
946 946
947/* 947/*
948 * Store a type and its type string, so we can later share this type 948 * Store a type and its type string, so we can later share this type
949 * if we read the same type string from the input file. 949 * if we read the same type string from the input file.
950 */ 950 */
951static unsigned short 951static unsigned short
952storetyp(type_t *tp, const char *cp, size_t len, int h) 952storetyp(type_t *tp, const char *cp, size_t len, int h)
953{ 953{
954 static unsigned int tidx = 1; /* 0 is reserved */ 954 static unsigned int tidx = 1; /* 0 is reserved */
955 thtab_t *thte; 955 thtab_t *thte;
956 char *name; 956 char *name;
957 957
958 if (tidx >= USHRT_MAX) 958 if (tidx >= USHRT_MAX)
959 errx(1, "sorry, too many types"); 959 errx(1, "sorry, too many types");
960 960
961 if (tidx == tlstlen - 1) { 961 if (tidx == tlstlen - 1) {
962 tlst = xrealloc(tlst, (tlstlen * 2) * sizeof(*tlst)); 962 tlst = xrealloc(tlst, (tlstlen * 2) * sizeof(*tlst));
963 (void)memset(tlst + tlstlen, 0, tlstlen * sizeof(*tlst)); 963 (void)memset(tlst + tlstlen, 0, tlstlen * sizeof(*tlst));
964 tlstlen *= 2; 964 tlstlen *= 2;
965 } 965 }
966 966
967 tlst[tidx] = tp; 967 tlst[tidx] = tp;
968 968
969 /* create a hash table entry */ 969 /* create a hash table entry */
@@ -992,30 +992,30 @@ thash(const char *s, size_t len) @@ -992,30 +992,30 @@ thash(const char *s, size_t len)
992 while (len-- != 0) { 992 while (len-- != 0) {
993 v = (v << sizeof(v)) + (unsigned char)*s++; 993 v = (v << sizeof(v)) + (unsigned char)*s++;
994 v ^= v >> (sizeof(v) * CHAR_BIT - sizeof(v)); 994 v ^= v >> (sizeof(v) * CHAR_BIT - sizeof(v));
995 } 995 }
996 return v % THSHSIZ2; 996 return v % THSHSIZ2;
997} 997}
998 998
999/* 999/*
1000 * Read a string enclosed by "". This string may contain quoted chars. 1000 * Read a string enclosed by "". This string may contain quoted chars.
1001 */ 1001 */
1002static char * 1002static char *
1003inpqstrg(const char *src, const char **epp) 1003inpqstrg(const char *src, const char **epp)
1004{ 1004{
1005 char *strg, *dst; 1005 char *strg, *dst;
1006 size_t slen; 1006 size_t slen;
1007 char c; 1007 char c;
1008 int v; 1008 int v;
1009 1009
1010 dst = strg = xmalloc(slen = 32); 1010 dst = strg = xmalloc(slen = 32);
1011 1011
1012 if ((c = *src++) != '"') 1012 if ((c = *src++) != '"')
1013 inperr("not quote: %c", c); 1013 inperr("not quote: %c", c);
1014 if ((c = *src++) == '\0') 1014 if ((c = *src++) == '\0')
1015 inperr("trailing data: %c", c); 1015 inperr("trailing data: %c", c);
1016 1016
1017 while (c != '"') { 1017 while (c != '"') {
1018 if (c == '\\') { 1018 if (c == '\\') {
1019 if ((c = *src++) == '\0') 1019 if ((c = *src++) == '\0')
1020 inperr("missing after \\"); 1020 inperr("missing after \\");
1021 switch (c) { 1021 switch (c) {
@@ -1075,54 +1075,54 @@ inpqstrg(const char *src, const char **e @@ -1075,54 +1075,54 @@ inpqstrg(const char *src, const char **e
1075 } 1075 }
1076 *dst = '\0'; 1076 *dst = '\0';
1077 1077
1078 *epp = src; 1078 *epp = src;
1079 return strg; 1079 return strg;
1080} 1080}
1081 1081
1082/* 1082/*
1083 * Read the name of a symbol in static memory. 1083 * Read the name of a symbol in static memory.
1084 */ 1084 */
1085static const char * 1085static const char *
1086inpname(const char *cp, const char **epp) 1086inpname(const char *cp, const char **epp)
1087{ 1087{
1088 static char *buf; 1088 static char *buf;
1089 static size_t blen = 0; 1089 static size_t blen = 0;
1090 size_t len, i; 1090 size_t len, i;
1091 char c; 1091 char c;
1092 1092
1093 len = parse_int(&cp); 1093 len = parse_int(&cp);
1094 if (len + 1 > blen) 1094 if (len + 1 > blen)
1095 buf = xrealloc(buf, blen = len + 1); 1095 buf = xrealloc(buf, blen = len + 1);
1096 for (i = 0; i < len; i++) { 1096 for (i = 0; i < len; i++) {
1097 c = *cp++; 1097 c = *cp++;
1098 if (!ch_isalnum(c) && c != '_') 1098 if (!ch_isalnum(c) && c != '_')
1099 inperr("not alnum or _: %c", c); 1099 inperr("not alnum or _: %c", c);
1100 buf[i] = c; 1100 buf[i] = c;
1101 } 1101 }
1102 buf[i] = '\0'; 1102 buf[i] = '\0';
1103 1103
1104 *epp = cp; 1104 *epp = cp;
1105 return buf; 1105 return buf;
1106} 1106}
1107 1107
1108/* 1108/*
1109 * Return the index of a file name. If the name cannot be found, create 1109 * Return the index of a file name. If the name cannot be found, create
1110 * a new entry and return the index of the newly created entry. 1110 * a new entry and return the index of the newly created entry.
1111 */ 1111 */
1112static int 1112static int
1113getfnidx(const char *fn) 1113getfnidx(const char *fn)
1114{ 1114{
1115 size_t i; 1115 size_t i;
1116 1116
1117 /* 0 is reserved */ 1117 /* 0 is reserved */
1118 for (i = 1; fnames[i] != NULL; i++) { 1118 for (i = 1; fnames[i] != NULL; i++) {
1119 if (strcmp(fnames[i], fn) == 0) 1119 if (strcmp(fnames[i], fn) == 0)
1120 return (int)i; 1120 return (int)i;
1121 } 1121 }
1122 1122
1123 if (i == nfnames - 1) { 1123 if (i == nfnames - 1) {
1124 size_t nlen = nfnames * 2; 1124 size_t nlen = nfnames * 2;
1125 fnames = xrealloc(fnames, nlen * sizeof(*fnames)); 1125 fnames = xrealloc(fnames, nlen * sizeof(*fnames));
1126 (void)memset(fnames + nfnames, 0, nfnames * sizeof(*fnames)); 1126 (void)memset(fnames + nfnames, 0, nfnames * sizeof(*fnames));
1127 flines = xrealloc(flines, nlen * sizeof(*flines)); 1127 flines = xrealloc(flines, nlen * sizeof(*flines));
1128 (void)memset(flines + nfnames, 0, nfnames * sizeof(*flines)); 1128 (void)memset(flines + nfnames, 0, nfnames * sizeof(*flines));
@@ -1130,31 +1130,31 @@ getfnidx(const char *fn) @@ -1130,31 +1130,31 @@ getfnidx(const char *fn)
1130 } 1130 }
1131 1131
1132 fnames[i] = xstrdup(fn); 1132 fnames[i] = xstrdup(fn);
1133 flines[i] = 0; 1133 flines[i] = 0;
1134 return (int)i; 1134 return (int)i;
1135} 1135}
1136 1136
1137/* 1137/*
1138 * Separate symbols with static and external linkage. 1138 * Separate symbols with static and external linkage.
1139 */ 1139 */
1140void 1140void
1141mkstatic(hte_t *hte) 1141mkstatic(hte_t *hte)
1142{ 1142{
1143 sym_t *sym1, **symp, *sym; 1143 sym_t *sym1, **symp, *sym;
1144 fcall_t **callp, *call; 1144 fcall_t **callp, *call;
1145 usym_t **usymp, *usym; 1145 usym_t **usymp, *usym;
1146 hte_t *nhte; 1146 hte_t *nhte;
1147 bool ofnd; 1147 bool ofnd;
1148 1148
1149 /* Look for first static definition */ 1149 /* Look for first static definition */
1150 for (sym1 = hte->h_syms; sym1 != NULL; sym1 = sym1->s_next) { 1150 for (sym1 = hte->h_syms; sym1 != NULL; sym1 = sym1->s_next) {
1151 if (sym1->s_static) 1151 if (sym1->s_static)
1152 break; 1152 break;
1153 } 1153 }
1154 if (sym1 == NULL) 1154 if (sym1 == NULL)
1155 return; 1155 return;
1156 1156
1157 /* Do nothing if this name is used only in one translation unit. */ 1157 /* Do nothing if this name is used only in one translation unit. */
1158 ofnd = false; 1158 ofnd = false;
1159 for (sym = hte->h_syms; sym != NULL && !ofnd; sym = sym->s_next) { 1159 for (sym = hte->h_syms; sym != NULL && !ofnd; sym = sym->s_next) {
1160 if (sym->s_pos.p_src != sym1->s_pos.p_src) 1160 if (sym->s_pos.p_src != sym1->s_pos.p_src)

cvs diff -r1.109 -r1.110 src/usr.bin/xlint/xlint/xlint.c (expand / switch to unified diff)

--- src/usr.bin/xlint/xlint/xlint.c 2023/02/19 19:27:02 1.109
+++ src/usr.bin/xlint/xlint/xlint.c 2023/06/09 13:03:49 1.110
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: xlint.c,v 1.109 2023/02/19 19:27:02 rillig Exp $ */ 1/* $NetBSD: xlint.c,v 1.110 2023/06/09 13:03:49 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. 4 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
5 * Copyright (c) 1994, 1995 Jochen Pohl 5 * Copyright (c) 1994, 1995 Jochen Pohl
6 * All Rights Reserved. 6 * All Rights Reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
@@ -28,27 +28,27 @@ @@ -28,27 +28,27 @@
28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */ 33 */
34 34
35#if HAVE_NBTOOL_CONFIG_H 35#if HAVE_NBTOOL_CONFIG_H
36#include "nbtool_config.h" 36#include "nbtool_config.h"
37#endif 37#endif
38 38
39#include <sys/cdefs.h> 39#include <sys/cdefs.h>
40#if defined(__RCSID) 40#if defined(__RCSID)
41__RCSID("$NetBSD: xlint.c,v 1.109 2023/02/19 19:27:02 rillig Exp $"); 41__RCSID("$NetBSD: xlint.c,v 1.110 2023/06/09 13:03:49 rillig Exp $");
42#endif 42#endif
43 43
44#include <sys/param.h> 44#include <sys/param.h>
45#include <sys/wait.h> 45#include <sys/wait.h>
46#include <sys/stat.h> 46#include <sys/stat.h>
47#include <sys/utsname.h> 47#include <sys/utsname.h>
48#include <errno.h> 48#include <errno.h>
49#include <stdarg.h> 49#include <stdarg.h>
50#include <fcntl.h> 50#include <fcntl.h>
51#include <paths.h> 51#include <paths.h>
52#include <signal.h> 52#include <signal.h>
53#include <stdio.h> 53#include <stdio.h>
54#include <stdlib.h> 54#include <stdlib.h>
@@ -619,30 +619,30 @@ main(int argc, char *argv[]) @@ -619,30 +619,30 @@ main(int argc, char *argv[])
619 lint2.outlib = NULL; 619 lint2.outlib = NULL;
620 620
621 terminate(0); 621 terminate(0);
622 /* NOTREACHED */ 622 /* NOTREACHED */
623} 623}
624 624
625/* 625/*
626 * Read a file name from the command line 626 * Read a file name from the command line
627 * and pass it through lint1 if it is a C source. 627 * and pass it through lint1 if it is a C source.
628 */ 628 */
629static void 629static void
630handle_filename(const char *name) 630handle_filename(const char *name)
631{ 631{
632 const char *bn, *suff; 632 const char *bn, *suff;
633 char *ofn; 633 char *ofn;
634 size_t len; 634 size_t len;
635 int fd; 635 int fd;
636 636
637 bn = lbasename(name, '/'); 637 bn = lbasename(name, '/');
638 suff = lbasename(bn, '.'); 638 suff = lbasename(bn, '.');
639 639
640 if (strcmp(suff, "ln") == 0) { 640 if (strcmp(suff, "ln") == 0) {
641 /* only for lint2 */ 641 /* only for lint2 */
642 if (!iflag) 642 if (!iflag)
643 list_add(&lint2.infiles, name); 643 list_add(&lint2.infiles, name);
644 return; 644 return;
645 } 645 }
646 646
647 if (strcmp(suff, "c") != 0 && 647 if (strcmp(suff, "c") != 0 &&
648 (strncmp(bn, "llib-l", 6) != 0 || bn != suff)) { 648 (strncmp(bn, "llib-l", 6) != 0 || bn != suff)) {
@@ -706,27 +706,27 @@ needs_quoting: @@ -706,27 +706,27 @@ needs_quoting:
706 (void)putchar('\''); 706 (void)putchar('\'');
707 for (const char *p = s; *p != '\0'; p++) { 707 for (const char *p = s; *p != '\0'; p++) {
708 if (*p == '\'') 708 if (*p == '\'')
709 (void)printf("'\\''"); 709 (void)printf("'\\''");
710 else 710 else
711 (void)putchar(*p); 711 (void)putchar(*p);
712 } 712 }
713 (void)putchar('\''); 713 (void)putchar('\'');
714} 714}
715 715
716static void 716static void
717run_child(const char *path, list *args, const char *crfn, int fdout) 717run_child(const char *path, list *args, const char *crfn, int fdout)
718{ 718{
719 int status, rv, signo; 719 int status, rv, signo;
720 720
721 if (Vflag) { 721 if (Vflag) {
722 print_sh_quoted(args->items[0]); 722 print_sh_quoted(args->items[0]);
723 for (size_t i = 1; i < args->len - 1; i++) { 723 for (size_t i = 1; i < args->len - 1; i++) {
724 (void)printf(" "); 724 (void)printf(" ");
725 print_sh_quoted(args->items[i]); 725 print_sh_quoted(args->items[i]);
726 } 726 }
727 (void)printf("\n"); 727 (void)printf("\n");
728 } 728 }
729 729
730 currfn = crfn; 730 currfn = crfn;
731 731
732 (void)fflush(stdout); 732 (void)fflush(stdout);
@@ -799,43 +799,43 @@ found: @@ -799,43 +799,43 @@ found:
799} 799}
800 800
801static void 801static void
802find_libs(const list *l) 802find_libs(const list *l)
803{ 803{
804 804
805 for (size_t i = 0; i < l->len; i++) 805 for (size_t i = 0; i < l->len; i++)
806 find_lib(l->items[i]); 806 find_lib(l->items[i]);
807} 807}
808 808
809static bool 809static bool
810file_is_readable(const char *path) 810file_is_readable(const char *path)
811{ 811{
812 struct stat sbuf; 812 struct stat sbuf;
813 813
814 if (stat(path, &sbuf) == -1) 814 if (stat(path, &sbuf) == -1)
815 return false; 815 return false;
816 if (!S_ISREG(sbuf.st_mode)) 816 if (!S_ISREG(sbuf.st_mode))
817 return false; 817 return false;
818 if (access(path, R_OK) == -1) 818 if (access(path, R_OK) == -1)
819 return false; 819 return false;
820 return true; 820 return true;
821} 821}
822 822
823static void 823static void
824cat(const list *srcs, const char *dest) 824cat(const list *srcs, const char *dest)
825{ 825{
826 int ifd, ofd; 826 int ifd, ofd;
827 ssize_t rlen; 827 ssize_t rlen;
828 char buf[0x4000]; 828 char buf[0x4000];
829 829
830 if ((ofd = open(dest, O_WRONLY | O_CREAT | O_TRUNC, 0666)) == -1) { 830 if ((ofd = open(dest, O_WRONLY | O_CREAT | O_TRUNC, 0666)) == -1) {
831 warn("cannot open %s", dest); 831 warn("cannot open %s", dest);
832 terminate(-1); 832 terminate(-1);
833 } 833 }
834 834
835 for (size_t i = 0; i < srcs->len; i++) { 835 for (size_t i = 0; i < srcs->len; i++) {
836 const char *src = srcs->items[i]; 836 const char *src = srcs->items[i];
837 if ((ifd = open(src, O_RDONLY)) == -1) { 837 if ((ifd = open(src, O_RDONLY)) == -1) {
838 warn("cannot open %s", src); 838 warn("cannot open %s", src);
839 terminate(-1); 839 terminate(-1);
840 } 840 }
841 do { 841 do {