Fri Jul 23 17:06:37 2021 UTC ()
lint: rename cstk_t to control_statement

Rename the variables as well.  Their previous name 'ci' was not easy to
understand, the 'i' may have meant 'stack item'.  The new name 'cs'
simply means 'control statement'.

No functional change.


(rillig)
diff -r1.114 -r1.115 src/usr.bin/xlint/lint1/func.c
diff -r1.117 -r1.118 src/usr.bin/xlint/lint1/lint1.h

cvs diff -r1.114 -r1.115 src/usr.bin/xlint/lint1/func.c (switch to unified diff)

--- src/usr.bin/xlint/lint1/func.c 2021/07/20 19:35:53 1.114
+++ src/usr.bin/xlint/lint1/func.c 2021/07/23 17:06:37 1.115
@@ -1,1377 +1,1377 @@ @@ -1,1377 +1,1377 @@
1/* $NetBSD: func.c,v 1.114 2021/07/20 19:35:53 rillig Exp $ */ 1/* $NetBSD: func.c,v 1.115 2021/07/23 17:06:37 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#if HAVE_NBTOOL_CONFIG_H 34#if HAVE_NBTOOL_CONFIG_H
35#include "nbtool_config.h" 35#include "nbtool_config.h"
36#endif 36#endif
37 37
38#include <sys/cdefs.h> 38#include <sys/cdefs.h>
39#if defined(__RCSID) && !defined(lint) 39#if defined(__RCSID) && !defined(lint)
40__RCSID("$NetBSD: func.c,v 1.114 2021/07/20 19:35:53 rillig Exp $"); 40__RCSID("$NetBSD: func.c,v 1.115 2021/07/23 17:06:37 rillig Exp $");
41#endif 41#endif
42 42
43#include <stdlib.h> 43#include <stdlib.h>
44#include <string.h> 44#include <string.h>
45 45
46#include "lint1.h" 46#include "lint1.h"
47#include "cgram.h" 47#include "cgram.h"
48 48
49/* 49/*
50 * Contains a pointer to the symbol table entry of the current function 50 * Contains a pointer to the symbol table entry of the current function
51 * definition. 51 * definition.
52 */ 52 */
53sym_t *funcsym; 53sym_t *funcsym;
54 54
55/* Is set as long as a statement can be reached. Must be set at level 0. */ 55/* Is set as long as a statement can be reached. Must be set at level 0. */
56bool reached = true; 56bool reached = true;
57 57
58/* 58/*
59 * Is true by default, can be cleared by NOTREACHED. 59 * Is true by default, can be cleared by NOTREACHED.
60 * Is reset to true whenever 'reached' changes. 60 * Is reset to true whenever 'reached' changes.
61 */ 61 */
62bool warn_about_unreachable; 62bool warn_about_unreachable;
63 63
64/* 64/*
65 * In conjunction with 'reached', controls printing of "fallthrough on ..." 65 * In conjunction with 'reached', controls printing of "fallthrough on ..."
66 * warnings. 66 * warnings.
67 * Reset by each statement and set by FALLTHROUGH, switch (switch1()) 67 * Reset by each statement and set by FALLTHROUGH, switch (switch1())
68 * and case (label()). 68 * and case (label()).
69 * 69 *
70 * Control statements if, for, while and switch do not reset seen_fallthrough 70 * Control statements if, for, while and switch do not reset seen_fallthrough
71 * because this must be done by the controlled statement. At least for if this 71 * because this must be done by the controlled statement. At least for if this
72 * is important because ** FALLTHROUGH ** after "if (expr) statement" is 72 * is important because ** FALLTHROUGH ** after "if (expr) statement" is
73 * evaluated before the following token, which causes reduction of above. 73 * evaluated before the following token, which causes reduction of above.
74 * This means that ** FALLTHROUGH ** after "if ..." would always be ignored. 74 * This means that ** FALLTHROUGH ** after "if ..." would always be ignored.
75 */ 75 */
76bool seen_fallthrough; 76bool seen_fallthrough;
77 77
78/* The innermost control statement */ 78/* The innermost control statement */
79cstk_t *cstmt; 79control_statement *cstmt;
80 80
81/* 81/*
82 * Number of arguments which will be checked for usage in following 82 * Number of arguments which will be checked for usage in following
83 * function definition. -1 stands for all arguments. 83 * function definition. -1 stands for all arguments.
84 * 84 *
85 * The position of the last ARGSUSED comment is stored in argsused_pos. 85 * The position of the last ARGSUSED comment is stored in argsused_pos.
86 */ 86 */
87int nargusg = -1; 87int nargusg = -1;
88pos_t argsused_pos; 88pos_t argsused_pos;
89 89
90/* 90/*
91 * Number of arguments of the following function definition whose types 91 * Number of arguments of the following function definition whose types
92 * shall be checked by lint2. -1 stands for all arguments. 92 * shall be checked by lint2. -1 stands for all arguments.
93 * 93 *
94 * The position of the last VARARGS comment is stored in vapos. 94 * The position of the last VARARGS comment is stored in vapos.
95 */ 95 */
96int nvararg = -1; 96int nvararg = -1;
97pos_t vapos; 97pos_t vapos;
98 98
99/* 99/*
100 * Both printflike_argnum and scanflike_argnum contain the 1-based number 100 * Both printflike_argnum and scanflike_argnum contain the 1-based number
101 * of the string argument which shall be used to check the types of remaining 101 * of the string argument which shall be used to check the types of remaining
102 * arguments (for PRINTFLIKE and SCANFLIKE). 102 * arguments (for PRINTFLIKE and SCANFLIKE).
103 * 103 *
104 * printflike_pos and scanflike_pos are the positions of the last PRINTFLIKE 104 * printflike_pos and scanflike_pos are the positions of the last PRINTFLIKE
105 * or SCANFLIKE comment. 105 * or SCANFLIKE comment.
106 */ 106 */
107int printflike_argnum = -1; 107int printflike_argnum = -1;
108int scanflike_argnum = -1; 108int scanflike_argnum = -1;
109pos_t printflike_pos; 109pos_t printflike_pos;
110pos_t scanflike_pos; 110pos_t scanflike_pos;
111 111
112/* 112/*
113 * If both plibflg and llibflg are set, prototypes are written as function 113 * If both plibflg and llibflg are set, prototypes are written as function
114 * definitions to the output file. 114 * definitions to the output file.
115 */ 115 */
116bool plibflg; 116bool plibflg;
117 117
118/* 118/*
119 * True means that no warnings about constants in conditional 119 * True means that no warnings about constants in conditional
120 * context are printed. 120 * context are printed.
121 */ 121 */
122bool constcond_flag; 122bool constcond_flag;
123 123
124/* 124/*
125 * llibflg is set if a lint library shall be created. The effect of 125 * llibflg is set if a lint library shall be created. The effect of
126 * llibflg is that all defined symbols are treated as used. 126 * llibflg is that all defined symbols are treated as used.
127 * (The LINTLIBRARY comment also resets vflag.) 127 * (The LINTLIBRARY comment also resets vflag.)
128 */ 128 */
129bool llibflg; 129bool llibflg;
130 130
131/* 131/*
132 * Nonzero if warnings are suppressed by a LINTED directive 132 * Nonzero if warnings are suppressed by a LINTED directive
133 * LWARN_BAD: error 133 * LWARN_BAD: error
134 * LWARN_ALL: warnings on 134 * LWARN_ALL: warnings on
135 * LWARN_NONE: all warnings ignored 135 * LWARN_NONE: all warnings ignored
136 * 0..n: warning n ignored 136 * 0..n: warning n ignored
137 */ 137 */
138int lwarn = LWARN_ALL; 138int lwarn = LWARN_ALL;
139 139
140/* 140/*
141 * Whether bitfield type errors are suppressed by a BITFIELDTYPE 141 * Whether bitfield type errors are suppressed by a BITFIELDTYPE
142 * directive. 142 * directive.
143 */ 143 */
144bool bitfieldtype_ok; 144bool bitfieldtype_ok;
145 145
146/* 146/*
147 * Whether complaints about use of "long long" are suppressed in 147 * Whether complaints about use of "long long" are suppressed in
148 * the next statement or declaration. 148 * the next statement or declaration.
149 */ 149 */
150bool quadflg; 150bool quadflg;
151 151
152/* 152/*
153 * Puts a new element at the top of the stack used for control statements. 153 * Puts a new element at the top of the stack used for control statements.
154 */ 154 */
155void 155void
156begin_control_statement(control_statement_kind kind) 156begin_control_statement(control_statement_kind kind)
157{ 157{
158 cstk_t *ci; 158 control_statement *cs;
159 159
160 ci = xcalloc(1, sizeof(*ci)); 160 cs = xcalloc(1, sizeof(*cs));
161 ci->c_kind = kind; 161 cs->c_kind = kind;
162 ci->c_surrounding = cstmt; 162 cs->c_surrounding = cstmt;
163 cstmt = ci; 163 cstmt = cs;
164} 164}
165 165
166/* 166/*
167 * Removes the top element of the stack used for control statements. 167 * Removes the top element of the stack used for control statements.
168 */ 168 */
169void 169void
170end_control_statement(control_statement_kind kind) 170end_control_statement(control_statement_kind kind)
171{ 171{
172 cstk_t *ci; 172 control_statement *cs;
173 case_label_t *cl, *next; 173 case_label_t *cl, *next;
174 174
175 lint_assert(cstmt != NULL); 175 lint_assert(cstmt != NULL);
176 176
177 while (cstmt->c_kind != kind) 177 while (cstmt->c_kind != kind)
178 cstmt = cstmt->c_surrounding; 178 cstmt = cstmt->c_surrounding;
179 179
180 ci = cstmt; 180 cs = cstmt;
181 cstmt = ci->c_surrounding; 181 cstmt = cs->c_surrounding;
182 182
183 for (cl = ci->c_case_labels; cl != NULL; cl = next) { 183 for (cl = cs->c_case_labels; cl != NULL; cl = next) {
184 next = cl->cl_next; 184 next = cl->cl_next;
185 free(cl); 185 free(cl);
186 } 186 }
187 187
188 free(ci->c_switch_type); 188 free(cs->c_switch_type);
189 free(ci); 189 free(cs);
190} 190}
191 191
192static void 192static void
193set_reached(bool new_reached) 193set_reached(bool new_reached)
194{ 194{
195#ifdef DEBUG 195#ifdef DEBUG
196 printf("%s:%d: %s -> %s\n", curr_pos.p_file, curr_pos.p_line, 196 printf("%s:%d: %s -> %s\n", curr_pos.p_file, curr_pos.p_line,
197 reached ? "reachable" : "unreachable", 197 reached ? "reachable" : "unreachable",
198 new_reached ? "reachable" : "unreachable"); 198 new_reached ? "reachable" : "unreachable");
199#endif 199#endif
200 reached = new_reached; 200 reached = new_reached;
201 warn_about_unreachable = true; 201 warn_about_unreachable = true;
202} 202}
203 203
204/* 204/*
205 * Prints a warning if a statement cannot be reached. 205 * Prints a warning if a statement cannot be reached.
206 */ 206 */
207void 207void
208check_statement_reachable(void) 208check_statement_reachable(void)
209{ 209{
210 if (!reached && warn_about_unreachable) { 210 if (!reached && warn_about_unreachable) {
211 /* statement not reached */ 211 /* statement not reached */
212 warning(193); 212 warning(193);
213 warn_about_unreachable = false; 213 warn_about_unreachable = false;
214 } 214 }
215} 215}
216 216
217/* 217/*
218 * Called after a function declaration which introduces a function definition 218 * Called after a function declaration which introduces a function definition
219 * and before an (optional) old style argument declaration list. 219 * and before an (optional) old style argument declaration list.
220 * 220 *
221 * Puts all symbols declared in the prototype or in an old style argument 221 * Puts all symbols declared in the prototype or in an old style argument
222 * list back to the symbol table. 222 * list back to the symbol table.
223 * 223 *
224 * Does the usual checking of storage class, type (return value), 224 * Does the usual checking of storage class, type (return value),
225 * redeclaration, etc. 225 * redeclaration, etc.
226 */ 226 */
227void 227void
228funcdef(sym_t *fsym) 228funcdef(sym_t *fsym)
229{ 229{
230 int n; 230 int n;
231 bool dowarn; 231 bool dowarn;
232 sym_t *arg, *sym, *rdsym; 232 sym_t *arg, *sym, *rdsym;
233 233
234 funcsym = fsym; 234 funcsym = fsym;
235 235
236 /* 236 /*
237 * Put all symbols declared in the argument list back to the 237 * Put all symbols declared in the argument list back to the
238 * symbol table. 238 * symbol table.
239 */ 239 */
240 for (sym = dcs->d_func_proto_syms; sym != NULL; sym = sym->s_dlnxt) { 240 for (sym = dcs->d_func_proto_syms; sym != NULL; sym = sym->s_dlnxt) {
241 if (sym->s_block_level != -1) { 241 if (sym->s_block_level != -1) {
242 lint_assert(sym->s_block_level == 1); 242 lint_assert(sym->s_block_level == 1);
243 inssym(1, sym); 243 inssym(1, sym);
244 } 244 }
245 } 245 }
246 246
247 /* 247 /*
248 * In old_style_function() we did not know whether it is an old 248 * In old_style_function() we did not know whether it is an old
249 * style function definition or only an old style declaration, 249 * style function definition or only an old style declaration,
250 * if there are no arguments inside the argument list ("f()"). 250 * if there are no arguments inside the argument list ("f()").
251 */ 251 */
252 if (!fsym->s_type->t_proto && fsym->s_args == NULL) 252 if (!fsym->s_type->t_proto && fsym->s_args == NULL)
253 fsym->s_osdef = true; 253 fsym->s_osdef = true;
254 254
255 check_type(fsym); 255 check_type(fsym);
256 256
257 /* 257 /*
258 * check_type() checks for almost all possible errors, but not for 258 * check_type() checks for almost all possible errors, but not for
259 * incomplete return values (these are allowed in declarations) 259 * incomplete return values (these are allowed in declarations)
260 */ 260 */
261 if (fsym->s_type->t_subt->t_tspec != VOID && 261 if (fsym->s_type->t_subt->t_tspec != VOID &&
262 is_incomplete(fsym->s_type->t_subt)) { 262 is_incomplete(fsym->s_type->t_subt)) {
263 /* cannot return incomplete type */ 263 /* cannot return incomplete type */
264 error(67); 264 error(67);
265 } 265 }
266 266
267 fsym->s_def = DEF; 267 fsym->s_def = DEF;
268 268
269 if (fsym->s_scl == TYPEDEF) { 269 if (fsym->s_scl == TYPEDEF) {
270 fsym->s_scl = EXTERN; 270 fsym->s_scl = EXTERN;
271 /* illegal storage class */ 271 /* illegal storage class */
272 error(8); 272 error(8);
273 } 273 }
274 274
275 if (dcs->d_inline) 275 if (dcs->d_inline)
276 fsym->s_inline = true; 276 fsym->s_inline = true;
277 277
278 /* 278 /*
279 * Arguments in new style function declarations need a name. 279 * Arguments in new style function declarations need a name.
280 * (void is already removed from the list of arguments) 280 * (void is already removed from the list of arguments)
281 */ 281 */
282 n = 1; 282 n = 1;
283 for (arg = fsym->s_type->t_args; arg != NULL; arg = arg->s_next) { 283 for (arg = fsym->s_type->t_args; arg != NULL; arg = arg->s_next) {
284 if (arg->s_scl == ABSTRACT) { 284 if (arg->s_scl == ABSTRACT) {
285 lint_assert(arg->s_name == unnamed); 285 lint_assert(arg->s_name == unnamed);
286 /* formal parameter lacks name: param #%d */ 286 /* formal parameter lacks name: param #%d */
287 error(59, n); 287 error(59, n);
288 } else { 288 } else {
289 lint_assert(arg->s_name != unnamed); 289 lint_assert(arg->s_name != unnamed);
290 } 290 }
291 n++; 291 n++;
292 } 292 }
293 293
294 /* 294 /*
295 * We must also remember the position. s_def_pos is overwritten 295 * We must also remember the position. s_def_pos is overwritten
296 * if this is an old style definition and we had already a 296 * if this is an old style definition and we had already a
297 * prototype. 297 * prototype.
298 */ 298 */
299 dcs->d_func_def_pos = fsym->s_def_pos; 299 dcs->d_func_def_pos = fsym->s_def_pos;
300 300
301 if ((rdsym = dcs->d_redeclared_symbol) != NULL) { 301 if ((rdsym = dcs->d_redeclared_symbol) != NULL) {
302 302
303 if (!check_redeclaration(fsym, (dowarn = false, &dowarn))) { 303 if (!check_redeclaration(fsym, (dowarn = false, &dowarn))) {
304 304
305 /* 305 /*
306 * Print nothing if the newly defined function 306 * Print nothing if the newly defined function
307 * is defined in old style. A better warning will 307 * is defined in old style. A better warning will
308 * be printed in check_func_lint_directives(). 308 * be printed in check_func_lint_directives().
309 */ 309 */
310 if (dowarn && !fsym->s_osdef) { 310 if (dowarn && !fsym->s_osdef) {
311 if (sflag) 311 if (sflag)
312 /* redeclaration of %s */ 312 /* redeclaration of %s */
313 error(27, fsym->s_name); 313 error(27, fsym->s_name);
314 else 314 else
315 /* redeclaration of %s */ 315 /* redeclaration of %s */
316 warning(27, fsym->s_name); 316 warning(27, fsym->s_name);
317 print_previous_declaration(-1, rdsym); 317 print_previous_declaration(-1, rdsym);
318 } 318 }
319 319
320 copy_usage_info(fsym, rdsym); 320 copy_usage_info(fsym, rdsym);
321 321
322 /* 322 /*
323 * If the old symbol was a prototype and the new 323 * If the old symbol was a prototype and the new
324 * one is none, overtake the position of the 324 * one is none, overtake the position of the
325 * declaration of the prototype. 325 * declaration of the prototype.
326 */ 326 */
327 if (fsym->s_osdef && rdsym->s_type->t_proto) 327 if (fsym->s_osdef && rdsym->s_type->t_proto)
328 fsym->s_def_pos = rdsym->s_def_pos; 328 fsym->s_def_pos = rdsym->s_def_pos;
329 329
330 complete_type(fsym, rdsym); 330 complete_type(fsym, rdsym);
331 331
332 if (rdsym->s_inline) 332 if (rdsym->s_inline)
333 fsym->s_inline = true; 333 fsym->s_inline = true;
334 334
335 } 335 }
336 336
337 /* remove the old symbol from the symbol table */ 337 /* remove the old symbol from the symbol table */
338 rmsym(rdsym); 338 rmsym(rdsym);
339 339
340 } 340 }
341 341
342 if (fsym->s_osdef && !fsym->s_type->t_proto) { 342 if (fsym->s_osdef && !fsym->s_type->t_proto) {
343 if (sflag && hflag && strcmp(fsym->s_name, "main") != 0) 343 if (sflag && hflag && strcmp(fsym->s_name, "main") != 0)
344 /* function definition is not a prototype */ 344 /* function definition is not a prototype */
345 warning(286); 345 warning(286);
346 } 346 }
347 347
348 if (dcs->d_notyp) 348 if (dcs->d_notyp)
349 fsym->s_return_type_implicit_int = true; 349 fsym->s_return_type_implicit_int = true;
350 350
351 set_reached(true); 351 set_reached(true);
352} 352}
353 353
354static void 354static void
355check_missing_return_value(void) 355check_missing_return_value(void)
356{ 356{
357 if (funcsym->s_type->t_subt->t_tspec == VOID) 357 if (funcsym->s_type->t_subt->t_tspec == VOID)
358 return; 358 return;
359 if (funcsym->s_return_type_implicit_int) 359 if (funcsym->s_return_type_implicit_int)
360 return; 360 return;
361 361
362 /* C99 5.1.2.2.3 "Program termination" p1 */ 362 /* C99 5.1.2.2.3 "Program termination" p1 */
363 if (Sflag && strcmp(funcsym->s_name, "main") == 0) 363 if (Sflag && strcmp(funcsym->s_name, "main") == 0)
364 return; 364 return;
365 365
366 /* function %s falls off bottom without returning value */ 366 /* function %s falls off bottom without returning value */
367 warning(217, funcsym->s_name); 367 warning(217, funcsym->s_name);
368} 368}
369 369
370/* 370/*
371 * Called at the end of a function definition. 371 * Called at the end of a function definition.
372 */ 372 */
373void 373void
374funcend(void) 374funcend(void)
375{ 375{
376 sym_t *arg; 376 sym_t *arg;
377 int n; 377 int n;
378 378
379 if (reached) { 379 if (reached) {
380 cstmt->c_had_return_noval = true; 380 cstmt->c_had_return_noval = true;
381 check_missing_return_value(); 381 check_missing_return_value();
382 } 382 }
383 383
384 /* 384 /*
385 * This warning is printed only if the return value was implicitly 385 * This warning is printed only if the return value was implicitly
386 * declared to be int. Otherwise the wrong return statement 386 * declared to be int. Otherwise the wrong return statement
387 * has already printed a warning. 387 * has already printed a warning.
388 */ 388 */
389 if (cstmt->c_had_return_noval && cstmt->c_had_return_value && 389 if (cstmt->c_had_return_noval && cstmt->c_had_return_value &&
390 funcsym->s_return_type_implicit_int) 390 funcsym->s_return_type_implicit_int)
391 /* function %s has return (e); and return; */ 391 /* function %s has return (e); and return; */
392 warning(216, funcsym->s_name); 392 warning(216, funcsym->s_name);
393 393
394 /* Print warnings for unused arguments */ 394 /* Print warnings for unused arguments */
395 arg = dcs->d_func_args; 395 arg = dcs->d_func_args;
396 n = 0; 396 n = 0;
397 while (arg != NULL && (nargusg == -1 || n < nargusg)) { 397 while (arg != NULL && (nargusg == -1 || n < nargusg)) {
398 check_usage_sym(dcs->d_asm, arg); 398 check_usage_sym(dcs->d_asm, arg);
399 arg = arg->s_next; 399 arg = arg->s_next;
400 n++; 400 n++;
401 } 401 }
402 nargusg = -1; 402 nargusg = -1;
403 403
404 /* 404 /*
405 * write the information about the function definition to the 405 * write the information about the function definition to the
406 * output file 406 * output file
407 * inline functions explicitly declared extern are written as 407 * inline functions explicitly declared extern are written as
408 * declarations only. 408 * declarations only.
409 */ 409 */
410 if (dcs->d_scl == EXTERN && funcsym->s_inline) { 410 if (dcs->d_scl == EXTERN && funcsym->s_inline) {
411 outsym(funcsym, funcsym->s_scl, DECL); 411 outsym(funcsym, funcsym->s_scl, DECL);
412 } else { 412 } else {
413 outfdef(funcsym, &dcs->d_func_def_pos, 413 outfdef(funcsym, &dcs->d_func_def_pos,
414 cstmt->c_had_return_value, funcsym->s_osdef, 414 cstmt->c_had_return_value, funcsym->s_osdef,
415 dcs->d_func_args); 415 dcs->d_func_args);
416 } 416 }
417 417
418 /* clean up after syntax errors, see test stmt_for.c. */ 418 /* clean up after syntax errors, see test stmt_for.c. */
419 while (dcs->d_next != NULL) 419 while (dcs->d_next != NULL)
420 dcs = dcs->d_next; 420 dcs = dcs->d_next;
421 421
422 /* 422 /*
423 * remove all symbols declared during argument declaration from 423 * remove all symbols declared during argument declaration from
424 * the symbol table 424 * the symbol table
425 */ 425 */
426 lint_assert(dcs->d_next == NULL); 426 lint_assert(dcs->d_next == NULL);
427 lint_assert(dcs->d_ctx == EXTERN); 427 lint_assert(dcs->d_ctx == EXTERN);
428 rmsyms(dcs->d_func_proto_syms); 428 rmsyms(dcs->d_func_proto_syms);
429 429
430 /* must be set on level 0 */ 430 /* must be set on level 0 */
431 set_reached(true); 431 set_reached(true);
432} 432}
433 433
434void 434void
435named_label(sym_t *sym) 435named_label(sym_t *sym)
436{ 436{
437 437
438 if (sym->s_set) { 438 if (sym->s_set) {
439 /* label %s redefined */ 439 /* label %s redefined */
440 error(194, sym->s_name); 440 error(194, sym->s_name);
441 } else { 441 } else {
442 mark_as_set(sym); 442 mark_as_set(sym);
443 } 443 }
444 444
445 set_reached(true); 445 set_reached(true);
446} 446}
447 447
448static void 448static void
449check_case_label_bitand(const tnode_t *case_expr, const tnode_t *switch_expr) 449check_case_label_bitand(const tnode_t *case_expr, const tnode_t *switch_expr)
450{ 450{
451 uint64_t case_value, mask; 451 uint64_t case_value, mask;
452 452
453 if (switch_expr->tn_op != BITAND || 453 if (switch_expr->tn_op != BITAND ||
454 switch_expr->tn_right->tn_op != CON) 454 switch_expr->tn_right->tn_op != CON)
455 return; 455 return;
456 456
457 lint_assert(case_expr->tn_op == CON); 457 lint_assert(case_expr->tn_op == CON);
458 case_value = case_expr->tn_val->v_quad; 458 case_value = case_expr->tn_val->v_quad;
459 mask = switch_expr->tn_right->tn_val->v_quad; 459 mask = switch_expr->tn_right->tn_val->v_quad;
460 460
461 if ((case_value & ~mask) != 0) { 461 if ((case_value & ~mask) != 0) {
462 /* statement not reached */ 462 /* statement not reached */
463 warning(193); 463 warning(193);
464 } 464 }
465} 465}
466 466
467static void 467static void
468check_case_label_enum(const tnode_t *tn, const cstk_t *ci) 468check_case_label_enum(const tnode_t *tn, const control_statement *cs)
469{ 469{
470 /* similar to typeok_enum in tree.c */ 470 /* similar to typeok_enum in tree.c */
471 471
472 if (!(tn->tn_type->t_is_enum || ci->c_switch_type->t_is_enum)) 472 if (!(tn->tn_type->t_is_enum || cs->c_switch_type->t_is_enum))
473 return; 473 return;
474 if (tn->tn_type->t_is_enum && ci->c_switch_type->t_is_enum && 474 if (tn->tn_type->t_is_enum && cs->c_switch_type->t_is_enum &&
475 tn->tn_type->t_enum == ci->c_switch_type->t_enum) 475 tn->tn_type->t_enum == cs->c_switch_type->t_enum)
476 return; 476 return;
477 477
478#if 0 /* not yet ready, see msg_130.c */ 478#if 0 /* not yet ready, see msg_130.c */
479 /* enum type mismatch: '%s' '%s' '%s' */ 479 /* enum type mismatch: '%s' '%s' '%s' */
480 warning(130, type_name(ci->c_switch_type), op_name(EQ), 480 warning(130, type_name(cs->c_switch_type), op_name(EQ),
481 type_name(tn->tn_type)); 481 type_name(tn->tn_type));
482#endif 482#endif
483} 483}
484 484
485static void 485static void
486check_case_label(tnode_t *tn, cstk_t *ci) 486check_case_label(tnode_t *tn, control_statement *cs)
487{ 487{
488 case_label_t *cl; 488 case_label_t *cl;
489 val_t *v; 489 val_t *v;
490 val_t nv; 490 val_t nv;
491 tspec_t t; 491 tspec_t t;
492 492
493 if (ci == NULL) { 493 if (cs == NULL) {
494 /* case not in switch */ 494 /* case not in switch */
495 error(195); 495 error(195);
496 return; 496 return;
497 } 497 }
498 498
499 if (tn != NULL && tn->tn_op != CON) { 499 if (tn != NULL && tn->tn_op != CON) {
500 /* non-constant case expression */ 500 /* non-constant case expression */
501 error(197); 501 error(197);
502 return; 502 return;
503 } 503 }
504 504
505 if (tn != NULL && !is_integer(tn->tn_type->t_tspec)) { 505 if (tn != NULL && !is_integer(tn->tn_type->t_tspec)) {
506 /* non-integral case expression */ 506 /* non-integral case expression */
507 error(198); 507 error(198);
508 return; 508 return;
509 } 509 }
510 510
511 check_case_label_bitand(tn, ci->c_switch_expr); 511 check_case_label_bitand(tn, cs->c_switch_expr);
512 check_case_label_enum(tn, ci); 512 check_case_label_enum(tn, cs);
513 513
514 lint_assert(ci->c_switch_type != NULL); 514 lint_assert(cs->c_switch_type != NULL);
515 515
516 if (reached && !seen_fallthrough) { 516 if (reached && !seen_fallthrough) {
517 if (hflag) 517 if (hflag)
518 /* fallthrough on case statement */ 518 /* fallthrough on case statement */
519 warning(220); 519 warning(220);
520 } 520 }
521 521
522 t = tn->tn_type->t_tspec; 522 t = tn->tn_type->t_tspec;
523 if (t == LONG || t == ULONG || 523 if (t == LONG || t == ULONG ||
524 t == QUAD || t == UQUAD) { 524 t == QUAD || t == UQUAD) {
525 if (tflag) 525 if (tflag)
526 /* case label must be of type `int' in traditional C */ 526 /* case label must be of type `int' in traditional C */
527 warning(203); 527 warning(203);
528 } 528 }
529 529
530 /* 530 /*
531 * get the value of the expression and convert it 531 * get the value of the expression and convert it
532 * to the type of the switch expression 532 * to the type of the switch expression
533 */ 533 */
534 v = constant(tn, true); 534 v = constant(tn, true);
535 (void)memset(&nv, 0, sizeof(nv)); 535 (void)memset(&nv, 0, sizeof(nv));
536 convert_constant(CASE, 0, ci->c_switch_type, &nv, v); 536 convert_constant(CASE, 0, cs->c_switch_type, &nv, v);
537 free(v); 537 free(v);
538 538
539 /* look if we had this value already */ 539 /* look if we had this value already */
540 for (cl = ci->c_case_labels; cl != NULL; cl = cl->cl_next) { 540 for (cl = cs->c_case_labels; cl != NULL; cl = cl->cl_next) {
541 if (cl->cl_val.v_quad == nv.v_quad) 541 if (cl->cl_val.v_quad == nv.v_quad)
542 break; 542 break;
543 } 543 }
544 if (cl != NULL && is_uinteger(nv.v_tspec)) { 544 if (cl != NULL && is_uinteger(nv.v_tspec)) {
545 /* duplicate case in switch: %lu */ 545 /* duplicate case in switch: %lu */
546 error(200, (u_long)nv.v_quad); 546 error(200, (u_long)nv.v_quad);
547 } else if (cl != NULL) { 547 } else if (cl != NULL) {
548 /* duplicate case in switch: %ld */ 548 /* duplicate case in switch: %ld */
549 error(199, (long)nv.v_quad); 549 error(199, (long)nv.v_quad);
550 } else { 550 } else {
551 check_getopt_case_label(nv.v_quad); 551 check_getopt_case_label(nv.v_quad);
552 552
553 /* append the value to the list of case values */ 553 /* append the value to the list of case values */
554 cl = xcalloc(1, sizeof(*cl)); 554 cl = xcalloc(1, sizeof(*cl));
555 cl->cl_val = nv; 555 cl->cl_val = nv;
556 cl->cl_next = ci->c_case_labels; 556 cl->cl_next = cs->c_case_labels;
557 ci->c_case_labels = cl; 557 cs->c_case_labels = cl;
558 } 558 }
559} 559}
560 560
561void 561void
562case_label(tnode_t *tn) 562case_label(tnode_t *tn)
563{ 563{
564 cstk_t *ci; 564 control_statement *cs;
565 565
566 /* find the innermost switch statement */ 566 /* find the innermost switch statement */
567 for (ci = cstmt; ci != NULL && !ci->c_switch; ci = ci->c_surrounding) 567 for (cs = cstmt; cs != NULL && !cs->c_switch; cs = cs->c_surrounding)
568 continue; 568 continue;
569 569
570 check_case_label(tn, ci); 570 check_case_label(tn, cs);
571 571
572 expr_free_all(); 572 expr_free_all();
573 573
574 set_reached(true); 574 set_reached(true);
575} 575}
576 576
577void 577void
578default_label(void) 578default_label(void)
579{ 579{
580 cstk_t *ci; 580 control_statement *cs;
581 581
582 /* find the innermost switch statement */ 582 /* find the innermost switch statement */
583 for (ci = cstmt; ci != NULL && !ci->c_switch; ci = ci->c_surrounding) 583 for (cs = cstmt; cs != NULL && !cs->c_switch; cs = cs->c_surrounding)
584 continue; 584 continue;
585 585
586 if (ci == NULL) { 586 if (cs == NULL) {
587 /* default outside switch */ 587 /* default outside switch */
588 error(201); 588 error(201);
589 } else if (ci->c_default) { 589 } else if (cs->c_default) {
590 /* duplicate default in switch */ 590 /* duplicate default in switch */
591 error(202); 591 error(202);
592 } else { 592 } else {
593 if (reached && !seen_fallthrough) { 593 if (reached && !seen_fallthrough) {
594 if (hflag) 594 if (hflag)
595 /* fallthrough on default statement */ 595 /* fallthrough on default statement */
596 warning(284); 596 warning(284);
597 } 597 }
598 ci->c_default = true; 598 cs->c_default = true;
599 } 599 }
600 600
601 set_reached(true); 601 set_reached(true);
602} 602}
603 603
604static tnode_t * 604static tnode_t *
605check_controlling_expression(tnode_t *tn) 605check_controlling_expression(tnode_t *tn)
606{ 606{
607 607
608 if (tn != NULL) 608 if (tn != NULL)
609 tn = cconv(tn); 609 tn = cconv(tn);
610 if (tn != NULL) 610 if (tn != NULL)
611 tn = promote(NOOP, false, tn); 611 tn = promote(NOOP, false, tn);
612 612
613 if (tn != NULL && !is_scalar(tn->tn_type->t_tspec)) { 613 if (tn != NULL && !is_scalar(tn->tn_type->t_tspec)) {
614 /* C99 6.5.15p4 for the ?: operator; see typeok:QUEST */ 614 /* C99 6.5.15p4 for the ?: operator; see typeok:QUEST */
615 /* C99 6.8.4.1p1 for if statements */ 615 /* C99 6.8.4.1p1 for if statements */
616 /* C99 6.8.5p2 for while, do and for loops */ 616 /* C99 6.8.5p2 for while, do and for loops */
617 /* controlling expressions must have scalar type */ 617 /* controlling expressions must have scalar type */
618 error(204); 618 error(204);
619 return NULL; 619 return NULL;
620 } 620 }
621 621
622 if (tn != NULL && Tflag && !is_typeok_bool_operand(tn)) { 622 if (tn != NULL && Tflag && !is_typeok_bool_operand(tn)) {
623 /* controlling expression must be bool, not '%s' */ 623 /* controlling expression must be bool, not '%s' */
624 error(333, tspec_name(tn->tn_type->t_tspec)); 624 error(333, tspec_name(tn->tn_type->t_tspec));
625 } 625 }
626 626
627 return tn; 627 return tn;
628} 628}
629 629
630/* 630/*
631 * T_IF T_LPAREN expr T_RPAREN 631 * T_IF T_LPAREN expr T_RPAREN
632 */ 632 */
633void 633void
634if1(tnode_t *tn) 634if1(tnode_t *tn)
635{ 635{
636 636
637 if (tn != NULL) 637 if (tn != NULL)
638 tn = check_controlling_expression(tn); 638 tn = check_controlling_expression(tn);
639 if (tn != NULL) 639 if (tn != NULL)
640 expr(tn, false, true, false, false); 640 expr(tn, false, true, false, false);
641 begin_control_statement(CS_IF); 641 begin_control_statement(CS_IF);
642 642
643 if (tn != NULL && tn->tn_op == CON && !tn->tn_system_dependent) { 643 if (tn != NULL && tn->tn_op == CON && !tn->tn_system_dependent) {
644 /* XXX: what if inside 'if (0)'? */ 644 /* XXX: what if inside 'if (0)'? */
645 set_reached(constant_is_nonzero(tn)); 645 set_reached(constant_is_nonzero(tn));
646 /* XXX: what about always_else? */ 646 /* XXX: what about always_else? */
647 cstmt->c_always_then = reached; 647 cstmt->c_always_then = reached;
648 } 648 }
649} 649}
650 650
651/* 651/*
652 * if_without_else 652 * if_without_else
653 * if_without_else T_ELSE 653 * if_without_else T_ELSE
654 */ 654 */
655void 655void
656if2(void) 656if2(void)
657{ 657{
658 658
659 cstmt->c_reached_end_of_then = reached; 659 cstmt->c_reached_end_of_then = reached;
660 /* XXX: what if inside 'if (0)'? */ 660 /* XXX: what if inside 'if (0)'? */
661 set_reached(!cstmt->c_always_then); 661 set_reached(!cstmt->c_always_then);
662} 662}
663 663
664/* 664/*
665 * if_without_else 665 * if_without_else
666 * if_without_else T_ELSE statement 666 * if_without_else T_ELSE statement
667 */ 667 */
668void 668void
669if3(bool els) 669if3(bool els)
670{ 670{
671 if (cstmt->c_reached_end_of_then) 671 if (cstmt->c_reached_end_of_then)
672 set_reached(true); 672 set_reached(true);
673 else if (cstmt->c_always_then) 673 else if (cstmt->c_always_then)
674 set_reached(false); 674 set_reached(false);
675 else if (!els) 675 else if (!els)
676 set_reached(true); 676 set_reached(true);
677 677
678 end_control_statement(CS_IF); 678 end_control_statement(CS_IF);
679} 679}
680 680
681/* 681/*
682 * T_SWITCH T_LPAREN expr T_RPAREN 682 * T_SWITCH T_LPAREN expr T_RPAREN
683 */ 683 */
684void 684void
685switch1(tnode_t *tn) 685switch1(tnode_t *tn)
686{ 686{
687 tspec_t t; 687 tspec_t t;
688 type_t *tp; 688 type_t *tp;
689 689
690 if (tn != NULL) 690 if (tn != NULL)
691 tn = cconv(tn); 691 tn = cconv(tn);
692 if (tn != NULL) 692 if (tn != NULL)
693 tn = promote(NOOP, false, tn); 693 tn = promote(NOOP, false, tn);
694 if (tn != NULL && !is_integer(tn->tn_type->t_tspec)) { 694 if (tn != NULL && !is_integer(tn->tn_type->t_tspec)) {
695 /* switch expression must have integral type */ 695 /* switch expression must have integral type */
696 error(205); 696 error(205);
697 tn = NULL; 697 tn = NULL;
698 } 698 }
699 if (tn != NULL && tflag) { 699 if (tn != NULL && tflag) {
700 t = tn->tn_type->t_tspec; 700 t = tn->tn_type->t_tspec;
701 if (t == LONG || t == ULONG || t == QUAD || t == UQUAD) { 701 if (t == LONG || t == ULONG || t == QUAD || t == UQUAD) {
702 /* switch expr. must be of type `int' in trad. C */ 702 /* switch expr. must be of type `int' in trad. C */
703 warning(271); 703 warning(271);
704 } 704 }
705 } 705 }
706 706
707 /* 707 /*
708 * Remember the type of the expression. Because it's possible 708 * Remember the type of the expression. Because it's possible
709 * that (*tp) is allocated on tree memory, the type must be 709 * that (*tp) is allocated on tree memory, the type must be
710 * duplicated. This is not too complicated because it is 710 * duplicated. This is not too complicated because it is
711 * only an integer type. 711 * only an integer type.
712 */ 712 */
713 tp = xcalloc(1, sizeof(*tp)); 713 tp = xcalloc(1, sizeof(*tp));
714 if (tn != NULL) { 714 if (tn != NULL) {
715 tp->t_tspec = tn->tn_type->t_tspec; 715 tp->t_tspec = tn->tn_type->t_tspec;
716 if ((tp->t_is_enum = tn->tn_type->t_is_enum) != false) 716 if ((tp->t_is_enum = tn->tn_type->t_is_enum) != false)
717 tp->t_enum = tn->tn_type->t_enum; 717 tp->t_enum = tn->tn_type->t_enum;
718 } else { 718 } else {
719 tp->t_tspec = INT; 719 tp->t_tspec = INT;
720 } 720 }
721 721
722 /* leak the memory, for check_case_label_bitand */ 722 /* leak the memory, for check_case_label_bitand */
723 expr_save_memory(); 723 expr_save_memory();
724 724
725 check_getopt_begin_switch(); 725 check_getopt_begin_switch();
726 expr(tn, true, false, false, false); 726 expr(tn, true, false, false, false);
727 727
728 begin_control_statement(CS_SWITCH); 728 begin_control_statement(CS_SWITCH);
729 cstmt->c_switch = true; 729 cstmt->c_switch = true;
730 cstmt->c_switch_type = tp; 730 cstmt->c_switch_type = tp;
731 cstmt->c_switch_expr = tn; 731 cstmt->c_switch_expr = tn;
732 732
733 set_reached(false); 733 set_reached(false);
734 seen_fallthrough = true; 734 seen_fallthrough = true;
735} 735}
736 736
737/* 737/*
738 * switch_expr statement 738 * switch_expr statement
739 */ 739 */
740void 740void
741switch2(void) 741switch2(void)
742{ 742{
743 int nenum = 0, nclab = 0; 743 int nenum = 0, nclab = 0;
744 sym_t *esym; 744 sym_t *esym;
745 case_label_t *cl; 745 case_label_t *cl;
746 746
747 lint_assert(cstmt->c_switch_type != NULL); 747 lint_assert(cstmt->c_switch_type != NULL);
748 748
749 if (cstmt->c_switch_type->t_is_enum) { 749 if (cstmt->c_switch_type->t_is_enum) {
750 /* 750 /*
751 * Warn if the number of case labels is different from the 751 * Warn if the number of case labels is different from the
752 * number of enumerators. 752 * number of enumerators.
753 */ 753 */
754 nenum = nclab = 0; 754 nenum = nclab = 0;
755 lint_assert(cstmt->c_switch_type->t_enum != NULL); 755 lint_assert(cstmt->c_switch_type->t_enum != NULL);
756 for (esym = cstmt->c_switch_type->t_enum->en_first_enumerator; 756 for (esym = cstmt->c_switch_type->t_enum->en_first_enumerator;
757 esym != NULL; esym = esym->s_next) { 757 esym != NULL; esym = esym->s_next) {
758 nenum++; 758 nenum++;
759 } 759 }
760 for (cl = cstmt->c_case_labels; cl != NULL; cl = cl->cl_next) 760 for (cl = cstmt->c_case_labels; cl != NULL; cl = cl->cl_next)
761 nclab++; 761 nclab++;
762 if (hflag && eflag && nenum != nclab && !cstmt->c_default) { 762 if (hflag && eflag && nenum != nclab && !cstmt->c_default) {
763 /* enumeration value(s) not handled in switch */ 763 /* enumeration value(s) not handled in switch */
764 warning(206); 764 warning(206);
765 } 765 }
766 } 766 }
767 767
768 check_getopt_end_switch(); 768 check_getopt_end_switch();
769 769
770 if (cstmt->c_break) { 770 if (cstmt->c_break) {
771 /* 771 /*
772 * The end of the switch statement is always reached since 772 * The end of the switch statement is always reached since
773 * c_break is only set if a break statement can actually 773 * c_break is only set if a break statement can actually
774 * be reached. 774 * be reached.
775 */ 775 */
776 set_reached(true); 776 set_reached(true);
777 } else if (cstmt->c_default || 777 } else if (cstmt->c_default ||
778 (hflag && cstmt->c_switch_type->t_is_enum && 778 (hflag && cstmt->c_switch_type->t_is_enum &&
779 nenum == nclab)) { 779 nenum == nclab)) {
780 /* 780 /*
781 * The end of the switch statement is reached if the end 781 * The end of the switch statement is reached if the end
782 * of the last statement inside it is reached. 782 * of the last statement inside it is reached.
783 */ 783 */
784 } else { 784 } else {
785 /* 785 /*
786 * There are possible values that are not handled in the 786 * There are possible values that are not handled in the
787 * switch statement. 787 * switch statement.
788 */ 788 */
789 set_reached(true); 789 set_reached(true);
790 } 790 }
791 791
792 end_control_statement(CS_SWITCH); 792 end_control_statement(CS_SWITCH);
793} 793}
794 794
795/* 795/*
796 * T_WHILE T_LPAREN expr T_RPAREN 796 * T_WHILE T_LPAREN expr T_RPAREN
797 */ 797 */
798void 798void
799while1(tnode_t *tn) 799while1(tnode_t *tn)
800{ 800{
801 bool body_reached; 801 bool body_reached;
802 802
803 if (!reached) { 803 if (!reached) {
804 /* loop not entered at top */ 804 /* loop not entered at top */
805 warning(207); 805 warning(207);
806 /* FIXME: that's plain wrong. */ 806 /* FIXME: that's plain wrong. */
807 set_reached(true); 807 set_reached(true);
808 } 808 }
809 809
810 if (tn != NULL) 810 if (tn != NULL)
811 tn = check_controlling_expression(tn); 811 tn = check_controlling_expression(tn);
812 812
813 begin_control_statement(CS_WHILE); 813 begin_control_statement(CS_WHILE);
814 cstmt->c_loop = true; 814 cstmt->c_loop = true;
815 cstmt->c_maybe_endless = is_nonzero(tn); 815 cstmt->c_maybe_endless = is_nonzero(tn);
816 body_reached = !is_zero(tn); 816 body_reached = !is_zero(tn);
817 817
818 check_getopt_begin_while(tn); 818 check_getopt_begin_while(tn);
819 expr(tn, false, true, true, false); 819 expr(tn, false, true, true, false);
820 820
821 set_reached(body_reached); 821 set_reached(body_reached);
822} 822}
823 823
824/* 824/*
825 * while_expr statement 825 * while_expr statement
826 * while_expr error 826 * while_expr error
827 */ 827 */
828void 828void
829while2(void) 829while2(void)
830{ 830{
831 831
832 /* 832 /*
833 * The end of the loop can be reached if it is no endless loop 833 * The end of the loop can be reached if it is no endless loop
834 * or there was a break statement which was reached. 834 * or there was a break statement which was reached.
835 */ 835 */
836 set_reached(!cstmt->c_maybe_endless || cstmt->c_break); 836 set_reached(!cstmt->c_maybe_endless || cstmt->c_break);
837 837
838 check_getopt_end_while(); 838 check_getopt_end_while();
839 end_control_statement(CS_WHILE); 839 end_control_statement(CS_WHILE);
840} 840}
841 841
842/* 842/*
843 * T_DO 843 * T_DO
844 */ 844 */
845void 845void
846do1(void) 846do1(void)
847{ 847{
848 848
849 if (!reached) { 849 if (!reached) {
850 /* loop not entered at top */ 850 /* loop not entered at top */
851 warning(207); 851 warning(207);
852 set_reached(true); 852 set_reached(true);
853 } 853 }
854 854
855 begin_control_statement(CS_DO_WHILE); 855 begin_control_statement(CS_DO_WHILE);
856 cstmt->c_loop = true; 856 cstmt->c_loop = true;
857} 857}
858 858
859/* 859/*
860 * do statement do_while_expr 860 * do statement do_while_expr
861 * do error 861 * do error
862 */ 862 */
863void 863void
864do2(tnode_t *tn) 864do2(tnode_t *tn)
865{ 865{
866 866
867 /* 867 /*
868 * If there was a continue statement, the expression controlling the 868 * If there was a continue statement, the expression controlling the
869 * loop is reached. 869 * loop is reached.
870 */ 870 */
871 if (cstmt->c_continue) 871 if (cstmt->c_continue)
872 set_reached(true); 872 set_reached(true);
873 873
874 if (tn != NULL) 874 if (tn != NULL)
875 tn = check_controlling_expression(tn); 875 tn = check_controlling_expression(tn);
876 876
877 if (tn != NULL && tn->tn_op == CON) { 877 if (tn != NULL && tn->tn_op == CON) {
878 cstmt->c_maybe_endless = constant_is_nonzero(tn); 878 cstmt->c_maybe_endless = constant_is_nonzero(tn);
879 if (!cstmt->c_maybe_endless && cstmt->c_continue) 879 if (!cstmt->c_maybe_endless && cstmt->c_continue)
880 /* continue in 'do ... while (0)' loop */ 880 /* continue in 'do ... while (0)' loop */
881 error(323); 881 error(323);
882 } 882 }
883 883
884 expr(tn, false, true, true, true); 884 expr(tn, false, true, true, true);
885 885
886 if (cstmt->c_maybe_endless) 886 if (cstmt->c_maybe_endless)
887 set_reached(false); 887 set_reached(false);
888 if (cstmt->c_break) 888 if (cstmt->c_break)
889 set_reached(true); 889 set_reached(true);
890 890
891 end_control_statement(CS_DO_WHILE); 891 end_control_statement(CS_DO_WHILE);
892} 892}
893 893
894/* 894/*
895 * T_FOR T_LPAREN opt_expr T_SEMI opt_expr T_SEMI opt_expr T_RPAREN 895 * T_FOR T_LPAREN opt_expr T_SEMI opt_expr T_SEMI opt_expr T_RPAREN
896 */ 896 */
897void 897void
898for1(tnode_t *tn1, tnode_t *tn2, tnode_t *tn3) 898for1(tnode_t *tn1, tnode_t *tn2, tnode_t *tn3)
899{ 899{
900 900
901 /* 901 /*
902 * If there is no initialization expression it is possible that 902 * If there is no initialization expression it is possible that
903 * it is intended not to enter the loop at top. 903 * it is intended not to enter the loop at top.
904 */ 904 */
905 if (tn1 != NULL && !reached) { 905 if (tn1 != NULL && !reached) {
906 /* loop not entered at top */ 906 /* loop not entered at top */
907 warning(207); 907 warning(207);
908 set_reached(true); 908 set_reached(true);
909 } 909 }
910 910
911 begin_control_statement(CS_FOR); 911 begin_control_statement(CS_FOR);
912 cstmt->c_loop = true; 912 cstmt->c_loop = true;
913 913
914 /* 914 /*
915 * Store the tree memory for the reinitialization expression. 915 * Store the tree memory for the reinitialization expression.
916 * Also remember this expression itself. We must check it at 916 * Also remember this expression itself. We must check it at
917 * the end of the loop to get "used but not set" warnings correct. 917 * the end of the loop to get "used but not set" warnings correct.
918 */ 918 */
919 cstmt->c_for_expr3_mem = expr_save_memory(); 919 cstmt->c_for_expr3_mem = expr_save_memory();
920 cstmt->c_for_expr3 = tn3; 920 cstmt->c_for_expr3 = tn3;
921 cstmt->c_for_expr3_pos = curr_pos; 921 cstmt->c_for_expr3_pos = curr_pos;
922 cstmt->c_for_expr3_csrc_pos = csrc_pos; 922 cstmt->c_for_expr3_csrc_pos = csrc_pos;
923 923
924 if (tn1 != NULL) 924 if (tn1 != NULL)
925 expr(tn1, false, false, true, false); 925 expr(tn1, false, false, true, false);
926 926
927 if (tn2 != NULL) 927 if (tn2 != NULL)
928 tn2 = check_controlling_expression(tn2); 928 tn2 = check_controlling_expression(tn2);
929 if (tn2 != NULL) 929 if (tn2 != NULL)
930 expr(tn2, false, true, true, false); 930 expr(tn2, false, true, true, false);
931 931
932 cstmt->c_maybe_endless = tn2 == NULL || is_nonzero(tn2); 932 cstmt->c_maybe_endless = tn2 == NULL || is_nonzero(tn2);
933 933
934 /* Checking the reinitialization expression is done in for2() */ 934 /* Checking the reinitialization expression is done in for2() */
935 935
936 set_reached(!is_zero(tn2)); 936 set_reached(!is_zero(tn2));
937} 937}
938 938
939/* 939/*
940 * for_exprs statement 940 * for_exprs statement
941 * for_exprs error 941 * for_exprs error
942 */ 942 */
943void 943void
944for2(void) 944for2(void)
945{ 945{
946 pos_t cpos, cspos; 946 pos_t cpos, cspos;
947 tnode_t *tn3; 947 tnode_t *tn3;
948 948
949 if (cstmt->c_continue) 949 if (cstmt->c_continue)
950 set_reached(true); 950 set_reached(true);
951 951
952 cpos = curr_pos; 952 cpos = curr_pos;
953 cspos = csrc_pos; 953 cspos = csrc_pos;
954 954
955 /* Restore the tree memory for the reinitialization expression */ 955 /* Restore the tree memory for the reinitialization expression */
956 expr_restore_memory(cstmt->c_for_expr3_mem); 956 expr_restore_memory(cstmt->c_for_expr3_mem);
957 tn3 = cstmt->c_for_expr3; 957 tn3 = cstmt->c_for_expr3;
958 curr_pos = cstmt->c_for_expr3_pos; 958 curr_pos = cstmt->c_for_expr3_pos;
959 csrc_pos = cstmt->c_for_expr3_csrc_pos; 959 csrc_pos = cstmt->c_for_expr3_csrc_pos;
960 960
961 /* simply "statement not reached" would be confusing */ 961 /* simply "statement not reached" would be confusing */
962 if (!reached && warn_about_unreachable) { 962 if (!reached && warn_about_unreachable) {
963 /* end-of-loop code not reached */ 963 /* end-of-loop code not reached */
964 warning(223); 964 warning(223);
965 set_reached(true); 965 set_reached(true);
966 } 966 }
967 967
968 if (tn3 != NULL) { 968 if (tn3 != NULL) {
969 expr(tn3, false, false, true, false); 969 expr(tn3, false, false, true, false);
970 } else { 970 } else {
971 expr_free_all(); 971 expr_free_all();
972 } 972 }
973 973
974 curr_pos = cpos; 974 curr_pos = cpos;
975 csrc_pos = cspos; 975 csrc_pos = cspos;
976 976
977 /* An endless loop without break will never terminate */ 977 /* An endless loop without break will never terminate */
978 /* TODO: What if the loop contains a 'return'? */ 978 /* TODO: What if the loop contains a 'return'? */
979 set_reached(cstmt->c_break || !cstmt->c_maybe_endless); 979 set_reached(cstmt->c_break || !cstmt->c_maybe_endless);
980 980
981 end_control_statement(CS_FOR); 981 end_control_statement(CS_FOR);
982} 982}
983 983
984/* 984/*
985 * T_GOTO identifier T_SEMI 985 * T_GOTO identifier T_SEMI
986 */ 986 */
987void 987void
988do_goto(sym_t *lab) 988do_goto(sym_t *lab)
989{ 989{
990 990
991 mark_as_used(lab, false, false); 991 mark_as_used(lab, false, false);
992 992
993 check_statement_reachable(); 993 check_statement_reachable();
994 994
995 set_reached(false); 995 set_reached(false);
996} 996}
997 997
998/* 998/*
999 * T_BREAK T_SEMI 999 * T_BREAK T_SEMI
1000 */ 1000 */
1001void 1001void
1002do_break(void) 1002do_break(void)
1003{ 1003{
1004 cstk_t *ci; 1004 control_statement *cs;
1005 1005
1006 ci = cstmt; 1006 cs = cstmt;
1007 while (ci != NULL && !ci->c_loop && !ci->c_switch) 1007 while (cs != NULL && !cs->c_loop && !cs->c_switch)
1008 ci = ci->c_surrounding; 1008 cs = cs->c_surrounding;
1009 1009
1010 if (ci == NULL) { 1010 if (cs == NULL) {
1011 /* break outside loop or switch */ 1011 /* break outside loop or switch */
1012 error(208); 1012 error(208);
1013 } else { 1013 } else {
1014 if (reached) 1014 if (reached)
1015 ci->c_break = true; 1015 cs->c_break = true;
1016 } 1016 }
1017 1017
1018 if (bflag) 1018 if (bflag)
1019 check_statement_reachable(); 1019 check_statement_reachable();
1020 1020
1021 set_reached(false); 1021 set_reached(false);
1022} 1022}
1023 1023
1024/* 1024/*
1025 * T_CONTINUE T_SEMI 1025 * T_CONTINUE T_SEMI
1026 */ 1026 */
1027void 1027void
1028do_continue(void) 1028do_continue(void)
1029{ 1029{
1030 cstk_t *ci; 1030 control_statement *cs;
1031 1031
1032 for (ci = cstmt; ci != NULL && !ci->c_loop; ci = ci->c_surrounding) 1032 for (cs = cstmt; cs != NULL && !cs->c_loop; cs = cs->c_surrounding)
1033 continue; 1033 continue;
1034 1034
1035 if (ci == NULL) { 1035 if (cs == NULL) {
1036 /* continue outside loop */ 1036 /* continue outside loop */
1037 error(209); 1037 error(209);
1038 } else { 1038 } else {
1039 /* TODO: only if reachable, for symmetry with c_break */ 1039 /* TODO: only if reachable, for symmetry with c_break */
1040 ci->c_continue = true; 1040 cs->c_continue = true;
1041 } 1041 }
1042 1042
1043 check_statement_reachable(); 1043 check_statement_reachable();
1044 1044
1045 set_reached(false); 1045 set_reached(false);
1046} 1046}
1047 1047
1048/* 1048/*
1049 * T_RETURN T_SEMI 1049 * T_RETURN T_SEMI
1050 * T_RETURN expr T_SEMI 1050 * T_RETURN expr T_SEMI
1051 */ 1051 */
1052void 1052void
1053do_return(tnode_t *tn) 1053do_return(tnode_t *tn)
1054{ 1054{
1055 tnode_t *ln, *rn; 1055 tnode_t *ln, *rn;
1056 cstk_t *ci; 1056 control_statement *cs;
1057 op_t op; 1057 op_t op;
1058 1058
1059 ci = cstmt; 1059 cs = cstmt;
1060 if (ci == NULL) { 1060 if (cs == NULL) {
1061 /* syntax error '%s' */ 1061 /* syntax error '%s' */
1062 error(249, "return outside function"); 1062 error(249, "return outside function");
1063 return; 1063 return;
1064 } 1064 }
1065 1065
1066 for (; ci->c_surrounding != NULL; ci = ci->c_surrounding) 1066 for (; cs->c_surrounding != NULL; cs = cs->c_surrounding)
1067 continue; 1067 continue;
1068 1068
1069 if (tn != NULL) 1069 if (tn != NULL)
1070 ci->c_had_return_value = true; 1070 cs->c_had_return_value = true;
1071 else 1071 else
1072 ci->c_had_return_noval = true; 1072 cs->c_had_return_noval = true;
1073 1073
1074 if (tn != NULL && funcsym->s_type->t_subt->t_tspec == VOID) { 1074 if (tn != NULL && funcsym->s_type->t_subt->t_tspec == VOID) {
1075 /* void function %s cannot return value */ 1075 /* void function %s cannot return value */
1076 error(213, funcsym->s_name); 1076 error(213, funcsym->s_name);
1077 expr_free_all(); 1077 expr_free_all();
1078 tn = NULL; 1078 tn = NULL;
1079 } else if (tn == NULL && funcsym->s_type->t_subt->t_tspec != VOID) { 1079 } else if (tn == NULL && funcsym->s_type->t_subt->t_tspec != VOID) {
1080 /* 1080 /*
1081 * Assume that the function has a return value only if it 1081 * Assume that the function has a return value only if it
1082 * is explicitly declared. 1082 * is explicitly declared.
1083 */ 1083 */
1084 if (!funcsym->s_return_type_implicit_int) 1084 if (!funcsym->s_return_type_implicit_int)
1085 /* function %s expects to return value */ 1085 /* function %s expects to return value */
1086 warning(214, funcsym->s_name); 1086 warning(214, funcsym->s_name);
1087 } 1087 }
1088 1088
1089 if (tn != NULL) { 1089 if (tn != NULL) {
1090 1090
1091 /* Create a temporary node for the left side */ 1091 /* Create a temporary node for the left side */
1092 ln = expr_zalloc(sizeof(*ln)); 1092 ln = expr_zalloc(sizeof(*ln));
1093 ln->tn_op = NAME; 1093 ln->tn_op = NAME;
1094 ln->tn_type = expr_dup_type(funcsym->s_type->t_subt); 1094 ln->tn_type = expr_dup_type(funcsym->s_type->t_subt);
1095 ln->tn_type->t_const = false; 1095 ln->tn_type->t_const = false;
1096 ln->tn_lvalue = true; 1096 ln->tn_lvalue = true;
1097 ln->tn_sym = funcsym; /* better than nothing */ 1097 ln->tn_sym = funcsym; /* better than nothing */
1098 1098
1099 tn = build_binary(ln, RETURN, tn); 1099 tn = build_binary(ln, RETURN, tn);
1100 1100
1101 if (tn != NULL) { 1101 if (tn != NULL) {
1102 rn = tn->tn_right; 1102 rn = tn->tn_right;
1103 while ((op = rn->tn_op) == CVT || op == PLUS) 1103 while ((op = rn->tn_op) == CVT || op == PLUS)
1104 rn = rn->tn_left; 1104 rn = rn->tn_left;
1105 if (rn->tn_op == ADDR && rn->tn_left->tn_op == NAME && 1105 if (rn->tn_op == ADDR && rn->tn_left->tn_op == NAME &&
1106 rn->tn_left->tn_sym->s_scl == AUTO) { 1106 rn->tn_left->tn_sym->s_scl == AUTO) {
1107 /* %s returns pointer to automatic object */ 1107 /* %s returns pointer to automatic object */
1108 warning(302, funcsym->s_name); 1108 warning(302, funcsym->s_name);
1109 } 1109 }
1110 } 1110 }
1111 1111
1112 expr(tn, true, false, true, false); 1112 expr(tn, true, false, true, false);
1113 1113
1114 } else { 1114 } else {
1115 1115
1116 check_statement_reachable(); 1116 check_statement_reachable();
1117 1117
1118 } 1118 }
1119 1119
1120 set_reached(false); 1120 set_reached(false);
1121} 1121}
1122 1122
1123/* 1123/*
1124 * Do some cleanup after a global declaration or definition. 1124 * Do some cleanup after a global declaration or definition.
1125 * Especially remove information about unused lint comments. 1125 * Especially remove information about unused lint comments.
1126 */ 1126 */
1127void 1127void
1128global_clean_up_decl(bool silent) 1128global_clean_up_decl(bool silent)
1129{ 1129{
1130 1130
1131 if (nargusg != -1) { 1131 if (nargusg != -1) {
1132 if (!silent) { 1132 if (!silent) {
1133 /* must precede function definition: ** %s ** */ 1133 /* must precede function definition: ** %s ** */
1134 warning_at(282, &argsused_pos, "ARGSUSED"); 1134 warning_at(282, &argsused_pos, "ARGSUSED");
1135 } 1135 }
1136 nargusg = -1; 1136 nargusg = -1;
1137 } 1137 }
1138 if (nvararg != -1) { 1138 if (nvararg != -1) {
1139 if (!silent) { 1139 if (!silent) {
1140 /* must precede function definition: ** %s ** */ 1140 /* must precede function definition: ** %s ** */
1141 warning_at(282, &vapos, "VARARGS"); 1141 warning_at(282, &vapos, "VARARGS");
1142 } 1142 }
1143 nvararg = -1; 1143 nvararg = -1;
1144 } 1144 }
1145 if (printflike_argnum != -1) { 1145 if (printflike_argnum != -1) {
1146 if (!silent) { 1146 if (!silent) {
1147 /* must precede function definition: ** %s ** */ 1147 /* must precede function definition: ** %s ** */
1148 warning_at(282, &printflike_pos, "PRINTFLIKE"); 1148 warning_at(282, &printflike_pos, "PRINTFLIKE");
1149 } 1149 }
1150 printflike_argnum = -1; 1150 printflike_argnum = -1;
1151 } 1151 }
1152 if (scanflike_argnum != -1) { 1152 if (scanflike_argnum != -1) {
1153 if (!silent) { 1153 if (!silent) {
1154 /* must precede function definition: ** %s ** */ 1154 /* must precede function definition: ** %s ** */
1155 warning_at(282, &scanflike_pos, "SCANFLIKE"); 1155 warning_at(282, &scanflike_pos, "SCANFLIKE");
1156 } 1156 }
1157 scanflike_argnum = -1; 1157 scanflike_argnum = -1;
1158 } 1158 }
1159 1159
1160 dcs->d_asm = false; 1160 dcs->d_asm = false;
1161 1161
1162 /* 1162 /*
1163 * Needed for BSD yacc in case of parse errors; GNU Bison 3.0.4 is 1163 * Needed for BSD yacc in case of parse errors; GNU Bison 3.0.4 is
1164 * fine. See gcc_attribute.c, function_with_unknown_attribute. 1164 * fine. See gcc_attribute.c, function_with_unknown_attribute.
1165 */ 1165 */
1166 attron = false; 1166 attron = false;
1167} 1167}
1168 1168
1169/* 1169/*
1170 * ARGSUSED comment 1170 * ARGSUSED comment
1171 * 1171 *
1172 * Only the first n arguments of the following function are checked 1172 * Only the first n arguments of the following function are checked
1173 * for usage. A missing argument is taken to be 0. 1173 * for usage. A missing argument is taken to be 0.
1174 */ 1174 */
1175void 1175void
1176argsused(int n) 1176argsused(int n)
1177{ 1177{
1178 1178
1179 if (n == -1) 1179 if (n == -1)
1180 n = 0; 1180 n = 0;
1181 1181
1182 if (dcs->d_ctx != EXTERN) { 1182 if (dcs->d_ctx != EXTERN) {
1183 /* must be outside function: ** %s ** */ 1183 /* must be outside function: ** %s ** */
1184 warning(280, "ARGSUSED"); 1184 warning(280, "ARGSUSED");
1185 return; 1185 return;
1186 } 1186 }
1187 if (nargusg != -1) { 1187 if (nargusg != -1) {
1188 /* duplicate use of ** %s ** */ 1188 /* duplicate use of ** %s ** */
1189 warning(281, "ARGSUSED"); 1189 warning(281, "ARGSUSED");
1190 } 1190 }
1191 nargusg = n; 1191 nargusg = n;
1192 argsused_pos = curr_pos; 1192 argsused_pos = curr_pos;
1193} 1193}
1194 1194
1195/* 1195/*
1196 * VARARGS comment 1196 * VARARGS comment
1197 * 1197 *
1198 * Causes lint2 to check only the first n arguments for compatibility 1198 * Causes lint2 to check only the first n arguments for compatibility
1199 * with the function definition. A missing argument is taken to be 0. 1199 * with the function definition. A missing argument is taken to be 0.
1200 */ 1200 */
1201void 1201void
1202varargs(int n) 1202varargs(int n)
1203{ 1203{
1204 1204
1205 if (n == -1) 1205 if (n == -1)
1206 n = 0; 1206 n = 0;
1207 1207
1208 if (dcs->d_ctx != EXTERN) { 1208 if (dcs->d_ctx != EXTERN) {
1209 /* must be outside function: ** %s ** */ 1209 /* must be outside function: ** %s ** */
1210 warning(280, "VARARGS"); 1210 warning(280, "VARARGS");
1211 return; 1211 return;
1212 } 1212 }
1213 if (nvararg != -1) { 1213 if (nvararg != -1) {
1214 /* duplicate use of ** %s ** */ 1214 /* duplicate use of ** %s ** */
1215 warning(281, "VARARGS"); 1215 warning(281, "VARARGS");
1216 } 1216 }
1217 nvararg = n; 1217 nvararg = n;
1218 vapos = curr_pos; 1218 vapos = curr_pos;
1219} 1219}
1220 1220
1221/* 1221/*
1222 * PRINTFLIKE comment 1222 * PRINTFLIKE comment
1223 * 1223 *
1224 * Check all arguments until the (n-1)-th as usual. The n-th argument is 1224 * Check all arguments until the (n-1)-th as usual. The n-th argument is
1225 * used the check the types of remaining arguments. 1225 * used the check the types of remaining arguments.
1226 */ 1226 */
1227void 1227void
1228printflike(int n) 1228printflike(int n)
1229{ 1229{
1230 1230
1231 if (n == -1) 1231 if (n == -1)
1232 n = 0; 1232 n = 0;
1233 1233
1234 if (dcs->d_ctx != EXTERN) { 1234 if (dcs->d_ctx != EXTERN) {
1235 /* must be outside function: ** %s ** */ 1235 /* must be outside function: ** %s ** */
1236 warning(280, "PRINTFLIKE"); 1236 warning(280, "PRINTFLIKE");
1237 return; 1237 return;
1238 } 1238 }
1239 if (printflike_argnum != -1) { 1239 if (printflike_argnum != -1) {
1240 /* duplicate use of ** %s ** */ 1240 /* duplicate use of ** %s ** */
1241 warning(281, "PRINTFLIKE"); 1241 warning(281, "PRINTFLIKE");
1242 } 1242 }
1243 printflike_argnum = n; 1243 printflike_argnum = n;
1244 printflike_pos = curr_pos; 1244 printflike_pos = curr_pos;
1245} 1245}
1246 1246
1247/* 1247/*
1248 * SCANFLIKE comment 1248 * SCANFLIKE comment
1249 * 1249 *
1250 * Check all arguments until the (n-1)-th as usual. The n-th argument is 1250 * Check all arguments until the (n-1)-th as usual. The n-th argument is
1251 * used the check the types of remaining arguments. 1251 * used the check the types of remaining arguments.
1252 */ 1252 */
1253void 1253void
1254scanflike(int n) 1254scanflike(int n)
1255{ 1255{
1256 1256
1257 if (n == -1) 1257 if (n == -1)
1258 n = 0; 1258 n = 0;
1259 1259
1260 if (dcs->d_ctx != EXTERN) { 1260 if (dcs->d_ctx != EXTERN) {
1261 /* must be outside function: ** %s ** */ 1261 /* must be outside function: ** %s ** */
1262 warning(280, "SCANFLIKE"); 1262 warning(280, "SCANFLIKE");
1263 return; 1263 return;
1264 } 1264 }
1265 if (scanflike_argnum != -1) { 1265 if (scanflike_argnum != -1) {
1266 /* duplicate use of ** %s ** */ 1266 /* duplicate use of ** %s ** */
1267 warning(281, "SCANFLIKE"); 1267 warning(281, "SCANFLIKE");
1268 } 1268 }
1269 scanflike_argnum = n; 1269 scanflike_argnum = n;
1270 scanflike_pos = curr_pos; 1270 scanflike_pos = curr_pos;
1271} 1271}
1272 1272
1273/* 1273/*
1274 * Set the line number for a CONSTCOND comment. At this and the following 1274 * Set the line number for a CONSTCOND comment. At this and the following
1275 * line no warnings about constants in conditional contexts are printed. 1275 * line no warnings about constants in conditional contexts are printed.
1276 */ 1276 */
1277/* ARGSUSED */ 1277/* ARGSUSED */
1278void 1278void
1279constcond(int n) 1279constcond(int n)
1280{ 1280{
1281 1281
1282 constcond_flag = true; 1282 constcond_flag = true;
1283} 1283}
1284 1284
1285/* 1285/*
1286 * Suppress printing of "fallthrough on ..." warnings until next 1286 * Suppress printing of "fallthrough on ..." warnings until next
1287 * statement. 1287 * statement.
1288 */ 1288 */
1289/* ARGSUSED */ 1289/* ARGSUSED */
1290void 1290void
1291fallthru(int n) 1291fallthru(int n)
1292{ 1292{
1293 1293
1294 seen_fallthrough = true; 1294 seen_fallthrough = true;
1295} 1295}
1296 1296
1297/* 1297/*
1298 * Stop warnings about statements which cannot be reached. Also tells lint 1298 * Stop warnings about statements which cannot be reached. Also tells lint
1299 * that the following statements cannot be reached (e.g. after exit()). 1299 * that the following statements cannot be reached (e.g. after exit()).
1300 */ 1300 */
1301/* ARGSUSED */ 1301/* ARGSUSED */
1302void 1302void
1303not_reached(int n) 1303not_reached(int n)
1304{ 1304{
1305 1305
1306 set_reached(false); 1306 set_reached(false);
1307 warn_about_unreachable = false; 1307 warn_about_unreachable = false;
1308} 1308}
1309 1309
1310/* ARGSUSED */ 1310/* ARGSUSED */
1311void 1311void
1312lintlib(int n) 1312lintlib(int n)
1313{ 1313{
1314 1314
1315 if (dcs->d_ctx != EXTERN) { 1315 if (dcs->d_ctx != EXTERN) {
1316 /* must be outside function: ** %s ** */ 1316 /* must be outside function: ** %s ** */
1317 warning(280, "LINTLIBRARY"); 1317 warning(280, "LINTLIBRARY");
1318 return; 1318 return;
1319 } 1319 }
1320 llibflg = true; 1320 llibflg = true;
1321 vflag = false; 1321 vflag = false;
1322} 1322}
1323 1323
1324/* 1324/*
1325 * Suppress most warnings at the current and the following line. 1325 * Suppress most warnings at the current and the following line.
1326 */ 1326 */
1327/* ARGSUSED */ 1327/* ARGSUSED */
1328void 1328void
1329linted(int n) 1329linted(int n)
1330{ 1330{
1331 1331
1332#ifdef DEBUG 1332#ifdef DEBUG
1333 printf("%s, %d: lwarn = %d\n", curr_pos.p_file, curr_pos.p_line, n); 1333 printf("%s, %d: lwarn = %d\n", curr_pos.p_file, curr_pos.p_line, n);
1334#endif 1334#endif
1335 lwarn = n; 1335 lwarn = n;
1336} 1336}
1337 1337
1338/* 1338/*
1339 * Suppress bitfield type errors on the current line. 1339 * Suppress bitfield type errors on the current line.
1340 */ 1340 */
1341/* ARGSUSED */ 1341/* ARGSUSED */
1342void 1342void
1343bitfieldtype(int n) 1343bitfieldtype(int n)
1344{ 1344{
1345 1345
1346#ifdef DEBUG 1346#ifdef DEBUG
1347 printf("%s, %d: bitfieldtype_ok = true\n", curr_pos.p_file, 1347 printf("%s, %d: bitfieldtype_ok = true\n", curr_pos.p_file,
1348 curr_pos.p_line); 1348 curr_pos.p_line);
1349#endif 1349#endif
1350 bitfieldtype_ok = true; 1350 bitfieldtype_ok = true;
1351} 1351}
1352 1352
1353/* 1353/*
1354 * PROTOLIB in conjunction with LINTLIBRARY can be used to handle 1354 * PROTOLIB in conjunction with LINTLIBRARY can be used to handle
1355 * prototypes like function definitions. This is done if the argument 1355 * prototypes like function definitions. This is done if the argument
1356 * to PROTOLIB is nonzero. Otherwise prototypes are handled normally. 1356 * to PROTOLIB is nonzero. Otherwise prototypes are handled normally.
1357 */ 1357 */
1358void 1358void
1359protolib(int n) 1359protolib(int n)
1360{ 1360{
1361 1361
1362 if (dcs->d_ctx != EXTERN) { 1362 if (dcs->d_ctx != EXTERN) {
1363 /* must be outside function: ** %s ** */ 1363 /* must be outside function: ** %s ** */
1364 warning(280, "PROTOLIB"); 1364 warning(280, "PROTOLIB");
1365 return; 1365 return;
1366 } 1366 }
1367 plibflg = n != 0; 1367 plibflg = n != 0;
1368} 1368}
1369 1369
1370/* The next statement/declaration may use "long long" without a diagnostic. */ 1370/* The next statement/declaration may use "long long" without a diagnostic. */
1371/* ARGSUSED */ 1371/* ARGSUSED */
1372void 1372void
1373longlong(int n) 1373longlong(int n)
1374{ 1374{
1375 1375
1376 quadflg = true; 1376 quadflg = true;
1377} 1377}

cvs diff -r1.117 -r1.118 src/usr.bin/xlint/lint1/lint1.h (switch to unified diff)

--- src/usr.bin/xlint/lint1/lint1.h 2021/07/23 16:48:48 1.117
+++ src/usr.bin/xlint/lint1/lint1.h 2021/07/23 17:06:37 1.118
@@ -1,583 +1,583 @@ @@ -1,583 +1,583 @@
1/* $NetBSD: lint1.h,v 1.117 2021/07/23 16:48:48 rillig Exp $ */ 1/* $NetBSD: lint1.h,v 1.118 2021/07/23 17:06:37 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#include "lint.h" 35#include "lint.h"
36#include "err-msgs.h" 36#include "err-msgs.h"
37#include "op.h" 37#include "op.h"
38 38
39/* 39/*
40 * XXX - Super conservative so that works for most systems, but we should 40 * XXX - Super conservative so that works for most systems, but we should
41 * not depend on the host settings but the target settings in determining 41 * not depend on the host settings but the target settings in determining
42 * the alignment. The only valid use for this is in mem1.c; uses in decl.c 42 * the alignment. The only valid use for this is in mem1.c; uses in decl.c
43 * are bogus. 43 * are bogus.
44 */ 44 */
45#ifndef WORST_ALIGN 45#ifndef WORST_ALIGN
46#ifdef _LP64 46#ifdef _LP64
47# define AVAL 15 47# define AVAL 15
48#else 48#else
49# define AVAL 7 49# define AVAL 7
50#endif 50#endif
51#define WORST_ALIGN(x) (((x) + AVAL) & ~AVAL) 51#define WORST_ALIGN(x) (((x) + AVAL) & ~AVAL)
52#endif 52#endif
53 53
54#define LWARN_BAD (-3) 54#define LWARN_BAD (-3)
55#define LWARN_ALL (-2) 55#define LWARN_ALL (-2)
56#define LWARN_NONE (-1) 56#define LWARN_NONE (-1)
57 57
58/* 58/*
59 * Describes the position of a declaration or anything else. 59 * Describes the position of a declaration or anything else.
60 * 60 *
61 * FIXME: Just a single file:lineno pair is not enough to accurately describe 61 * FIXME: Just a single file:lineno pair is not enough to accurately describe
62 * the position of a symbol. The whole inclusion path at that point must be 62 * the position of a symbol. The whole inclusion path at that point must be
63 * stored as well. This makes a difference for symbols from included 63 * stored as well. This makes a difference for symbols from included
64 * headers, see print_stack_trace. 64 * headers, see print_stack_trace.
65 */ 65 */
66typedef struct { 66typedef struct {
67 const char *p_file; 67 const char *p_file;
68 int p_line; 68 int p_line;
69 int p_uniq; /* uniquifier */ 69 int p_uniq; /* uniquifier */
70} pos_t; 70} pos_t;
71 71
72/* Copies curr_pos, keeping things unique. */ 72/* Copies curr_pos, keeping things unique. */
73#define UNIQUE_CURR_POS(pos) \ 73#define UNIQUE_CURR_POS(pos) \
74 do { \ 74 do { \
75 (pos) = curr_pos; \ 75 (pos) = curr_pos; \
76 curr_pos.p_uniq++; \ 76 curr_pos.p_uniq++; \
77 if (curr_pos.p_file == csrc_pos.p_file) \ 77 if (curr_pos.p_file == csrc_pos.p_file) \
78 csrc_pos.p_uniq++; \ 78 csrc_pos.p_uniq++; \
79 } while (false) 79 } while (false)
80 80
81/* 81/*
82 * Strings cannot be referenced to simply by a pointer to its first 82 * Strings cannot be referenced to simply by a pointer to its first
83 * char. This is because strings can contain NUL characters other than the 83 * char. This is because strings can contain NUL characters other than the
84 * trailing NUL. 84 * trailing NUL.
85 * 85 *
86 * Strings are stored with a trailing NUL. 86 * Strings are stored with a trailing NUL.
87 */ 87 */
88typedef struct strg { 88typedef struct strg {
89 tspec_t st_tspec; /* CHAR or WCHAR */ 89 tspec_t st_tspec; /* CHAR or WCHAR */
90 size_t st_len; /* length without trailing NUL */ 90 size_t st_len; /* length without trailing NUL */
91 union { 91 union {
92 u_char *_st_cp; 92 u_char *_st_cp;
93 wchar_t *_st_wcp; 93 wchar_t *_st_wcp;
94 } st_u; 94 } st_u;
95} strg_t; 95} strg_t;
96 96
97#define st_cp st_u._st_cp 97#define st_cp st_u._st_cp
98#define st_wcp st_u._st_wcp 98#define st_wcp st_u._st_wcp
99 99
100/* 100/*
101 * qualifiers (only for lex/yacc interface) 101 * qualifiers (only for lex/yacc interface)
102 */ 102 */
103typedef enum { 103typedef enum {
104 CONST, VOLATILE, RESTRICT, THREAD 104 CONST, VOLATILE, RESTRICT, THREAD
105} tqual_t; 105} tqual_t;
106 106
107/* An integer or floating-point value. */ 107/* An integer or floating-point value. */
108typedef struct { 108typedef struct {
109 tspec_t v_tspec; 109 tspec_t v_tspec;
110 /* 110 /*
111 * Set if an integer constant is unsigned only in C90 and later, but 111 * Set if an integer constant is unsigned only in C90 and later, but
112 * not in traditional C. 112 * not in traditional C.
113 * 113 *
114 * See the operators table in ops.def, columns "l r". 114 * See the operators table in ops.def, columns "l r".
115 */ 115 */
116 bool v_unsigned_since_c90; 116 bool v_unsigned_since_c90;
117 union { 117 union {
118 int64_t _v_quad; /* integers */ 118 int64_t _v_quad; /* integers */
119 ldbl_t _v_ldbl; /* floats */ 119 ldbl_t _v_ldbl; /* floats */
120 } v_u; 120 } v_u;
121} val_t; 121} val_t;
122 122
123#define v_quad v_u._v_quad 123#define v_quad v_u._v_quad
124#define v_ldbl v_u._v_ldbl 124#define v_ldbl v_u._v_ldbl
125 125
126/* 126/*
127 * Structures of type struct_or_union uniquely identify structures. This can't 127 * Structures of type struct_or_union uniquely identify structures. This can't
128 * be done in structures of type type_t, because these are copied 128 * be done in structures of type type_t, because these are copied
129 * if they must be modified. So it would not be possible to check 129 * if they must be modified. So it would not be possible to check
130 * if two structures are identical by comparing the pointers to 130 * if two structures are identical by comparing the pointers to
131 * the type structures. 131 * the type structures.
132 * 132 *
133 * The typename is used if the structure is unnamed to identify 133 * The typename is used if the structure is unnamed to identify
134 * the structure type in pass 2. 134 * the structure type in pass 2.
135 */ 135 */
136typedef struct { 136typedef struct {
137 u_int sou_size_in_bits; 137 u_int sou_size_in_bits;
138 u_int sou_align_in_bits : 15; 138 u_int sou_align_in_bits : 15;
139 bool sou_incomplete : 1; 139 bool sou_incomplete : 1;
140 struct sym *sou_first_member; 140 struct sym *sou_first_member;
141 struct sym *sou_tag; 141 struct sym *sou_tag;
142 struct sym *sou_first_typedef; 142 struct sym *sou_first_typedef;
143} struct_or_union; 143} struct_or_union;
144 144
145/* 145/*
146 * same as above for enums 146 * same as above for enums
147 */ 147 */
148typedef struct { 148typedef struct {
149 bool en_incomplete : 1; 149 bool en_incomplete : 1;
150 struct sym *en_first_enumerator; 150 struct sym *en_first_enumerator;
151 struct sym *en_tag; 151 struct sym *en_tag;
152 struct sym *en_first_typedef; 152 struct sym *en_first_typedef;
153} enumeration; 153} enumeration;
154 154
155/* 155/*
156 * The type of an expression or object. Complex types are formed via t_subt 156 * The type of an expression or object. Complex types are formed via t_subt
157 * (for arrays, pointers and functions), as well as t_str. 157 * (for arrays, pointers and functions), as well as t_str.
158 */ 158 */
159struct lint1_type { 159struct lint1_type {
160 tspec_t t_tspec; /* type specifier */ 160 tspec_t t_tspec; /* type specifier */
161 bool t_incomplete_array : 1; 161 bool t_incomplete_array : 1;
162 bool t_const : 1; /* const modifier */ 162 bool t_const : 1; /* const modifier */
163 bool t_volatile : 1; /* volatile modifier */ 163 bool t_volatile : 1; /* volatile modifier */
164 bool t_proto : 1; /* function prototype (t_args valid) */ 164 bool t_proto : 1; /* function prototype (t_args valid) */
165 bool t_vararg : 1; /* prototype with '...' */ 165 bool t_vararg : 1; /* prototype with '...' */
166 bool t_typedef : 1; /* type defined with typedef */ 166 bool t_typedef : 1; /* type defined with typedef */
167 bool t_bitfield : 1; 167 bool t_bitfield : 1;
168 /* 168 /*
169 * Either the type is currently an enum (having t_tspec ENUM), or 169 * Either the type is currently an enum (having t_tspec ENUM), or
170 * it is an integer type (typically INT) that has been implicitly 170 * it is an integer type (typically INT) that has been implicitly
171 * converted from an enum type. In both cases, t_enum is valid. 171 * converted from an enum type. In both cases, t_enum is valid.
172 * 172 *
173 * The information about a former enum type is retained to allow 173 * The information about a former enum type is retained to allow
174 * type checks in expressions such as ((var1 & 0x0001) == var2), to 174 * type checks in expressions such as ((var1 & 0x0001) == var2), to
175 * detect when var1 and var2 are from incompatible enum types. 175 * detect when var1 and var2 are from incompatible enum types.
176 */ 176 */
177 bool t_is_enum : 1; 177 bool t_is_enum : 1;
178 bool t_packed : 1; 178 bool t_packed : 1;
179 union { 179 union {
180 int _t_dim; /* dimension (if ARRAY) */ 180 int _t_dim; /* dimension (if ARRAY) */
181 struct_or_union *_t_str; 181 struct_or_union *_t_str;
182 enumeration *_t_enum; 182 enumeration *_t_enum;
183 struct sym *_t_args; /* arguments (if t_proto) */ 183 struct sym *_t_args; /* arguments (if t_proto) */
184 } t_u; 184 } t_u;
185 struct { 185 struct {
186 u_int _t_flen : 8; /* length of bit-field */ 186 u_int _t_flen : 8; /* length of bit-field */
187 u_int _t_foffs : 24; /* offset of bit-field */ 187 u_int _t_foffs : 24; /* offset of bit-field */
188 } t_b; 188 } t_b;
189 struct lint1_type *t_subt; /* element type (if ARRAY), 189 struct lint1_type *t_subt; /* element type (if ARRAY),
190 * return value (if FUNC), 190 * return value (if FUNC),
191 * target type (if PTR) */ 191 * target type (if PTR) */
192}; 192};
193 193
194#define t_dim t_u._t_dim 194#define t_dim t_u._t_dim
195#define t_str t_u._t_str 195#define t_str t_u._t_str
196#define t_enum t_u._t_enum 196#define t_enum t_u._t_enum
197#define t_args t_u._t_args 197#define t_args t_u._t_args
198#define t_flen t_b._t_flen 198#define t_flen t_b._t_flen
199#define t_foffs t_b._t_foffs 199#define t_foffs t_b._t_foffs
200 200
201/* 201/*
202 * types of symbols 202 * types of symbols
203 */ 203 */
204typedef enum { 204typedef enum {
205 FVFT, /* variables, functions, type names, enums */ 205 FVFT, /* variables, functions, type names, enums */
206 FMEMBER, /* members of structs or unions */ 206 FMEMBER, /* members of structs or unions */
207 FTAG, /* tags */ 207 FTAG, /* tags */
208 FLABEL /* labels */ 208 FLABEL /* labels */
209} symt_t; 209} symt_t;
210 210
211/* 211/*
212 * storage classes and related things 212 * storage classes and related things
213 */ 213 */
214typedef enum { 214typedef enum {
215 NOSCL, 215 NOSCL,
216 EXTERN, /* external symbols (independent of decl_t) */ 216 EXTERN, /* external symbols (independent of decl_t) */
217 STATIC, /* static symbols (local and global) */ 217 STATIC, /* static symbols (local and global) */
218 AUTO, /* automatic symbols (except register) */ 218 AUTO, /* automatic symbols (except register) */
219 REG, /* register */ 219 REG, /* register */
220 TYPEDEF, /* typedef */ 220 TYPEDEF, /* typedef */
221 STRUCT_TAG, 221 STRUCT_TAG,
222 UNION_TAG, 222 UNION_TAG,
223 ENUM_TAG, 223 ENUM_TAG,
224 MOS, /* member of struct */ 224 MOS, /* member of struct */
225 MOU, /* member of union */ 225 MOU, /* member of union */
226 CTCONST, /* enumerator, enum constant or bool constant */ 226 CTCONST, /* enumerator, enum constant or bool constant */
227 ABSTRACT, /* abstract symbol (sizeof, casts, unnamed argument) */ 227 ABSTRACT, /* abstract symbol (sizeof, casts, unnamed argument) */
228 ARG, /* argument */ 228 ARG, /* argument */
229 PROTO_ARG, /* used in declaration stack during prototype 229 PROTO_ARG, /* used in declaration stack during prototype
230 declaration */ 230 declaration */
231 INLINE /* only used by the parser */ 231 INLINE /* only used by the parser */
232} scl_t; 232} scl_t;
233 233
234/* 234/*
235 * symbol table entry 235 * symbol table entry
236 */ 236 */
237typedef struct sym { 237typedef struct sym {
238 const char *s_name; 238 const char *s_name;
239 const char *s_rename; /* renamed symbol's given name */ 239 const char *s_rename; /* renamed symbol's given name */
240 pos_t s_def_pos; /* position of last (prototype) definition, 240 pos_t s_def_pos; /* position of last (prototype) definition,
241 prototype declaration, no-prototype-def., 241 prototype declaration, no-prototype-def.,
242 tentative definition or declaration, 242 tentative definition or declaration,
243 in this order */ 243 in this order */
244 pos_t s_set_pos; /* position of first initialization */ 244 pos_t s_set_pos; /* position of first initialization */
245 pos_t s_use_pos; /* position of first use */ 245 pos_t s_use_pos; /* position of first use */
246 symt_t s_kind; /* type of symbol */ 246 symt_t s_kind; /* type of symbol */
247 const struct kwtab *s_keyword; 247 const struct kwtab *s_keyword;
248 bool s_bitfield : 1; 248 bool s_bitfield : 1;
249 bool s_set : 1; /* variable set, label defined */ 249 bool s_set : 1; /* variable set, label defined */
250 bool s_used : 1; /* variable/label used */ 250 bool s_used : 1; /* variable/label used */
251 bool s_arg : 1; /* symbol is function argument */ 251 bool s_arg : 1; /* symbol is function argument */
252 bool s_reg : 1; /* symbol is register variable */ 252 bool s_reg : 1; /* symbol is register variable */
253 bool s_defarg : 1; /* undefined symbol in old style function 253 bool s_defarg : 1; /* undefined symbol in old style function
254 definition */ 254 definition */
255 bool s_return_type_implicit_int : 1; 255 bool s_return_type_implicit_int : 1;
256 bool s_osdef : 1; /* symbol stems from old style function def. */ 256 bool s_osdef : 1; /* symbol stems from old style function def. */
257 bool s_inline : 1; /* true if this is an inline function */ 257 bool s_inline : 1; /* true if this is an inline function */
258 struct sym *s_ext_sym; /* for local declared external symbols pointer 258 struct sym *s_ext_sym; /* for local declared external symbols pointer
259 to external symbol with same name */ 259 to external symbol with same name */
260 def_t s_def; /* declared, tentative defined, defined */ 260 def_t s_def; /* declared, tentative defined, defined */
261 scl_t s_scl; /* storage class */ 261 scl_t s_scl; /* storage class */
262 int s_block_level; /* level of declaration, -1 if not in symbol 262 int s_block_level; /* level of declaration, -1 if not in symbol
263 table */ 263 table */
264 type_t *s_type; 264 type_t *s_type;
265 val_t s_value; /* value (if enum or bool constant) */ 265 val_t s_value; /* value (if enum or bool constant) */
266 union { 266 union {
267 struct_or_union *_s_st; 267 struct_or_union *_s_st;
268 enumeration *_s_et; 268 enumeration *_s_et;
269 tspec_t _s_tsp; /* type (only for keywords) */ 269 tspec_t _s_tsp; /* type (only for keywords) */
270 tqual_t _s_tqu; /* qualifier (only for keywords) */ 270 tqual_t _s_tqu; /* qualifier (only for keywords) */
271 struct sym *_s_args; /* arguments in old style function 271 struct sym *_s_args; /* arguments in old style function
272 definitions */ 272 definitions */
273 } u; 273 } u;
274 struct sym *s_link; /* next symbol with same hash value */ 274 struct sym *s_link; /* next symbol with same hash value */
275 struct sym **s_rlink; /* pointer to s_link of prev. symbol */ 275 struct sym **s_rlink; /* pointer to s_link of prev. symbol */
276 struct sym *s_next; /* next struct/union member, enumerator, 276 struct sym *s_next; /* next struct/union member, enumerator,
277 argument */ 277 argument */
278 struct sym *s_dlnxt; /* next symbol declared on same level */ 278 struct sym *s_dlnxt; /* next symbol declared on same level */
279} sym_t; 279} sym_t;
280 280
281#define s_styp u._s_st 281#define s_styp u._s_st
282#define s_etyp u._s_et 282#define s_etyp u._s_et
283#define s_tspec u._s_tsp 283#define s_tspec u._s_tsp
284#define s_tqual u._s_tqu 284#define s_tqual u._s_tqu
285#define s_args u._s_args 285#define s_args u._s_args
286 286
287/* 287/*
288 * Used to keep some information about symbols before they are entered 288 * Used to keep some information about symbols before they are entered
289 * into the symbol table. 289 * into the symbol table.
290 */ 290 */
291typedef struct sbuf { 291typedef struct sbuf {
292 const char *sb_name; /* name of symbol */ 292 const char *sb_name; /* name of symbol */
293 size_t sb_len; /* length (without '\0') */ 293 size_t sb_len; /* length (without '\0') */
294 int sb_hash; /* hash value */ 294 int sb_hash; /* hash value */
295 sym_t *sb_sym; /* symbol table entry */ 295 sym_t *sb_sym; /* symbol table entry */
296 struct sbuf *sb_next; /* for freelist */ 296 struct sbuf *sb_next; /* for freelist */
297} sbuf_t; 297} sbuf_t;
298 298
299 299
300/* 300/*
301 * tree node 301 * tree node
302 */ 302 */
303typedef struct tnode { 303typedef struct tnode {
304 op_t tn_op; /* operator */ 304 op_t tn_op; /* operator */
305 type_t *tn_type; /* type */ 305 type_t *tn_type; /* type */
306 bool tn_lvalue : 1; /* node is lvalue */ 306 bool tn_lvalue : 1; /* node is lvalue */
307 bool tn_cast : 1; /* if tn_op == CVT, it's an explicit cast */ 307 bool tn_cast : 1; /* if tn_op == CVT, it's an explicit cast */
308 bool tn_parenthesized : 1; 308 bool tn_parenthesized : 1;
309 bool tn_relaxed : 1; /* in strict bool mode, allow mixture between 309 bool tn_relaxed : 1; /* in strict bool mode, allow mixture between
310 * bool and scalar, for backwards 310 * bool and scalar, for backwards
311 * compatibility 311 * compatibility
312 */ 312 */
313 bool tn_system_dependent : 1; /* depends on sizeof or offsetof */ 313 bool tn_system_dependent : 1; /* depends on sizeof or offsetof */
314 union { 314 union {
315 struct { 315 struct {
316 struct tnode *_tn_left; /* (left) operand */ 316 struct tnode *_tn_left; /* (left) operand */
317 struct tnode *_tn_right; /* right operand */ 317 struct tnode *_tn_right; /* right operand */
318 } tn_s; 318 } tn_s;
319 sym_t *_tn_sym; /* symbol if op == NAME */ 319 sym_t *_tn_sym; /* symbol if op == NAME */
320 val_t *_tn_val; /* value if op == CON */ 320 val_t *_tn_val; /* value if op == CON */
321 strg_t *_tn_string; /* string if op == STRING */ 321 strg_t *_tn_string; /* string if op == STRING */
322 } tn_u; 322 } tn_u;
323} tnode_t; 323} tnode_t;
324 324
325#define tn_left tn_u.tn_s._tn_left 325#define tn_left tn_u.tn_s._tn_left
326#define tn_right tn_u.tn_s._tn_right 326#define tn_right tn_u.tn_s._tn_right
327#define tn_sym tn_u._tn_sym 327#define tn_sym tn_u._tn_sym
328#define tn_val tn_u._tn_val 328#define tn_val tn_u._tn_val
329#define tn_string tn_u._tn_string 329#define tn_string tn_u._tn_string
330 330
331struct generic_association { 331struct generic_association {
332 type_t *ga_arg; /* NULL means default or error */ 332 type_t *ga_arg; /* NULL means default or error */
333 tnode_t *ga_result; /* NULL means error */ 333 tnode_t *ga_result; /* NULL means error */
334 struct generic_association *ga_prev; 334 struct generic_association *ga_prev;
335}; 335};
336 336
337/* 337/*
338 * For nested declarations a stack exists, which holds all information 338 * For nested declarations a stack exists, which holds all information
339 * needed for the current level. dcs points to the innermost element of this 339 * needed for the current level. dcs points to the innermost element of this
340 * stack. 340 * stack.
341 * 341 *
342 * d_ctx describes the context of the current declaration. Its value is 342 * d_ctx describes the context of the current declaration. Its value is
343 * one of 343 * one of
344 * EXTERN global declarations 344 * EXTERN global declarations
345 * MOS or MOU declarations of struct or union members 345 * MOS or MOU declarations of struct or union members
346 * CTCONST declarations of enums or boolean constants 346 * CTCONST declarations of enums or boolean constants
347 * ARG declaration of arguments in old-style function 347 * ARG declaration of arguments in old-style function
348 * definitions 348 * definitions
349 * PROTO_ARG declaration of arguments in function prototypes 349 * PROTO_ARG declaration of arguments in function prototypes
350 * AUTO declaration of local symbols 350 * AUTO declaration of local symbols
351 * ABSTRACT abstract declarations (sizeof, casts) 351 * ABSTRACT abstract declarations (sizeof, casts)
352 * 352 *
353 */ 353 */
354typedef struct dinfo { 354typedef struct dinfo {
355 tspec_t d_abstract_type;/* VOID, BOOL, CHAR, INT or COMPLEX */ 355 tspec_t d_abstract_type;/* VOID, BOOL, CHAR, INT or COMPLEX */
356 tspec_t d_complex_mod; /* FLOAT or DOUBLE */ 356 tspec_t d_complex_mod; /* FLOAT or DOUBLE */
357 tspec_t d_sign_mod; /* SIGNED or UNSIGN */ 357 tspec_t d_sign_mod; /* SIGNED or UNSIGN */
358 tspec_t d_rank_mod; /* SHORT, LONG or QUAD */ 358 tspec_t d_rank_mod; /* SHORT, LONG or QUAD */
359 scl_t d_scl; /* storage class */ 359 scl_t d_scl; /* storage class */
360 type_t *d_type; /* after end_type() pointer to the type used 360 type_t *d_type; /* after end_type() pointer to the type used
361 for all declarators */ 361 for all declarators */
362 sym_t *d_redeclared_symbol; 362 sym_t *d_redeclared_symbol;
363 u_int d_offset; /* offset of next structure member */ 363 u_int d_offset; /* offset of next structure member */
364 u_int d_sou_align_in_bits; /* alignment required for current 364 u_int d_sou_align_in_bits; /* alignment required for current
365 * structure */ 365 * structure */
366 scl_t d_ctx; /* context of declaration */ 366 scl_t d_ctx; /* context of declaration */
367 bool d_const : 1; /* const in declaration specifiers */ 367 bool d_const : 1; /* const in declaration specifiers */
368 bool d_volatile : 1; /* volatile in declaration specifiers */ 368 bool d_volatile : 1; /* volatile in declaration specifiers */
369 bool d_inline : 1; /* inline in declaration specifiers */ 369 bool d_inline : 1; /* inline in declaration specifiers */
370 bool d_multiple_storage_classes : 1; /* reported in end_type */ 370 bool d_multiple_storage_classes : 1; /* reported in end_type */
371 bool d_invalid_type_combination : 1; 371 bool d_invalid_type_combination : 1;
372 bool d_nonempty_decl : 1; /* if at least one tag is declared 372 bool d_nonempty_decl : 1; /* if at least one tag is declared
373 * ... in the current function decl. */ 373 * ... in the current function decl. */
374 bool d_vararg : 1; 374 bool d_vararg : 1;
375 bool d_proto : 1; /* current function decl. is prototype */ 375 bool d_proto : 1; /* current function decl. is prototype */
376 bool d_notyp : 1; /* set if no type specifier was present */ 376 bool d_notyp : 1; /* set if no type specifier was present */
377 bool d_asm : 1; /* set if d_ctx == AUTO and asm() present */ 377 bool d_asm : 1; /* set if d_ctx == AUTO and asm() present */
378 bool d_packed : 1; 378 bool d_packed : 1;
379 bool d_used : 1; 379 bool d_used : 1;
380 type_t *d_tagtyp; /* tag during member declaration */ 380 type_t *d_tagtyp; /* tag during member declaration */
381 sym_t *d_func_args; /* list of arguments during function def. */ 381 sym_t *d_func_args; /* list of arguments during function def. */
382 pos_t d_func_def_pos; /* position of function definition */ 382 pos_t d_func_def_pos; /* position of function definition */
383 sym_t *d_dlsyms; /* first symbol declared at this level */ 383 sym_t *d_dlsyms; /* first symbol declared at this level */
384 sym_t **d_ldlsym; /* points to s_dlnxt in last symbol decl. 384 sym_t **d_ldlsym; /* points to s_dlnxt in last symbol decl.
385 at this level */ 385 at this level */
386 sym_t *d_func_proto_syms; /* symbols defined in prototype */ 386 sym_t *d_func_proto_syms; /* symbols defined in prototype */
387 struct dinfo *d_next; /* next level */ 387 struct dinfo *d_next; /* next level */
388} dinfo_t; 388} dinfo_t;
389 389
390/* One level of pointer indirection in declarators, including qualifiers. */ 390/* One level of pointer indirection in declarators, including qualifiers. */
391typedef struct qual_ptr { 391typedef struct qual_ptr {
392 bool p_const: 1; 392 bool p_const: 1;
393 bool p_volatile: 1; 393 bool p_volatile: 1;
394 bool p_pointer: 1; 394 bool p_pointer: 1;
395 struct qual_ptr *p_next; 395 struct qual_ptr *p_next;
396} qual_ptr; 396} qual_ptr;
397 397
398/* 398/*
399 * The values of the 'case' labels, linked via cl_next in reverse order of 399 * The values of the 'case' labels, linked via cl_next in reverse order of
400 * appearance in the code, that is from bottom to top. 400 * appearance in the code, that is from bottom to top.
401 */ 401 */
402typedef struct case_label { 402typedef struct case_label {
403 val_t cl_val; 403 val_t cl_val;
404 struct case_label *cl_next; 404 struct case_label *cl_next;
405} case_label_t; 405} case_label_t;
406 406
407typedef enum { 407typedef enum {
408 CS_DO_WHILE, 408 CS_DO_WHILE,
409 CS_FOR, 409 CS_FOR,
410 CS_FUNCTION_BODY, 410 CS_FUNCTION_BODY,
411 CS_IF, 411 CS_IF,
412 CS_SWITCH, 412 CS_SWITCH,
413 CS_WHILE 413 CS_WHILE
414} control_statement_kind; 414} control_statement_kind;
415 415
416/* 416/*
417 * Used to keep information about nested control statements. 417 * Used to keep information about nested control statements.
418 */ 418 */
419typedef struct control_statement { 419typedef struct control_statement {
420 control_statement_kind c_kind; /* to ensure proper nesting */ 420 control_statement_kind c_kind; /* to ensure proper nesting */
421 bool c_loop : 1; /* 'continue' and 'break' are valid */ 421 bool c_loop : 1; /* 'continue' and 'break' are valid */
422 bool c_switch : 1; /* 'case' and 'break' are valid */ 422 bool c_switch : 1; /* 'case' and 'break' are valid */
423 bool c_break : 1; /* the loop/switch has a reachable 423 bool c_break : 1; /* the loop/switch has a reachable
424 * 'break' statement */ 424 * 'break' statement */
425 bool c_continue : 1; /* the loop has a reachable 'continue' 425 bool c_continue : 1; /* the loop has a reachable 'continue'
426 * statement */ 426 * statement */
427 bool c_default : 1; /* the switch has a 'default' label */ 427 bool c_default : 1; /* the switch has a 'default' label */
428 bool c_maybe_endless : 1; /* the controlling expression is 428 bool c_maybe_endless : 1; /* the controlling expression is
429 * always true (as in 'for (;;)' or 429 * always true (as in 'for (;;)' or
430 * 'while (1)'), there may be break 430 * 'while (1)'), there may be break
431 * statements though */ 431 * statements though */
432 bool c_always_then : 1; 432 bool c_always_then : 1;
433 bool c_reached_end_of_then : 1; 433 bool c_reached_end_of_then : 1;
434 bool c_had_return_noval : 1; /* had "return;" */ 434 bool c_had_return_noval : 1; /* had "return;" */
435 bool c_had_return_value : 1; /* had "return expr;" */ 435 bool c_had_return_value : 1; /* had "return expr;" */
436 436
437 type_t *c_switch_type; /* type of switch expression */ 437 type_t *c_switch_type; /* type of switch expression */
438 tnode_t *c_switch_expr; 438 tnode_t *c_switch_expr;
439 case_label_t *c_case_labels; /* list of case values */ 439 case_label_t *c_case_labels; /* list of case values */
440 440
441 struct memory_block *c_for_expr3_mem; /* saved memory for end of loop 441 struct memory_block *c_for_expr3_mem; /* saved memory for end of loop
442 * expression in for() */ 442 * expression in for() */
443 tnode_t *c_for_expr3; /* end of loop expr in for() */ 443 tnode_t *c_for_expr3; /* end of loop expr in for() */
444 pos_t c_for_expr3_pos; /* position of end of loop expr */ 444 pos_t c_for_expr3_pos; /* position of end of loop expr */
445 pos_t c_for_expr3_csrc_pos; /* same for csrc_pos */ 445 pos_t c_for_expr3_csrc_pos; /* same for csrc_pos */
446 446
447 struct control_statement *c_surrounding; 447 struct control_statement *c_surrounding;
448} cstk_t; 448} control_statement;
449 449
450typedef struct { 450typedef struct {
451 size_t lo; /* inclusive */ 451 size_t lo; /* inclusive */
452 size_t hi; /* inclusive */ 452 size_t hi; /* inclusive */
453} range_t; 453} range_t;
454 454
455#include "externs1.h" 455#include "externs1.h"
456 456
457#define ERR_SETSIZE 1024 457#define ERR_SETSIZE 1024
458#define __NERRBITS (sizeof(unsigned int)) 458#define __NERRBITS (sizeof(unsigned int))
459 459
460typedef struct err_set { 460typedef struct err_set {
461 unsigned int errs_bits[(ERR_SETSIZE + __NERRBITS-1) / __NERRBITS]; 461 unsigned int errs_bits[(ERR_SETSIZE + __NERRBITS-1) / __NERRBITS];
462} err_set; 462} err_set;
463 463
464#define ERR_SET(n, p) \ 464#define ERR_SET(n, p) \
465 ((p)->errs_bits[(n)/__NERRBITS] |= (1 << ((n) % __NERRBITS))) 465 ((p)->errs_bits[(n)/__NERRBITS] |= (1 << ((n) % __NERRBITS)))
466#define ERR_CLR(n, p) \ 466#define ERR_CLR(n, p) \
467 ((p)->errs_bits[(n)/__NERRBITS] &= ~(1 << ((n) % __NERRBITS))) 467 ((p)->errs_bits[(n)/__NERRBITS] &= ~(1 << ((n) % __NERRBITS)))
468#define ERR_ISSET(n, p) \ 468#define ERR_ISSET(n, p) \
469 (((p)->errs_bits[(n)/__NERRBITS] & (1 << ((n) % __NERRBITS))) != 0) 469 (((p)->errs_bits[(n)/__NERRBITS] & (1 << ((n) % __NERRBITS))) != 0)
470#define ERR_ZERO(p) (void)memset((p), 0, sizeof(*(p))) 470#define ERR_ZERO(p) (void)memset((p), 0, sizeof(*(p)))
471 471
472#define INTERNAL_ERROR(fmt, args...) \ 472#define INTERNAL_ERROR(fmt, args...) \
473 internal_error(__FILE__, __LINE__, fmt, ##args) 473 internal_error(__FILE__, __LINE__, fmt, ##args)
474 474
475#define lint_assert(cond) \ 475#define lint_assert(cond) \
476 do { \ 476 do { \
477 if (!(cond)) \ 477 if (!(cond)) \
478 assert_failed(__FILE__, __LINE__, __func__, #cond); \ 478 assert_failed(__FILE__, __LINE__, __func__, #cond); \
479 } while (false) 479 } while (false)
480 480
481#ifdef BLKDEBUG 481#ifdef BLKDEBUG
482#define ZERO 0xa5 482#define ZERO 0xa5
483#else 483#else
484#define ZERO 0 484#define ZERO 0
485#endif 485#endif
486 486
487extern err_set msgset; 487extern err_set msgset;
488 488
489 489
490#ifdef DEBUG 490#ifdef DEBUG
491# include "err-msgs.h" 491# include "err-msgs.h"
492 492
493/* ARGSUSED */ 493/* ARGSUSED */
494static inline void __attribute__((format(printf, 1, 2))) 494static inline void __attribute__((format(printf, 1, 2)))
495check_printf(const char *fmt, ...) 495check_printf(const char *fmt, ...)
496{ 496{
497} 497}
498 498
499# define wrap_check_printf_at(func, msgid, pos, args...) \ 499# define wrap_check_printf_at(func, msgid, pos, args...) \
500 do { \ 500 do { \
501 check_printf(__CONCAT(MSG_, msgid), ##args); \ 501 check_printf(__CONCAT(MSG_, msgid), ##args); \
502 (func)(msgid, pos, ##args); \ 502 (func)(msgid, pos, ##args); \
503 } while (false) 503 } while (false)
504 504
505# define error_at(msgid, pos, args...) \ 505# define error_at(msgid, pos, args...) \
506 wrap_check_printf_at(error_at, msgid, pos, ##args) 506 wrap_check_printf_at(error_at, msgid, pos, ##args)
507# define warning_at(msgid, pos, args...) \ 507# define warning_at(msgid, pos, args...) \
508 wrap_check_printf_at(warning_at, msgid, pos, ##args) 508 wrap_check_printf_at(warning_at, msgid, pos, ##args)
509# define message_at(msgid, pos, args...) \ 509# define message_at(msgid, pos, args...) \
510 wrap_check_printf_at(message_at, msgid, pos, ##args) 510 wrap_check_printf_at(message_at, msgid, pos, ##args)
511 511
512# define wrap_check_printf(func, msgid, args...) \ 512# define wrap_check_printf(func, msgid, args...) \
513 do { \ 513 do { \
514 check_printf(__CONCAT(MSG_, msgid), ##args); \ 514 check_printf(__CONCAT(MSG_, msgid), ##args); \
515 (func)(msgid, ##args); \ 515 (func)(msgid, ##args); \
516 } while (false) 516 } while (false)
517 517
518# define error(msgid, args...) wrap_check_printf(error, msgid, ##args) 518# define error(msgid, args...) wrap_check_printf(error, msgid, ##args)
519# define warning(msgid, args...) wrap_check_printf(warning, msgid, ##args) 519# define warning(msgid, args...) wrap_check_printf(warning, msgid, ##args)
520# define message(msgid, args...) wrap_check_printf(message, msgid, ##args) 520# define message(msgid, args...) wrap_check_printf(message, msgid, ##args)
521# define gnuism(msgid, args...) wrap_check_printf(gnuism, msgid, ##args) 521# define gnuism(msgid, args...) wrap_check_printf(gnuism, msgid, ##args)
522# define c99ism(msgid, args...) wrap_check_printf(c99ism, msgid, ##args) 522# define c99ism(msgid, args...) wrap_check_printf(c99ism, msgid, ##args)
523# define c11ism(msgid, args...) wrap_check_printf(c11ism, msgid, ##args) 523# define c11ism(msgid, args...) wrap_check_printf(c11ism, msgid, ##args)
524#endif 524#endif
525 525
526static inline bool 526static inline bool
527is_nonzero_val(const val_t *val) 527is_nonzero_val(const val_t *val)
528{ 528{
529 return is_floating(val->v_tspec) 529 return is_floating(val->v_tspec)
530 ? val->v_ldbl != 0.0 530 ? val->v_ldbl != 0.0
531 : val->v_quad != 0; 531 : val->v_quad != 0;
532} 532}
533 533
534static inline bool 534static inline bool
535constant_is_nonzero(const tnode_t *tn) 535constant_is_nonzero(const tnode_t *tn)
536{ 536{
537 lint_assert(tn->tn_op == CON); 537 lint_assert(tn->tn_op == CON);
538 lint_assert(tn->tn_type->t_tspec == tn->tn_val->v_tspec); 538 lint_assert(tn->tn_type->t_tspec == tn->tn_val->v_tspec);
539 return is_nonzero_val(tn->tn_val); 539 return is_nonzero_val(tn->tn_val);
540} 540}
541 541
542static inline bool 542static inline bool
543is_zero(const tnode_t *tn) 543is_zero(const tnode_t *tn)
544{ 544{
545 return tn != NULL && tn->tn_op == CON && !is_nonzero_val(tn->tn_val); 545 return tn != NULL && tn->tn_op == CON && !is_nonzero_val(tn->tn_val);
546} 546}
547 547
548static inline bool 548static inline bool
549is_nonzero(const tnode_t *tn) 549is_nonzero(const tnode_t *tn)
550{ 550{
551 return tn != NULL && tn->tn_op == CON && is_nonzero_val(tn->tn_val); 551 return tn != NULL && tn->tn_op == CON && is_nonzero_val(tn->tn_val);
552} 552}
553 553
554static inline uint64_t 554static inline uint64_t
555bit(unsigned i) 555bit(unsigned i)
556{ 556{
557 lint_assert(i < 64); 557 lint_assert(i < 64);
558 return (uint64_t)1 << i; 558 return (uint64_t)1 << i;
559} 559}
560 560
561static inline uint64_t 561static inline uint64_t
562value_bits(unsigned bitsize) 562value_bits(unsigned bitsize)
563{ 563{
564 lint_assert(bitsize > 0); 564 lint_assert(bitsize > 0);
565 565
566 /* for long double (80 or 128), double _Complex (128) */ 566 /* for long double (80 or 128), double _Complex (128) */
567 /* 567 /*
568 * XXX: double _Complex does not have 128 bits of precision, 568 * XXX: double _Complex does not have 128 bits of precision,
569 * therefore it should never be necessary to query the value bits 569 * therefore it should never be necessary to query the value bits
570 * of such a type; see d_c99_complex_split.c to trigger this case. 570 * of such a type; see d_c99_complex_split.c to trigger this case.
571 */ 571 */
572 if (bitsize >= 64) 572 if (bitsize >= 64)
573 return ~((uint64_t)0); 573 return ~((uint64_t)0);
574 574
575 return ~(~(uint64_t)0 << bitsize); 575 return ~(~(uint64_t)0 << bitsize);
576} 576}
577 577
578/* C99 6.7.8p7 */ 578/* C99 6.7.8p7 */
579static inline bool 579static inline bool
580is_struct_or_union(tspec_t t) 580is_struct_or_union(tspec_t t)
581{ 581{
582 return t == STRUCT || t == UNION; 582 return t == STRUCT || t == UNION;
583} 583}