Sat Jul 29 07:26:53 2023 UTC ()
lint: constify


(rillig)
diff -r1.364 -r1.365 src/usr.bin/xlint/lint1/decl.c
diff -r1.200 -r1.201 src/usr.bin/xlint/lint1/externs1.h

cvs diff -r1.364 -r1.365 src/usr.bin/xlint/lint1/decl.c (switch to unified diff)

--- src/usr.bin/xlint/lint1/decl.c 2023/07/29 07:03:19 1.364
+++ src/usr.bin/xlint/lint1/decl.c 2023/07/29 07:26:53 1.365
@@ -1,1040 +1,1040 @@ @@ -1,1040 +1,1040 @@
1/* $NetBSD: decl.c,v 1.364 2023/07/29 07:03:19 rillig Exp $ */ 1/* $NetBSD: decl.c,v 1.365 2023/07/29 07:26:53 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
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement: 17 * must display the following acknowledgement:
18 * This product includes software developed by Jochen Pohl for 18 * This product includes software developed by Jochen Pohl for
19 * The NetBSD Project. 19 * The NetBSD Project.
20 * 4. The name of the author may not be used to endorse or promote products 20 * 4. The name of the author may not be used to endorse or promote products
21 * derived from this software without specific prior written permission. 21 * derived from this software without specific prior written permission.
22 * 22 *
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
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#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.364 2023/07/29 07:03:19 rillig Exp $"); 41__RCSID("$NetBSD: decl.c,v 1.365 2023/07/29 07:26:53 rillig Exp $");
42#endif 42#endif
43 43
44#include <sys/param.h> 44#include <sys/param.h>
45#include <limits.h> 45#include <limits.h>
46#include <stdlib.h> 46#include <stdlib.h>
47#include <string.h> 47#include <string.h>
48 48
49#include "lint1.h" 49#include "lint1.h"
50 50
51const char unnamed[] = "<unnamed>"; 51const char unnamed[] = "<unnamed>";
52 52
53/* shared type structures for arithmetic types and void */ 53/* shared type structures for arithmetic types and void */
54static type_t typetab[NTSPEC]; 54static type_t typetab[NTSPEC];
55 55
56/* value of next enumerator during declaration of enum types */ 56/* value of next enumerator during declaration of enum types */
57int enumval; 57int enumval;
58 58
59/* 59/*
60 * Points to the innermost element of a stack that contains information about 60 * Points to the innermost element of a stack that contains information about
61 * nested declarations, such as struct declarations, function prototypes, 61 * nested declarations, such as struct declarations, function prototypes,
62 * local variables. 62 * local variables.
63 */ 63 */
64decl_level *dcs; 64decl_level *dcs;
65 65
66 66
67/* 67/*
68 * initializes all global vars used in declarations 68 * initializes all global vars used in declarations
69 */ 69 */
70void 70void
71initdecl(void) 71initdecl(void)
72{ 72{
73 73
74 /* declaration stack */ 74 /* declaration stack */
75 dcs = xcalloc(1, sizeof(*dcs)); 75 dcs = xcalloc(1, sizeof(*dcs));
76 dcs->d_kind = DLK_EXTERN; 76 dcs->d_kind = DLK_EXTERN;
77 dcs->d_last_dlsym = &dcs->d_first_dlsym; 77 dcs->d_last_dlsym = &dcs->d_first_dlsym;
78 78
79 if (!pflag) { 79 if (!pflag) {
80 for (size_t i = 0; i < NTSPEC; i++) { 80 for (size_t i = 0; i < NTSPEC; i++) {
81 if (ttab[i].tt_rank_kind != RK_NONE) 81 if (ttab[i].tt_rank_kind != RK_NONE)
82 ttab[i].tt_rank_value = 82 ttab[i].tt_rank_value =
83 ttab[i].tt_size_in_bits; 83 ttab[i].tt_size_in_bits;
84 } 84 }
85 ttab[BOOL].tt_rank_value = 1; 85 ttab[BOOL].tt_rank_value = 1;
86 } 86 }
87 87
88 if (Tflag) { 88 if (Tflag) {
89 ttab[BOOL].tt_is_integer = false; 89 ttab[BOOL].tt_is_integer = false;
90 ttab[BOOL].tt_is_uinteger = false; 90 ttab[BOOL].tt_is_uinteger = false;
91 ttab[BOOL].tt_is_arithmetic = false; 91 ttab[BOOL].tt_is_arithmetic = false;
92 } 92 }
93 93
94 /* struct, union, enum, ptr, array and func are not shared. */ 94 /* struct, union, enum, ptr, array and func are not shared. */
95 for (int i = (int)SIGNED; i < (int)STRUCT; i++) 95 for (int i = (int)SIGNED; i < (int)STRUCT; i++)
96 typetab[i].t_tspec = (tspec_t)i; 96 typetab[i].t_tspec = (tspec_t)i;
97} 97}
98 98
99/* 99/*
100 * Returns a shared type structure for arithmetic types and void. 100 * Returns a shared type structure for arithmetic types and void.
101 * 101 *
102 * It's important to duplicate this structure using block_dup_type or 102 * It's important to duplicate this structure using block_dup_type or
103 * expr_dup_type if it is to be modified (adding qualifiers or anything 103 * expr_dup_type if it is to be modified (adding qualifiers or anything
104 * else). 104 * else).
105 */ 105 */
106type_t * 106type_t *
107gettyp(tspec_t t) 107gettyp(tspec_t t)
108{ 108{
109 109
110 lint_assert((int)t < (int)STRUCT); 110 lint_assert((int)t < (int)STRUCT);
111 /* TODO: make the return type 'const' */ 111 /* TODO: make the return type 'const' */
112 return &typetab[t]; 112 return &typetab[t];
113} 113}
114 114
115type_t * 115type_t *
116block_dup_type(const type_t *tp) 116block_dup_type(const type_t *tp)
117{ 117{
118 118
119 type_t *ntp = block_zero_alloc(sizeof(*ntp), "type"); 119 type_t *ntp = block_zero_alloc(sizeof(*ntp), "type");
120 *ntp = *tp; 120 *ntp = *tp;
121 return ntp; 121 return ntp;
122} 122}
123 123
124/* Duplicate a type, free the allocated memory after the expression. */ 124/* Duplicate a type, free the allocated memory after the expression. */
125type_t * 125type_t *
126expr_dup_type(const type_t *tp) 126expr_dup_type(const type_t *tp)
127{ 127{
128 128
129 type_t *ntp = expr_zero_alloc(sizeof(*ntp), "type"); 129 type_t *ntp = expr_zero_alloc(sizeof(*ntp), "type");
130 *ntp = *tp; 130 *ntp = *tp;
131 return ntp; 131 return ntp;
132} 132}
133 133
134/* 134/*
135 * Return the unqualified version of the type. The returned type is freed at 135 * Return the unqualified version of the type. The returned type is freed at
136 * the end of the current expression. 136 * the end of the current expression.
137 * 137 *
138 * See C99 6.2.5p25. 138 * See C99 6.2.5p25.
139 */ 139 */
140type_t * 140type_t *
141expr_unqualified_type(const type_t *tp) 141expr_unqualified_type(const type_t *tp)
142{ 142{
143 143
144 type_t *ntp = expr_zero_alloc(sizeof(*ntp), "type"); 144 type_t *ntp = expr_zero_alloc(sizeof(*ntp), "type");
145 *ntp = *tp; 145 *ntp = *tp;
146 ntp->t_const = false; 146 ntp->t_const = false;
147 ntp->t_volatile = false; 147 ntp->t_volatile = false;
148 148
149 /* 149 /*
150 * In case of a struct or union type, the members should lose their 150 * In case of a struct or union type, the members should lose their
151 * qualifiers as well, but that would require a deep copy of the 151 * qualifiers as well, but that would require a deep copy of the
152 * struct or union type. This in turn would defeat the type 152 * struct or union type. This in turn would defeat the type
153 * comparison in types_compatible, which simply tests whether 153 * comparison in types_compatible, which simply tests whether
154 * tp1->t_sou == tp2->t_sou. 154 * tp1->t_sou == tp2->t_sou.
155 */ 155 */
156 156
157 return ntp; 157 return ntp;
158} 158}
159 159
160/* 160/*
161 * Returns whether the argument is void or an incomplete array, struct, union 161 * Returns whether the argument is void or an incomplete array, struct, union
162 * or enum type. 162 * or enum type.
163 */ 163 */
164bool 164bool
165is_incomplete(const type_t *tp) 165is_incomplete(const type_t *tp)
166{ 166{
167 tspec_t t = tp->t_tspec; 167 tspec_t t = tp->t_tspec;
168 168
169 if (t == VOID) 169 if (t == VOID)
170 return true; 170 return true;
171 if (t == ARRAY) 171 if (t == ARRAY)
172 return tp->t_incomplete_array; 172 return tp->t_incomplete_array;
173 if (is_struct_or_union(t)) 173 if (is_struct_or_union(t))
174 return tp->t_sou->sou_incomplete; 174 return tp->t_sou->sou_incomplete;
175 if (t == ENUM) 175 if (t == ENUM)
176 return tp->t_enum->en_incomplete; 176 return tp->t_enum->en_incomplete;
177 return false; 177 return false;
178} 178}
179 179
180void 180void
181dcs_add_function_specifier(function_specifier fs) 181dcs_add_function_specifier(function_specifier fs)
182{ 182{
183 debug_step("%s: %s", __func__, function_specifier_name(fs)); 183 debug_step("%s: %s", __func__, function_specifier_name(fs));
184 if (fs == FS_INLINE) { 184 if (fs == FS_INLINE) {
185 if (dcs->d_inline) 185 if (dcs->d_inline)
186 /* duplicate '%s' */ 186 /* duplicate '%s' */
187 warning(10, "inline"); 187 warning(10, "inline");
188 dcs->d_inline = true; 188 dcs->d_inline = true;
189 } 189 }
190} 190}
191 191
192/* 192/*
193 * Remember the storage class of the current declaration and detect multiple 193 * Remember the storage class of the current declaration and detect multiple
194 * storage classes. 194 * storage classes.
195 */ 195 */
196void 196void
197dcs_add_storage_class(scl_t sc) 197dcs_add_storage_class(scl_t sc)
198{ 198{
199 199
200 if (dcs->d_type != NULL || dcs->d_abstract_type != NO_TSPEC || 200 if (dcs->d_type != NULL || dcs->d_abstract_type != NO_TSPEC ||
201 dcs->d_sign_mod != NO_TSPEC || dcs->d_rank_mod != NO_TSPEC) { 201 dcs->d_sign_mod != NO_TSPEC || dcs->d_rank_mod != NO_TSPEC) {
202 /* storage class after type is obsolescent */ 202 /* storage class after type is obsolescent */
203 warning(83); 203 warning(83);
204 } 204 }
205 205
206 if (dcs->d_scl == NOSCL) 206 if (dcs->d_scl == NOSCL)
207 dcs->d_scl = sc; 207 dcs->d_scl = sc;
208 else if ((dcs->d_scl == EXTERN && sc == THREAD_LOCAL) 208 else if ((dcs->d_scl == EXTERN && sc == THREAD_LOCAL)
209 || (dcs->d_scl == THREAD_LOCAL && sc == EXTERN)) 209 || (dcs->d_scl == THREAD_LOCAL && sc == EXTERN))
210 dcs->d_scl = EXTERN; /* ignore thread_local */ 210 dcs->d_scl = EXTERN; /* ignore thread_local */
211 else if ((dcs->d_scl == STATIC && sc == THREAD_LOCAL) 211 else if ((dcs->d_scl == STATIC && sc == THREAD_LOCAL)
212 || (dcs->d_scl == THREAD_LOCAL && sc == STATIC)) 212 || (dcs->d_scl == THREAD_LOCAL && sc == STATIC))
213 dcs->d_scl = STATIC; /* ignore thread_local */ 213 dcs->d_scl = STATIC; /* ignore thread_local */
214 else 214 else
215 dcs->d_multiple_storage_classes = true; 215 dcs->d_multiple_storage_classes = true;
216} 216}
217 217
218/* Merge the signedness into the abstract type. */ 218/* Merge the signedness into the abstract type. */
219static tspec_t 219static tspec_t
220merge_signedness(tspec_t t, tspec_t s) 220merge_signedness(tspec_t t, tspec_t s)
221{ 221{
222 222
223 if (s == SIGNED) 223 if (s == SIGNED)
224 return t == CHAR ? SCHAR : t; 224 return t == CHAR ? SCHAR : t;
225 if (s != UNSIGN) 225 if (s != UNSIGN)
226 return t; 226 return t;
227 return t == CHAR ? UCHAR 227 return t == CHAR ? UCHAR
228 : t == SHORT ? USHORT 228 : t == SHORT ? USHORT
229 : t == INT ? UINT 229 : t == INT ? UINT
230 : t == LONG ? ULONG 230 : t == LONG ? ULONG
231 : t == LLONG ? ULLONG 231 : t == LLONG ? ULLONG
232 : t; 232 : t;
233} 233}
234 234
235/* 235/*
236 * Called if a list of declaration specifiers contains a typedef name 236 * Called if a list of declaration specifiers contains a typedef name
237 * and other specifiers (except struct, union, enum, typedef name). 237 * and other specifiers (except struct, union, enum, typedef name).
238 */ 238 */
239static type_t * 239static type_t *
240typedef_error(type_t *td, tspec_t t) 240typedef_error(type_t *td, tspec_t t)
241{ 241{
242 242
243 tspec_t t2 = td->t_tspec; 243 tspec_t t2 = td->t_tspec;
244 244
245 if ((t == SIGNED || t == UNSIGN) && 245 if ((t == SIGNED || t == UNSIGN) &&
246 (t2 == CHAR || t2 == SHORT || t2 == INT || 246 (t2 == CHAR || t2 == SHORT || t2 == INT ||
247 t2 == LONG || t2 == LLONG)) { 247 t2 == LONG || t2 == LLONG)) {
248 if (allow_c90) 248 if (allow_c90)
249 /* modifying typedef with '%s'; only qualifiers... */ 249 /* modifying typedef with '%s'; only qualifiers... */
250 warning(5, tspec_name(t)); 250 warning(5, tspec_name(t));
251 td = block_dup_type(gettyp(merge_signedness(t2, t))); 251 td = block_dup_type(gettyp(merge_signedness(t2, t)));
252 td->t_typedef = true; 252 td->t_typedef = true;
253 return td; 253 return td;
254 } 254 }
255 255
256 if (t == SHORT && (t2 == INT || t2 == UINT)) { 256 if (t == SHORT && (t2 == INT || t2 == UINT)) {
257 /* modifying typedef with '%s'; only qualifiers allowed */ 257 /* modifying typedef with '%s'; only qualifiers allowed */
258 warning(5, "short"); 258 warning(5, "short");
259 td = block_dup_type(gettyp(t2 == INT ? SHORT : USHORT)); 259 td = block_dup_type(gettyp(t2 == INT ? SHORT : USHORT));
260 td->t_typedef = true; 260 td->t_typedef = true;
261 return td; 261 return td;
262 } 262 }
263 263
264 if (t != LONG) 264 if (t != LONG)
265 goto invalid; 265 goto invalid;
266 266
267 if (t2 == INT) 267 if (t2 == INT)
268 td = gettyp(LONG); 268 td = gettyp(LONG);
269 else if (t2 == UINT) 269 else if (t2 == UINT)
270 td = gettyp(ULONG); 270 td = gettyp(ULONG);
271 else if (t2 == LONG) 271 else if (t2 == LONG)
272 td = gettyp(LLONG); 272 td = gettyp(LLONG);
273 else if (t2 == ULONG) 273 else if (t2 == ULONG)
274 td = gettyp(ULLONG); 274 td = gettyp(ULLONG);
275 else if (t2 == FLOAT) 275 else if (t2 == FLOAT)
276 td = gettyp(DOUBLE); 276 td = gettyp(DOUBLE);
277 else if (t2 == DOUBLE) 277 else if (t2 == DOUBLE)
278 td = gettyp(LDOUBLE); 278 td = gettyp(LDOUBLE);
279 else if (t2 == DCOMPLEX) 279 else if (t2 == DCOMPLEX)
280 td = gettyp(LCOMPLEX); 280 td = gettyp(LCOMPLEX);
281 else 281 else
282 goto invalid; 282 goto invalid;
283 283
284 /* modifying typedef with '%s'; only qualifiers allowed */ 284 /* modifying typedef with '%s'; only qualifiers allowed */
285 warning(5, "long"); 285 warning(5, "long");
286 td = block_dup_type(td); 286 td = block_dup_type(td);
287 td->t_typedef = true; 287 td->t_typedef = true;
288 return td; 288 return td;
289 289
290invalid: 290invalid:
291 /* Anything else is not accepted. */ 291 /* Anything else is not accepted. */
292 dcs->d_invalid_type_combination = true; 292 dcs->d_invalid_type_combination = true;
293 return td; 293 return td;
294} 294}
295 295
296/* 296/*
297 * Remember the type, modifier or typedef name returned by the parser in the 297 * Remember the type, modifier or typedef name returned by the parser in the
298 * top element of the declaration stack. This information is used in 298 * top element of the declaration stack. This information is used in
299 * dcs_end_type to build the type used for all declarators in this declaration. 299 * dcs_end_type to build the type used for all declarators in this declaration.
300 * 300 *
301 * If tp->t_typedef is true, the type comes from a previously defined typename. 301 * If tp->t_typedef is true, the type comes from a previously defined typename.
302 * Otherwise, it comes from a type specifier (int, long, ...) or a 302 * Otherwise, it comes from a type specifier (int, long, ...) or a
303 * struct/union/enum tag. 303 * struct/union/enum tag.
304 */ 304 */
305void 305void
306dcs_add_type(type_t *tp) 306dcs_add_type(type_t *tp)
307{ 307{
308 308
309 debug_step("%s: %s", __func__, type_name(tp)); 309 debug_step("%s: %s", __func__, type_name(tp));
310 if (tp->t_typedef) { 310 if (tp->t_typedef) {
311 /* 311 /*
312 * something like "typedef int a; int a b;" 312 * something like "typedef int a; int a b;"
313 * This should not happen with current grammar. 313 * This should not happen with current grammar.
314 */ 314 */
315 lint_assert(dcs->d_type == NULL); 315 lint_assert(dcs->d_type == NULL);
316 lint_assert(dcs->d_abstract_type == NO_TSPEC); 316 lint_assert(dcs->d_abstract_type == NO_TSPEC);
317 lint_assert(dcs->d_sign_mod == NO_TSPEC); 317 lint_assert(dcs->d_sign_mod == NO_TSPEC);
318 lint_assert(dcs->d_rank_mod == NO_TSPEC); 318 lint_assert(dcs->d_rank_mod == NO_TSPEC);
319 319
320 dcs->d_type = tp; 320 dcs->d_type = tp;
321 return; 321 return;
322 } 322 }
323 323
324 tspec_t t = tp->t_tspec; 324 tspec_t t = tp->t_tspec;
325 if (is_struct_or_union(t) || t == ENUM) { 325 if (is_struct_or_union(t) || t == ENUM) {
326 /* 326 /*
327 * something like "int struct a ..." 327 * something like "int struct a ..."
328 * struct/union/enum with anything else is not allowed 328 * struct/union/enum with anything else is not allowed
329 */ 329 */
330 if (dcs->d_type != NULL || dcs->d_abstract_type != NO_TSPEC || 330 if (dcs->d_type != NULL || dcs->d_abstract_type != NO_TSPEC ||
331 dcs->d_rank_mod != NO_TSPEC || dcs->d_sign_mod != NO_TSPEC) { 331 dcs->d_rank_mod != NO_TSPEC || dcs->d_sign_mod != NO_TSPEC) {
332 dcs->d_invalid_type_combination = true; 332 dcs->d_invalid_type_combination = true;
333 dcs->d_abstract_type = NO_TSPEC; 333 dcs->d_abstract_type = NO_TSPEC;
334 dcs->d_sign_mod = NO_TSPEC; 334 dcs->d_sign_mod = NO_TSPEC;
335 dcs->d_rank_mod = NO_TSPEC; 335 dcs->d_rank_mod = NO_TSPEC;
336 } 336 }
337 dcs->d_type = tp; 337 dcs->d_type = tp;
338 return; 338 return;
339 } 339 }
340 340
341 if (dcs->d_type != NULL && !dcs->d_type->t_typedef) { 341 if (dcs->d_type != NULL && !dcs->d_type->t_typedef) {
342 /* 342 /*
343 * something like "struct a int" 343 * something like "struct a int"
344 * struct/union/enum with anything else is not allowed 344 * struct/union/enum with anything else is not allowed
345 */ 345 */
346 dcs->d_invalid_type_combination = true; 346 dcs->d_invalid_type_combination = true;
347 return; 347 return;
348 } 348 }
349 349
350 if (t == COMPLEX) { 350 if (t == COMPLEX) {
351 if (dcs->d_complex_mod == FLOAT) 351 if (dcs->d_complex_mod == FLOAT)
352 t = FCOMPLEX; 352 t = FCOMPLEX;
353 else if (dcs->d_complex_mod == DOUBLE) 353 else if (dcs->d_complex_mod == DOUBLE)
354 t = DCOMPLEX; 354 t = DCOMPLEX;
355 else { 355 else {
356 /* invalid type for _Complex */ 356 /* invalid type for _Complex */
357 error(308); 357 error(308);
358 t = DCOMPLEX; /* just as a fallback */ 358 t = DCOMPLEX; /* just as a fallback */
359 } 359 }
360 dcs->d_complex_mod = NO_TSPEC; 360 dcs->d_complex_mod = NO_TSPEC;
361 } 361 }
362 362
363 if (t == LONG && dcs->d_rank_mod == LONG) { 363 if (t == LONG && dcs->d_rank_mod == LONG) {
364 /* "long long" or "long ... long" */ 364 /* "long long" or "long ... long" */
365 t = LLONG; 365 t = LLONG;
366 dcs->d_rank_mod = NO_TSPEC; 366 dcs->d_rank_mod = NO_TSPEC;
367 if (!suppress_longlong) 367 if (!suppress_longlong)
368 /* %s does not support 'long long' */ 368 /* %s does not support 'long long' */
369 c99ism(265, allow_c90 ? "C90" : "traditional C"); 369 c99ism(265, allow_c90 ? "C90" : "traditional C");
370 } 370 }
371 371
372 if (dcs->d_type != NULL && dcs->d_type->t_typedef) { 372 if (dcs->d_type != NULL && dcs->d_type->t_typedef) {
373 /* something like "typedef int a; a long ..." */ 373 /* something like "typedef int a; a long ..." */
374 dcs->d_type = typedef_error(dcs->d_type, t); 374 dcs->d_type = typedef_error(dcs->d_type, t);
375 return; 375 return;
376 } 376 }
377 377
378 /* now it can be only a combination of arithmetic types and void */ 378 /* now it can be only a combination of arithmetic types and void */
379 if (t == SIGNED || t == UNSIGN) { 379 if (t == SIGNED || t == UNSIGN) {
380 if (dcs->d_sign_mod != NO_TSPEC) 380 if (dcs->d_sign_mod != NO_TSPEC)
381 dcs->d_invalid_type_combination = true; 381 dcs->d_invalid_type_combination = true;
382 dcs->d_sign_mod = t; 382 dcs->d_sign_mod = t;
383 } else if (t == SHORT || t == LONG || t == LLONG) { 383 } else if (t == SHORT || t == LONG || t == LLONG) {
384 if (dcs->d_rank_mod != NO_TSPEC) 384 if (dcs->d_rank_mod != NO_TSPEC)
385 dcs->d_invalid_type_combination = true; 385 dcs->d_invalid_type_combination = true;
386 dcs->d_rank_mod = t; 386 dcs->d_rank_mod = t;
387 } else if (t == FLOAT || t == DOUBLE) { 387 } else if (t == FLOAT || t == DOUBLE) {
388 if (dcs->d_rank_mod == NO_TSPEC || dcs->d_rank_mod == LONG) { 388 if (dcs->d_rank_mod == NO_TSPEC || dcs->d_rank_mod == LONG) {
389 if (dcs->d_complex_mod != NO_TSPEC 389 if (dcs->d_complex_mod != NO_TSPEC
390 || (t == FLOAT && dcs->d_rank_mod == LONG)) 390 || (t == FLOAT && dcs->d_rank_mod == LONG))
391 dcs->d_invalid_type_combination = true; 391 dcs->d_invalid_type_combination = true;
392 dcs->d_complex_mod = t; 392 dcs->d_complex_mod = t;
393 } else { 393 } else {
394 if (dcs->d_abstract_type != NO_TSPEC) 394 if (dcs->d_abstract_type != NO_TSPEC)
395 dcs->d_invalid_type_combination = true; 395 dcs->d_invalid_type_combination = true;
396 dcs->d_abstract_type = t; 396 dcs->d_abstract_type = t;
397 } 397 }
398 } else if (t == PTR) { 398 } else if (t == PTR) {
399 dcs->d_type = tp; 399 dcs->d_type = tp;
400 } else { 400 } else {
401 if (dcs->d_abstract_type != NO_TSPEC) 401 if (dcs->d_abstract_type != NO_TSPEC)
402 dcs->d_invalid_type_combination = true; 402 dcs->d_invalid_type_combination = true;
403 dcs->d_abstract_type = t; 403 dcs->d_abstract_type = t;
404 } 404 }
405} 405}
406 406
407static void 407static void
408set_first_typedef(type_t *tp, sym_t *sym) 408set_first_typedef(type_t *tp, sym_t *sym)
409{ 409{
410 410
411 tspec_t t = tp->t_tspec; 411 tspec_t t = tp->t_tspec;
412 if (is_struct_or_union(t) && tp->t_sou->sou_first_typedef == NULL) 412 if (is_struct_or_union(t) && tp->t_sou->sou_first_typedef == NULL)
413 tp->t_sou->sou_first_typedef = sym; 413 tp->t_sou->sou_first_typedef = sym;
414 if (t == ENUM && tp->t_enum->en_first_typedef == NULL) 414 if (t == ENUM && tp->t_enum->en_first_typedef == NULL)
415 tp->t_enum->en_first_typedef = sym; 415 tp->t_enum->en_first_typedef = sym;
416} 416}
417 417
418static unsigned int 418static unsigned int
419bit_fields_width(const sym_t **mem, bool *named) 419bit_fields_width(const sym_t **mem, bool *named)
420{ 420{
421 unsigned int width = 0; 421 unsigned int width = 0;
422 unsigned int align = 0; 422 unsigned int align = 0;
423 while (*mem != NULL && (*mem)->s_type->t_bitfield) { 423 while (*mem != NULL && (*mem)->s_type->t_bitfield) {
424 if ((*mem)->s_name != unnamed) 424 if ((*mem)->s_name != unnamed)
425 *named = true; 425 *named = true;
426 width += (*mem)->s_type->t_bit_field_width; 426 width += (*mem)->s_type->t_bit_field_width;
427 unsigned int mem_align = alignment_in_bits((*mem)->s_type); 427 unsigned int mem_align = alignment_in_bits((*mem)->s_type);
428 if (mem_align > align) 428 if (mem_align > align)
429 align = mem_align; 429 align = mem_align;
430 *mem = (*mem)->s_next; 430 *mem = (*mem)->s_next;
431 } 431 }
432 return (width + align - 1) & -align; 432 return (width + align - 1) & -align;
433} 433}
434 434
435static void 435static void
436pack_struct_or_union(type_t *tp) 436pack_struct_or_union(type_t *tp)
437{ 437{
438 438
439 if (!is_struct_or_union(tp->t_tspec)) { 439 if (!is_struct_or_union(tp->t_tspec)) {
440 /* attribute '%s' ignored for '%s' */ 440 /* attribute '%s' ignored for '%s' */
441 warning(326, "packed", type_name(tp)); 441 warning(326, "packed", type_name(tp));
442 return; 442 return;
443 } 443 }
444 444
445 unsigned int bits = 0; 445 unsigned int bits = 0;
446 bool named = false; 446 bool named = false;
447 for (const sym_t *mem = tp->t_sou->sou_first_member; 447 for (const sym_t *mem = tp->t_sou->sou_first_member;
448 mem != NULL; mem = mem->s_next) { 448 mem != NULL; mem = mem->s_next) {
449 // TODO: Maybe update mem->u.s_member.sm_offset_in_bits. 449 // TODO: Maybe update mem->u.s_member.sm_offset_in_bits.
450 if (mem->s_type->t_bitfield) { 450 if (mem->s_type->t_bitfield) {
451 bits += bit_fields_width(&mem, &named); 451 bits += bit_fields_width(&mem, &named);
452 if (mem == NULL) 452 if (mem == NULL)
453 break; 453 break;
454 } 454 }
455 unsigned int mem_bits = type_size_in_bits(mem->s_type); 455 unsigned int mem_bits = type_size_in_bits(mem->s_type);
456 if (tp->t_tspec == STRUCT) 456 if (tp->t_tspec == STRUCT)
457 bits += mem_bits; 457 bits += mem_bits;
458 else if (mem_bits > bits) 458 else if (mem_bits > bits)
459 bits = mem_bits; 459 bits = mem_bits;
460 } 460 }
461 tp->t_sou->sou_size_in_bits = bits; 461 tp->t_sou->sou_size_in_bits = bits;
462} 462}
463 463
464void 464void
465dcs_add_packed(void) 465dcs_add_packed(void)
466{ 466{
467 if (dcs->d_type == NULL) 467 if (dcs->d_type == NULL)
468 dcs->d_packed = true; 468 dcs->d_packed = true;
469 else 469 else
470 pack_struct_or_union(dcs->d_type); 470 pack_struct_or_union(dcs->d_type);
471} 471}
472 472
473void 473void
474dcs_set_used(void) 474dcs_set_used(void)
475{ 475{
476 dcs->d_used = true; 476 dcs->d_used = true;
477} 477}
478 478
479/* 479/*
480 * Remember a qualifier that is part of the declaration specifiers (and not the 480 * Remember a qualifier that is part of the declaration specifiers (and not the
481 * declarator). The remembered qualifier is used by dcs_end_type for all 481 * declarator). The remembered qualifier is used by dcs_end_type for all
482 * declarators. 482 * declarators.
483 */ 483 */
484void 484void
485dcs_add_qualifiers(type_qualifiers qs) 485dcs_add_qualifiers(type_qualifiers qs)
486{ 486{
487 add_type_qualifiers(&dcs->d_qual, qs); 487 add_type_qualifiers(&dcs->d_qual, qs);
488} 488}
489 489
490void 490void
491begin_declaration_level(decl_level_kind kind) 491begin_declaration_level(decl_level_kind kind)
492{ 492{
493 493
494 decl_level *dl = xcalloc(1, sizeof(*dl)); 494 decl_level *dl = xcalloc(1, sizeof(*dl));
495 dl->d_enclosing = dcs; 495 dl->d_enclosing = dcs;
496 dl->d_kind = kind; 496 dl->d_kind = kind;
497 dl->d_last_dlsym = &dl->d_first_dlsym; 497 dl->d_last_dlsym = &dl->d_first_dlsym;
498 dcs = dl; 498 dcs = dl;
499 debug_enter(); 499 debug_enter();
500 debug_dcs(true); 500 debug_dcs(true);
501} 501}
502 502
503void 503void
504end_declaration_level(void) 504end_declaration_level(void)
505{ 505{
506 506
507 debug_dcs(true); 507 debug_dcs(true);
508 508
509 decl_level *dl = dcs; 509 decl_level *dl = dcs;
510 dcs = dl->d_enclosing; 510 dcs = dl->d_enclosing;
511 lint_assert(dcs != NULL); 511 lint_assert(dcs != NULL);
512 512
513 switch (dl->d_kind) { 513 switch (dl->d_kind) {
514 case DLK_STRUCT: 514 case DLK_STRUCT:
515 case DLK_UNION: 515 case DLK_UNION:
516 case DLK_ENUM: 516 case DLK_ENUM:
517 /* 517 /*
518 * Symbols declared in (nested) structs or enums are part of 518 * Symbols declared in (nested) structs or enums are part of
519 * the next level (they are removed from the symbol table if 519 * the next level (they are removed from the symbol table if
520 * the symbols of the outer level are removed). 520 * the symbols of the outer level are removed).
521 */ 521 */
522 if ((*dcs->d_last_dlsym = dl->d_first_dlsym) != NULL) 522 if ((*dcs->d_last_dlsym = dl->d_first_dlsym) != NULL)
523 dcs->d_last_dlsym = dl->d_last_dlsym; 523 dcs->d_last_dlsym = dl->d_last_dlsym;
524 break; 524 break;
525 case DLK_OLD_STYLE_ARGS: 525 case DLK_OLD_STYLE_ARGS:
526 /* 526 /*
527 * All symbols in dcs->d_first_dlsym are introduced in 527 * All symbols in dcs->d_first_dlsym are introduced in
528 * old-style argument declarations (it's not clean, but 528 * old-style argument declarations (it's not clean, but
529 * possible). They are appended to the list of symbols declared 529 * possible). They are appended to the list of symbols declared
530 * in an old-style argument identifier list or a new-style 530 * in an old-style argument identifier list or a new-style
531 * parameter type list. 531 * parameter type list.
532 */ 532 */
533 if (dl->d_first_dlsym != NULL) { 533 if (dl->d_first_dlsym != NULL) {
534 *dl->d_last_dlsym = dcs->d_func_proto_syms; 534 *dl->d_last_dlsym = dcs->d_func_proto_syms;
535 dcs->d_func_proto_syms = dl->d_first_dlsym; 535 dcs->d_func_proto_syms = dl->d_first_dlsym;
536 } 536 }
537 break; 537 break;
538 case DLK_ABSTRACT: 538 case DLK_ABSTRACT:
539 /* 539 /*
540 * Append all symbols declared in the abstract declaration to 540 * Append all symbols declared in the abstract declaration to
541 * the list of symbols declared in the surrounding declaration 541 * the list of symbols declared in the surrounding declaration
542 * or block. 542 * or block.
543 * 543 *
544 * XXX I'm not sure whether they should be removed from the 544 * XXX I'm not sure whether they should be removed from the
545 * symbol table now or later. 545 * symbol table now or later.
546 */ 546 */
547 if ((*dcs->d_last_dlsym = dl->d_first_dlsym) != NULL) 547 if ((*dcs->d_last_dlsym = dl->d_first_dlsym) != NULL)
548 dcs->d_last_dlsym = dl->d_last_dlsym; 548 dcs->d_last_dlsym = dl->d_last_dlsym;
549 break; 549 break;
550 case DLK_AUTO: 550 case DLK_AUTO:
551 check_usage(dl); 551 check_usage(dl);
552 /* FALLTHROUGH */ 552 /* FALLTHROUGH */
553 case DLK_PROTO_PARAMS: 553 case DLK_PROTO_PARAMS:
554 /* usage of arguments will be checked by end_function() */ 554 /* usage of arguments will be checked by end_function() */
555 symtab_remove_level(dl->d_first_dlsym); 555 symtab_remove_level(dl->d_first_dlsym);
556 break; 556 break;
557 case DLK_EXTERN: 557 case DLK_EXTERN:
558 /* there is nothing around an external declaration */ 558 /* there is nothing around an external declaration */
559 /* FALLTHROUGH */ 559 /* FALLTHROUGH */
560 default: 560 default:
561 lint_assert(/*CONSTCOND*/false); 561 lint_assert(/*CONSTCOND*/false);
562 } 562 }
563 free(dl); 563 free(dl);
564 debug_leave(); 564 debug_leave();
565} 565}
566 566
567/* 567/*
568 * Set flag d_asm in all declaration stack elements up to the outermost one. 568 * Set flag d_asm in all declaration stack elements up to the outermost one.
569 * 569 *
570 * This is used to mark compound statements which have, possibly in nested 570 * This is used to mark compound statements which have, possibly in nested
571 * compound statements, asm statements. For these compound statements, no 571 * compound statements, asm statements. For these compound statements, no
572 * warnings about unused or uninitialized variables are printed. 572 * warnings about unused or uninitialized variables are printed.
573 * 573 *
574 * There is no need to clear d_asm in decl_level structs with context AUTO, as 574 * There is no need to clear d_asm in decl_level structs with context AUTO, as
575 * these structs are freed at the end of the compound statement. But it must be 575 * these structs are freed at the end of the compound statement. But it must be
576 * cleared in the outermost decl_level struct, which has context EXTERN. This 576 * cleared in the outermost decl_level struct, which has context EXTERN. This
577 * could be done in dcs_begin_type and would work for C90, but not for C99 or 577 * could be done in dcs_begin_type and would work for C90, but not for C99 or
578 * C++ (due to mixed statements and declarations). Thus, we clear it in 578 * C++ (due to mixed statements and declarations). Thus, we clear it in
579 * global_clean_up_decl. 579 * global_clean_up_decl.
580 */ 580 */
581void 581void
582dcs_set_asm(void) 582dcs_set_asm(void)
583{ 583{
584 584
585 for (decl_level *dl = dcs; dl != NULL; dl = dl->d_enclosing) 585 for (decl_level *dl = dcs; dl != NULL; dl = dl->d_enclosing)
586 dl->d_asm = true; 586 dl->d_asm = true;
587} 587}
588 588
589void 589void
590dcs_begin_type(void) 590dcs_begin_type(void)
591{ 591{
592 592
593 debug_enter(); 593 debug_enter();
594 dcs->d_abstract_type = NO_TSPEC; 594 dcs->d_abstract_type = NO_TSPEC;
595 dcs->d_complex_mod = NO_TSPEC; 595 dcs->d_complex_mod = NO_TSPEC;
596 dcs->d_sign_mod = NO_TSPEC; 596 dcs->d_sign_mod = NO_TSPEC;
597 dcs->d_rank_mod = NO_TSPEC; 597 dcs->d_rank_mod = NO_TSPEC;
598 dcs->d_scl = NOSCL; 598 dcs->d_scl = NOSCL;
599 dcs->d_type = NULL; 599 dcs->d_type = NULL;
600 dcs->d_qual = (type_qualifiers) { .tq_const = false }; 600 dcs->d_qual = (type_qualifiers) { .tq_const = false };
601 dcs->d_inline = false; 601 dcs->d_inline = false;
602 dcs->d_multiple_storage_classes = false; 602 dcs->d_multiple_storage_classes = false;
603 dcs->d_invalid_type_combination = false; 603 dcs->d_invalid_type_combination = false;
604 dcs->d_nonempty_decl = false; 604 dcs->d_nonempty_decl = false;
605 dcs->d_no_type_specifier = false; 605 dcs->d_no_type_specifier = false;
606} 606}
607 607
608static void 608static void
609dcs_adjust_storage_class(void) 609dcs_adjust_storage_class(void)
610{ 610{
611 if (dcs->d_kind == DLK_EXTERN) { 611 if (dcs->d_kind == DLK_EXTERN) {
612 if (dcs->d_scl == REG || dcs->d_scl == AUTO) { 612 if (dcs->d_scl == REG || dcs->d_scl == AUTO) {
613 /* illegal storage class */ 613 /* illegal storage class */
614 error(8); 614 error(8);
615 dcs->d_scl = NOSCL; 615 dcs->d_scl = NOSCL;
616 } 616 }
617 } else if (dcs->d_kind == DLK_OLD_STYLE_ARGS || 617 } else if (dcs->d_kind == DLK_OLD_STYLE_ARGS ||
618 dcs->d_kind == DLK_PROTO_PARAMS) { 618 dcs->d_kind == DLK_PROTO_PARAMS) {
619 if (dcs->d_scl != NOSCL && dcs->d_scl != REG) { 619 if (dcs->d_scl != NOSCL && dcs->d_scl != REG) {
620 /* only 'register' is valid as storage class ... */ 620 /* only 'register' is valid as storage class ... */
621 error(9); 621 error(9);
622 dcs->d_scl = NOSCL; 622 dcs->d_scl = NOSCL;
623 } 623 }
624 } 624 }
625} 625}
626 626
627/* 627/*
628 * Merge the declaration specifiers from dcs into dcs->d_type. 628 * Merge the declaration specifiers from dcs into dcs->d_type.
629 * 629 *
630 * See C99 6.7.2 "Type specifiers". 630 * See C99 6.7.2 "Type specifiers".
631 */ 631 */
632static void 632static void
633dcs_merge_declaration_specifiers(void) 633dcs_merge_declaration_specifiers(void)
634{ 634{
635 tspec_t t = dcs->d_abstract_type; 635 tspec_t t = dcs->d_abstract_type;
636 tspec_t c = dcs->d_complex_mod; 636 tspec_t c = dcs->d_complex_mod;
637 tspec_t s = dcs->d_sign_mod; 637 tspec_t s = dcs->d_sign_mod;
638 tspec_t l = dcs->d_rank_mod; 638 tspec_t l = dcs->d_rank_mod;
639 type_t *tp = dcs->d_type; 639 type_t *tp = dcs->d_type;
640 640
641 if (tp != NULL) { 641 if (tp != NULL) {
642 lint_assert(t == NO_TSPEC); 642 lint_assert(t == NO_TSPEC);
643 lint_assert(s == NO_TSPEC); 643 lint_assert(s == NO_TSPEC);
644 lint_assert(l == NO_TSPEC); 644 lint_assert(l == NO_TSPEC);
645 return; 645 return;
646 } 646 }
647 647
648 debug_step("%s: %s", __func__, type_name(tp)); 648 debug_step("%s: %s", __func__, type_name(tp));
649 649
650 if (t == NO_TSPEC && s == NO_TSPEC && l == NO_TSPEC && c == NO_TSPEC) 650 if (t == NO_TSPEC && s == NO_TSPEC && l == NO_TSPEC && c == NO_TSPEC)
651 dcs->d_no_type_specifier = true; 651 dcs->d_no_type_specifier = true;
652 if (t == NO_TSPEC && s == NO_TSPEC && (l == NO_TSPEC || l == LONG)) 652 if (t == NO_TSPEC && s == NO_TSPEC && (l == NO_TSPEC || l == LONG))
653 t = c; 653 t = c;
654 654
655 if (t == NO_TSPEC) 655 if (t == NO_TSPEC)
656 t = INT; 656 t = INT;
657 if (s == NO_TSPEC && t == INT) 657 if (s == NO_TSPEC && t == INT)
658 s = SIGNED; 658 s = SIGNED;
659 if (l != NO_TSPEC && t == CHAR) { 659 if (l != NO_TSPEC && t == CHAR) {
660 dcs->d_invalid_type_combination = true; 660 dcs->d_invalid_type_combination = true;
661 l = NO_TSPEC; 661 l = NO_TSPEC;
662 } 662 }
663 if (l == LONG && t == FLOAT) { 663 if (l == LONG && t == FLOAT) {
664 l = NO_TSPEC; 664 l = NO_TSPEC;
665 t = DOUBLE; 665 t = DOUBLE;
666 if (allow_c90) 666 if (allow_c90)
667 /* use 'double' instead of 'long float' */ 667 /* use 'double' instead of 'long float' */
668 warning(6); 668 warning(6);
669 } 669 }
670 if ((l == LONG && t == DOUBLE) || t == LDOUBLE) { 670 if ((l == LONG && t == DOUBLE) || t == LDOUBLE) {
671 l = NO_TSPEC; 671 l = NO_TSPEC;
672 t = LDOUBLE; 672 t = LDOUBLE;
673 } 673 }
674 if (t == LDOUBLE && !allow_c90) { 674 if (t == LDOUBLE && !allow_c90) {
675 /* 'long double' is illegal in traditional C */ 675 /* 'long double' is illegal in traditional C */
676 warning(266); 676 warning(266);
677 } 677 }
678 if (l == LONG && t == DCOMPLEX) { 678 if (l == LONG && t == DCOMPLEX) {
679 l = NO_TSPEC; 679 l = NO_TSPEC;
680 t = LCOMPLEX; 680 t = LCOMPLEX;
681 } 681 }
682 682
683 if (t != INT && t != CHAR && (s != NO_TSPEC || l != NO_TSPEC)) { 683 if (t != INT && t != CHAR && (s != NO_TSPEC || l != NO_TSPEC)) {
684 dcs->d_invalid_type_combination = true; 684 dcs->d_invalid_type_combination = true;
685 l = s = NO_TSPEC; 685 l = s = NO_TSPEC;
686 } 686 }
687 if (l != NO_TSPEC) 687 if (l != NO_TSPEC)
688 t = l; 688 t = l;
689 dcs->d_type = gettyp(merge_signedness(t, s)); 689 dcs->d_type = gettyp(merge_signedness(t, s));
690} 690}
691 691
692/* Create a type in 'dcs->d_type' from the information gathered in 'dcs'. */ 692/* Create a type in 'dcs->d_type' from the information gathered in 'dcs'. */
693void 693void
694dcs_end_type(void) 694dcs_end_type(void)
695{ 695{
696 696
697 dcs_merge_declaration_specifiers(); 697 dcs_merge_declaration_specifiers();
698 698
699 if (dcs->d_multiple_storage_classes) { 699 if (dcs->d_multiple_storage_classes) {
700 /* only one storage class allowed */ 700 /* only one storage class allowed */
701 error(7); 701 error(7);
702 } 702 }
703 if (dcs->d_invalid_type_combination) { 703 if (dcs->d_invalid_type_combination) {
704 /* illegal type combination */ 704 /* illegal type combination */
705 error(4); 705 error(4);
706 } 706 }
707 707
708 dcs_adjust_storage_class(); 708 dcs_adjust_storage_class();
709 709
710 if (dcs->d_qual.tq_const && dcs->d_type->t_const 710 if (dcs->d_qual.tq_const && dcs->d_type->t_const
711 && !dcs->d_type->t_typeof) { 711 && !dcs->d_type->t_typeof) {
712 lint_assert(dcs->d_type->t_typedef); 712 lint_assert(dcs->d_type->t_typedef);
713 /* typedef already qualified with '%s' */ 713 /* typedef already qualified with '%s' */
714 warning(68, "const"); 714 warning(68, "const");
715 } 715 }
716 if (dcs->d_qual.tq_volatile && dcs->d_type->t_volatile && 716 if (dcs->d_qual.tq_volatile && dcs->d_type->t_volatile &&
717 !dcs->d_type->t_typeof) { 717 !dcs->d_type->t_typeof) {
718 lint_assert(dcs->d_type->t_typedef); 718 lint_assert(dcs->d_type->t_typedef);
719 /* typedef already qualified with '%s' */ 719 /* typedef already qualified with '%s' */
720 warning(68, "volatile"); 720 warning(68, "volatile");
721 } 721 }
722 722
723 if (dcs->d_qual.tq_const || dcs->d_qual.tq_volatile) { 723 if (dcs->d_qual.tq_const || dcs->d_qual.tq_volatile) {
724 dcs->d_type = block_dup_type(dcs->d_type); 724 dcs->d_type = block_dup_type(dcs->d_type);
725 dcs->d_type->t_const |= dcs->d_qual.tq_const; 725 dcs->d_type->t_const |= dcs->d_qual.tq_const;
726 dcs->d_type->t_volatile |= dcs->d_qual.tq_volatile; 726 dcs->d_type->t_volatile |= dcs->d_qual.tq_volatile;
727 } 727 }
728 728
729 debug_leave(); 729 debug_leave();
730} 730}
731 731
732/* 732/*
733 * Return the length of a type in bits. For bit-fields, return the length of 733 * Return the length of a type in bits. For bit-fields, return the length of
734 * the underlying storage type. 734 * the underlying storage type.
735 * 735 *
736 * Printing a message if the outermost dimension of an array is 0 must 736 * Printing a message if the outermost dimension of an array is 0 must
737 * be done by the caller. All other problems are reported by this function 737 * be done by the caller. All other problems are reported by this function
738 * if name is not NULL. 738 * if name is not NULL.
739 */ 739 */
740int 740int
741length_in_bits(const type_t *tp, const char *name) 741length_in_bits(const type_t *tp, const char *name)
742{ 742{
743 743
744 if (tp == NULL) 744 if (tp == NULL)
745 return -1; 745 return -1;
746 746
747 unsigned int elem = 1; 747 unsigned int elem = 1;
748 while (tp->t_tspec == ARRAY) { 748 while (tp->t_tspec == ARRAY) {
749 elem *= tp->t_dim; 749 elem *= tp->t_dim;
750 tp = tp->t_subt; 750 tp = tp->t_subt;
751 } 751 }
752 752
753 if (is_struct_or_union(tp->t_tspec)) { 753 if (is_struct_or_union(tp->t_tspec)) {
754 if (is_incomplete(tp) && name != NULL) { 754 if (is_incomplete(tp) && name != NULL) {
755 /* '%s' has incomplete type '%s' */ 755 /* '%s' has incomplete type '%s' */
756 error(31, name, type_name(tp)); 756 error(31, name, type_name(tp));
757 } 757 }
758 return (int)(elem * tp->t_sou->sou_size_in_bits); 758 return (int)(elem * tp->t_sou->sou_size_in_bits);
759 } 759 }
760 760
761 if (tp->t_tspec == ENUM && is_incomplete(tp) && name != NULL) 761 if (tp->t_tspec == ENUM && is_incomplete(tp) && name != NULL)
762 /* incomplete enum type '%s' */ 762 /* incomplete enum type '%s' */
763 warning(13, name); 763 warning(13, name);
764 764
765 lint_assert(tp->t_tspec != FUNC); 765 lint_assert(tp->t_tspec != FUNC);
766 766
767 unsigned int elsz = size_in_bits(tp->t_tspec); 767 unsigned int elsz = size_in_bits(tp->t_tspec);
768 /* 768 /*
769 * Workaround until the type parser (see add_function, add_array, 769 * Workaround until the type parser (see add_function, add_array,
770 * add_pointer) does not construct the invalid intermediate declaration 770 * add_pointer) does not construct the invalid intermediate declaration
771 * 'void b[4]' for the legitimate declaration 'void *b[4]'. 771 * 'void b[4]' for the legitimate declaration 'void *b[4]'.
772 */ 772 */
773 if (sytxerr > 0 && elsz == 0) 773 if (sytxerr > 0 && elsz == 0)
774 elsz = CHAR_SIZE; 774 elsz = CHAR_SIZE;
775 lint_assert(elsz > 0); 775 lint_assert(elsz > 0);
776 return (int)(elem * elsz); 776 return (int)(elem * elsz);
777} 777}
778 778
779unsigned int 779unsigned int
780alignment_in_bits(const type_t *tp) 780alignment_in_bits(const type_t *tp)
781{ 781{
782 782
783 /* Super conservative so that it works for most systems. */ 783 /* Super conservative so that it works for most systems. */
784 unsigned int worst_align_in_bits = 2 * LONG_SIZE; 784 unsigned int worst_align_in_bits = 2 * LONG_SIZE;
785 785
786 while (tp->t_tspec == ARRAY) 786 while (tp->t_tspec == ARRAY)
787 tp = tp->t_subt; 787 tp = tp->t_subt;
788 788
789 tspec_t t = tp->t_tspec; 789 tspec_t t = tp->t_tspec;
790 unsigned int a; 790 unsigned int a;
791 if (is_struct_or_union(t)) 791 if (is_struct_or_union(t))
792 a = tp->t_sou->sou_align_in_bits; 792 a = tp->t_sou->sou_align_in_bits;
793 else { 793 else {
794 lint_assert(t != FUNC); 794 lint_assert(t != FUNC);
795 if ((a = size_in_bits(t)) == 0) 795 if ((a = size_in_bits(t)) == 0)
796 a = CHAR_SIZE; 796 a = CHAR_SIZE;
797 else if (a > worst_align_in_bits) 797 else if (a > worst_align_in_bits)
798 a = worst_align_in_bits; 798 a = worst_align_in_bits;
799 } 799 }
800 lint_assert(a >= CHAR_SIZE); 800 lint_assert(a >= CHAR_SIZE);
801 lint_assert(a <= worst_align_in_bits); 801 lint_assert(a <= worst_align_in_bits);
802 return a; 802 return a;
803} 803}
804 804
805/* 805/*
806 * Concatenate two lists of symbols by s_next. Used by declarations of 806 * Concatenate two lists of symbols by s_next. Used by declarations of
807 * struct/union/enum elements and parameters. 807 * struct/union/enum elements and parameters.
808 */ 808 */
809sym_t * 809sym_t *
810concat_symbols(sym_t *l1, sym_t *l2) 810concat_symbols(sym_t *l1, sym_t *l2)
811{ 811{
812 812
813 if (l1 == NULL) 813 if (l1 == NULL)
814 return l2; 814 return l2;
815 sym_t *l = l1; 815 sym_t *l = l1;
816 while (l->s_next != NULL) 816 while (l->s_next != NULL)
817 l = l->s_next; 817 l = l->s_next;
818 l->s_next = l2; 818 l->s_next = l2;
819 return l1; 819 return l1;
820} 820}
821 821
822/* 822/*
823 * Check if the type of the given symbol is valid. 823 * Check if the type of the given symbol is valid.
824 * 824 *
825 * Invalid types are: 825 * Invalid types are:
826 * - arrays of incomplete types or functions 826 * - arrays of incomplete types or functions
827 * - functions returning arrays or functions 827 * - functions returning arrays or functions
828 * - void types other than type of function or pointer 828 * - void types other than type of function or pointer
829 */ 829 */
830void 830void
831check_type(sym_t *sym) 831check_type(sym_t *sym)
832{ 832{
833 833
834 type_t **tpp = &sym->s_type; 834 type_t **tpp = &sym->s_type;
835 tspec_t to = NO_TSPEC; 835 tspec_t to = NO_TSPEC;
836 while (*tpp != NULL) { 836 while (*tpp != NULL) {
837 type_t *tp = *tpp; 837 type_t *tp = *tpp;
838 tspec_t t = tp->t_tspec; 838 tspec_t t = tp->t_tspec;
839 /* 839 /*
840 * If this is the type of an old-style function definition, 840 * If this is the type of an old-style function definition,
841 * a better warning is printed in begin_function(). 841 * a better warning is printed in begin_function().
842 */ 842 */
843 if (t == FUNC && !tp->t_proto && 843 if (t == FUNC && !tp->t_proto &&
844 !(to == NO_TSPEC && sym->s_osdef)) { 844 !(to == NO_TSPEC && sym->s_osdef)) {
845 /* TODO: Make this an error in C99 mode as well. */ 845 /* TODO: Make this an error in C99 mode as well. */
846 if ((!allow_trad && !allow_c99) && hflag) 846 if ((!allow_trad && !allow_c99) && hflag)
847 /* function declaration is not a prototype */ 847 /* function declaration is not a prototype */
848 warning(287); 848 warning(287);
849 } 849 }
850 if (to == FUNC) { 850 if (to == FUNC) {
851 if (t == FUNC || t == ARRAY) { 851 if (t == FUNC || t == ARRAY) {
852 /* function returns illegal type '%s' */ 852 /* function returns illegal type '%s' */
853 error(15, type_name(tp)); 853 error(15, type_name(tp));
854 *tpp = block_derive_type( 854 *tpp = block_derive_type(
855 t == FUNC ? *tpp : (*tpp)->t_subt, PTR); 855 t == FUNC ? *tpp : (*tpp)->t_subt, PTR);
856 return; 856 return;
857 } 857 }
858 if (tp->t_const || tp->t_volatile) { 858 if (tp->t_const || tp->t_volatile) {
859 /* TODO: Make this a warning in C99 mode as well. */ 859 /* TODO: Make this a warning in C99 mode as well. */
860 if (!allow_trad && !allow_c99) { /* XXX or better allow_c90? */ 860 if (!allow_trad && !allow_c99) { /* XXX or better allow_c90? */
861 /* function cannot return const... */ 861 /* function cannot return const... */
862 warning(228); 862 warning(228);
863 } 863 }
864 } 864 }
865 } else if (to == ARRAY) { 865 } else if (to == ARRAY) {
866 if (t == FUNC) { 866 if (t == FUNC) {
867 /* array of function is illegal */ 867 /* array of function is illegal */
868 error(16); 868 error(16);
869 *tpp = gettyp(INT); 869 *tpp = gettyp(INT);
870 return; 870 return;
871 } 871 }
872 if (t == ARRAY && tp->t_dim == 0) { 872 if (t == ARRAY && tp->t_dim == 0) {
873 /* null dimension */ 873 /* null dimension */
874 error(17); 874 error(17);
875 return; 875 return;
876 } 876 }
877 if (t == VOID) { 877 if (t == VOID) {
878 /* illegal use of 'void' */ 878 /* illegal use of 'void' */
879 error(18); 879 error(18);
880 *tpp = gettyp(INT); 880 *tpp = gettyp(INT);
881 } 881 }
882 /* 882 /*
883 * No need to check for incomplete types here as 883 * No need to check for incomplete types here as
884 * length_in_bits already does this. 884 * length_in_bits already does this.
885 */ 885 */
886 } else if (to == NO_TSPEC && t == VOID) { 886 } else if (to == NO_TSPEC && t == VOID) {
887 if (dcs->d_kind == DLK_PROTO_PARAMS) { 887 if (dcs->d_kind == DLK_PROTO_PARAMS) {
888 if (sym->s_scl != ABSTRACT) { 888 if (sym->s_scl != ABSTRACT) {
889 lint_assert(sym->s_name != unnamed); 889 lint_assert(sym->s_name != unnamed);
890 /* void parameter '%s' cannot ... */ 890 /* void parameter '%s' cannot ... */
891 error(61, sym->s_name); 891 error(61, sym->s_name);
892 *tpp = gettyp(INT); 892 *tpp = gettyp(INT);
893 } 893 }
894 } else if (dcs->d_kind == DLK_ABSTRACT) { 894 } else if (dcs->d_kind == DLK_ABSTRACT) {
895 /* ok */ 895 /* ok */
896 } else if (sym->s_scl != TYPEDEF) { 896 } else if (sym->s_scl != TYPEDEF) {
897 /* void type for '%s' */ 897 /* void type for '%s' */
898 error(19, sym->s_name); 898 error(19, sym->s_name);
899 *tpp = gettyp(INT); 899 *tpp = gettyp(INT);
900 } 900 }
901 } 901 }
902 if (t == VOID && to != PTR) { 902 if (t == VOID && to != PTR) {
903 if (tp->t_const || tp->t_volatile) { 903 if (tp->t_const || tp->t_volatile) {
904 /* inappropriate qualifiers with 'void' */ 904 /* inappropriate qualifiers with 'void' */
905 warning(69); 905 warning(69);
906 tp->t_const = tp->t_volatile = false; 906 tp->t_const = tp->t_volatile = false;
907 } 907 }
908 } 908 }
909 tpp = &tp->t_subt; 909 tpp = &tp->t_subt;
910 to = t; 910 to = t;
911 } 911 }
912} 912}
913 913
914/* 914/*
915 * In traditional C, the only portable type for bit-fields is unsigned int. 915 * In traditional C, the only portable type for bit-fields is unsigned int.
916 * 916 *
917 * In C90, the only allowed types for bit-fields are int, signed int and 917 * In C90, the only allowed types for bit-fields are int, signed int and
918 * unsigned int (3.5.2.1). There is no mention of implementation-defined 918 * unsigned int (3.5.2.1). There is no mention of implementation-defined
919 * types. 919 * types.
920 * 920 *
921 * In C99, the only portable types for bit-fields are _Bool, signed int and 921 * In C99, the only portable types for bit-fields are _Bool, signed int and
922 * unsigned int (6.7.2.1p4). In addition, C99 allows "or some other 922 * unsigned int (6.7.2.1p4). In addition, C99 allows "or some other
923 * implementation-defined type". 923 * implementation-defined type".
924 */ 924 */
925static void 925static void
926check_bit_field_type(sym_t *dsym, type_t **const inout_tp, tspec_t *inout_t) 926check_bit_field_type(sym_t *dsym, type_t **const inout_tp, tspec_t *inout_t)
927{ 927{
928 type_t *tp = *inout_tp; 928 type_t *tp = *inout_tp;
929 tspec_t t = *inout_t; 929 tspec_t t = *inout_t;
930 930
931 if (t == CHAR || t == UCHAR || t == SCHAR || 931 if (t == CHAR || t == UCHAR || t == SCHAR ||
932 t == SHORT || t == USHORT || t == ENUM) { 932 t == SHORT || t == USHORT || t == ENUM) {
933 if (!suppress_bitfieldtype) { 933 if (!suppress_bitfieldtype) {
934 /* TODO: Make this an error in C99 mode as well. */ 934 /* TODO: Make this an error in C99 mode as well. */
935 if (!allow_trad && !allow_c99) { 935 if (!allow_trad && !allow_c99) {
936 type_t *btp = block_dup_type(tp); 936 type_t *btp = block_dup_type(tp);
937 btp->t_bitfield = false; 937 btp->t_bitfield = false;
938 /* bit-field type '%s' invalid in ANSI C */ 938 /* bit-field type '%s' invalid in ANSI C */
939 warning(273, type_name(btp)); 939 warning(273, type_name(btp));
940 } else if (pflag) { 940 } else if (pflag) {
941 type_t *btp = block_dup_type(tp); 941 type_t *btp = block_dup_type(tp);
942 btp->t_bitfield = false; 942 btp->t_bitfield = false;
943 /* nonportable bit-field type '%s' */ 943 /* nonportable bit-field type '%s' */
944 warning(34, type_name(btp)); 944 warning(34, type_name(btp));
945 } 945 }
946 } 946 }
947 } else if (t == INT && dcs->d_sign_mod == NO_TSPEC) { 947 } else if (t == INT && dcs->d_sign_mod == NO_TSPEC) {
948 if (pflag && !suppress_bitfieldtype) { 948 if (pflag && !suppress_bitfieldtype) {
949 /* bit-field of type plain 'int' has ... */ 949 /* bit-field of type plain 'int' has ... */
950 warning(344); 950 warning(344);
951 } 951 }
952 } else if (!(t == INT || t == UINT || t == BOOL 952 } else if (!(t == INT || t == UINT || t == BOOL
953 || (is_integer(t) && (suppress_bitfieldtype || allow_gcc)))) { 953 || (is_integer(t) && (suppress_bitfieldtype || allow_gcc)))) {
954 954
955 type_t *btp = block_dup_type(tp); 955 type_t *btp = block_dup_type(tp);
956 btp->t_bitfield = false; 956 btp->t_bitfield = false;
957 /* illegal bit-field type '%s' */ 957 /* illegal bit-field type '%s' */
958 warning(35, type_name(btp)); 958 warning(35, type_name(btp));
959 959
960 unsigned int width = tp->t_bit_field_width; 960 unsigned int width = tp->t_bit_field_width;
961 dsym->s_type = tp = block_dup_type(gettyp(t = INT)); 961 dsym->s_type = tp = block_dup_type(gettyp(t = INT));
962 if ((tp->t_bit_field_width = width) > size_in_bits(t)) 962 if ((tp->t_bit_field_width = width) > size_in_bits(t))
963 tp->t_bit_field_width = size_in_bits(t); 963 tp->t_bit_field_width = size_in_bits(t);
964 *inout_t = t; 964 *inout_t = t;
965 *inout_tp = tp; 965 *inout_tp = tp;
966 } 966 }
967} 967}
968 968
969static void 969static void
970check_bit_field(sym_t *dsym, tspec_t *inout_t, type_t **const inout_tp) 970check_bit_field(sym_t *dsym, tspec_t *inout_t, type_t **const inout_tp)
971{ 971{
972 972
973 check_bit_field_type(dsym, inout_tp, inout_t); 973 check_bit_field_type(dsym, inout_tp, inout_t);
974 974
975 type_t *tp = *inout_tp; 975 type_t *tp = *inout_tp;
976 tspec_t t = *inout_t; 976 tspec_t t = *inout_t;
977 unsigned int t_width = size_in_bits(t); 977 unsigned int t_width = size_in_bits(t);
978 if (tp->t_bit_field_width > t_width) { 978 if (tp->t_bit_field_width > t_width) {
979 /* illegal bit-field size: %d */ 979 /* illegal bit-field size: %d */
980 error(36, (int)tp->t_bit_field_width); 980 error(36, (int)tp->t_bit_field_width);
981 tp->t_bit_field_width = t_width; 981 tp->t_bit_field_width = t_width;
982 } else if (tp->t_bit_field_width == 0 && dsym->s_name != unnamed) { 982 } else if (tp->t_bit_field_width == 0 && dsym->s_name != unnamed) {
983 /* zero size bit-field */ 983 /* zero size bit-field */
984 error(37); 984 error(37);
985 tp->t_bit_field_width = t_width; 985 tp->t_bit_field_width = t_width;
986 } 986 }
987 if (dsym->s_scl == UNION_MEMBER) { 987 if (dsym->s_scl == UNION_MEMBER) {
988 /* bit-field in union is very unusual */ 988 /* bit-field in union is very unusual */
989 warning(41); 989 warning(41);
990 dsym->s_type->t_bitfield = false; 990 dsym->s_type->t_bitfield = false;
991 dsym->s_bitfield = false; 991 dsym->s_bitfield = false;
992 } 992 }
993} 993}
994 994
995/* Aligns the next structure element as required. */ 995/* Aligns the next structure element as required. */
996static void 996static void
997dcs_align(unsigned int member_alignment, unsigned int bit_field_width) 997dcs_align(unsigned int member_alignment, unsigned int bit_field_width)
998{ 998{
999 999
1000 if (member_alignment > dcs->d_sou_align_in_bits) 1000 if (member_alignment > dcs->d_sou_align_in_bits)
1001 dcs->d_sou_align_in_bits = member_alignment; 1001 dcs->d_sou_align_in_bits = member_alignment;
1002 1002
1003 unsigned int offset = (dcs->d_sou_size_in_bits + member_alignment - 1) 1003 unsigned int offset = (dcs->d_sou_size_in_bits + member_alignment - 1)
1004 & ~(member_alignment - 1); 1004 & ~(member_alignment - 1);
1005 if (bit_field_width == 0 1005 if (bit_field_width == 0
1006 || dcs->d_sou_size_in_bits + bit_field_width > offset) 1006 || dcs->d_sou_size_in_bits + bit_field_width > offset)
1007 dcs->d_sou_size_in_bits = offset; 1007 dcs->d_sou_size_in_bits = offset;
1008} 1008}
1009 1009
1010/* Add a member to the struct or union type that is being built in 'dcs'. */ 1010/* Add a member to the struct or union type that is being built in 'dcs'. */
1011static void 1011static void
1012dcs_add_member(sym_t *mem) 1012dcs_add_member(sym_t *mem)
1013{ 1013{
1014 type_t *tp = mem->s_type; 1014 type_t *tp = mem->s_type;
1015 1015
1016 unsigned int union_size = 0; 1016 unsigned int union_size = 0;
1017 if (dcs->d_kind == DLK_UNION) { 1017 if (dcs->d_kind == DLK_UNION) {
1018 union_size = dcs->d_sou_size_in_bits; 1018 union_size = dcs->d_sou_size_in_bits;
1019 dcs->d_sou_size_in_bits = 0; 1019 dcs->d_sou_size_in_bits = 0;
1020 } 1020 }
1021 1021
1022 if (mem->s_bitfield) { 1022 if (mem->s_bitfield) {
1023 dcs_align(alignment_in_bits(tp), tp->t_bit_field_width); 1023 dcs_align(alignment_in_bits(tp), tp->t_bit_field_width);
1024 // XXX: Why round down? 1024 // XXX: Why round down?
1025 mem->u.s_member.sm_offset_in_bits = dcs->d_sou_size_in_bits 1025 mem->u.s_member.sm_offset_in_bits = dcs->d_sou_size_in_bits
1026 - dcs->d_sou_size_in_bits % size_in_bits(tp->t_tspec); 1026 - dcs->d_sou_size_in_bits % size_in_bits(tp->t_tspec);
1027 tp->t_bit_field_offset = dcs->d_sou_size_in_bits 1027 tp->t_bit_field_offset = dcs->d_sou_size_in_bits
1028 - mem->u.s_member.sm_offset_in_bits; 1028 - mem->u.s_member.sm_offset_in_bits;
1029 dcs->d_sou_size_in_bits += tp->t_bit_field_width; 1029 dcs->d_sou_size_in_bits += tp->t_bit_field_width;
1030 } else { 1030 } else {
1031 dcs_align(alignment_in_bits(tp), 0); 1031 dcs_align(alignment_in_bits(tp), 0);
1032 mem->u.s_member.sm_offset_in_bits = dcs->d_sou_size_in_bits; 1032 mem->u.s_member.sm_offset_in_bits = dcs->d_sou_size_in_bits;
1033 dcs->d_sou_size_in_bits += type_size_in_bits(tp); 1033 dcs->d_sou_size_in_bits += type_size_in_bits(tp);
1034 } 1034 }
1035 1035
1036 if (union_size > dcs->d_sou_size_in_bits) 1036 if (union_size > dcs->d_sou_size_in_bits)
1037 dcs->d_sou_size_in_bits = union_size; 1037 dcs->d_sou_size_in_bits = union_size;
1038} 1038}
1039 1039
1040sym_t * 1040sym_t *
@@ -1796,1388 +1796,1388 @@ check_extern_declaration(const sym_t *sy @@ -1796,1388 +1796,1388 @@ check_extern_declaration(const sym_t *sy
1796 } 1796 }
1797 if (any_query_enabled && 1797 if (any_query_enabled &&
1798 sym->s_type->t_tspec == FUNC && 1798 sym->s_type->t_tspec == FUNC &&
1799 sym->s_scl == EXTERN && 1799 sym->s_scl == EXTERN &&
1800 sym->s_def == DECL && 1800 sym->s_def == DECL &&
1801 !in_system_header) { 1801 !in_system_header) {
1802 /* redundant 'extern' in function declaration of '%s' */ 1802 /* redundant 'extern' in function declaration of '%s' */
1803 query_message(13, sym->s_name); 1803 query_message(13, sym->s_name);
1804 } 1804 }
1805} 1805}
1806 1806
1807/* 1807/*
1808 * Check whether the symbol cannot be initialized due to type/storage class. 1808 * Check whether the symbol cannot be initialized due to type/storage class.
1809 * Return whether an error has been detected. 1809 * Return whether an error has been detected.
1810 */ 1810 */
1811static bool 1811static bool
1812check_init(sym_t *sym) 1812check_init(sym_t *sym)
1813{ 1813{
1814 1814
1815 if (sym->s_type->t_tspec == FUNC) { 1815 if (sym->s_type->t_tspec == FUNC) {
1816 /* cannot initialize function '%s' */ 1816 /* cannot initialize function '%s' */
1817 error(24, sym->s_name); 1817 error(24, sym->s_name);
1818 return true; 1818 return true;
1819 } 1819 }
1820 if (sym->s_scl == TYPEDEF) { 1820 if (sym->s_scl == TYPEDEF) {
1821 /* cannot initialize typedef '%s' */ 1821 /* cannot initialize typedef '%s' */
1822 error(25, sym->s_name); 1822 error(25, sym->s_name);
1823 return true; 1823 return true;
1824 } 1824 }
1825 if (sym->s_scl == EXTERN && sym->s_def == DECL) { 1825 if (sym->s_scl == EXTERN && sym->s_def == DECL) {
1826 if (dcs->d_kind == DLK_EXTERN) { 1826 if (dcs->d_kind == DLK_EXTERN) {
1827 /* cannot initialize extern declaration '%s' */ 1827 /* cannot initialize extern declaration '%s' */
1828 warning(26, sym->s_name); 1828 warning(26, sym->s_name);
1829 } else { 1829 } else {
1830 /* cannot initialize extern declaration '%s' */ 1830 /* cannot initialize extern declaration '%s' */
1831 error(26, sym->s_name); 1831 error(26, sym->s_name);
1832 return true; 1832 return true;
1833 } 1833 }
1834 } 1834 }
1835 1835
1836 return false; 1836 return false;
1837} 1837}
1838 1838
1839/* 1839/*
1840 * Compares a prototype declaration with the remembered arguments of a previous 1840 * Compares a prototype declaration with the remembered arguments of a previous
1841 * old-style function definition. 1841 * old-style function definition.
1842 */ 1842 */
1843static bool 1843static bool
1844check_old_style_definition(sym_t *rdsym, sym_t *dsym) 1844check_old_style_definition(sym_t *rdsym, sym_t *dsym)
1845{ 1845{
1846 1846
1847 sym_t *args = rdsym->u.s_old_style_args; 1847 sym_t *args = rdsym->u.s_old_style_args;
1848 sym_t *pargs = dsym->s_type->t_args; 1848 sym_t *pargs = dsym->s_type->t_args;
1849 1849
1850 bool msg = false; 1850 bool msg = false;
1851 1851
1852 int narg = 0; 1852 int narg = 0;
1853 for (sym_t *arg = args; arg != NULL; arg = arg->s_next) 1853 for (sym_t *arg = args; arg != NULL; arg = arg->s_next)
1854 narg++; 1854 narg++;
1855 int nparg = 0; 1855 int nparg = 0;
1856 for (sym_t *parg = pargs; parg != NULL; parg = parg->s_next) 1856 for (sym_t *parg = pargs; parg != NULL; parg = parg->s_next)
1857 nparg++; 1857 nparg++;
1858 if (narg != nparg) { 1858 if (narg != nparg) {
1859 /* prototype does not match old-style definition */ 1859 /* prototype does not match old-style definition */
1860 error(63); 1860 error(63);
1861 msg = true; 1861 msg = true;
1862 goto end; 1862 goto end;
1863 } 1863 }
1864 1864
1865 sym_t *arg = args; 1865 sym_t *arg = args;
1866 sym_t *parg = pargs; 1866 sym_t *parg = pargs;
1867 int n = 1; 1867 int n = 1;
1868 while (narg-- > 0) { 1868 while (narg-- > 0) {
1869 bool dowarn = false; 1869 bool dowarn = false;
1870 /* 1870 /*
1871 * If it does not match due to promotion and lint runs in 1871 * If it does not match due to promotion and lint runs in
1872 * "traditional to C90" migration mode, print only a warning. 1872 * "traditional to C90" migration mode, print only a warning.
1873 * 1873 *
1874 * XXX: Where is this "only a warning"? 1874 * XXX: Where is this "only a warning"?
1875 */ 1875 */
1876 if (!types_compatible(arg->s_type, parg->s_type, 1876 if (!types_compatible(arg->s_type, parg->s_type,
1877 true, true, &dowarn) || 1877 true, true, &dowarn) ||
1878 dowarn) { 1878 dowarn) {
1879 /* prototype does not match old-style ... */ 1879 /* prototype does not match old-style ... */
1880 error(299, n); 1880 error(299, n);
1881 msg = true; 1881 msg = true;
1882 } 1882 }
1883 arg = arg->s_next; 1883 arg = arg->s_next;
1884 parg = parg->s_next; 1884 parg = parg->s_next;
1885 n++; 1885 n++;
1886 } 1886 }
1887 1887
1888end: 1888end:
1889 if (msg && rflag) { 1889 if (msg && rflag) {
1890 /* old-style definition */ 1890 /* old-style definition */
1891 message_at(300, &rdsym->s_def_pos); 1891 message_at(300, &rdsym->s_def_pos);
1892 } 1892 }
1893 1893
1894 return msg; 1894 return msg;
1895} 1895}
1896 1896
1897/* Process a single external or 'static' declarator. */ 1897/* Process a single external or 'static' declarator. */
1898static void 1898static void
1899declare_extern(sym_t *dsym, bool has_initializer, sbuf_t *renaming) 1899declare_extern(sym_t *dsym, bool has_initializer, sbuf_t *renaming)
1900{ 1900{
1901 1901
1902 if (renaming != NULL) { 1902 if (renaming != NULL) {
1903 lint_assert(dsym->s_rename == NULL); 1903 lint_assert(dsym->s_rename == NULL);
1904 1904
1905 char *s = level_zero_alloc(1, renaming->sb_len + 1, "string"); 1905 char *s = level_zero_alloc(1, renaming->sb_len + 1, "string");
1906 (void)memcpy(s, renaming->sb_name, renaming->sb_len + 1); 1906 (void)memcpy(s, renaming->sb_name, renaming->sb_len + 1);
1907 dsym->s_rename = s; 1907 dsym->s_rename = s;
1908 } 1908 }
1909 1909
1910 check_extern_declaration(dsym); 1910 check_extern_declaration(dsym);
1911 1911
1912 check_function_definition(dsym, true); 1912 check_function_definition(dsym, true);
1913 1913
1914 check_type(dsym); 1914 check_type(dsym);
1915 1915
1916 if (has_initializer && !check_init(dsym)) 1916 if (has_initializer && !check_init(dsym))
1917 dsym->s_def = DEF; 1917 dsym->s_def = DEF;
1918 1918
1919 /* 1919 /*
1920 * Declarations of functions are marked as "tentative" in 1920 * Declarations of functions are marked as "tentative" in
1921 * declarator_name(). This is wrong because there are no 1921 * declarator_name(). This is wrong because there are no
1922 * tentative function definitions. 1922 * tentative function definitions.
1923 */ 1923 */
1924 if (dsym->s_type->t_tspec == FUNC && dsym->s_def == TDEF) 1924 if (dsym->s_type->t_tspec == FUNC && dsym->s_def == TDEF)
1925 dsym->s_def = DECL; 1925 dsym->s_def = DECL;
1926 1926
1927 if (dcs->d_inline) { 1927 if (dcs->d_inline) {
1928 if (dsym->s_type->t_tspec == FUNC) { 1928 if (dsym->s_type->t_tspec == FUNC) {
1929 dsym->s_inline = true; 1929 dsym->s_inline = true;
1930 } else { 1930 } else {
1931 /* variable '%s' declared inline */ 1931 /* variable '%s' declared inline */
1932 warning(268, dsym->s_name); 1932 warning(268, dsym->s_name);
1933 } 1933 }
1934 } 1934 }
1935 1935
1936 /* Write the declaration into the output file */ 1936 /* Write the declaration into the output file */
1937 if (plibflg && llibflg && 1937 if (plibflg && llibflg &&
1938 dsym->s_type->t_tspec == FUNC && dsym->s_type->t_proto) { 1938 dsym->s_type->t_tspec == FUNC && dsym->s_type->t_proto) {
1939 /* 1939 /*
1940 * With both LINTLIBRARY and PROTOLIB the prototype is 1940 * With both LINTLIBRARY and PROTOLIB the prototype is
1941 * written as a function definition to the output file. 1941 * written as a function definition to the output file.
1942 */ 1942 */
1943 bool rval = dsym->s_type->t_subt->t_tspec != VOID; 1943 bool rval = dsym->s_type->t_subt->t_tspec != VOID;
1944 outfdef(dsym, &dsym->s_def_pos, rval, false, NULL); 1944 outfdef(dsym, &dsym->s_def_pos, rval, false, NULL);
1945 } else if (!is_compiler_builtin(dsym->s_name) 1945 } else if (!is_compiler_builtin(dsym->s_name)
1946 && !(has_initializer && dsym->s_type->t_incomplete_array)) { 1946 && !(has_initializer && dsym->s_type->t_incomplete_array)) {
1947 outsym(dsym, dsym->s_scl, dsym->s_def); 1947 outsym(dsym, dsym->s_scl, dsym->s_def);
1948 } 1948 }
1949 1949
1950 sym_t *rdsym = dcs->d_redeclared_symbol; 1950 sym_t *rdsym = dcs->d_redeclared_symbol;
1951 if (rdsym != NULL) { 1951 if (rdsym != NULL) {
1952 1952
1953 /* 1953 /*
1954 * If the old symbol stems from an old-style function 1954 * If the old symbol stems from an old-style function
1955 * definition, we have remembered the params in 1955 * definition, we have remembered the params in
1956 * rdsym->s_old_style_args and compare them with the params 1956 * rdsym->s_old_style_args and compare them with the params
1957 * of the prototype. 1957 * of the prototype.
1958 */ 1958 */
1959 bool redec = rdsym->s_osdef && dsym->s_type->t_proto && 1959 bool redec = rdsym->s_osdef && dsym->s_type->t_proto &&
1960 check_old_style_definition(rdsym, dsym); 1960 check_old_style_definition(rdsym, dsym);
1961 1961
1962 bool dowarn = false; 1962 bool dowarn = false;
1963 if (!redec && !check_redeclaration(dsym, &dowarn)) { 1963 if (!redec && !check_redeclaration(dsym, &dowarn)) {
1964 if (dowarn) { 1964 if (dowarn) {
1965 /* TODO: Make this an error in C99 mode as well. */ 1965 /* TODO: Make this an error in C99 mode as well. */
1966 if (!allow_trad && !allow_c99) 1966 if (!allow_trad && !allow_c99)
1967 /* redeclaration of '%s' */ 1967 /* redeclaration of '%s' */
1968 error(27, dsym->s_name); 1968 error(27, dsym->s_name);
1969 else 1969 else
1970 /* redeclaration of '%s' */ 1970 /* redeclaration of '%s' */
1971 warning(27, dsym->s_name); 1971 warning(27, dsym->s_name);
1972 print_previous_declaration(rdsym); 1972 print_previous_declaration(rdsym);
1973 } 1973 }
1974 1974
1975 /* 1975 /*
1976 * Take over the remembered params if the new symbol 1976 * Take over the remembered params if the new symbol
1977 * is not a prototype. 1977 * is not a prototype.
1978 */ 1978 */
1979 if (rdsym->s_osdef && !dsym->s_type->t_proto) { 1979 if (rdsym->s_osdef && !dsym->s_type->t_proto) {
1980 dsym->s_osdef = rdsym->s_osdef; 1980 dsym->s_osdef = rdsym->s_osdef;
1981 dsym->u.s_old_style_args = 1981 dsym->u.s_old_style_args =
1982 rdsym->u.s_old_style_args; 1982 rdsym->u.s_old_style_args;
1983 dsym->s_def_pos = rdsym->s_def_pos; 1983 dsym->s_def_pos = rdsym->s_def_pos;
1984 } 1984 }
1985 1985
1986 if (rdsym->s_type->t_proto && !dsym->s_type->t_proto) 1986 if (rdsym->s_type->t_proto && !dsym->s_type->t_proto)
1987 dsym->s_def_pos = rdsym->s_def_pos; 1987 dsym->s_def_pos = rdsym->s_def_pos;
1988 else if (rdsym->s_def == DEF && dsym->s_def != DEF) 1988 else if (rdsym->s_def == DEF && dsym->s_def != DEF)
1989 dsym->s_def_pos = rdsym->s_def_pos; 1989 dsym->s_def_pos = rdsym->s_def_pos;
1990 1990
1991 copy_usage_info(dsym, rdsym); 1991 copy_usage_info(dsym, rdsym);
1992 1992
1993 /* Once a name is defined, it remains defined. */ 1993 /* Once a name is defined, it remains defined. */
1994 if (rdsym->s_def == DEF) 1994 if (rdsym->s_def == DEF)
1995 dsym->s_def = DEF; 1995 dsym->s_def = DEF;
1996 1996
1997 /* once a function is inline, it remains inline */ 1997 /* once a function is inline, it remains inline */
1998 if (rdsym->s_inline) 1998 if (rdsym->s_inline)
1999 dsym->s_inline = true; 1999 dsym->s_inline = true;
2000 2000
2001 complete_type(dsym, rdsym); 2001 complete_type(dsym, rdsym);
2002 } 2002 }
2003 2003
2004 rmsym(rdsym); 2004 rmsym(rdsym);
2005 } 2005 }
2006 2006
2007 if (dsym->s_scl == TYPEDEF) { 2007 if (dsym->s_scl == TYPEDEF) {
2008 dsym->s_type = block_dup_type(dsym->s_type); 2008 dsym->s_type = block_dup_type(dsym->s_type);
2009 dsym->s_type->t_typedef = true; 2009 dsym->s_type->t_typedef = true;
2010 set_first_typedef(dsym->s_type, dsym); 2010 set_first_typedef(dsym->s_type, dsym);
2011 } 2011 }
2012} 2012}
2013 2013
2014void 2014void
2015declare(sym_t *decl, bool has_initializer, sbuf_t *renaming) 2015declare(sym_t *decl, bool has_initializer, sbuf_t *renaming)
2016{ 2016{
2017 2017
2018 if (dcs->d_kind == DLK_EXTERN) 2018 if (dcs->d_kind == DLK_EXTERN)
2019 declare_extern(decl, has_initializer, renaming); 2019 declare_extern(decl, has_initializer, renaming);
2020 else if (dcs->d_kind == DLK_OLD_STYLE_ARGS || 2020 else if (dcs->d_kind == DLK_OLD_STYLE_ARGS ||
2021 dcs->d_kind == DLK_PROTO_PARAMS) { 2021 dcs->d_kind == DLK_PROTO_PARAMS) {
2022 if (renaming != NULL) { 2022 if (renaming != NULL) {
2023 /* symbol renaming can't be used on function arguments */ 2023 /* symbol renaming can't be used on function arguments */
2024 error(310); 2024 error(310);
2025 } else 2025 } else
2026 (void)declare_argument(decl, has_initializer); 2026 (void)declare_argument(decl, has_initializer);
2027 } else { 2027 } else {
2028 lint_assert(dcs->d_kind == DLK_AUTO); 2028 lint_assert(dcs->d_kind == DLK_AUTO);
2029 if (renaming != NULL) { 2029 if (renaming != NULL) {
2030 /* symbol renaming can't be used on automatic variables */ 2030 /* symbol renaming can't be used on automatic variables */
2031 error(311); 2031 error(311);
2032 } else 2032 } else
2033 declare_local(decl, has_initializer); 2033 declare_local(decl, has_initializer);
2034 } 2034 }
2035} 2035}
2036 2036
2037/* 2037/*
2038 * Copies information about usage into a new symbol table entry of 2038 * Copies information about usage into a new symbol table entry of
2039 * the same symbol. 2039 * the same symbol.
2040 */ 2040 */
2041void 2041void
2042copy_usage_info(sym_t *sym, sym_t *rdsym) 2042copy_usage_info(sym_t *sym, sym_t *rdsym)
2043{ 2043{
2044 2044
2045 sym->s_set_pos = rdsym->s_set_pos; 2045 sym->s_set_pos = rdsym->s_set_pos;
2046 sym->s_use_pos = rdsym->s_use_pos; 2046 sym->s_use_pos = rdsym->s_use_pos;
2047 sym->s_set = rdsym->s_set; 2047 sym->s_set = rdsym->s_set;
2048 sym->s_used = rdsym->s_used; 2048 sym->s_used = rdsym->s_used;
2049} 2049}
2050 2050
2051/* 2051/*
2052 * Prints an error and returns true if a symbol is redeclared/redefined. 2052 * Prints an error and returns true if a symbol is redeclared/redefined.
2053 * Otherwise, returns false and, in some cases of minor problems, prints 2053 * Otherwise, returns false and, in some cases of minor problems, prints
2054 * a warning. 2054 * a warning.
2055 */ 2055 */
2056bool 2056bool
2057check_redeclaration(sym_t *dsym, bool *dowarn) 2057check_redeclaration(sym_t *dsym, bool *dowarn)
2058{ 2058{
2059 2059
2060 sym_t *rdsym = dcs->d_redeclared_symbol; 2060 sym_t *rdsym = dcs->d_redeclared_symbol;
2061 if (rdsym->s_scl == ENUM_CONST) { 2061 if (rdsym->s_scl == ENUM_CONST) {
2062 /* redeclaration of '%s' */ 2062 /* redeclaration of '%s' */
2063 error(27, dsym->s_name); 2063 error(27, dsym->s_name);
2064 print_previous_declaration(rdsym); 2064 print_previous_declaration(rdsym);
2065 return true; 2065 return true;
2066 } 2066 }
2067 if (rdsym->s_scl == TYPEDEF) { 2067 if (rdsym->s_scl == TYPEDEF) {
2068 /* typedef '%s' redeclared */ 2068 /* typedef '%s' redeclared */
2069 error(89, dsym->s_name); 2069 error(89, dsym->s_name);
2070 print_previous_declaration(rdsym); 2070 print_previous_declaration(rdsym);
2071 return true; 2071 return true;
2072 } 2072 }
2073 if (dsym->s_scl == TYPEDEF) { 2073 if (dsym->s_scl == TYPEDEF) {
2074 /* redeclaration of '%s' */ 2074 /* redeclaration of '%s' */
2075 error(27, dsym->s_name); 2075 error(27, dsym->s_name);
2076 print_previous_declaration(rdsym); 2076 print_previous_declaration(rdsym);
2077 return true; 2077 return true;
2078 } 2078 }
2079 if (rdsym->s_def == DEF && dsym->s_def == DEF) { 2079 if (rdsym->s_def == DEF && dsym->s_def == DEF) {
2080 /* redefinition of '%s' */ 2080 /* redefinition of '%s' */
2081 error(28, dsym->s_name); 2081 error(28, dsym->s_name);
2082 print_previous_declaration(rdsym); 2082 print_previous_declaration(rdsym);
2083 return true; 2083 return true;
2084 } 2084 }
2085 if (!types_compatible(rdsym->s_type, dsym->s_type, 2085 if (!types_compatible(rdsym->s_type, dsym->s_type,
2086 false, false, dowarn)) { 2086 false, false, dowarn)) {
2087 /* redeclaration of '%s' with type '%s', expected '%s' */ 2087 /* redeclaration of '%s' with type '%s', expected '%s' */
2088 error(347, dsym->s_name, 2088 error(347, dsym->s_name,
2089 type_name(dsym->s_type), type_name(rdsym->s_type)); 2089 type_name(dsym->s_type), type_name(rdsym->s_type));
2090 print_previous_declaration(rdsym); 2090 print_previous_declaration(rdsym);
2091 return true; 2091 return true;
2092 } 2092 }
2093 if (rdsym->s_scl == EXTERN && dsym->s_scl == EXTERN) 2093 if (rdsym->s_scl == EXTERN && dsym->s_scl == EXTERN)
2094 return false; 2094 return false;
2095 if (rdsym->s_scl == STATIC && dsym->s_scl == STATIC) 2095 if (rdsym->s_scl == STATIC && dsym->s_scl == STATIC)
2096 return false; 2096 return false;
2097 if (rdsym->s_scl == STATIC && dsym->s_def == DECL) 2097 if (rdsym->s_scl == STATIC && dsym->s_def == DECL)
2098 return false; 2098 return false;
2099 if (rdsym->s_scl == EXTERN && rdsym->s_def == DEF) { 2099 if (rdsym->s_scl == EXTERN && rdsym->s_def == DEF) {
2100 /* 2100 /*
2101 * All cases except "int a = 1; static int a;" are caught 2101 * All cases except "int a = 1; static int a;" are caught
2102 * above with or without a warning 2102 * above with or without a warning
2103 */ 2103 */
2104 /* redeclaration of '%s' */ 2104 /* redeclaration of '%s' */
2105 error(27, dsym->s_name); 2105 error(27, dsym->s_name);
2106 print_previous_declaration(rdsym); 2106 print_previous_declaration(rdsym);
2107 return true; 2107 return true;
2108 } 2108 }
2109 if (rdsym->s_scl == EXTERN) { 2109 if (rdsym->s_scl == EXTERN) {
2110 /* '%s' was previously declared extern, becomes static */ 2110 /* '%s' was previously declared extern, becomes static */
2111 warning(29, dsym->s_name); 2111 warning(29, dsym->s_name);
2112 print_previous_declaration(rdsym); 2112 print_previous_declaration(rdsym);
2113 return false; 2113 return false;
2114 } 2114 }
2115 /* 2115 /*
2116 * Now it's one of: 2116 * Now it's one of:
2117 * "static a; int a;", "static a; int a = 1;", "static a = 1; int a;" 2117 * "static a; int a;", "static a; int a = 1;", "static a = 1; int a;"
2118 */ 2118 */
2119 /* TODO: Make this an error in C99 mode as well. */ 2119 /* TODO: Make this an error in C99 mode as well. */
2120 if (!allow_trad && !allow_c99) { 2120 if (!allow_trad && !allow_c99) {
2121 /* redeclaration of '%s'; ANSI C requires static */ 2121 /* redeclaration of '%s'; ANSI C requires static */
2122 warning(30, dsym->s_name); 2122 warning(30, dsym->s_name);
2123 print_previous_declaration(rdsym); 2123 print_previous_declaration(rdsym);
2124 } 2124 }
2125 dsym->s_scl = STATIC; 2125 dsym->s_scl = STATIC;
2126 return false; 2126 return false;
2127} 2127}
2128 2128
2129static bool 2129static bool
2130qualifiers_correspond(const type_t *tp1, const type_t *tp2, bool ignqual) 2130qualifiers_correspond(const type_t *tp1, const type_t *tp2, bool ignqual)
2131{ 2131{
2132 2132
2133 if (tp1->t_const != tp2->t_const && !ignqual && allow_c90) 2133 if (tp1->t_const != tp2->t_const && !ignqual && allow_c90)
2134 return false; 2134 return false;
2135 if (tp1->t_volatile != tp2->t_volatile && !ignqual && allow_c90) 2135 if (tp1->t_volatile != tp2->t_volatile && !ignqual && allow_c90)
2136 return false; 2136 return false;
2137 return true; 2137 return true;
2138} 2138}
2139 2139
2140bool 2140bool
2141pointer_types_are_compatible(const type_t *tp1, const type_t *tp2, bool ignqual) 2141pointer_types_are_compatible(const type_t *tp1, const type_t *tp2, bool ignqual)
2142{ 2142{
2143 2143
2144 return tp1->t_tspec == VOID || tp2->t_tspec == VOID || 2144 return tp1->t_tspec == VOID || tp2->t_tspec == VOID ||
2145 qualifiers_correspond(tp1, tp2, ignqual); 2145 qualifiers_correspond(tp1, tp2, ignqual);
2146} 2146}
2147 2147
2148static bool 2148static bool
2149prototypes_compatible(const type_t *tp1, const type_t *tp2, bool *dowarn) 2149prototypes_compatible(const type_t *tp1, const type_t *tp2, bool *dowarn)
2150{ 2150{
2151 2151
2152 if (tp1->t_vararg != tp2->t_vararg) 2152 if (tp1->t_vararg != tp2->t_vararg)
2153 return false; 2153 return false;
2154 2154
2155 sym_t *a1 = tp1->t_args; 2155 sym_t *a1 = tp1->t_args;
2156 sym_t *a2 = tp2->t_args; 2156 sym_t *a2 = tp2->t_args;
2157 2157
2158 for (; a1 != NULL && a2 != NULL; a1 = a1->s_next, a2 = a2->s_next) { 2158 for (; a1 != NULL && a2 != NULL; a1 = a1->s_next, a2 = a2->s_next) {
2159 if (!types_compatible(a1->s_type, a2->s_type, 2159 if (!types_compatible(a1->s_type, a2->s_type,
2160 true, false, dowarn)) 2160 true, false, dowarn))
2161 return false; 2161 return false;
2162 } 2162 }
2163 return a1 == a2; 2163 return a1 == a2;
2164} 2164}
2165 2165
2166/* 2166/*
2167 * Returns whether all parameters of a prototype are compatible with an 2167 * Returns whether all parameters of a prototype are compatible with an
2168 * old-style function declaration. 2168 * old-style function declaration.
2169 * 2169 *
2170 * This is the case if the following conditions are met: 2170 * This is the case if the following conditions are met:
2171 * 1. the prototype has a fixed number of parameters 2171 * 1. the prototype has a fixed number of parameters
2172 * 2. no parameter is of type float 2172 * 2. no parameter is of type float
2173 * 3. no parameter is converted to another type if integer promotion 2173 * 3. no parameter is converted to another type if integer promotion
2174 * is applied on it 2174 * is applied on it
2175 */ 2175 */
2176static bool 2176static bool
2177matches_no_arg_function(const type_t *tp, bool *dowarn) 2177matches_no_arg_function(const type_t *tp, bool *dowarn)
2178{ 2178{
2179 2179
2180 if (tp->t_vararg && dowarn != NULL) 2180 if (tp->t_vararg && dowarn != NULL)
2181 *dowarn = true; 2181 *dowarn = true;
2182 for (sym_t *arg = tp->t_args; arg != NULL; arg = arg->s_next) { 2182 for (sym_t *arg = tp->t_args; arg != NULL; arg = arg->s_next) {
2183 tspec_t t = arg->s_type->t_tspec; 2183 tspec_t t = arg->s_type->t_tspec;
2184 if (t == FLOAT || 2184 if (t == FLOAT ||
2185 t == CHAR || t == SCHAR || t == UCHAR || 2185 t == CHAR || t == SCHAR || t == UCHAR ||
2186 t == SHORT || t == USHORT) { 2186 t == SHORT || t == USHORT) {
2187 if (dowarn != NULL) 2187 if (dowarn != NULL)
2188 *dowarn = true; 2188 *dowarn = true;
2189 } 2189 }
2190 } 2190 }
2191 /* FIXME: Always returning true cannot be correct. */ 2191 /* FIXME: Always returning true cannot be correct. */
2192 return true; 2192 return true;
2193} 2193}
2194 2194
2195/*- 2195/*-
2196 * ignqual ignore type qualifiers; used for function parameters 2196 * ignqual ignore type qualifiers; used for function parameters
2197 * promot promote the left type; used for comparison of parameters of 2197 * promot promote the left type; used for comparison of parameters of
2198 * old-style function definitions with parameters of prototypes. 2198 * old-style function definitions with parameters of prototypes.
2199 * *dowarn is set to true if an old-style function declaration is not 2199 * *dowarn is set to true if an old-style function declaration is not
2200 * compatible with a prototype 2200 * compatible with a prototype
2201 */ 2201 */
2202bool 2202bool
2203types_compatible(const type_t *tp1, const type_t *tp2, 2203types_compatible(const type_t *tp1, const type_t *tp2,
2204 bool ignqual, bool promot, bool *dowarn) 2204 bool ignqual, bool promot, bool *dowarn)
2205{ 2205{
2206 2206
2207 while (tp1 != NULL && tp2 != NULL) { 2207 while (tp1 != NULL && tp2 != NULL) {
2208 tspec_t t = tp1->t_tspec; 2208 tspec_t t = tp1->t_tspec;
2209 if (promot) { 2209 if (promot) {
2210 if (t == FLOAT) 2210 if (t == FLOAT)
2211 t = DOUBLE; 2211 t = DOUBLE;
2212 else if (t == CHAR || t == SCHAR) 2212 else if (t == CHAR || t == SCHAR)
2213 t = INT; 2213 t = INT;
2214 else if (t == UCHAR) 2214 else if (t == UCHAR)
2215 t = allow_c90 ? INT : UINT; 2215 t = allow_c90 ? INT : UINT;
2216 else if (t == SHORT) 2216 else if (t == SHORT)
2217 t = INT; 2217 t = INT;
2218 else if (t == USHORT) { 2218 else if (t == USHORT) {
2219 /* CONSTCOND */ 2219 /* CONSTCOND */
2220 t = TARG_INT_MAX < TARG_USHRT_MAX || !allow_c90 2220 t = TARG_INT_MAX < TARG_USHRT_MAX || !allow_c90
2221 ? UINT : INT; 2221 ? UINT : INT;
2222 } 2222 }
2223 } 2223 }
2224 2224
2225 if (t != tp2->t_tspec) 2225 if (t != tp2->t_tspec)
2226 return false; 2226 return false;
2227 2227
2228 if (!qualifiers_correspond(tp1, tp2, ignqual)) 2228 if (!qualifiers_correspond(tp1, tp2, ignqual))
2229 return false; 2229 return false;
2230 2230
2231 if (is_struct_or_union(t)) 2231 if (is_struct_or_union(t))
2232 return tp1->t_sou == tp2->t_sou; 2232 return tp1->t_sou == tp2->t_sou;
2233 2233
2234 if (t == ENUM && eflag) 2234 if (t == ENUM && eflag)
2235 return tp1->t_enum == tp2->t_enum; 2235 return tp1->t_enum == tp2->t_enum;
2236 2236
2237 if (t == ARRAY && tp1->t_dim != tp2->t_dim) { 2237 if (t == ARRAY && tp1->t_dim != tp2->t_dim) {
2238 if (tp1->t_dim != 0 && tp2->t_dim != 0) 2238 if (tp1->t_dim != 0 && tp2->t_dim != 0)
2239 return false; 2239 return false;
2240 } 2240 }
2241 2241
2242 /* don't check prototypes for traditional */ 2242 /* don't check prototypes for traditional */
2243 if (t == FUNC && allow_c90) { 2243 if (t == FUNC && allow_c90) {
2244 if (tp1->t_proto && tp2->t_proto) { 2244 if (tp1->t_proto && tp2->t_proto) {
2245 if (!prototypes_compatible(tp1, tp2, dowarn)) 2245 if (!prototypes_compatible(tp1, tp2, dowarn))
2246 return false; 2246 return false;
2247 } else if (tp1->t_proto) { 2247 } else if (tp1->t_proto) {
2248 if (!matches_no_arg_function(tp1, dowarn)) 2248 if (!matches_no_arg_function(tp1, dowarn))
2249 return false; 2249 return false;
2250 } else if (tp2->t_proto) { 2250 } else if (tp2->t_proto) {
2251 if (!matches_no_arg_function(tp2, dowarn)) 2251 if (!matches_no_arg_function(tp2, dowarn))
2252 return false; 2252 return false;
2253 } 2253 }
2254 } 2254 }
2255 2255
2256 tp1 = tp1->t_subt; 2256 tp1 = tp1->t_subt;
2257 tp2 = tp2->t_subt; 2257 tp2 = tp2->t_subt;
2258 ignqual = promot = false; 2258 ignqual = promot = false;
2259 } 2259 }
2260 2260
2261 return tp1 == tp2; 2261 return tp1 == tp2;
2262} 2262}
2263 2263
2264/* 2264/*
2265 * Completes a type by copying the dimension and prototype information from a 2265 * Completes a type by copying the dimension and prototype information from a
2266 * second compatible type. 2266 * second compatible type.
2267 * 2267 *
2268 * Following lines are legal: 2268 * Following lines are legal:
2269 * "typedef a[]; a b; a b[10]; a c; a c[20];" 2269 * "typedef a[]; a b; a b[10]; a c; a c[20];"
2270 * "typedef ft(); ft f; f(int); ft g; g(long);" 2270 * "typedef ft(); ft f; f(int); ft g; g(long);"
2271 * This means that, if a type is completed, the type structure must be 2271 * This means that, if a type is completed, the type structure must be
2272 * duplicated. 2272 * duplicated.
2273 */ 2273 */
2274void 2274void
2275complete_type(sym_t *dsym, sym_t *ssym) 2275complete_type(sym_t *dsym, sym_t *ssym)
2276{ 2276{
2277 type_t **dstp = &dsym->s_type; 2277 type_t **dstp = &dsym->s_type;
2278 type_t *src = ssym->s_type; 2278 type_t *src = ssym->s_type;
2279 2279
2280 while (*dstp != NULL) { 2280 while (*dstp != NULL) {
2281 type_t *dst = *dstp; 2281 type_t *dst = *dstp;
2282 lint_assert(src != NULL); 2282 lint_assert(src != NULL);
2283 lint_assert(dst->t_tspec == src->t_tspec); 2283 lint_assert(dst->t_tspec == src->t_tspec);
2284 if (dst->t_tspec == ARRAY) { 2284 if (dst->t_tspec == ARRAY) {
2285 if (dst->t_dim == 0 && src->t_dim != 0) { 2285 if (dst->t_dim == 0 && src->t_dim != 0) {
2286 *dstp = dst = block_dup_type(dst); 2286 *dstp = dst = block_dup_type(dst);
2287 dst->t_dim = src->t_dim; 2287 dst->t_dim = src->t_dim;
2288 dst->t_incomplete_array = false; 2288 dst->t_incomplete_array = false;
2289 } 2289 }
2290 } else if (dst->t_tspec == FUNC) { 2290 } else if (dst->t_tspec == FUNC) {
2291 if (!dst->t_proto && src->t_proto) { 2291 if (!dst->t_proto && src->t_proto) {
2292 *dstp = dst = block_dup_type(dst); 2292 *dstp = dst = block_dup_type(dst);
2293 dst->t_proto = true; 2293 dst->t_proto = true;
2294 dst->t_args = src->t_args; 2294 dst->t_args = src->t_args;
2295 } 2295 }
2296 } 2296 }
2297 dstp = &dst->t_subt; 2297 dstp = &dst->t_subt;
2298 src = src->t_subt; 2298 src = src->t_subt;
2299 } 2299 }
2300} 2300}
2301 2301
2302/* 2302/*
2303 * Completes the declaration of a single argument. 2303 * Completes the declaration of a single argument.
2304 */ 2304 */
2305sym_t * 2305sym_t *
2306declare_argument(sym_t *sym, bool has_initializer) 2306declare_argument(sym_t *sym, bool has_initializer)
2307{ 2307{
2308 2308
2309 check_function_definition(sym, true); 2309 check_function_definition(sym, true);
2310 2310
2311 check_type(sym); 2311 check_type(sym);
2312 2312
2313 if (dcs->d_redeclared_symbol != NULL && 2313 if (dcs->d_redeclared_symbol != NULL &&
2314 dcs->d_redeclared_symbol->s_block_level == block_level) { 2314 dcs->d_redeclared_symbol->s_block_level == block_level) {
2315 /* redeclaration of formal parameter '%s' */ 2315 /* redeclaration of formal parameter '%s' */
2316 error(237, sym->s_name); 2316 error(237, sym->s_name);
2317 rmsym(dcs->d_redeclared_symbol); 2317 rmsym(dcs->d_redeclared_symbol);
2318 sym->s_arg = true; 2318 sym->s_arg = true;
2319 } 2319 }
2320 2320
2321 if (!sym->s_arg) { 2321 if (!sym->s_arg) {
2322 /* declared argument '%s' is missing */ 2322 /* declared argument '%s' is missing */
2323 error(53, sym->s_name); 2323 error(53, sym->s_name);
2324 sym->s_arg = true; 2324 sym->s_arg = true;
2325 } 2325 }
2326 2326
2327 if (has_initializer) { 2327 if (has_initializer) {
2328 /* cannot initialize parameter '%s' */ 2328 /* cannot initialize parameter '%s' */
2329 error(52, sym->s_name); 2329 error(52, sym->s_name);
2330 } 2330 }
2331 2331
2332 if (sym->s_type == NULL) /* for c(void()) */ 2332 if (sym->s_type == NULL) /* for c(void()) */
2333 sym->s_type = gettyp(VOID); 2333 sym->s_type = gettyp(VOID);
2334 2334
2335 tspec_t t = sym->s_type->t_tspec; 2335 tspec_t t = sym->s_type->t_tspec;
2336 if (t == ARRAY) 2336 if (t == ARRAY)
2337 sym->s_type = block_derive_type(sym->s_type->t_subt, PTR); 2337 sym->s_type = block_derive_type(sym->s_type->t_subt, PTR);
2338 if (t == FUNC) { 2338 if (t == FUNC) {
2339 if (!allow_c90) 2339 if (!allow_c90)
2340 /* parameter '%s' has function type, should be ... */ 2340 /* parameter '%s' has function type, should be ... */
2341 warning(50, sym->s_name); 2341 warning(50, sym->s_name);
2342 sym->s_type = block_derive_type(sym->s_type, PTR); 2342 sym->s_type = block_derive_type(sym->s_type, PTR);
2343 } 2343 }
2344 if (t == FLOAT && !allow_c90) 2344 if (t == FLOAT && !allow_c90)
2345 sym->s_type = gettyp(DOUBLE); 2345 sym->s_type = gettyp(DOUBLE);
2346 2346
2347 if (dcs->d_inline) 2347 if (dcs->d_inline)
2348 /* parameter '%s' declared inline */ 2348 /* parameter '%s' declared inline */
2349 warning(269, sym->s_name); 2349 warning(269, sym->s_name);
2350 2350
2351 /* 2351 /*
2352 * Arguments must have complete types. length_in_bits prints the 2352 * Arguments must have complete types. length_in_bits prints the
2353 * needed error messages (null dimension is impossible because arrays 2353 * needed error messages (null dimension is impossible because arrays
2354 * are converted to pointers). 2354 * are converted to pointers).
2355 */ 2355 */
2356 if (sym->s_type->t_tspec != VOID) 2356 if (sym->s_type->t_tspec != VOID)
2357 (void)length_in_bits(sym->s_type, sym->s_name); 2357 (void)length_in_bits(sym->s_type, sym->s_name);
2358 2358
2359 sym->s_used = dcs->d_used; 2359 sym->s_used = dcs->d_used;
2360 mark_as_set(sym); 2360 mark_as_set(sym);
2361 2361
2362 return sym; 2362 return sym;
2363} 2363}
2364 2364
2365static bool 2365static bool
2366is_character_pointer(const type_t *tp) 2366is_character_pointer(const type_t *tp)
2367{ 2367{
2368 tspec_t st; 2368 tspec_t st;
2369 2369
2370 return tp->t_tspec == PTR && 2370 return tp->t_tspec == PTR &&
2371 (st = tp->t_subt->t_tspec, 2371 (st = tp->t_subt->t_tspec,
2372 st == CHAR || st == SCHAR || st == UCHAR); 2372 st == CHAR || st == SCHAR || st == UCHAR);
2373} 2373}
2374 2374
2375void 2375void
2376check_func_lint_directives(void) 2376check_func_lint_directives(void)
2377{ 2377{
2378 2378
2379 /* check for illegal combinations of lint directives */ 2379 /* check for illegal combinations of lint directives */
2380 if (printflike_argnum != -1 && scanflike_argnum != -1) { 2380 if (printflike_argnum != -1 && scanflike_argnum != -1) {
2381 /* ** PRINTFLIKE ** and ** SCANFLIKE ** cannot be combined */ 2381 /* ** PRINTFLIKE ** and ** SCANFLIKE ** cannot be combined */
2382 warning(289); 2382 warning(289);
2383 printflike_argnum = scanflike_argnum = -1; 2383 printflike_argnum = scanflike_argnum = -1;
2384 } 2384 }
2385 if (nvararg != -1 && 2385 if (nvararg != -1 &&
2386 (printflike_argnum != -1 || scanflike_argnum != -1)) { 2386 (printflike_argnum != -1 || scanflike_argnum != -1)) {
2387 /* dubious use of ** VARARGS ** with ** %s ** */ 2387 /* dubious use of ** VARARGS ** with ** %s ** */
2388 warning(288, 2388 warning(288,
2389 printflike_argnum != -1 ? "PRINTFLIKE" : "SCANFLIKE"); 2389 printflike_argnum != -1 ? "PRINTFLIKE" : "SCANFLIKE");
2390 nvararg = -1; 2390 nvararg = -1;
2391 } 2391 }
2392 2392
2393 /* 2393 /*
2394 * check if the argument of a lint directive is compatible with the 2394 * check if the argument of a lint directive is compatible with the
2395 * number of arguments. 2395 * number of arguments.
2396 */ 2396 */
2397 int narg = 0; 2397 int narg = 0;
2398 for (sym_t *arg = dcs->d_func_args; arg != NULL; arg = arg->s_next) 2398 for (sym_t *arg = dcs->d_func_args; arg != NULL; arg = arg->s_next)
2399 narg++; 2399 narg++;
2400 if (nargusg > narg) { 2400 if (nargusg > narg) {
2401 /* argument number mismatch in comment ** %s ** */ 2401 /* argument number mismatch in comment ** %s ** */
2402 warning(283, "ARGSUSED"); 2402 warning(283, "ARGSUSED");
2403 nargusg = 0; 2403 nargusg = 0;
2404 } 2404 }
2405 if (nvararg > narg) { 2405 if (nvararg > narg) {
2406 /* argument number mismatch in comment ** %s ** */ 2406 /* argument number mismatch in comment ** %s ** */
2407 warning(283, "VARARGS"); 2407 warning(283, "VARARGS");
2408 nvararg = 0; 2408 nvararg = 0;
2409 } 2409 }
2410 if (printflike_argnum > narg) { 2410 if (printflike_argnum > narg) {
2411 /* argument number mismatch in comment ** %s ** */ 2411 /* argument number mismatch in comment ** %s ** */
2412 warning(283, "PRINTFLIKE"); 2412 warning(283, "PRINTFLIKE");
2413 printflike_argnum = -1; 2413 printflike_argnum = -1;
2414 } else if (printflike_argnum == 0) { 2414 } else if (printflike_argnum == 0) {
2415 printflike_argnum = -1; 2415 printflike_argnum = -1;
2416 } 2416 }
2417 if (scanflike_argnum > narg) { 2417 if (scanflike_argnum > narg) {
2418 /* argument number mismatch in comment ** %s ** */ 2418 /* argument number mismatch in comment ** %s ** */
2419 warning(283, "SCANFLIKE"); 2419 warning(283, "SCANFLIKE");
2420 scanflike_argnum = -1; 2420 scanflike_argnum = -1;
2421 } else if (scanflike_argnum == 0) { 2421 } else if (scanflike_argnum == 0) {
2422 scanflike_argnum = -1; 2422 scanflike_argnum = -1;
2423 } 2423 }
2424 if (printflike_argnum != -1 || scanflike_argnum != -1) { 2424 if (printflike_argnum != -1 || scanflike_argnum != -1) {
2425 narg = printflike_argnum != -1 2425 narg = printflike_argnum != -1
2426 ? printflike_argnum : scanflike_argnum; 2426 ? printflike_argnum : scanflike_argnum;
2427 sym_t *arg = dcs->d_func_args; 2427 sym_t *arg = dcs->d_func_args;
2428 for (int n = 1; n < narg; n++) 2428 for (int n = 1; n < narg; n++)
2429 arg = arg->s_next; 2429 arg = arg->s_next;
2430 if (!is_character_pointer(arg->s_type)) { 2430 if (!is_character_pointer(arg->s_type)) {
2431 /* argument %d must be 'char *' for PRINTFLIKE/... */ 2431 /* argument %d must be 'char *' for PRINTFLIKE/... */
2432 warning(293, narg); 2432 warning(293, narg);
2433 printflike_argnum = scanflike_argnum = -1; 2433 printflike_argnum = scanflike_argnum = -1;
2434 } 2434 }
2435 } 2435 }
2436} 2436}
2437 2437
2438/* 2438/*
2439 * Checks compatibility of an old-style function definition with a previous 2439 * Checks compatibility of an old-style function definition with a previous
2440 * prototype declaration. 2440 * prototype declaration.
2441 * Returns true if the position of the previous declaration should be reported. 2441 * Returns true if the position of the previous declaration should be reported.
2442 */ 2442 */
2443static bool 2443static bool
2444check_prototype_declaration(sym_t *arg, sym_t *parg) 2444check_prototype_declaration(sym_t *arg, sym_t *parg)
2445{ 2445{
2446 type_t *tp = arg->s_type; 2446 type_t *tp = arg->s_type;
2447 type_t *ptp = parg->s_type; 2447 type_t *ptp = parg->s_type;
2448 bool dowarn = false; 2448 bool dowarn = false;
2449 2449
2450 if (!types_compatible(tp, ptp, true, true, &dowarn)) { 2450 if (!types_compatible(tp, ptp, true, true, &dowarn)) {
2451 if (types_compatible(tp, ptp, true, false, &dowarn)) { 2451 if (types_compatible(tp, ptp, true, false, &dowarn)) {
2452 /* type of '%s' does not match prototype */ 2452 /* type of '%s' does not match prototype */
2453 return gnuism(58, arg->s_name); 2453 return gnuism(58, arg->s_name);
2454 } else { 2454 } else {
2455 /* type of '%s' does not match prototype */ 2455 /* type of '%s' does not match prototype */
2456 error(58, arg->s_name); 2456 error(58, arg->s_name);
2457 return true; 2457 return true;
2458 } 2458 }
2459 } 2459 }
2460 if (dowarn) { 2460 if (dowarn) {
2461 /* TODO: Make this an error in C99 mode as well. */ 2461 /* TODO: Make this an error in C99 mode as well. */
2462 if (!allow_trad && !allow_c99) 2462 if (!allow_trad && !allow_c99)
2463 /* type of '%s' does not match prototype */ 2463 /* type of '%s' does not match prototype */
2464 error(58, arg->s_name); 2464 error(58, arg->s_name);
2465 else 2465 else
2466 /* type of '%s' does not match prototype */ 2466 /* type of '%s' does not match prototype */
2467 warning(58, arg->s_name); 2467 warning(58, arg->s_name);
2468 return true; 2468 return true;
2469 } 2469 }
2470 2470
2471 return false; 2471 return false;
2472} 2472}
2473 2473
2474/* 2474/*
2475 * Warn about arguments in old-style function definitions that default to int. 2475 * Warn about arguments in old-style function definitions that default to int.
2476 * Check that an old-style function definition is compatible to a previous 2476 * Check that an old-style function definition is compatible to a previous
2477 * prototype. 2477 * prototype.
2478 */ 2478 */
2479void 2479void
2480check_func_old_style_arguments(void) 2480check_func_old_style_arguments(void)
2481{ 2481{
2482 int narg; 2482 int narg;
2483 int nparg; 2483 int nparg;
2484 bool msg; 2484 bool msg;
2485 2485
2486 sym_t *args = funcsym->u.s_old_style_args; 2486 sym_t *args = funcsym->u.s_old_style_args;
2487 sym_t *pargs = funcsym->s_type->t_args; 2487 sym_t *pargs = funcsym->s_type->t_args;
2488 2488
2489 /* 2489 /*
2490 * print a warning for each argument of an old-style function 2490 * print a warning for each argument of an old-style function
2491 * definition which defaults to int 2491 * definition which defaults to int
2492 */ 2492 */
2493 for (sym_t *arg = args; arg != NULL; arg = arg->s_next) { 2493 for (sym_t *arg = args; arg != NULL; arg = arg->s_next) {
2494 if (arg->s_defarg) { 2494 if (arg->s_defarg) {
2495 /* type of argument '%s' defaults to 'int' */ 2495 /* type of argument '%s' defaults to 'int' */
2496 warning(32, arg->s_name); 2496 warning(32, arg->s_name);
2497 arg->s_defarg = false; 2497 arg->s_defarg = false;
2498 mark_as_set(arg); 2498 mark_as_set(arg);
2499 } 2499 }
2500 } 2500 }
2501 2501
2502 /* 2502 /*
2503 * If this is an old-style function definition and a prototype 2503 * If this is an old-style function definition and a prototype
2504 * exists, compare the types of arguments. 2504 * exists, compare the types of arguments.
2505 */ 2505 */
2506 if (funcsym->s_osdef && funcsym->s_type->t_proto) { 2506 if (funcsym->s_osdef && funcsym->s_type->t_proto) {
2507 /* 2507 /*
2508 * If the number of arguments does not match, we need not 2508 * If the number of arguments does not match, we need not
2509 * continue. 2509 * continue.
2510 */ 2510 */
2511 narg = nparg = 0; 2511 narg = nparg = 0;
2512 msg = false; 2512 msg = false;
2513 for (sym_t *parg = pargs; parg != NULL; parg = parg->s_next) 2513 for (sym_t *parg = pargs; parg != NULL; parg = parg->s_next)
2514 nparg++; 2514 nparg++;
2515 for (sym_t *arg = args; arg != NULL; arg = arg->s_next) 2515 for (sym_t *arg = args; arg != NULL; arg = arg->s_next)
2516 narg++; 2516 narg++;
2517 if (narg != nparg) { 2517 if (narg != nparg) {
2518 /* parameter mismatch: %d declared, %d defined */ 2518 /* parameter mismatch: %d declared, %d defined */
2519 error(51, nparg, narg); 2519 error(51, nparg, narg);
2520 msg = true; 2520 msg = true;
2521 } else { 2521 } else {
2522 sym_t *parg = pargs; 2522 sym_t *parg = pargs;
2523 sym_t *arg = args; 2523 sym_t *arg = args;
2524 while (narg-- > 0) { 2524 while (narg-- > 0) {
2525 msg |= check_prototype_declaration(arg, parg); 2525 msg |= check_prototype_declaration(arg, parg);
2526 parg = parg->s_next; 2526 parg = parg->s_next;
2527 arg = arg->s_next; 2527 arg = arg->s_next;
2528 } 2528 }
2529 } 2529 }
2530 if (msg && rflag) { 2530 if (msg && rflag) {
2531 /* prototype declaration */ 2531 /* prototype declaration */
2532 message_at(285, &dcs->d_redeclared_symbol->s_def_pos); 2532 message_at(285, &dcs->d_redeclared_symbol->s_def_pos);
2533 } 2533 }
2534 2534
2535 /* from now on the prototype is valid */ 2535 /* from now on the prototype is valid */
2536 funcsym->s_osdef = false; 2536 funcsym->s_osdef = false;
2537 funcsym->u.s_old_style_args = NULL; 2537 funcsym->u.s_old_style_args = NULL;
2538 } 2538 }
2539} 2539}
2540 2540
2541static void 2541static void
2542check_local_hiding(const sym_t *dsym) 2542check_local_hiding(const sym_t *dsym)
2543{ 2543{
2544 switch (dsym->s_scl) { 2544 switch (dsym->s_scl) {
2545 case AUTO: 2545 case AUTO:
2546 /* automatic '%s' hides external declaration */ 2546 /* automatic '%s' hides external declaration */
2547 warning(86, dsym->s_name); 2547 warning(86, dsym->s_name);
2548 break; 2548 break;
2549 case STATIC: 2549 case STATIC:
2550 /* static '%s' hides external declaration */ 2550 /* static '%s' hides external declaration */
2551 warning(87, dsym->s_name); 2551 warning(87, dsym->s_name);
2552 break; 2552 break;
2553 case TYPEDEF: 2553 case TYPEDEF:
2554 /* typedef '%s' hides external declaration */ 2554 /* typedef '%s' hides external declaration */
2555 warning(88, dsym->s_name); 2555 warning(88, dsym->s_name);
2556 break; 2556 break;
2557 case EXTERN: 2557 case EXTERN:
2558 /* Already checked in declare_external_in_block. */ 2558 /* Already checked in declare_external_in_block. */
2559 break; 2559 break;
2560 default: 2560 default:
2561 lint_assert(/*CONSTCOND*/false); 2561 lint_assert(/*CONSTCOND*/false);
2562 } 2562 }
2563} 2563}
2564 2564
2565static void 2565static void
2566check_local_redeclaration(const sym_t *dsym, sym_t *rdsym) 2566check_local_redeclaration(const sym_t *dsym, sym_t *rdsym)
2567{ 2567{
2568 if (rdsym->s_block_level == 0) { 2568 if (rdsym->s_block_level == 0) {
2569 if (hflag) 2569 if (hflag)
2570 check_local_hiding(dsym); 2570 check_local_hiding(dsym);
2571 2571
2572 } else if (rdsym->s_block_level == block_level) { 2572 } else if (rdsym->s_block_level == block_level) {
2573 2573
2574 /* no hflag, because it's illegal! */ 2574 /* no hflag, because it's illegal! */
2575 if (rdsym->s_arg) { 2575 if (rdsym->s_arg) {
2576 /* 2576 /*
2577 * if allow_c90, a "redeclaration of '%s'" error 2577 * if allow_c90, a "redeclaration of '%s'" error
2578 * is produced below 2578 * is produced below
2579 */ 2579 */
2580 if (!allow_c90) { 2580 if (!allow_c90) {
2581 if (hflag) { 2581 if (hflag) {
2582 /* declaration of '%s' hides ... */ 2582 /* declaration of '%s' hides ... */
2583 warning(91, dsym->s_name); 2583 warning(91, dsym->s_name);
2584 } 2584 }
2585 rmsym(rdsym); 2585 rmsym(rdsym);
2586 } 2586 }
2587 } 2587 }
2588 2588
2589 } else if (rdsym->s_block_level < block_level) { 2589 } else if (rdsym->s_block_level < block_level) {
2590 if (hflag) { 2590 if (hflag) {
2591 /* declaration of '%s' hides earlier one */ 2591 /* declaration of '%s' hides earlier one */
2592 warning(95, dsym->s_name); 2592 warning(95, dsym->s_name);
2593 } 2593 }
2594 } 2594 }
2595 2595
2596 if (rdsym->s_block_level == block_level) { 2596 if (rdsym->s_block_level == block_level) {
2597 /* redeclaration of '%s' */ 2597 /* redeclaration of '%s' */
2598 error(27, dsym->s_name); 2598 error(27, dsym->s_name);
2599 rmsym(rdsym); 2599 rmsym(rdsym);
2600 } 2600 }
2601} 2601}
2602 2602
2603/* Processes (re)declarations of external symbols inside blocks. */ 2603/* Processes (re)declarations of external symbols inside blocks. */
2604static void 2604static void
2605declare_external_in_block(sym_t *dsym) 2605declare_external_in_block(sym_t *dsym)
2606{ 2606{
2607 2607
2608 /* look for a symbol with the same name */ 2608 /* look for a symbol with the same name */
2609 sym_t *esym = dcs->d_redeclared_symbol; 2609 sym_t *esym = dcs->d_redeclared_symbol;
2610 while (esym != NULL && esym->s_block_level != 0) { 2610 while (esym != NULL && esym->s_block_level != 0) {
2611 while ((esym = esym->s_symtab_next) != NULL) { 2611 while ((esym = esym->s_symtab_next) != NULL) {
2612 if (esym->s_kind != FVFT) 2612 if (esym->s_kind != FVFT)
2613 continue; 2613 continue;
2614 if (strcmp(dsym->s_name, esym->s_name) == 0) 2614 if (strcmp(dsym->s_name, esym->s_name) == 0)
2615 break; 2615 break;
2616 } 2616 }
2617 } 2617 }
2618 if (esym == NULL) 2618 if (esym == NULL)
2619 return; 2619 return;
2620 if (esym->s_scl != EXTERN && esym->s_scl != STATIC) { 2620 if (esym->s_scl != EXTERN && esym->s_scl != STATIC) {
2621 /* gcc accepts this without a warning, pcc prints an error. */ 2621 /* gcc accepts this without a warning, pcc prints an error. */
2622 /* redeclaration of '%s' */ 2622 /* redeclaration of '%s' */
2623 warning(27, dsym->s_name); 2623 warning(27, dsym->s_name);
2624 print_previous_declaration(esym); 2624 print_previous_declaration(esym);
2625 return; 2625 return;
2626 } 2626 }
2627 2627
2628 bool dowarn = false; 2628 bool dowarn = false;
2629 bool compatible = types_compatible(esym->s_type, dsym->s_type, 2629 bool compatible = types_compatible(esym->s_type, dsym->s_type,
2630 false, false, &dowarn); 2630 false, false, &dowarn);
2631 2631
2632 if (!compatible || dowarn) { 2632 if (!compatible || dowarn) {
2633 if (esym->s_scl == EXTERN) { 2633 if (esym->s_scl == EXTERN) {
2634 /* inconsistent redeclaration of extern '%s' */ 2634 /* inconsistent redeclaration of extern '%s' */
2635 warning(90, dsym->s_name); 2635 warning(90, dsym->s_name);
2636 print_previous_declaration(esym); 2636 print_previous_declaration(esym);
2637 } else { 2637 } else {
2638 /* inconsistent redeclaration of static '%s' */ 2638 /* inconsistent redeclaration of static '%s' */
2639 warning(92, dsym->s_name); 2639 warning(92, dsym->s_name);
2640 print_previous_declaration(esym); 2640 print_previous_declaration(esym);
2641 } 2641 }
2642 } 2642 }
2643 2643
2644 if (compatible) { 2644 if (compatible) {
2645 /* 2645 /*
2646 * Remember the external symbol, so we can update usage 2646 * Remember the external symbol, so we can update usage
2647 * information at the end of the block. 2647 * information at the end of the block.
2648 */ 2648 */
2649 dsym->s_ext_sym = esym; 2649 dsym->s_ext_sym = esym;
2650 } 2650 }
2651} 2651}
2652 2652
2653/* 2653/*
2654 * Completes a single local declaration/definition. 2654 * Completes a single local declaration/definition.
2655 */ 2655 */
2656void 2656void
2657declare_local(sym_t *dsym, bool has_initializer) 2657declare_local(sym_t *dsym, bool has_initializer)
2658{ 2658{
2659 2659
2660 /* Correct a mistake done in declarator_name(). */ 2660 /* Correct a mistake done in declarator_name(). */
2661 if (dsym->s_type->t_tspec == FUNC) { 2661 if (dsym->s_type->t_tspec == FUNC) {
2662 dsym->s_def = DECL; 2662 dsym->s_def = DECL;
2663 if (dcs->d_scl == NOSCL) 2663 if (dcs->d_scl == NOSCL)
2664 dsym->s_scl = EXTERN; 2664 dsym->s_scl = EXTERN;
2665 } 2665 }
2666 2666
2667 if (dsym->s_scl == EXTERN) { 2667 if (dsym->s_scl == EXTERN) {
2668 /* nested 'extern' declaration of '%s' */ 2668 /* nested 'extern' declaration of '%s' */
2669 warning(352, dsym->s_name); 2669 warning(352, dsym->s_name);
2670 } 2670 }
2671 2671
2672 if (dsym->s_type->t_tspec == FUNC) { 2672 if (dsym->s_type->t_tspec == FUNC) {
2673 if (dsym->s_scl == STATIC) { 2673 if (dsym->s_scl == STATIC) {
2674 /* dubious static function '%s' at block level */ 2674 /* dubious static function '%s' at block level */
2675 warning(93, dsym->s_name); 2675 warning(93, dsym->s_name);
2676 dsym->s_scl = EXTERN; 2676 dsym->s_scl = EXTERN;
2677 } else if (dsym->s_scl != EXTERN && dsym->s_scl != TYPEDEF) { 2677 } else if (dsym->s_scl != EXTERN && dsym->s_scl != TYPEDEF) {
2678 /* function '%s' has illegal storage class */ 2678 /* function '%s' has illegal storage class */
2679 error(94, dsym->s_name); 2679 error(94, dsym->s_name);
2680 dsym->s_scl = EXTERN; 2680 dsym->s_scl = EXTERN;
2681 } 2681 }
2682 } 2682 }
2683 2683
2684 /* 2684 /*
2685 * functions may be declared inline at local scope, although 2685 * functions may be declared inline at local scope, although
2686 * this has no effect for a later definition of the same 2686 * this has no effect for a later definition of the same
2687 * function. 2687 * function.
2688 * XXX it should have an effect if !allow_c90 is set. this would 2688 * XXX it should have an effect if !allow_c90 is set. this would
2689 * also be the way gcc behaves. 2689 * also be the way gcc behaves.
2690 */ 2690 */
2691 if (dcs->d_inline) { 2691 if (dcs->d_inline) {
2692 if (dsym->s_type->t_tspec == FUNC) 2692 if (dsym->s_type->t_tspec == FUNC)
2693 dsym->s_inline = true; 2693 dsym->s_inline = true;
2694 else { 2694 else {
2695 /* variable '%s' declared inline */ 2695 /* variable '%s' declared inline */
2696 warning(268, dsym->s_name); 2696 warning(268, dsym->s_name);
2697 } 2697 }
2698 } 2698 }
2699 2699
2700 check_function_definition(dsym, true); 2700 check_function_definition(dsym, true);
2701 2701
2702 check_type(dsym); 2702 check_type(dsym);
2703 2703
2704 if (dcs->d_redeclared_symbol != NULL && dsym->s_scl == EXTERN) 2704 if (dcs->d_redeclared_symbol != NULL && dsym->s_scl == EXTERN)
2705 declare_external_in_block(dsym); 2705 declare_external_in_block(dsym);
2706 2706
2707 if (dsym->s_scl == EXTERN) { 2707 if (dsym->s_scl == EXTERN) {
2708 /* 2708 /*
2709 * XXX if the static variable at level 0 is only defined 2709 * XXX if the static variable at level 0 is only defined
2710 * later, checking will be possible. 2710 * later, checking will be possible.
2711 */ 2711 */
2712 if (dsym->s_ext_sym == NULL) 2712 if (dsym->s_ext_sym == NULL)
2713 outsym(dsym, EXTERN, dsym->s_def); 2713 outsym(dsym, EXTERN, dsym->s_def);
2714 else 2714 else
2715 outsym(dsym, dsym->s_ext_sym->s_scl, dsym->s_def); 2715 outsym(dsym, dsym->s_ext_sym->s_scl, dsym->s_def);
2716 } 2716 }
2717 2717
2718 if (dcs->d_redeclared_symbol != NULL) 2718 if (dcs->d_redeclared_symbol != NULL)
2719 check_local_redeclaration(dsym, dcs->d_redeclared_symbol); 2719 check_local_redeclaration(dsym, dcs->d_redeclared_symbol);
2720 2720
2721 if (has_initializer && !check_init(dsym)) { 2721 if (has_initializer && !check_init(dsym)) {
2722 dsym->s_def = DEF; 2722 dsym->s_def = DEF;
2723 mark_as_set(dsym); 2723 mark_as_set(dsym);
2724 } 2724 }
2725 2725
2726 if (dsym->s_scl == TYPEDEF) { 2726 if (dsym->s_scl == TYPEDEF) {
2727 dsym->s_type = block_dup_type(dsym->s_type); 2727 dsym->s_type = block_dup_type(dsym->s_type);
2728 dsym->s_type->t_typedef = true; 2728 dsym->s_type->t_typedef = true;
2729 set_first_typedef(dsym->s_type, dsym); 2729 set_first_typedef(dsym->s_type, dsym);
2730 } 2730 }
2731 2731
2732 if (dsym->s_scl == STATIC && any_query_enabled) { 2732 if (dsym->s_scl == STATIC && any_query_enabled) {
2733 /* static variable '%s' in function */ 2733 /* static variable '%s' in function */
2734 query_message(11, dsym->s_name); 2734 query_message(11, dsym->s_name);
2735 } 2735 }
2736} 2736}
2737 2737
2738/* Create a symbol for an abstract declaration. */ 2738/* Create a symbol for an abstract declaration. */
2739sym_t * 2739sym_t *
2740abstract_name(void) 2740abstract_name(void)
2741{ 2741{
2742 2742
2743 lint_assert(dcs->d_kind == DLK_ABSTRACT 2743 lint_assert(dcs->d_kind == DLK_ABSTRACT
2744 || dcs->d_kind == DLK_PROTO_PARAMS); 2744 || dcs->d_kind == DLK_PROTO_PARAMS);
2745 2745
2746 sym_t *sym = block_zero_alloc(sizeof(*sym), "sym"); 2746 sym_t *sym = block_zero_alloc(sizeof(*sym), "sym");
2747 sym->s_name = unnamed; 2747 sym->s_name = unnamed;
2748 sym->s_def = DEF; 2748 sym->s_def = DEF;
2749 sym->s_scl = ABSTRACT; 2749 sym->s_scl = ABSTRACT;
2750 sym->s_block_level = -1; 2750 sym->s_block_level = -1;
2751 sym->s_arg = dcs->d_kind == DLK_PROTO_PARAMS; 2751 sym->s_arg = dcs->d_kind == DLK_PROTO_PARAMS;
2752 2752
2753 /* 2753 /*
2754 * At this point, dcs->d_type contains only the basic type. That 2754 * At this point, dcs->d_type contains only the basic type. That
2755 * type will be updated later, adding pointers, arrays and functions 2755 * type will be updated later, adding pointers, arrays and functions
2756 * as necessary. 2756 * as necessary.
2757 */ 2757 */
2758 /* 2758 /*
2759 * XXX: This is not the correct type. For example in msg_347, it is 2759 * XXX: This is not the correct type. For example in msg_347, it is
2760 * the type of the last prototype parameter, but it should rather be 2760 * the type of the last prototype parameter, but it should rather be
2761 * the return type of the function. 2761 * the return type of the function.
2762 */ 2762 */
2763 sym->s_type = dcs->d_type; 2763 sym->s_type = dcs->d_type;
2764 dcs->d_redeclared_symbol = NULL; 2764 dcs->d_redeclared_symbol = NULL;
2765 2765
2766 return sym; 2766 return sym;
2767} 2767}
2768 2768
2769/* Removes anything which has nothing to do on global level. */ 2769/* Removes anything which has nothing to do on global level. */
2770void 2770void
2771global_clean_up(void) 2771global_clean_up(void)
2772{ 2772{
2773 2773
2774 while (dcs->d_enclosing != NULL) 2774 while (dcs->d_enclosing != NULL)
2775 end_declaration_level(); 2775 end_declaration_level();
2776 2776
2777 clean_up_after_error(); 2777 clean_up_after_error();
2778 block_level = 0; 2778 block_level = 0;
2779 mem_block_level = 0; 2779 mem_block_level = 0;
2780 debug_step("%s: mem_block_level = %zu", __func__, mem_block_level); 2780 debug_step("%s: mem_block_level = %zu", __func__, mem_block_level);
2781 global_clean_up_decl(true); 2781 global_clean_up_decl(true);
2782} 2782}
2783 2783
2784sym_t * 2784sym_t *
2785declare_abstract_type(sym_t *sym) 2785declare_abstract_type(sym_t *sym)
2786{ 2786{
2787 2787
2788 check_function_definition(sym, true); 2788 check_function_definition(sym, true);
2789 check_type(sym); 2789 check_type(sym);
2790 return sym; 2790 return sym;
2791} 2791}
2792 2792
2793/* Checks size after declarations of variables and their initialization. */ 2793/* Checks size after declarations of variables and their initialization. */
2794void 2794void
2795check_size(sym_t *dsym) 2795check_size(const sym_t *dsym)
2796{ 2796{
2797 2797
2798 if (dsym->s_def == DEF && 2798 if (dsym->s_def == DEF &&
2799 dsym->s_scl != TYPEDEF && 2799 dsym->s_scl != TYPEDEF &&
2800 dsym->s_type->t_tspec != FUNC && 2800 dsym->s_type->t_tspec != FUNC &&
2801 length_in_bits(dsym->s_type, dsym->s_name) == 0 && 2801 length_in_bits(dsym->s_type, dsym->s_name) == 0 &&
2802 dsym->s_type->t_tspec == ARRAY && 2802 dsym->s_type->t_tspec == ARRAY &&
2803 dsym->s_type->t_dim == 0) { 2803 dsym->s_type->t_dim == 0) {
2804 if (!allow_c90) 2804 if (!allow_c90)
2805 /* empty array declaration for '%s' */ 2805 /* empty array declaration for '%s' */
2806 warning(190, dsym->s_name); 2806 warning(190, dsym->s_name);
2807 else 2807 else
2808 /* empty array declaration for '%s' */ 2808 /* empty array declaration for '%s' */
2809 error(190, dsym->s_name); 2809 error(190, dsym->s_name);
2810 } 2810 }
2811} 2811}
2812 2812
2813/* Mark an object as set if it is not already. */ 2813/* Mark an object as set if it is not already. */
2814void 2814void
2815mark_as_set(sym_t *sym) 2815mark_as_set(sym_t *sym)
2816{ 2816{
2817 2817
2818 if (!sym->s_set) { 2818 if (!sym->s_set) {
2819 sym->s_set = true; 2819 sym->s_set = true;
2820 sym->s_set_pos = unique_curr_pos(); 2820 sym->s_set_pos = unique_curr_pos();
2821 } 2821 }
2822} 2822}
2823 2823
2824/* Mark an object as used if it is not already. */ 2824/* Mark an object as used if it is not already. */
2825void 2825void
2826mark_as_used(sym_t *sym, bool fcall, bool szof) 2826mark_as_used(sym_t *sym, bool fcall, bool szof)
2827{ 2827{
2828 2828
2829 if (!sym->s_used) { 2829 if (!sym->s_used) {
2830 sym->s_used = true; 2830 sym->s_used = true;
2831 sym->s_use_pos = unique_curr_pos(); 2831 sym->s_use_pos = unique_curr_pos();
2832 } 2832 }
2833 /* 2833 /*
2834 * For function calls, another record is written. 2834 * For function calls, another record is written.
2835 * 2835 *
2836 * XXX: Should symbols used in sizeof() be treated as used or not? 2836 * XXX: Should symbols used in sizeof() be treated as used or not?
2837 * Probably not, because there is no point in declaring an external 2837 * Probably not, because there is no point in declaring an external
2838 * variable only to get its size. 2838 * variable only to get its size.
2839 */ 2839 */
2840 if (!fcall && !szof && sym->s_kind == FVFT && sym->s_scl == EXTERN) 2840 if (!fcall && !szof && sym->s_kind == FVFT && sym->s_scl == EXTERN)
2841 outusg(sym); 2841 outusg(sym);
2842} 2842}
2843 2843
2844/* Warns about variables and labels that are not used or only set. */ 2844/* Warns about variables and labels that are not used or only set. */
2845void 2845void
2846check_usage(decl_level *dl) 2846check_usage(const decl_level *dl)
2847{ 2847{
2848 /* for this warning LINTED has no effect */ 2848 /* for this warning LINTED has no effect */
2849 int saved_lwarn = lwarn; 2849 int saved_lwarn = lwarn;
2850 lwarn = LWARN_ALL; 2850 lwarn = LWARN_ALL;
2851 2851
2852 debug_step("begin lwarn %d", lwarn); 2852 debug_step("begin lwarn %d", lwarn);
2853 for (sym_t *sym = dl->d_first_dlsym; 2853 for (sym_t *sym = dl->d_first_dlsym;
2854 sym != NULL; sym = sym->s_level_next) 2854 sym != NULL; sym = sym->s_level_next)
2855 check_usage_sym(dl->d_asm, sym); 2855 check_usage_sym(dl->d_asm, sym);
2856 lwarn = saved_lwarn; 2856 lwarn = saved_lwarn;
2857 debug_step("end lwarn %d", lwarn); 2857 debug_step("end lwarn %d", lwarn);
2858} 2858}
2859 2859
2860static void 2860static void
2861check_argument_usage(bool novar, sym_t *arg) 2861check_argument_usage(bool novar, const sym_t *arg)
2862{ 2862{
2863 2863
2864 lint_assert(arg->s_set); 2864 lint_assert(arg->s_set);
2865 2865
2866 if (novar) 2866 if (novar)
2867 return; 2867 return;
2868 2868
2869 if (!arg->s_used && !vflag) { 2869 if (!arg->s_used && !vflag) {
2870 /* parameter '%s' unused in function '%s' */ 2870 /* parameter '%s' unused in function '%s' */
2871 warning_at(231, &arg->s_def_pos, arg->s_name, funcsym->s_name); 2871 warning_at(231, &arg->s_def_pos, arg->s_name, funcsym->s_name);
2872 } 2872 }
2873} 2873}
2874 2874
2875static void 2875static void
2876check_variable_usage(bool novar, sym_t *sym) 2876check_variable_usage(bool novar, const sym_t *sym)
2877{ 2877{
2878 2878
2879 lint_assert(block_level != 0); 2879 lint_assert(block_level != 0);
2880 2880
2881 /* example at file scope: int c = ({ return 3; }); */ 2881 /* example at file scope: int c = ({ return 3; }); */
2882 if (sym->s_block_level == 0 && ch_isdigit(sym->s_name[0])) 2882 if (sym->s_block_level == 0 && ch_isdigit(sym->s_name[0]))
2883 return; 2883 return;
2884 2884
2885 /* errors in expressions easily cause lots of these warnings */ 2885 /* errors in expressions easily cause lots of these warnings */
2886 if (seen_error) 2886 if (seen_error)
2887 return; 2887 return;
2888 2888
2889 /* 2889 /*
2890 * XXX Only variables are checked, although types should 2890 * XXX Only variables are checked, although types should
2891 * probably also be checked 2891 * probably also be checked
2892 */ 2892 */
2893 scl_t sc = sym->s_scl; 2893 scl_t sc = sym->s_scl;
2894 if (sc != EXTERN && sc != STATIC && sc != AUTO && sc != REG) 2894 if (sc != EXTERN && sc != STATIC && sc != AUTO && sc != REG)
2895 return; 2895 return;
2896 2896
2897 if (novar) 2897 if (novar)
2898 return; 2898 return;
2899 2899
2900 if (sc == EXTERN) { 2900 if (sc == EXTERN) {
2901 if (!sym->s_used && !sym->s_set) { 2901 if (!sym->s_used && !sym->s_set) {
2902 /* '%s' unused in function '%s' */ 2902 /* '%s' unused in function '%s' */
2903 warning_at(192, &sym->s_def_pos, 2903 warning_at(192, &sym->s_def_pos,
2904 sym->s_name, funcsym->s_name); 2904 sym->s_name, funcsym->s_name);
2905 } 2905 }
2906 } else { 2906 } else {
2907 if (sym->s_set && !sym->s_used) { 2907 if (sym->s_set && !sym->s_used) {
2908 /* '%s' set but not used in function '%s' */ 2908 /* '%s' set but not used in function '%s' */
2909 warning_at(191, &sym->s_set_pos, 2909 warning_at(191, &sym->s_set_pos,
2910 sym->s_name, funcsym->s_name); 2910 sym->s_name, funcsym->s_name);
2911 } else if (!sym->s_used) { 2911 } else if (!sym->s_used) {
2912 /* '%s' unused in function '%s' */ 2912 /* '%s' unused in function '%s' */
2913 warning_at(192, &sym->s_def_pos, 2913 warning_at(192, &sym->s_def_pos,
2914 sym->s_name, funcsym->s_name); 2914 sym->s_name, funcsym->s_name);
2915 } 2915 }
2916 } 2916 }
2917 2917
2918 if (sc == EXTERN) { 2918 if (sc == EXTERN) {
2919 /* 2919 /*
2920 * information about usage is taken over into the symbol 2920 * information about usage is taken over into the symbol
2921 * table entry at level 0 if the symbol was locally declared 2921 * table entry at level 0 if the symbol was locally declared
2922 * as an external symbol. 2922 * as an external symbol.
2923 * 2923 *
2924 * XXX This is wrong for symbols declared static at level 0 2924 * XXX This is wrong for symbols declared static at level 0
2925 * if the usage information stems from sizeof(). This is 2925 * if the usage information stems from sizeof(). This is
2926 * because symbols at level 0 only used in sizeof() are 2926 * because symbols at level 0 only used in sizeof() are
2927 * considered to not be used. 2927 * considered to not be used.
2928 */ 2928 */
2929 sym_t *xsym = sym->s_ext_sym; 2929 sym_t *xsym = sym->s_ext_sym;
2930 if (xsym != NULL) { 2930 if (xsym != NULL) {
2931 if (sym->s_used && !xsym->s_used) { 2931 if (sym->s_used && !xsym->s_used) {
2932 xsym->s_used = true; 2932 xsym->s_used = true;
2933 xsym->s_use_pos = sym->s_use_pos; 2933 xsym->s_use_pos = sym->s_use_pos;
2934 } 2934 }
2935 if (sym->s_set && !xsym->s_set) { 2935 if (sym->s_set && !xsym->s_set) {
2936 xsym->s_set = true; 2936 xsym->s_set = true;
2937 xsym->s_set_pos = sym->s_set_pos; 2937 xsym->s_set_pos = sym->s_set_pos;
2938 } 2938 }
2939 } 2939 }
2940 } 2940 }
2941} 2941}
2942 2942
2943static void 2943static void
2944check_label_usage(sym_t *lab) 2944check_label_usage(const sym_t *lab)
2945{ 2945{
2946 2946
2947 lint_assert(block_level == 1); 2947 lint_assert(block_level == 1);
2948 lint_assert(lab->s_block_level == 1); 2948 lint_assert(lab->s_block_level == 1);
2949 2949
2950 if (funcsym == NULL) 2950 if (funcsym == NULL)
2951 /* syntax error '%s' */ 2951 /* syntax error '%s' */
2952 error(249, "labels are only valid inside a function"); 2952 error(249, "labels are only valid inside a function");
2953 else if (lab->s_set && !lab->s_used) 2953 else if (lab->s_set && !lab->s_used)
2954 /* label '%s' unused in function '%s' */ 2954 /* label '%s' unused in function '%s' */
2955 warning_at(232, &lab->s_set_pos, lab->s_name, funcsym->s_name); 2955 warning_at(232, &lab->s_set_pos, lab->s_name, funcsym->s_name);
2956 else if (!lab->s_set) 2956 else if (!lab->s_set)
2957 /* undefined label '%s' */ 2957 /* undefined label '%s' */
2958 warning_at(23, &lab->s_use_pos, lab->s_name); 2958 warning_at(23, &lab->s_use_pos, lab->s_name);
2959} 2959}
2960 2960
2961static void 2961static void
2962check_tag_usage(sym_t *sym) 2962check_tag_usage(const sym_t *sym)
2963{ 2963{
2964 2964
2965 if (!is_incomplete(sym->s_type)) 2965 if (!is_incomplete(sym->s_type))
2966 return; 2966 return;
2967 2967
2968 /* always complain about incomplete tags declared inside blocks */ 2968 /* always complain about incomplete tags declared inside blocks */
2969 if (zflag || dcs->d_kind != DLK_EXTERN) 2969 if (zflag || dcs->d_kind != DLK_EXTERN)
2970 return; 2970 return;
2971 2971
2972 switch (sym->s_type->t_tspec) { 2972 switch (sym->s_type->t_tspec) {
2973 case STRUCT: 2973 case STRUCT:
2974 /* struct '%s' never defined */ 2974 /* struct '%s' never defined */
2975 warning_at(233, &sym->s_def_pos, sym->s_name); 2975 warning_at(233, &sym->s_def_pos, sym->s_name);
2976 break; 2976 break;
2977 case UNION: 2977 case UNION:
2978 /* union '%s' never defined */ 2978 /* union '%s' never defined */
2979 warning_at(234, &sym->s_def_pos, sym->s_name); 2979 warning_at(234, &sym->s_def_pos, sym->s_name);
2980 break; 2980 break;
2981 default: 2981 default:
2982 lint_assert(sym->s_type->t_tspec == ENUM); 2982 lint_assert(sym->s_type->t_tspec == ENUM);
2983 /* enum '%s' never defined */ 2983 /* enum '%s' never defined */
2984 warning_at(235, &sym->s_def_pos, sym->s_name); 2984 warning_at(235, &sym->s_def_pos, sym->s_name);
2985 break; 2985 break;
2986 } 2986 }
2987} 2987}
2988 2988
2989/* Warns about a variable or a label that is not used or only set. */ 2989/* Warns about a variable or a label that is not used or only set. */
2990void 2990void
2991check_usage_sym(bool novar, sym_t *sym) 2991check_usage_sym(bool novar, const sym_t *sym)
2992{ 2992{
2993 2993
2994 if (sym->s_block_level == -1) 2994 if (sym->s_block_level == -1)
2995 return; 2995 return;
2996 2996
2997 if (sym->s_kind == FVFT && sym->s_arg) 2997 if (sym->s_kind == FVFT && sym->s_arg)
2998 check_argument_usage(novar, sym); 2998 check_argument_usage(novar, sym);
2999 else if (sym->s_kind == FVFT) 2999 else if (sym->s_kind == FVFT)
3000 check_variable_usage(novar, sym); 3000 check_variable_usage(novar, sym);
3001 else if (sym->s_kind == FLABEL) 3001 else if (sym->s_kind == FLABEL)
3002 check_label_usage(sym); 3002 check_label_usage(sym);
3003 else if (sym->s_kind == FTAG) 3003 else if (sym->s_kind == FTAG)
3004 check_tag_usage(sym); 3004 check_tag_usage(sym);
3005} 3005}
3006 3006
3007static void 3007static void
3008check_global_variable_size(const sym_t *sym) 3008check_global_variable_size(const sym_t *sym)
3009{ 3009{
3010 3010
3011 if (sym->s_def != TDEF) 3011 if (sym->s_def != TDEF)
3012 return; 3012 return;
3013 if (sym->s_type->t_tspec == FUNC) { 3013 if (sym->s_type->t_tspec == FUNC) {
3014 /* Maybe a syntax error after a function declaration. */ 3014 /* Maybe a syntax error after a function declaration. */
3015 return; 3015 return;
3016 } 3016 }
3017 if (sym->s_def == TDEF && sym->s_type->t_tspec == VOID) { 3017 if (sym->s_def == TDEF && sym->s_type->t_tspec == VOID) {
3018 /* Prevent an internal error in length_in_bits below. */ 3018 /* Prevent an internal error in length_in_bits below. */
3019 return; 3019 return;
3020 } 3020 }
3021 3021
3022 pos_t cpos = curr_pos; 3022 pos_t cpos = curr_pos;
3023 curr_pos = sym->s_def_pos; 3023 curr_pos = sym->s_def_pos;
3024 int len_in_bits = length_in_bits(sym->s_type, sym->s_name); 3024 int len_in_bits = length_in_bits(sym->s_type, sym->s_name);
3025 curr_pos = cpos; 3025 curr_pos = cpos;
3026 3026
3027 if (len_in_bits == 0 && 3027 if (len_in_bits == 0 &&
3028 sym->s_type->t_tspec == ARRAY && sym->s_type->t_dim == 0) { 3028 sym->s_type->t_tspec == ARRAY && sym->s_type->t_dim == 0) {
3029 /* TODO: C99 6.7.5.2p1 defines this as an error as well. */ 3029 /* TODO: C99 6.7.5.2p1 defines this as an error as well. */
3030 if (!allow_c90 || 3030 if (!allow_c90 ||
3031 (sym->s_scl == EXTERN && (allow_trad || allow_c99))) { 3031 (sym->s_scl == EXTERN && (allow_trad || allow_c99))) {
3032 /* empty array declaration for '%s' */ 3032 /* empty array declaration for '%s' */
3033 warning_at(190, &sym->s_def_pos, sym->s_name); 3033 warning_at(190, &sym->s_def_pos, sym->s_name);
3034 } else { 3034 } else {
3035 /* empty array declaration for '%s' */ 3035 /* empty array declaration for '%s' */
3036 error_at(190, &sym->s_def_pos, sym->s_name); 3036 error_at(190, &sym->s_def_pos, sym->s_name);
3037 } 3037 }
3038 } 3038 }
3039} 3039}
3040 3040
3041static void 3041static void
3042check_unused_static_global_variable(const sym_t *sym) 3042check_unused_static_global_variable(const sym_t *sym)
3043{ 3043{
3044 if (sym->s_type->t_tspec == FUNC) { 3044 if (sym->s_type->t_tspec == FUNC) {
3045 if (sym->s_def == DEF) { 3045 if (sym->s_def == DEF) {
3046 if (!sym->s_inline) 3046 if (!sym->s_inline)
3047 /* static function '%s' unused */ 3047 /* static function '%s' unused */
3048 warning_at(236, &sym->s_def_pos, sym->s_name); 3048 warning_at(236, &sym->s_def_pos, sym->s_name);
3049 } else { 3049 } else {
3050 /* static function '%s' declared but not defined */ 3050 /* static function '%s' declared but not defined */
3051 warning_at(290, &sym->s_def_pos, sym->s_name); 3051 warning_at(290, &sym->s_def_pos, sym->s_name);
3052 } 3052 }
3053 } else if (!sym->s_set) { 3053 } else if (!sym->s_set) {
3054 /* static variable '%s' unused */ 3054 /* static variable '%s' unused */
3055 warning_at(226, &sym->s_def_pos, sym->s_name); 3055 warning_at(226, &sym->s_def_pos, sym->s_name);
3056 } else { 3056 } else {
3057 /* static variable '%s' set but not used */ 3057 /* static variable '%s' set but not used */
3058 warning_at(307, &sym->s_def_pos, sym->s_name); 3058 warning_at(307, &sym->s_def_pos, sym->s_name);
3059 } 3059 }
3060} 3060}
3061 3061
3062static void 3062static void
3063check_static_global_variable(const sym_t *sym) 3063check_static_global_variable(const sym_t *sym)
3064{ 3064{
3065 if (sym->s_type->t_tspec == FUNC && sym->s_used && sym->s_def != DEF) { 3065 if (sym->s_type->t_tspec == FUNC && sym->s_used && sym->s_def != DEF) {
3066 /* static function '%s' called but not defined */ 3066 /* static function '%s' called but not defined */
3067 error_at(225, &sym->s_use_pos, sym->s_name); 3067 error_at(225, &sym->s_use_pos, sym->s_name);
3068 } 3068 }
3069 3069
3070 if (!sym->s_used) 3070 if (!sym->s_used)
3071 check_unused_static_global_variable(sym); 3071 check_unused_static_global_variable(sym);
3072 3072
3073 if (allow_c90 && sym->s_def == TDEF && sym->s_type->t_const) { 3073 if (allow_c90 && sym->s_def == TDEF && sym->s_type->t_const) {
3074 /* const object '%s' should have initializer */ 3074 /* const object '%s' should have initializer */
3075 warning_at(227, &sym->s_def_pos, sym->s_name); 3075 warning_at(227, &sym->s_def_pos, sym->s_name);
3076 } 3076 }
3077} 3077}
3078 3078
3079static void 3079static void
3080check_global_variable(const sym_t *sym) 3080check_global_variable(const sym_t *sym)
3081{ 3081{
3082 scl_t scl = sym->s_scl; 3082 scl_t scl = sym->s_scl;
3083 3083
3084 if (scl == TYPEDEF || scl == BOOL_CONST || scl == ENUM_CONST) 3084 if (scl == TYPEDEF || scl == BOOL_CONST || scl == ENUM_CONST)
3085 return; 3085 return;
3086 3086
3087 if (scl == NOSCL) 3087 if (scl == NOSCL)
3088 return; /* May be caused by a syntax error. */ 3088 return; /* May be caused by a syntax error. */
3089 3089
3090 lint_assert(scl == EXTERN || scl == STATIC); 3090 lint_assert(scl == EXTERN || scl == STATIC);
3091 3091
3092 check_global_variable_size(sym); 3092 check_global_variable_size(sym);
3093 3093
3094 if (scl == STATIC) 3094 if (scl == STATIC)
3095 check_static_global_variable(sym); 3095 check_static_global_variable(sym);
3096} 3096}
3097 3097
3098/* 3098/*
3099 * Called after the entire translation unit has been parsed. 3099 * Called after the entire translation unit has been parsed.
3100 * Changes tentative definitions into definitions. 3100 * Changes tentative definitions into definitions.
3101 * Performs some tests on global symbols. Detected problems are: 3101 * Performs some tests on global symbols. Detected problems are:
3102 * - defined variables of incomplete type 3102 * - defined variables of incomplete type
3103 * - constant variables which are not initialized 3103 * - constant variables which are not initialized
3104 * - static symbols which are never used 3104 * - static symbols which are never used
3105 */ 3105 */
3106void 3106void
3107check_global_symbols(void) 3107check_global_symbols(void)
3108{ 3108{
3109 sym_t *sym; 3109 sym_t *sym;
3110 3110
3111 if (block_level != 0 || dcs->d_enclosing != NULL) 3111 if (block_level != 0 || dcs->d_enclosing != NULL)
3112 norecover(); 3112 norecover();
3113 3113
3114 for (sym = dcs->d_first_dlsym; sym != NULL; sym = sym->s_level_next) { 3114 for (sym = dcs->d_first_dlsym; sym != NULL; sym = sym->s_level_next) {
3115 if (sym->s_block_level == -1) 3115 if (sym->s_block_level == -1)
3116 continue; 3116 continue;
3117 if (sym->s_kind == FVFT) 3117 if (sym->s_kind == FVFT)
3118 check_global_variable(sym); 3118 check_global_variable(sym);
3119 else if (sym->s_kind == FTAG) 3119 else if (sym->s_kind == FTAG)
3120 check_tag_usage(sym); 3120 check_tag_usage(sym);
3121 else 3121 else
3122 lint_assert(sym->s_kind == FMEMBER); 3122 lint_assert(sym->s_kind == FMEMBER);
3123 } 3123 }
3124} 3124}
3125 3125
3126/* 3126/*
3127 * Prints information about location of previous definition/declaration. 3127 * Prints information about location of previous definition/declaration.
3128 */ 3128 */
3129void 3129void
3130print_previous_declaration(const sym_t *psym) 3130print_previous_declaration(const sym_t *psym)
3131{ 3131{
3132 3132
3133 if (!rflag) 3133 if (!rflag)
3134 return; 3134 return;
3135 3135
3136 if (psym->s_def == DEF || psym->s_def == TDEF) { 3136 if (psym->s_def == DEF || psym->s_def == TDEF) {
3137 /* previous definition of '%s' */ 3137 /* previous definition of '%s' */
3138 message_at(261, &psym->s_def_pos, psym->s_name); 3138 message_at(261, &psym->s_def_pos, psym->s_name);
3139 } else { 3139 } else {
3140 /* previous declaration of '%s' */ 3140 /* previous declaration of '%s' */
3141 message_at(260, &psym->s_def_pos, psym->s_name); 3141 message_at(260, &psym->s_def_pos, psym->s_name);
3142 } 3142 }
3143} 3143}
3144 3144
3145/* 3145/*
3146 * Gets a node for a constant and returns the value of this constant 3146 * Gets a node for a constant and returns the value of this constant
3147 * as integer. 3147 * as integer.
3148 * 3148 *
3149 * If the node is not constant or too large for int or of type float, 3149 * If the node is not constant or too large for int or of type float,
3150 * a warning will be printed. 3150 * a warning will be printed.
3151 * 3151 *
3152 * to_int_constant() should be used only inside declarations. If it is used in 3152 * to_int_constant() should be used only inside declarations. If it is used in
3153 * expressions, it frees the memory used for the expression. 3153 * expressions, it frees the memory used for the expression.
3154 */ 3154 */
3155int 3155int
3156to_int_constant(tnode_t *tn, bool required) 3156to_int_constant(tnode_t *tn, bool required)
3157{ 3157{
3158 3158
3159 if (tn == NULL) 3159 if (tn == NULL)
3160 return 1; 3160 return 1;
3161 3161
3162 val_t *v = integer_constant(tn, required); 3162 val_t *v = integer_constant(tn, required);
3163 bool is_unsigned = is_uinteger(v->v_tspec); 3163 bool is_unsigned = is_uinteger(v->v_tspec);
3164 int64_t val = v->u.integer; 3164 int64_t val = v->u.integer;
3165 free(v); 3165 free(v);
3166 3166
3167 /* 3167 /*
3168 * Abstract declarations are used inside expression. To free 3168 * Abstract declarations are used inside expression. To free
3169 * the memory would be a fatal error. 3169 * the memory would be a fatal error.
3170 * We don't free blocks that are inside casts because these 3170 * We don't free blocks that are inside casts because these
3171 * will be used later to match types. 3171 * will be used later to match types.
3172 */ 3172 */
3173 if (tn->tn_op != CON && dcs->d_kind != DLK_ABSTRACT) 3173 if (tn->tn_op != CON && dcs->d_kind != DLK_ABSTRACT)
3174 expr_free_all(); 3174 expr_free_all();
3175 3175
3176 bool out_of_bounds = is_unsigned 3176 bool out_of_bounds = is_unsigned
3177 ? (uint64_t)val > (uint64_t)TARG_INT_MAX 3177 ? (uint64_t)val > (uint64_t)TARG_INT_MAX
3178 : val > (int64_t)TARG_INT_MAX || val < (int64_t)TARG_INT_MIN; 3178 : val > (int64_t)TARG_INT_MAX || val < (int64_t)TARG_INT_MIN;
3179 if (out_of_bounds) 3179 if (out_of_bounds)
3180 /* integral constant too large */ 3180 /* integral constant too large */
3181 warning(56); 3181 warning(56);
3182 return (int)val; 3182 return (int)val;
3183} 3183}

cvs diff -r1.200 -r1.201 src/usr.bin/xlint/lint1/externs1.h (switch to unified diff)

--- src/usr.bin/xlint/lint1/externs1.h 2023/07/29 06:44:44 1.200
+++ src/usr.bin/xlint/lint1/externs1.h 2023/07/29 07:26:53 1.201
@@ -1,412 +1,412 @@ @@ -1,412 +1,412 @@
1/* $NetBSD: externs1.h,v 1.200 2023/07/29 06:44:44 rillig Exp $ */ 1/* $NetBSD: externs1.h,v 1.201 2023/07/29 07:26:53 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.
15 * 3. All advertising materials mentioning features or use of this software 15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement: 16 * must display the following acknowledgement:
17 * This product includes software developed by Jochen Pohl for 17 * This product includes software developed by Jochen Pohl for
18 * The NetBSD Project. 18 * The NetBSD Project.
19 * 4. The name of the author may not be used to endorse or promote products 19 * 4. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission. 20 * derived from this software without specific prior written permission.
21 * 21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
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#include <signal.h> 34#include <signal.h>
35 35
36/* 36/*
37 * main1.c 37 * main1.c
38 */ 38 */
39extern int aflag; 39extern int aflag;
40extern bool bflag; 40extern bool bflag;
41extern bool cflag; 41extern bool cflag;
42extern bool eflag; 42extern bool eflag;
43extern bool Fflag; 43extern bool Fflag;
44extern bool hflag; 44extern bool hflag;
45extern bool pflag; 45extern bool pflag;
46extern bool rflag; 46extern bool rflag;
47extern bool uflag; 47extern bool uflag;
48extern bool vflag; 48extern bool vflag;
49extern bool yflag; 49extern bool yflag;
50extern bool wflag; 50extern bool wflag;
51extern bool zflag; 51extern bool zflag;
52extern bool Tflag; 52extern bool Tflag;
53extern bool Pflag; 53extern bool Pflag;
54 54
55extern bool allow_trad; 55extern bool allow_trad;
56extern bool allow_c90; 56extern bool allow_c90;
57extern bool allow_c99; 57extern bool allow_c99;
58extern bool allow_c11; 58extern bool allow_c11;
59extern bool allow_c23; 59extern bool allow_c23;
60extern bool allow_gcc; 60extern bool allow_gcc;
61 61
62extern sig_atomic_t fpe; 62extern sig_atomic_t fpe;
63 63
64void norecover(void); 64void norecover(void);
65 65
66/* 66/*
67 * cgram.y 67 * cgram.y
68 */ 68 */
69extern int block_level; 69extern int block_level;
70extern size_t mem_block_level; 70extern size_t mem_block_level;
71extern int yydebug; 71extern int yydebug;
72 72
73int yyerror(const char *); 73int yyerror(const char *);
74int yyparse(void); 74int yyparse(void);
75 75
76/* 76/*
77 * scan.l 77 * scan.l
78 */ 78 */
79extern bool in_gcc_attribute; 79extern bool in_gcc_attribute;
80extern pos_t curr_pos; 80extern pos_t curr_pos;
81extern pos_t csrc_pos; 81extern pos_t csrc_pos;
82extern bool in_system_header; 82extern bool in_system_header;
83extern symt_t symtyp; 83extern symt_t symtyp;
84extern FILE *yyin; 84extern FILE *yyin;
85 85
86void initscan(void); 86void initscan(void);
87int64_t convert_integer(int64_t, tspec_t, unsigned int); 87int64_t convert_integer(int64_t, tspec_t, unsigned int);
88void clear_warn_flags(void); 88void clear_warn_flags(void);
89sym_t *getsym(sbuf_t *); 89sym_t *getsym(sbuf_t *);
90void clean_up_after_error(void); 90void clean_up_after_error(void);
91sym_t *pushdown(const sym_t *); 91sym_t *pushdown(const sym_t *);
92sym_t *mktempsym(type_t *); 92sym_t *mktempsym(type_t *);
93void rmsym(sym_t *); 93void rmsym(sym_t *);
94void symtab_remove_level(sym_t *); 94void symtab_remove_level(sym_t *);
95void inssym(int, sym_t *); 95void inssym(int, sym_t *);
96void freeyyv(void *, int); 96void freeyyv(void *, int);
97int yylex(void); 97int yylex(void);
98 98
99/* 99/*
100 * mem1.c 100 * mem1.c
101 */ 101 */
102const char *record_filename(const char *, size_t); 102const char *record_filename(const char *, size_t);
103int get_filename_id(const char *); 103int get_filename_id(const char *);
104void add_directory_replacement(char *); 104void add_directory_replacement(char *);
105const char *transform_filename(const char *, size_t); 105const char *transform_filename(const char *, size_t);
106 106
107#ifdef DEBUG_MEM 107#ifdef DEBUG_MEM
108void *block_zero_alloc(size_t, const char *); 108void *block_zero_alloc(size_t, const char *);
109void *level_zero_alloc(size_t, size_t, const char *); 109void *level_zero_alloc(size_t, size_t, const char *);
110#else 110#else
111void *block_zero_alloc(size_t); 111void *block_zero_alloc(size_t);
112void *level_zero_alloc(size_t, size_t); 112void *level_zero_alloc(size_t, size_t);
113#define block_zero_alloc(size, descr) (block_zero_alloc)(size) 113#define block_zero_alloc(size, descr) (block_zero_alloc)(size)
114#define level_zero_alloc(level, size, descr) (level_zero_alloc)(level, size) 114#define level_zero_alloc(level, size, descr) (level_zero_alloc)(level, size)
115#endif 115#endif
116void level_free_all(size_t); 116void level_free_all(size_t);
117 117
118#ifdef DEBUG_MEM 118#ifdef DEBUG_MEM
119void *expr_zero_alloc(size_t, const char *); 119void *expr_zero_alloc(size_t, const char *);
120#else 120#else
121void *expr_zero_alloc(size_t); 121void *expr_zero_alloc(size_t);
122#define expr_zero_alloc(size, descr) (expr_zero_alloc)(size) 122#define expr_zero_alloc(size, descr) (expr_zero_alloc)(size)
123#endif 123#endif
124tnode_t *expr_alloc_tnode(void); 124tnode_t *expr_alloc_tnode(void);
125void expr_free_all(void); 125void expr_free_all(void);
126memory_pool expr_save_memory(void); 126memory_pool expr_save_memory(void);
127void expr_restore_memory(memory_pool); 127void expr_restore_memory(memory_pool);
128 128
129/* 129/*
130 * debug.c 130 * debug.c
131 */ 131 */
132 132
133#ifdef DEBUG 133#ifdef DEBUG
134const char *decl_level_kind_name(decl_level_kind); 134const char *decl_level_kind_name(decl_level_kind);
135const char *scl_name(scl_t); 135const char *scl_name(scl_t);
136const char *symt_name(symt_t); 136const char *symt_name(symt_t);
137const char *type_qualifiers_string(type_qualifiers); 137const char *type_qualifiers_string(type_qualifiers);
138const char *function_specifier_name(function_specifier); 138const char *function_specifier_name(function_specifier);
139void debug_dcs(bool); 139void debug_dcs(bool);
140void debug_node(const tnode_t *); 140void debug_node(const tnode_t *);
141void debug_type(const type_t *); 141void debug_type(const type_t *);
142void debug_sym(const char *, const sym_t *, const char *); 142void debug_sym(const char *, const sym_t *, const char *);
143void debug_symtab(void); 143void debug_symtab(void);
144void debug_printf(const char *fmt, ...) __printflike(1, 2); 144void debug_printf(const char *fmt, ...) __printflike(1, 2);
145void debug_print_indent(void); 145void debug_print_indent(void);
146void debug_indent_inc(void); 146void debug_indent_inc(void);
147void debug_indent_dec(void); 147void debug_indent_dec(void);
148void debug_enter_func(const char *); 148void debug_enter_func(const char *);
149void debug_step(const char *fmt, ...) __printflike(1, 2); 149void debug_step(const char *fmt, ...) __printflike(1, 2);
150void debug_leave_func(const char *); 150void debug_leave_func(const char *);
151#define debug_enter() debug_enter_func(__func__) 151#define debug_enter() debug_enter_func(__func__)
152#define debug_leave() debug_leave_func(__func__) 152#define debug_leave() debug_leave_func(__func__)
153#else 153#else
154#define debug_noop() do { } while (false) 154#define debug_noop() do { } while (false)
155#define debug_dcs(all) debug_noop() 155#define debug_dcs(all) debug_noop()
156#define debug_sym(p, sym, s) debug_noop() 156#define debug_sym(p, sym, s) debug_noop()
157#define debug_symtab() debug_noop() 157#define debug_symtab() debug_noop()
158#define debug_node(tn) debug_noop() 158#define debug_node(tn) debug_noop()
159#define debug_type(tp) debug_noop() 159#define debug_type(tp) debug_noop()
160#define debug_printf(...) debug_noop() 160#define debug_printf(...) debug_noop()
161#define debug_print_indent() debug_noop() 161#define debug_print_indent() debug_noop()
162#define debug_indent_inc() debug_noop() 162#define debug_indent_inc() debug_noop()
163#define debug_indent_dec() debug_noop() 163#define debug_indent_dec() debug_noop()
164#define debug_enter() debug_noop() 164#define debug_enter() debug_noop()
165#define debug_step(...) debug_noop() 165#define debug_step(...) debug_noop()
166#define debug_leave() debug_noop() 166#define debug_leave() debug_noop()
167#endif 167#endif
168 168
169/* 169/*
170 * err.c 170 * err.c
171 */ 171 */
172extern bool seen_error; 172extern bool seen_error;
173extern bool seen_warning; 173extern bool seen_warning;
174extern int sytxerr; 174extern int sytxerr;
175extern bool any_query_enabled; 175extern bool any_query_enabled;
176 176
177void msglist(void); 177void msglist(void);
178void error_at(int, const pos_t *, ...); 178void error_at(int, const pos_t *, ...);
179void warning_at(int, const pos_t *, ...); 179void warning_at(int, const pos_t *, ...);
180void message_at(int, const pos_t *, ...); 180void message_at(int, const pos_t *, ...);
181void error(int, ...); 181void error(int, ...);
182void warning(int, ...); 182void warning(int, ...);
183bool gnuism(int, ...); 183bool gnuism(int, ...);
184void c99ism(int, ...); 184void c99ism(int, ...);
185void c11ism(int, ...); 185void c11ism(int, ...);
186void c23ism(int, ...); 186void c23ism(int, ...);
187void assert_failed(const char *, int, const char *, const char *) __dead; 187void assert_failed(const char *, int, const char *, const char *) __dead;
188void update_location(const char *, int, bool, bool); 188void update_location(const char *, int, bool, bool);
189void suppress_messages(const char *); 189void suppress_messages(const char *);
190 190
191void query_message(int, ...); 191void query_message(int, ...);
192void enable_queries(const char *); 192void enable_queries(const char *);
193 193
194/* 194/*
195 * decl.c 195 * decl.c
196 */ 196 */
197extern decl_level *dcs; 197extern decl_level *dcs;
198extern const char unnamed[]; 198extern const char unnamed[];
199extern int enumval; 199extern int enumval;
200 200
201void initdecl(void); 201void initdecl(void);
202type_t *gettyp(tspec_t); 202type_t *gettyp(tspec_t);
203type_t *block_dup_type(const type_t *); 203type_t *block_dup_type(const type_t *);
204type_t *expr_dup_type(const type_t *); 204type_t *expr_dup_type(const type_t *);
205type_t *expr_unqualified_type(const type_t *); 205type_t *expr_unqualified_type(const type_t *);
206bool is_incomplete(const type_t *); 206bool is_incomplete(const type_t *);
207void dcs_add_function_specifier(function_specifier); 207void dcs_add_function_specifier(function_specifier);
208void dcs_add_storage_class(scl_t); 208void dcs_add_storage_class(scl_t);
209void dcs_add_type(type_t *); 209void dcs_add_type(type_t *);
210void dcs_add_qualifiers(type_qualifiers); 210void dcs_add_qualifiers(type_qualifiers);
211void dcs_add_packed(void); 211void dcs_add_packed(void);
212void dcs_set_used(void); 212void dcs_set_used(void);
213void begin_declaration_level(decl_level_kind); 213void begin_declaration_level(decl_level_kind);
214void end_declaration_level(void); 214void end_declaration_level(void);
215void dcs_set_asm(void); 215void dcs_set_asm(void);
216void dcs_begin_type(void); 216void dcs_begin_type(void);
217void dcs_end_type(void); 217void dcs_end_type(void);
218int length_in_bits(const type_t *, const char *); 218int length_in_bits(const type_t *, const char *);
219unsigned int alignment_in_bits(const type_t *); 219unsigned int alignment_in_bits(const type_t *);
220sym_t *concat_symbols(sym_t *, sym_t *); 220sym_t *concat_symbols(sym_t *, sym_t *);
221void check_type(sym_t *); 221void check_type(sym_t *);
222sym_t *declare_unnamed_member(void); 222sym_t *declare_unnamed_member(void);
223sym_t *declare_member(sym_t *); 223sym_t *declare_member(sym_t *);
224sym_t *set_bit_field_width(sym_t *, int); 224sym_t *set_bit_field_width(sym_t *, int);
225void add_type_qualifiers(type_qualifiers *, type_qualifiers); 225void add_type_qualifiers(type_qualifiers *, type_qualifiers);
226qual_ptr *append_qualified_pointer(qual_ptr *, qual_ptr *); 226qual_ptr *append_qualified_pointer(qual_ptr *, qual_ptr *);
227sym_t *add_pointer(sym_t *, qual_ptr *); 227sym_t *add_pointer(sym_t *, qual_ptr *);
228sym_t *add_array(sym_t *, bool, int); 228sym_t *add_array(sym_t *, bool, int);
229sym_t *add_function(sym_t *, struct parameter_list); 229sym_t *add_function(sym_t *, struct parameter_list);
230void check_extern_declaration(const sym_t *); 230void check_extern_declaration(const sym_t *);
231void check_function_definition(sym_t *, bool); 231void check_function_definition(sym_t *, bool);
232sym_t *declarator_name(sym_t *); 232sym_t *declarator_name(sym_t *);
233sym_t *old_style_function_parameter_name(sym_t *); 233sym_t *old_style_function_parameter_name(sym_t *);
234type_t *make_tag_type(sym_t *, tspec_t, bool, bool); 234type_t *make_tag_type(sym_t *, tspec_t, bool, bool);
235const char *storage_class_name(scl_t); 235const char *storage_class_name(scl_t);
236type_t *complete_struct_or_union(sym_t *); 236type_t *complete_struct_or_union(sym_t *);
237type_t *complete_enum(sym_t *); 237type_t *complete_enum(sym_t *);
238sym_t *enumeration_constant(sym_t *, int, bool); 238sym_t *enumeration_constant(sym_t *, int, bool);
239void declare(sym_t *, bool, sbuf_t *); 239void declare(sym_t *, bool, sbuf_t *);
240void copy_usage_info(sym_t *, sym_t *); 240void copy_usage_info(sym_t *, sym_t *);
241bool check_redeclaration(sym_t *, bool *); 241bool check_redeclaration(sym_t *, bool *);
242bool pointer_types_are_compatible(const type_t *, const type_t *, bool); 242bool pointer_types_are_compatible(const type_t *, const type_t *, bool);
243bool types_compatible(const type_t *, const type_t *, bool, bool, bool *); 243bool types_compatible(const type_t *, const type_t *, bool, bool, bool *);
244void complete_type(sym_t *, sym_t *); 244void complete_type(sym_t *, sym_t *);
245sym_t *declare_argument(sym_t *, bool); 245sym_t *declare_argument(sym_t *, bool);
246void check_func_lint_directives(void); 246void check_func_lint_directives(void);
247void check_func_old_style_arguments(void); 247void check_func_old_style_arguments(void);
248 248
249void declare_local(sym_t *, bool); 249void declare_local(sym_t *, bool);
250sym_t *abstract_name(void); 250sym_t *abstract_name(void);
251void global_clean_up(void); 251void global_clean_up(void);
252sym_t *declare_abstract_type(sym_t *); 252sym_t *declare_abstract_type(sym_t *);
253void check_size(sym_t *); 253void check_size(const sym_t *);
254void mark_as_set(sym_t *); 254void mark_as_set(sym_t *);
255void mark_as_used(sym_t *, bool, bool); 255void mark_as_used(sym_t *, bool, bool);
256void check_usage(decl_level *); 256void check_usage(const decl_level *);
257void check_usage_sym(bool, sym_t *); 257void check_usage_sym(bool, const sym_t *);
258void check_global_symbols(void); 258void check_global_symbols(void);
259void print_previous_declaration(const sym_t *); 259void print_previous_declaration(const sym_t *);
260int to_int_constant(tnode_t *, bool); 260int to_int_constant(tnode_t *, bool);
261 261
262/* 262/*
263 * tree.c 263 * tree.c
264 */ 264 */
265const tnode_t *before_conversion(const tnode_t *); 265const tnode_t *before_conversion(const tnode_t *);
266type_t *block_derive_type(type_t *, tspec_t); 266type_t *block_derive_type(type_t *, tspec_t);
267type_t *expr_derive_type(type_t *, tspec_t); 267type_t *expr_derive_type(type_t *, tspec_t);
268bool is_compiler_builtin(const char *); 268bool is_compiler_builtin(const char *);
269tnode_t *build_constant(type_t *, val_t *); 269tnode_t *build_constant(type_t *, val_t *);
270tnode_t *build_name(sym_t *, bool); 270tnode_t *build_name(sym_t *, bool);
271tnode_t *build_string(strg_t *); 271tnode_t *build_string(strg_t *);
272tnode_t *build_generic_selection(const tnode_t *, 272tnode_t *build_generic_selection(const tnode_t *,
273 struct generic_association *); 273 struct generic_association *);
274 274
275tnode_t *build_binary(tnode_t *, op_t, bool, tnode_t *); 275tnode_t *build_binary(tnode_t *, op_t, bool, tnode_t *);
276tnode_t *build_unary(op_t, bool, tnode_t *); 276tnode_t *build_unary(op_t, bool, tnode_t *);
277tnode_t *build_member_access(tnode_t *, op_t, bool, sbuf_t *); 277tnode_t *build_member_access(tnode_t *, op_t, bool, sbuf_t *);
278tnode_t *cconv(tnode_t *); 278tnode_t *cconv(tnode_t *);
279bool is_typeok_bool_compares_with_zero(const tnode_t *); 279bool is_typeok_bool_compares_with_zero(const tnode_t *);
280bool typeok(op_t, int, const tnode_t *, const tnode_t *); 280bool typeok(op_t, int, const tnode_t *, const tnode_t *);
281tnode_t *promote(op_t, bool, tnode_t *); 281tnode_t *promote(op_t, bool, tnode_t *);
282tnode_t *convert(op_t, int, type_t *, tnode_t *); 282tnode_t *convert(op_t, int, type_t *, tnode_t *);
283void convert_constant(op_t, int, const type_t *, val_t *, val_t *); 283void convert_constant(op_t, int, const type_t *, val_t *, val_t *);
284tnode_t *build_sizeof(const type_t *); 284tnode_t *build_sizeof(const type_t *);
285tnode_t *build_offsetof(const type_t *, const sym_t *); 285tnode_t *build_offsetof(const type_t *, const sym_t *);
286tnode_t *build_alignof(const type_t *); 286tnode_t *build_alignof(const type_t *);
287tnode_t *cast(tnode_t *, type_t *); 287tnode_t *cast(tnode_t *, type_t *);
288tnode_t *build_function_argument(tnode_t *, tnode_t *); 288tnode_t *build_function_argument(tnode_t *, tnode_t *);
289tnode_t *build_function_call(tnode_t *, bool, tnode_t *); 289tnode_t *build_function_call(tnode_t *, bool, tnode_t *);
290val_t *integer_constant(tnode_t *, bool); 290val_t *integer_constant(tnode_t *, bool);
291void expr(tnode_t *, bool, bool, bool, bool); 291void expr(tnode_t *, bool, bool, bool, bool);
292void check_expr_misc(const tnode_t *, bool, bool, bool, bool, bool, bool); 292void check_expr_misc(const tnode_t *, bool, bool, bool, bool, bool, bool);
293bool constant_addr(const tnode_t *, const sym_t **, ptrdiff_t *); 293bool constant_addr(const tnode_t *, const sym_t **, ptrdiff_t *);
294strg_t *cat_strings(strg_t *, strg_t *); 294strg_t *cat_strings(strg_t *, strg_t *);
295unsigned int type_size_in_bits(const type_t *); 295unsigned int type_size_in_bits(const type_t *);
296sym_t *find_member(const struct_or_union *, const char *); 296sym_t *find_member(const struct_or_union *, const char *);
297 297
298void begin_statement_expr(void); 298void begin_statement_expr(void);
299void do_statement_expr(tnode_t *); 299void do_statement_expr(tnode_t *);
300tnode_t *end_statement_expr(void); 300tnode_t *end_statement_expr(void);
301bool in_statement_expr(void); 301bool in_statement_expr(void);
302 302
303/* 303/*
304 * func.c 304 * func.c
305 */ 305 */
306extern sym_t *funcsym; 306extern sym_t *funcsym;
307extern bool reached; 307extern bool reached;
308extern bool warn_about_unreachable; 308extern bool warn_about_unreachable;
309extern bool suppress_fallthrough; 309extern bool suppress_fallthrough;
310extern int nargusg; 310extern int nargusg;
311extern pos_t argsused_pos; 311extern pos_t argsused_pos;
312extern int nvararg; 312extern int nvararg;
313extern pos_t vapos; 313extern pos_t vapos;
314extern int printflike_argnum; 314extern int printflike_argnum;
315extern pos_t printflike_pos; 315extern pos_t printflike_pos;
316extern int scanflike_argnum; 316extern int scanflike_argnum;
317extern pos_t scanflike_pos; 317extern pos_t scanflike_pos;
318extern bool suppress_constcond; 318extern bool suppress_constcond;
319extern bool llibflg; 319extern bool llibflg;
320extern int lwarn; 320extern int lwarn;
321extern bool suppress_bitfieldtype; 321extern bool suppress_bitfieldtype;
322extern bool plibflg; 322extern bool plibflg;
323extern bool suppress_longlong; 323extern bool suppress_longlong;
324 324
325void begin_control_statement(control_statement_kind); 325void begin_control_statement(control_statement_kind);
326void end_control_statement(control_statement_kind); 326void end_control_statement(control_statement_kind);
327void check_statement_reachable(void); 327void check_statement_reachable(void);
328void begin_function(sym_t *); 328void begin_function(sym_t *);
329void end_function(void); 329void end_function(void);
330void named_label(sym_t *); 330void named_label(sym_t *);
331void case_label(tnode_t *); 331void case_label(tnode_t *);
332void default_label(void); 332void default_label(void);
333void stmt_if_expr(tnode_t *); 333void stmt_if_expr(tnode_t *);
334void stmt_if_then_stmt(void); 334void stmt_if_then_stmt(void);
335void stmt_if_else_stmt(bool); 335void stmt_if_else_stmt(bool);
336void stmt_switch_expr(tnode_t *); 336void stmt_switch_expr(tnode_t *);
337void stmt_switch_expr_stmt(void); 337void stmt_switch_expr_stmt(void);
338void stmt_while_expr(tnode_t *); 338void stmt_while_expr(tnode_t *);
339void stmt_while_expr_stmt(void); 339void stmt_while_expr_stmt(void);
340void stmt_do(void); 340void stmt_do(void);
341void stmt_do_while_expr(tnode_t *); 341void stmt_do_while_expr(tnode_t *);
342void stmt_for_exprs(tnode_t *, tnode_t *, tnode_t *); 342void stmt_for_exprs(tnode_t *, tnode_t *, tnode_t *);
343void stmt_for_exprs_stmt(void); 343void stmt_for_exprs_stmt(void);
344void stmt_goto(sym_t *); 344void stmt_goto(sym_t *);
345void stmt_continue(void); 345void stmt_continue(void);
346void stmt_break(void); 346void stmt_break(void);
347void stmt_return(bool, tnode_t *); 347void stmt_return(bool, tnode_t *);
348void global_clean_up_decl(bool); 348void global_clean_up_decl(bool);
349void handle_lint_comment(lint_comment, int); 349void handle_lint_comment(lint_comment, int);
350 350
351/* 351/*
352 * init.c 352 * init.c
353 */ 353 */
354void begin_initialization(sym_t *); 354void begin_initialization(sym_t *);
355void end_initialization(void); 355void end_initialization(void);
356sym_t *current_initsym(void); 356sym_t *current_initsym(void);
357 357
358void init_rbrace(void); 358void init_rbrace(void);
359void init_lbrace(void); 359void init_lbrace(void);
360void init_expr(tnode_t *); 360void init_expr(tnode_t *);
361void begin_designation(void); 361void begin_designation(void);
362void add_designator_member(sbuf_t *); 362void add_designator_member(sbuf_t *);
363void add_designator_subscript(range_t); 363void add_designator_subscript(range_t);
364 364
365/* 365/*
366 * emit.c 366 * emit.c
367 */ 367 */
368void outtype(const type_t *); 368void outtype(const type_t *);
369void outsym(const sym_t *, scl_t, def_t); 369void outsym(const sym_t *, scl_t, def_t);
370void outfdef(const sym_t *, const pos_t *, bool, bool, const sym_t *); 370void outfdef(const sym_t *, const pos_t *, bool, bool, const sym_t *);
371void outcall(const tnode_t *, bool, bool); 371void outcall(const tnode_t *, bool, bool);
372void outusg(const sym_t *); 372void outusg(const sym_t *);
373 373
374/* 374/*
375 * lex.c 375 * lex.c
376 */ 376 */
377int lex_name(const char *, size_t); 377int lex_name(const char *, size_t);
378int lex_integer_constant(const char *, size_t, int); 378int lex_integer_constant(const char *, size_t, int);
379int lex_floating_constant(const char *, size_t); 379int lex_floating_constant(const char *, size_t);
380int lex_operator(int, op_t); 380int lex_operator(int, op_t);
381int lex_string(void); 381int lex_string(void);
382int lex_wide_string(void); 382int lex_wide_string(void);
383int lex_character_constant(void); 383int lex_character_constant(void);
384int lex_wide_character_constant(void); 384int lex_wide_character_constant(void);
385void lex_directive(const char *); 385void lex_directive(const char *);
386void lex_next_line(void); 386void lex_next_line(void);
387void lex_comment(void); 387void lex_comment(void);
388void lex_slash_slash_comment(void); 388void lex_slash_slash_comment(void);
389void lex_unknown_character(int); 389void lex_unknown_character(int);
390int lex_input(void); 390int lex_input(void);
391 391
392/* 392/*
393 * ckbool.c 393 * ckbool.c
394 */ 394 */
395bool typeok_scalar_strict_bool(op_t, const mod_t *, int, 395bool typeok_scalar_strict_bool(op_t, const mod_t *, int,
396 const tnode_t *, const tnode_t *); 396 const tnode_t *, const tnode_t *);
397bool fallback_symbol_strict_bool(sym_t *); 397bool fallback_symbol_strict_bool(sym_t *);
398 398
399/* 399/*
400 * ckctype.c 400 * ckctype.c
401 */ 401 */
402void check_ctype_function_call(const tnode_t *, const tnode_t *); 402void check_ctype_function_call(const tnode_t *, const tnode_t *);
403void check_ctype_macro_invocation(const tnode_t *, const tnode_t *); 403void check_ctype_macro_invocation(const tnode_t *, const tnode_t *);
404 404
405/* 405/*
406 * ckgetopt.c 406 * ckgetopt.c
407 */ 407 */
408void check_getopt_begin_while(const tnode_t *); 408void check_getopt_begin_while(const tnode_t *);
409void check_getopt_begin_switch(void); 409void check_getopt_begin_switch(void);
410void check_getopt_case_label(int64_t); 410void check_getopt_case_label(int64_t);
411void check_getopt_end_switch(void); 411void check_getopt_end_switch(void);
412void check_getopt_end_while(void); 412void check_getopt_end_while(void);