lint: indent local variables consistently No binary change.diff -r1.18 -r1.19 src/usr.bin/xlint/common/emit.c
(rillig)
--- 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 */ | |
49 | static const char *loname; | 49 | static const char *loname; | |
50 | static FILE *lout; | 50 | static FILE *lout; | |
51 | 51 | |||
52 | /* output buffer data */ | 52 | /* output buffer data */ | |
53 | static ob_t ob; | 53 | static 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 | */ | |
106 | void | 106 | void | |
107 | outclr(void) | 107 | outclr(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 | /* |
--- 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 | |
128 | void | 128 | void | |
129 | inittyp(void) | 129 | inittyp(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 | } |
--- 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 | |||
51 | const char unnamed[] = "<unnamed>"; | 51 | const char unnamed[] = "<unnamed>"; | |
52 | 52 | |||
53 | /* shared type structures for arithmetic types and void */ | 53 | /* shared type structures for arithmetic types and void */ | |
54 | static type_t typetab[NTSPEC]; | 54 | static type_t typetab[NTSPEC]; | |
@@ -142,38 +142,38 @@ initdecl(void) | @@ -142,38 +142,38 @@ initdecl(void) | |||
142 | * else). | 142 | * else). | |
143 | */ | 143 | */ | |
144 | type_t * | 144 | type_t * | |
145 | gettyp(tspec_t t) | 145 | gettyp(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 | |||
152 | type_t * | 152 | type_t * | |
153 | block_dup_type(const type_t *tp) | 153 | block_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. */ | |
163 | type_t * | 163 | type_t * | |
164 | expr_dup_type(const type_t *tp) | 164 | expr_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 | */ | |
179 | type_t * | 179 | type_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 | */ | |
204 | bool | 204 | bool | |
205 | is_incomplete(const type_t *tp) | 205 | is_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 | */ | |
259 | void | 259 | void | |
260 | dcs_add_type(type_t *tp) | 260 | dcs_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 | */ | |
397 | static type_t * | 397 | static type_t * | |
398 | typedef_error(type_t *td, tspec_t t) | 398 | typedef_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 | */ | |
464 | static void | 464 | static void | |
465 | set_first_typedef(type_t *tp, sym_t *sym) | 465 | set_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 | |||
478 | static unsigned int | 478 | static unsigned int | |
479 | bit_field_size(sym_t **mem) | 479 | bit_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 | */ | |
572 | void | 572 | void | |
573 | begin_declaration_level(declaration_kind dk) | 573 | begin_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 | */ | |
589 | void | 589 | void | |
590 | end_declaration_level(void) | 590 | end_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 | */ | |
726 | static void | 726 | static void | |
727 | dcs_merge_declaration_specifiers(void) | 727 | dcs_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 | */ | |
917 | sym_t * | 917 | sym_t * | |
918 | concat_lists(sym_t *l1, sym_t *l2) | 918 | concat_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 | */ | |
939 | void | 939 | void | |
940 | check_type(sym_t *sym) | 940 | check_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 | */ | |
1109 | sym_t * | 1109 | sym_t * | |
1110 | declarator_1_struct_union(sym_t *dsym) | 1110 | declarator_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 | |||
1457 | static sym_t * | 1457 | static sym_t * | |
1458 | new_style_function(sym_t *args) | 1458 | new_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 | */ | |
1541 | sym_t * | 1541 | sym_t * | |
1542 | declarator_name(sym_t *sym) | 1542 | declarator_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 | */ | |
1669 | type_t * | 1669 | type_t * | |
1670 | make_tag_type(sym_t *tag, tspec_t kind, bool decl, bool semi) | 1670 | make_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 | */ | |
2294 | static bool | 2294 | static bool | |
2295 | matches_no_arg_function(const type_t *tp, bool *dowarn) | 2295 | matches_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 | */ | |
2318 | static bool | 2318 | static bool | |
2319 | check_old_style_definition(sym_t *rdsym, sym_t *dsym) | 2319 | check_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 | */ | |
2623 | static bool | 2623 | static bool | |
2624 | check_prototype_declaration(sym_t *arg, sym_t *parg) | 2624 | check_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 | */ | |
2859 | static bool | 2859 | static bool | |
2860 | check_init(sym_t *sym) | 2860 | check_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 | */ | |
2891 | sym_t * | 2891 | sym_t * | |
2892 | abstract_name(void) | 2892 | abstract_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 | |||
3071 | static void | 3071 | static void | |
3072 | check_variable_usage(bool novar, sym_t *sym) | 3072 | check_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 | */ | |
3196 | void | 3196 | void | |
3197 | check_global_symbols(void) | 3197 | check_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 | */ | |
3338 | int | 3338 | int | |
3339 | to_int_constant(tnode_t *tn, bool required) | 3339 | to_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) |
--- 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 | |||
46 | static void outtt(sym_t *, sym_t *); | 46 | static void outtt(sym_t *, sym_t *); | |
47 | static void outfstrg(strg_t *); | 47 | static 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 | */ | |
92 | void | 92 | void | |
93 | outtype(const type_t *tp) | 93 | outtype(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 | */ | |
351 | void | 351 | void | |
352 | outcall(const tnode_t *tn, bool retval_used, bool retval_discarded) | 352 | outcall(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 | */ | |
488 | static void | 488 | static void | |
489 | outfstrg(strg_t *strg) | 489 | outfstrg(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++; |
--- 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 */ | |
51 | int nerr; | 51 | int 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 | |||
519 | static void | 519 | static void | |
520 | verror_at(int msgid, const pos_t *pos, va_list ap) | 520 | verror_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 | |||
535 | static void | 535 | static void | |
536 | vwarning_at(int msgid, const pos_t *pos, va_list ap) | 536 | vwarning_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 | |||
572 | void | 572 | void | |
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 | |||
582 | void | 582 | void | |
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 | |||
592 | void | 592 | void | |
593 | assert_failed(const char *file, int line, const char *func, const char *cond) | 593 | assert_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 | |||
620 | void | 620 | void | |
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 | |||
630 | void | 630 | void | |
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 | |||
640 | void | 640 | void | |
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 | |||
650 | void | 650 | void | |
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 | |||
667 | void | 667 | void | |
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 | |||
680 | bool | 680 | bool | |
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 |
--- 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 | */ | |
53 | sym_t *funcsym; | 53 | sym_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 | */ | |
220 | void | 220 | void | |
221 | begin_function(sym_t *fsym) | 221 | begin_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 | */ | |
370 | void | 370 | void | |
371 | end_function(void) | 371 | end_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 | |||
485 | static void | 485 | static void | |
486 | check_case_label(tnode_t *tn, control_statement *cs) | 486 | check_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 | */ | |
687 | void | 687 | void | |
688 | switch1(tnode_t *tn) | 688 | switch1(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 | */ | |
743 | void | 743 | void | |
744 | switch2(void) | 744 | switch2(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 | */ | |
946 | void | 946 | void | |
947 | for2(void) | 947 | for2(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 |
--- 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 | */ | |
405 | static int | 405 | static int | |
406 | read_byte(void) | 406 | read_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 | |||
419 | static int | 419 | static int | |
420 | lex_keyword(sym_t *sym) | 420 | lex_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 "'". */ | |
847 | int | 847 | int | |
848 | lex_character_constant(void) | 848 | lex_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 | */ | |
889 | int | 889 | int | |
890 | lex_wide_character_constant(void) | 890 | lex_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 | */ | |
969 | void | 969 | void | |
970 | lex_directive(const char *yytext) | 970 | lex_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) | |||
1165 | void | 1165 | void | |
1166 | clear_warn_flags(void) | 1166 | clear_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 | |||
1174 | int | 1174 | int | |
1175 | lex_string(void) | 1175 | lex_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 | |||
1204 | int | 1204 | int | |
1205 | lex_wide_string(void) | 1205 | lex_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 | */ | |
1403 | void | 1403 | void | |
1404 | rmsyms(sym_t *syms) | 1404 | rmsyms(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 | |||
1442 | clean_up_after_error(void) | 1442 | clean_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. */ | |
1452 | sym_t * | 1452 | sym_t * | |
1453 | pushdown(const sym_t *sym) | 1453 | pushdown(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; |
--- 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 | |||
53 | typedef struct integer_constraints { | 53 | typedef 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'. */ | |
315 | type_t * | 315 | type_t * | |
316 | block_derive_type(type_t *tp, tspec_t t) | 316 | block_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 | */ | |
330 | type_t * | 330 | type_t * | |
331 | expr_derive_type(type_t *tp, tspec_t t) | 331 | expr_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 | */ | |
344 | static tnode_t * | 344 | static tnode_t * | |
345 | new_tnode(op_t op, bool sys, type_t *type, tnode_t *ln, tnode_t *rn) | 345 | new_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 | */ | |
368 | tnode_t * | 368 | tnode_t * | |
369 | build_constant(type_t *tp, val_t *v) | 369 | build_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 | |||
384 | static tnode_t * | 384 | static tnode_t * | |
385 | build_integer_constant(tspec_t t, int64_t q) | 385 | build_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 | |||
398 | static void | 398 | static void | |
399 | fallback_symbol(sym_t *sym) | 399 | fallback_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). */ | |
489 | tnode_t * | 489 | tnode_t * | |
490 | build_name(sym_t *sym, bool is_funcname) | 490 | build_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 | |||
527 | tnode_t * | 527 | tnode_t * | |
528 | build_string(strg_t *strg) | 528 | build_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 | |||
579 | is_out_of_char_range(const tnode_t *tn) | 579 | is_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 | */ | |
589 | static void | 589 | static void | |
590 | check_integer_comparison(op_t op, tnode_t *ln, tnode_t *rn) | 590 | check_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 | */ | |
753 | static tnode_t * | 753 | static tnode_t * | |
754 | build_address(bool sys, tnode_t *tn, bool noign) | 754 | build_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 | */ | |
932 | static tnode_t * | 932 | static tnode_t * | |
933 | build_struct_access(op_t op, bool sys, tnode_t *ln, tnode_t *rn) | 933 | build_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 | */ | |
1041 | static tnode_t * | 1041 | static tnode_t * | |
1042 | build_prepost_incdec(op_t op, bool sys, tnode_t *ln) | 1042 | build_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". */ | |
1213 | static tnode_t * | 1213 | static tnode_t * | |
1214 | build_colon(bool sys, tnode_t *ln, tnode_t *rn) | 1214 | build_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='). */ | |
1328 | static tnode_t * | 1328 | static tnode_t * | |
1329 | build_assignment(op_t op, bool sys, tnode_t *ln, tnode_t *rn) | 1329 | build_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 | */ | |
1400 | static tnode_t * | 1400 | static tnode_t * | |
1401 | build_real_imag(op_t op, bool sys, tnode_t *ln) | 1401 | build_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 | */ | |
1511 | static tnode_t * | 1511 | static tnode_t * | |
1512 | fold_bool(tnode_t *tn) | 1512 | fold_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 | */ | |
1576 | static tnode_t * | 1576 | static tnode_t * | |
1577 | fold_float(tnode_t *tn) | 1577 | fold_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 | */ | |
1669 | tnode_t * | 1669 | tnode_t * | |
1670 | build_binary(tnode_t *ln, op_t op, bool sys, tnode_t *rn) | 1670 | build_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 | */ | |
1896 | static sym_t * | 1896 | static sym_t * | |
1897 | struct_or_union_member(tnode_t *tn, op_t op, sym_t *msym) | 1897 | struct_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 | |||
2003 | tnode_t * | 2003 | tnode_t * | |
2004 | build_member_access(tnode_t *ln, op_t op, bool sys, sbuf_t *member) | 2004 | build_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 | */ | |
2868 | static bool | 2868 | static bool | |
2869 | check_assign_types_compatible(op_t op, int arg, | 2869 | check_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. */ | |
3188 | bool | 3188 | bool | |
3189 | typeok(op_t op, int arg, const tnode_t *ln, const tnode_t *rn) | 3189 | typeok(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 | */ | |
4138 | tnode_t * | 4138 | tnode_t * | |
4139 | cast(tnode_t *tn, type_t *tp) | 4139 | cast(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 | */ | |
4228 | static tnode_t * | 4228 | static tnode_t * | |
4229 | check_prototype_argument( | 4229 | check_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 | */ | |
4251 | static tnode_t * | 4251 | static tnode_t * | |
4252 | check_function_arguments(type_t *ftp, tnode_t *args) | 4252 | check_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 | */ | |
4324 | tnode_t * | 4324 | tnode_t * | |
4325 | build_function_call(tnode_t *func, bool sys, tnode_t *args) | 4325 | build_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 | */ | |
4738 | bool | 4738 | bool | |
4739 | constant_addr(const tnode_t *tn, const sym_t **symp, ptrdiff_t *offsp) | 4739 | constant_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)) |
--- 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 | |||
51 | static void check_used_not_defined(const hte_t *); | 51 | static void check_used_not_defined(const hte_t *); | |
52 | static void check_defined_not_used(const hte_t *); | 52 | static void check_defined_not_used(const hte_t *); | |
53 | static void check_declared_not_used_or_defined(const hte_t *); | 53 | static void check_declared_not_used_or_defined(const hte_t *); | |
54 | static void check_multiple_definitions(const hte_t *); | 54 | static 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 | |||
66 | static void too_few_arguments(const hte_t *, fcall_t *); | 66 | static void too_few_arguments(const hte_t *, fcall_t *); | |
67 | static void too_many_arguments(const hte_t *, fcall_t *); | 67 | static void too_many_arguments(const hte_t *, fcall_t *); | |
68 | static bool types_compatible(type_t *, type_t *, bool, bool, bool, bool *); | 68 | static bool types_compatible(type_t *, type_t *, bool, bool, bool, bool *); | |
69 | static bool prototypes_compatible(type_t *, type_t *, bool *); | 69 | static bool prototypes_compatible(type_t *, type_t *, bool *); | |
70 | static bool matches_no_arg_function(type_t *, bool *); | 70 | static 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 | */ | |
76 | void | 76 | void | |
77 | mark_main_as_used(void) | 77 | mark_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 | */ | |
88 | void | 88 | void | |
89 | check_name(const hte_t *hte) | 89 | check_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 | */ | |
133 | static void | 133 | static void | |
134 | check_used_not_defined(const hte_t *hte) | 134 | check_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 | */ | |
154 | static void | 154 | static void | |
155 | check_defined_not_used(const hte_t *hte) | 155 | check_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 | */ | |
175 | static void | 175 | static void | |
176 | check_declared_not_used_or_defined(const hte_t *hte) | 176 | check_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 | */ | |
197 | static void | 197 | static void | |
198 | check_multiple_definitions(const hte_t *hte) | 198 | check_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 | */ | |
236 | static void | 236 | static void | |
237 | chkvtui(const hte_t *hte, sym_t *def, sym_t *decl) | 237 | chkvtui(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 | */ | |
298 | static void | 298 | static void | |
299 | chkvtdi(const hte_t *hte, sym_t *def, sym_t *decl) | 299 | chkvtdi(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 | */ | |
340 | static void | 340 | static void | |
341 | chkfaui(const hte_t *hte, sym_t *def, sym_t *decl) | 341 | chkfaui(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 | */ | |
452 | static void | 452 | static void | |
453 | chkau(const hte_t *hte, int n, sym_t *def, sym_t *decl, pos_t *pos1p, | 453 | chkau(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 | */ | |
607 | static void | 607 | static void | |
608 | printflike(const hte_t *hte, fcall_t *call, int n, const char *fmt, type_t **ap) | 608 | printflike(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 | */ | |
832 | static void | 832 | static void | |
833 | scanflike(const hte_t *hte, fcall_t *call, int n, const char *fmt, type_t **ap) | 833 | scanflike(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 | */ | |
1073 | static void | 1073 | static void | |
1074 | check_return_values(const hte_t *hte, sym_t *def) | 1074 | check_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 | */ | |
1127 | static void | 1127 | static void | |
1128 | check_argument_declarations(const hte_t *hte, sym_t *def, sym_t *decl) | 1128 | check_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 | */ | |
1209 | static bool | 1209 | static bool | |
1210 | types_compatible(type_t *tp1, type_t *tp2, | 1210 | types_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 | */ | |
1336 | static bool | 1336 | static bool | |
1337 | prototypes_compatible(type_t *tp1, type_t *tp2, bool *dowarn) | 1337 | prototypes_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 | */ | |
1370 | static bool | 1370 | static bool | |
1371 | matches_no_arg_function(type_t *tp, bool *dowarn) | 1371 | matches_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 | } |
--- 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 | |||
42 | static void outtype(type_t *); | 42 | static void outtype(type_t *); | |
43 | static void outdef(hte_t *, sym_t *); | 43 | static void outdef(hte_t *, sym_t *); | |
44 | static void dumpname(hte_t *); | 44 | static void dumpname(hte_t *); | |
45 | static void outfiles(void); | 45 | static void outfiles(void); | |
46 | 46 | |||
47 | /* | 47 | /* | |
48 | * Write type into the output buffer. | 48 | * Write type into the output buffer. | |
49 | */ | 49 | */ | |
50 | static void | 50 | static void | |
51 | outtype(type_t *tp) | 51 | outtype(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 | */ | |
166 | static void | 166 | static void | |
167 | dumpname(hte_t *hte) | 167 | dumpname(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) { |
--- 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 | */ | |
87 | hte_t * | 87 | hte_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 | |||
150 | void | 150 | void | |
151 | symtab_init(void) | 151 | symtab_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 | */ | |
159 | void | 159 | void | |
160 | symtab_forall(void (*action)(hte_t *)) | 160 | symtab_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. */ | |
173 | void | 173 | void | |
174 | symtab_forall_sorted(void (*action)(hte_t *)) | 174 | symtab_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 | */ | |
196 | void | 196 | void | |
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 | } |
--- 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 */ | |
51 | bool xflag; | 51 | bool xflag; | |
52 | 52 | |||
53 | /* | 53 | /* | |
@@ -87,29 +87,29 @@ bool Fflag; | @@ -87,29 +87,29 @@ bool Fflag; | |||
87 | static const char **libs; | 87 | static const char **libs; | |
88 | 88 | |||
89 | static void usage(void) __attribute__((noreturn)); | 89 | static void usage(void) __attribute__((noreturn)); | |
90 | 90 | |||
91 | static void | 91 | static void | |
92 | check_name_non_const(hte_t *hte) | 92 | check_name_non_const(hte_t *hte) | |
93 | { | 93 | { | |
94 | check_name(hte); | 94 | check_name(hte); | |
95 | } | 95 | } | |
96 | 96 | |||
97 | int | 97 | int | |
98 | main(int argc, char *argv[]) | 98 | main(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': |
--- 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 | |||
49 | static const char *msgs[] = { | 49 | static 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 | |||
71 | void | 71 | void | |
72 | msg(int n, ...) | 72 | msg(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 | */ | |
87 | static const char * | 87 | static 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 | */ | |
104 | const char * | 104 | const char * | |
105 | mkpos(pos_t *posp) | 105 | mkpos(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 |
--- 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 | |||
214 | void | 214 | void | |
215 | readfile(const char *name) | 215 | readfile(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 | */ | |
315 | static void | 315 | static void | |
316 | funccall(pos_t pos, const char *cp) | 316 | funccall(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 | |||
332 | again: | 332 | again: | |
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 | */ | |
468 | static void | 468 | static void | |
469 | decldef(pos_t pos, const char *cp) | 469 | decldef(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 | */ | |
564 | static void | 564 | static void | |
565 | usedsym(pos_t pos, const char *cp) | 565 | usedsym(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 | */ | |
651 | static unsigned short | 651 | static unsigned short | |
652 | inptype(const char *cp, const char **epp) | 652 | inptype(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 | */ | |
753 | static size_t | 753 | static size_t | |
754 | gettlen(const char *cp, const char **epp) | 754 | gettlen(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 | */ | |
932 | static unsigned short | 932 | static unsigned short | |
933 | findtype(const char *cp, size_t len, int h) | 933 | findtype(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 | */ | |
951 | static unsigned short | 951 | static unsigned short | |
952 | storetyp(type_t *tp, const char *cp, size_t len, int h) | 952 | storetyp(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 | */ | |
1002 | static char * | 1002 | static char * | |
1003 | inpqstrg(const char *src, const char **epp) | 1003 | inpqstrg(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 | */ | |
1085 | static const char * | 1085 | static const char * | |
1086 | inpname(const char *cp, const char **epp) | 1086 | inpname(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 | */ | |
1112 | static int | 1112 | static int | |
1113 | getfnidx(const char *fn) | 1113 | getfnidx(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 | */ | |
1140 | void | 1140 | void | |
1141 | mkstatic(hte_t *hte) | 1141 | mkstatic(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) |
--- 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 | */ | |
629 | static void | 629 | static void | |
630 | handle_filename(const char *name) | 630 | handle_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 | |||
716 | static void | 716 | static void | |
717 | run_child(const char *path, list *args, const char *crfn, int fdout) | 717 | run_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 | |||
801 | static void | 801 | static void | |
802 | find_libs(const list *l) | 802 | find_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 | |||
809 | static bool | 809 | static bool | |
810 | file_is_readable(const char *path) | 810 | file_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 | |||
823 | static void | 823 | static void | |
824 | cat(const list *srcs, const char *dest) | 824 | cat(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 { |