decl.c revision 1.364 1 /* $NetBSD: decl.c,v 1.364 2023/07/29 07:03:19 rillig Exp $ */
2
3 /*
4 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
5 * Copyright (c) 1994, 1995 Jochen Pohl
6 * All Rights Reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by Jochen Pohl for
19 * The NetBSD Project.
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.
22 *
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
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
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
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
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35 #if HAVE_NBTOOL_CONFIG_H
36 #include "nbtool_config.h"
37 #endif
38
39 #include <sys/cdefs.h>
40 #if defined(__RCSID)
41 __RCSID("$NetBSD: decl.c,v 1.364 2023/07/29 07:03:19 rillig Exp $");
42 #endif
43
44 #include <sys/param.h>
45 #include <limits.h>
46 #include <stdlib.h>
47 #include <string.h>
48
49 #include "lint1.h"
50
51 const char unnamed[] = "<unnamed>";
52
53 /* shared type structures for arithmetic types and void */
54 static type_t typetab[NTSPEC];
55
56 /* value of next enumerator during declaration of enum types */
57 int enumval;
58
59 /*
60 * Points to the innermost element of a stack that contains information about
61 * nested declarations, such as struct declarations, function prototypes,
62 * local variables.
63 */
64 decl_level *dcs;
65
66
67 /*
68 * initializes all global vars used in declarations
69 */
70 void
71 initdecl(void)
72 {
73
74 /* declaration stack */
75 dcs = xcalloc(1, sizeof(*dcs));
76 dcs->d_kind = DLK_EXTERN;
77 dcs->d_last_dlsym = &dcs->d_first_dlsym;
78
79 if (!pflag) {
80 for (size_t i = 0; i < NTSPEC; i++) {
81 if (ttab[i].tt_rank_kind != RK_NONE)
82 ttab[i].tt_rank_value =
83 ttab[i].tt_size_in_bits;
84 }
85 ttab[BOOL].tt_rank_value = 1;
86 }
87
88 if (Tflag) {
89 ttab[BOOL].tt_is_integer = false;
90 ttab[BOOL].tt_is_uinteger = false;
91 ttab[BOOL].tt_is_arithmetic = false;
92 }
93
94 /* struct, union, enum, ptr, array and func are not shared. */
95 for (int i = (int)SIGNED; i < (int)STRUCT; i++)
96 typetab[i].t_tspec = (tspec_t)i;
97 }
98
99 /*
100 * Returns a shared type structure for arithmetic types and void.
101 *
102 * It's important to duplicate this structure using block_dup_type or
103 * expr_dup_type if it is to be modified (adding qualifiers or anything
104 * else).
105 */
106 type_t *
107 gettyp(tspec_t t)
108 {
109
110 lint_assert((int)t < (int)STRUCT);
111 /* TODO: make the return type 'const' */
112 return &typetab[t];
113 }
114
115 type_t *
116 block_dup_type(const type_t *tp)
117 {
118
119 type_t *ntp = block_zero_alloc(sizeof(*ntp), "type");
120 *ntp = *tp;
121 return ntp;
122 }
123
124 /* Duplicate a type, free the allocated memory after the expression. */
125 type_t *
126 expr_dup_type(const type_t *tp)
127 {
128
129 type_t *ntp = expr_zero_alloc(sizeof(*ntp), "type");
130 *ntp = *tp;
131 return ntp;
132 }
133
134 /*
135 * Return the unqualified version of the type. The returned type is freed at
136 * the end of the current expression.
137 *
138 * See C99 6.2.5p25.
139 */
140 type_t *
141 expr_unqualified_type(const type_t *tp)
142 {
143
144 type_t *ntp = expr_zero_alloc(sizeof(*ntp), "type");
145 *ntp = *tp;
146 ntp->t_const = false;
147 ntp->t_volatile = false;
148
149 /*
150 * In case of a struct or union type, the members should lose their
151 * qualifiers as well, but that would require a deep copy of the
152 * struct or union type. This in turn would defeat the type
153 * comparison in types_compatible, which simply tests whether
154 * tp1->t_sou == tp2->t_sou.
155 */
156
157 return ntp;
158 }
159
160 /*
161 * Returns whether the argument is void or an incomplete array, struct, union
162 * or enum type.
163 */
164 bool
165 is_incomplete(const type_t *tp)
166 {
167 tspec_t t = tp->t_tspec;
168
169 if (t == VOID)
170 return true;
171 if (t == ARRAY)
172 return tp->t_incomplete_array;
173 if (is_struct_or_union(t))
174 return tp->t_sou->sou_incomplete;
175 if (t == ENUM)
176 return tp->t_enum->en_incomplete;
177 return false;
178 }
179
180 void
181 dcs_add_function_specifier(function_specifier fs)
182 {
183 debug_step("%s: %s", __func__, function_specifier_name(fs));
184 if (fs == FS_INLINE) {
185 if (dcs->d_inline)
186 /* duplicate '%s' */
187 warning(10, "inline");
188 dcs->d_inline = true;
189 }
190 }
191
192 /*
193 * Remember the storage class of the current declaration and detect multiple
194 * storage classes.
195 */
196 void
197 dcs_add_storage_class(scl_t sc)
198 {
199
200 if (dcs->d_type != NULL || dcs->d_abstract_type != NO_TSPEC ||
201 dcs->d_sign_mod != NO_TSPEC || dcs->d_rank_mod != NO_TSPEC) {
202 /* storage class after type is obsolescent */
203 warning(83);
204 }
205
206 if (dcs->d_scl == NOSCL)
207 dcs->d_scl = sc;
208 else if ((dcs->d_scl == EXTERN && sc == THREAD_LOCAL)
209 || (dcs->d_scl == THREAD_LOCAL && sc == EXTERN))
210 dcs->d_scl = EXTERN; /* ignore thread_local */
211 else if ((dcs->d_scl == STATIC && sc == THREAD_LOCAL)
212 || (dcs->d_scl == THREAD_LOCAL && sc == STATIC))
213 dcs->d_scl = STATIC; /* ignore thread_local */
214 else
215 dcs->d_multiple_storage_classes = true;
216 }
217
218 /* Merge the signedness into the abstract type. */
219 static tspec_t
220 merge_signedness(tspec_t t, tspec_t s)
221 {
222
223 if (s == SIGNED)
224 return t == CHAR ? SCHAR : t;
225 if (s != UNSIGN)
226 return t;
227 return t == CHAR ? UCHAR
228 : t == SHORT ? USHORT
229 : t == INT ? UINT
230 : t == LONG ? ULONG
231 : t == LLONG ? ULLONG
232 : t;
233 }
234
235 /*
236 * Called if a list of declaration specifiers contains a typedef name
237 * and other specifiers (except struct, union, enum, typedef name).
238 */
239 static type_t *
240 typedef_error(type_t *td, tspec_t t)
241 {
242
243 tspec_t t2 = td->t_tspec;
244
245 if ((t == SIGNED || t == UNSIGN) &&
246 (t2 == CHAR || t2 == SHORT || t2 == INT ||
247 t2 == LONG || t2 == LLONG)) {
248 if (allow_c90)
249 /* modifying typedef with '%s'; only qualifiers... */
250 warning(5, tspec_name(t));
251 td = block_dup_type(gettyp(merge_signedness(t2, t)));
252 td->t_typedef = true;
253 return td;
254 }
255
256 if (t == SHORT && (t2 == INT || t2 == UINT)) {
257 /* modifying typedef with '%s'; only qualifiers allowed */
258 warning(5, "short");
259 td = block_dup_type(gettyp(t2 == INT ? SHORT : USHORT));
260 td->t_typedef = true;
261 return td;
262 }
263
264 if (t != LONG)
265 goto invalid;
266
267 if (t2 == INT)
268 td = gettyp(LONG);
269 else if (t2 == UINT)
270 td = gettyp(ULONG);
271 else if (t2 == LONG)
272 td = gettyp(LLONG);
273 else if (t2 == ULONG)
274 td = gettyp(ULLONG);
275 else if (t2 == FLOAT)
276 td = gettyp(DOUBLE);
277 else if (t2 == DOUBLE)
278 td = gettyp(LDOUBLE);
279 else if (t2 == DCOMPLEX)
280 td = gettyp(LCOMPLEX);
281 else
282 goto invalid;
283
284 /* modifying typedef with '%s'; only qualifiers allowed */
285 warning(5, "long");
286 td = block_dup_type(td);
287 td->t_typedef = true;
288 return td;
289
290 invalid:
291 /* Anything else is not accepted. */
292 dcs->d_invalid_type_combination = true;
293 return td;
294 }
295
296 /*
297 * Remember the type, modifier or typedef name returned by the parser in the
298 * top element of the declaration stack. This information is used in
299 * dcs_end_type to build the type used for all declarators in this declaration.
300 *
301 * If tp->t_typedef is true, the type comes from a previously defined typename.
302 * Otherwise, it comes from a type specifier (int, long, ...) or a
303 * struct/union/enum tag.
304 */
305 void
306 dcs_add_type(type_t *tp)
307 {
308
309 debug_step("%s: %s", __func__, type_name(tp));
310 if (tp->t_typedef) {
311 /*
312 * something like "typedef int a; int a b;"
313 * This should not happen with current grammar.
314 */
315 lint_assert(dcs->d_type == NULL);
316 lint_assert(dcs->d_abstract_type == NO_TSPEC);
317 lint_assert(dcs->d_sign_mod == NO_TSPEC);
318 lint_assert(dcs->d_rank_mod == NO_TSPEC);
319
320 dcs->d_type = tp;
321 return;
322 }
323
324 tspec_t t = tp->t_tspec;
325 if (is_struct_or_union(t) || t == ENUM) {
326 /*
327 * something like "int struct a ..."
328 * struct/union/enum with anything else is not allowed
329 */
330 if (dcs->d_type != NULL || dcs->d_abstract_type != NO_TSPEC ||
331 dcs->d_rank_mod != NO_TSPEC || dcs->d_sign_mod != NO_TSPEC) {
332 dcs->d_invalid_type_combination = true;
333 dcs->d_abstract_type = NO_TSPEC;
334 dcs->d_sign_mod = NO_TSPEC;
335 dcs->d_rank_mod = NO_TSPEC;
336 }
337 dcs->d_type = tp;
338 return;
339 }
340
341 if (dcs->d_type != NULL && !dcs->d_type->t_typedef) {
342 /*
343 * something like "struct a int"
344 * struct/union/enum with anything else is not allowed
345 */
346 dcs->d_invalid_type_combination = true;
347 return;
348 }
349
350 if (t == COMPLEX) {
351 if (dcs->d_complex_mod == FLOAT)
352 t = FCOMPLEX;
353 else if (dcs->d_complex_mod == DOUBLE)
354 t = DCOMPLEX;
355 else {
356 /* invalid type for _Complex */
357 error(308);
358 t = DCOMPLEX; /* just as a fallback */
359 }
360 dcs->d_complex_mod = NO_TSPEC;
361 }
362
363 if (t == LONG && dcs->d_rank_mod == LONG) {
364 /* "long long" or "long ... long" */
365 t = LLONG;
366 dcs->d_rank_mod = NO_TSPEC;
367 if (!suppress_longlong)
368 /* %s does not support 'long long' */
369 c99ism(265, allow_c90 ? "C90" : "traditional C");
370 }
371
372 if (dcs->d_type != NULL && dcs->d_type->t_typedef) {
373 /* something like "typedef int a; a long ..." */
374 dcs->d_type = typedef_error(dcs->d_type, t);
375 return;
376 }
377
378 /* now it can be only a combination of arithmetic types and void */
379 if (t == SIGNED || t == UNSIGN) {
380 if (dcs->d_sign_mod != NO_TSPEC)
381 dcs->d_invalid_type_combination = true;
382 dcs->d_sign_mod = t;
383 } else if (t == SHORT || t == LONG || t == LLONG) {
384 if (dcs->d_rank_mod != NO_TSPEC)
385 dcs->d_invalid_type_combination = true;
386 dcs->d_rank_mod = t;
387 } else if (t == FLOAT || t == DOUBLE) {
388 if (dcs->d_rank_mod == NO_TSPEC || dcs->d_rank_mod == LONG) {
389 if (dcs->d_complex_mod != NO_TSPEC
390 || (t == FLOAT && dcs->d_rank_mod == LONG))
391 dcs->d_invalid_type_combination = true;
392 dcs->d_complex_mod = t;
393 } else {
394 if (dcs->d_abstract_type != NO_TSPEC)
395 dcs->d_invalid_type_combination = true;
396 dcs->d_abstract_type = t;
397 }
398 } else if (t == PTR) {
399 dcs->d_type = tp;
400 } else {
401 if (dcs->d_abstract_type != NO_TSPEC)
402 dcs->d_invalid_type_combination = true;
403 dcs->d_abstract_type = t;
404 }
405 }
406
407 static void
408 set_first_typedef(type_t *tp, sym_t *sym)
409 {
410
411 tspec_t t = tp->t_tspec;
412 if (is_struct_or_union(t) && tp->t_sou->sou_first_typedef == NULL)
413 tp->t_sou->sou_first_typedef = sym;
414 if (t == ENUM && tp->t_enum->en_first_typedef == NULL)
415 tp->t_enum->en_first_typedef = sym;
416 }
417
418 static unsigned int
419 bit_fields_width(const sym_t **mem, bool *named)
420 {
421 unsigned int width = 0;
422 unsigned int align = 0;
423 while (*mem != NULL && (*mem)->s_type->t_bitfield) {
424 if ((*mem)->s_name != unnamed)
425 *named = true;
426 width += (*mem)->s_type->t_bit_field_width;
427 unsigned int mem_align = alignment_in_bits((*mem)->s_type);
428 if (mem_align > align)
429 align = mem_align;
430 *mem = (*mem)->s_next;
431 }
432 return (width + align - 1) & -align;
433 }
434
435 static void
436 pack_struct_or_union(type_t *tp)
437 {
438
439 if (!is_struct_or_union(tp->t_tspec)) {
440 /* attribute '%s' ignored for '%s' */
441 warning(326, "packed", type_name(tp));
442 return;
443 }
444
445 unsigned int bits = 0;
446 bool named = false;
447 for (const sym_t *mem = tp->t_sou->sou_first_member;
448 mem != NULL; mem = mem->s_next) {
449 // TODO: Maybe update mem->u.s_member.sm_offset_in_bits.
450 if (mem->s_type->t_bitfield) {
451 bits += bit_fields_width(&mem, &named);
452 if (mem == NULL)
453 break;
454 }
455 unsigned int mem_bits = type_size_in_bits(mem->s_type);
456 if (tp->t_tspec == STRUCT)
457 bits += mem_bits;
458 else if (mem_bits > bits)
459 bits = mem_bits;
460 }
461 tp->t_sou->sou_size_in_bits = bits;
462 }
463
464 void
465 dcs_add_packed(void)
466 {
467 if (dcs->d_type == NULL)
468 dcs->d_packed = true;
469 else
470 pack_struct_or_union(dcs->d_type);
471 }
472
473 void
474 dcs_set_used(void)
475 {
476 dcs->d_used = true;
477 }
478
479 /*
480 * Remember a qualifier that is part of the declaration specifiers (and not the
481 * declarator). The remembered qualifier is used by dcs_end_type for all
482 * declarators.
483 */
484 void
485 dcs_add_qualifiers(type_qualifiers qs)
486 {
487 add_type_qualifiers(&dcs->d_qual, qs);
488 }
489
490 void
491 begin_declaration_level(decl_level_kind kind)
492 {
493
494 decl_level *dl = xcalloc(1, sizeof(*dl));
495 dl->d_enclosing = dcs;
496 dl->d_kind = kind;
497 dl->d_last_dlsym = &dl->d_first_dlsym;
498 dcs = dl;
499 debug_enter();
500 debug_dcs(true);
501 }
502
503 void
504 end_declaration_level(void)
505 {
506
507 debug_dcs(true);
508
509 decl_level *dl = dcs;
510 dcs = dl->d_enclosing;
511 lint_assert(dcs != NULL);
512
513 switch (dl->d_kind) {
514 case DLK_STRUCT:
515 case DLK_UNION:
516 case DLK_ENUM:
517 /*
518 * Symbols declared in (nested) structs or enums are part of
519 * the next level (they are removed from the symbol table if
520 * the symbols of the outer level are removed).
521 */
522 if ((*dcs->d_last_dlsym = dl->d_first_dlsym) != NULL)
523 dcs->d_last_dlsym = dl->d_last_dlsym;
524 break;
525 case DLK_OLD_STYLE_ARGS:
526 /*
527 * All symbols in dcs->d_first_dlsym are introduced in
528 * old-style argument declarations (it's not clean, but
529 * possible). They are appended to the list of symbols declared
530 * in an old-style argument identifier list or a new-style
531 * parameter type list.
532 */
533 if (dl->d_first_dlsym != NULL) {
534 *dl->d_last_dlsym = dcs->d_func_proto_syms;
535 dcs->d_func_proto_syms = dl->d_first_dlsym;
536 }
537 break;
538 case DLK_ABSTRACT:
539 /*
540 * Append all symbols declared in the abstract declaration to
541 * the list of symbols declared in the surrounding declaration
542 * or block.
543 *
544 * XXX I'm not sure whether they should be removed from the
545 * symbol table now or later.
546 */
547 if ((*dcs->d_last_dlsym = dl->d_first_dlsym) != NULL)
548 dcs->d_last_dlsym = dl->d_last_dlsym;
549 break;
550 case DLK_AUTO:
551 check_usage(dl);
552 /* FALLTHROUGH */
553 case DLK_PROTO_PARAMS:
554 /* usage of arguments will be checked by end_function() */
555 symtab_remove_level(dl->d_first_dlsym);
556 break;
557 case DLK_EXTERN:
558 /* there is nothing around an external declaration */
559 /* FALLTHROUGH */
560 default:
561 lint_assert(/*CONSTCOND*/false);
562 }
563 free(dl);
564 debug_leave();
565 }
566
567 /*
568 * Set flag d_asm in all declaration stack elements up to the outermost one.
569 *
570 * This is used to mark compound statements which have, possibly in nested
571 * compound statements, asm statements. For these compound statements, no
572 * warnings about unused or uninitialized variables are printed.
573 *
574 * There is no need to clear d_asm in decl_level structs with context AUTO, as
575 * these structs are freed at the end of the compound statement. But it must be
576 * cleared in the outermost decl_level struct, which has context EXTERN. This
577 * could be done in dcs_begin_type and would work for C90, but not for C99 or
578 * C++ (due to mixed statements and declarations). Thus, we clear it in
579 * global_clean_up_decl.
580 */
581 void
582 dcs_set_asm(void)
583 {
584
585 for (decl_level *dl = dcs; dl != NULL; dl = dl->d_enclosing)
586 dl->d_asm = true;
587 }
588
589 void
590 dcs_begin_type(void)
591 {
592
593 debug_enter();
594 dcs->d_abstract_type = NO_TSPEC;
595 dcs->d_complex_mod = NO_TSPEC;
596 dcs->d_sign_mod = NO_TSPEC;
597 dcs->d_rank_mod = NO_TSPEC;
598 dcs->d_scl = NOSCL;
599 dcs->d_type = NULL;
600 dcs->d_qual = (type_qualifiers) { .tq_const = false };
601 dcs->d_inline = false;
602 dcs->d_multiple_storage_classes = false;
603 dcs->d_invalid_type_combination = false;
604 dcs->d_nonempty_decl = false;
605 dcs->d_no_type_specifier = false;
606 }
607
608 static void
609 dcs_adjust_storage_class(void)
610 {
611 if (dcs->d_kind == DLK_EXTERN) {
612 if (dcs->d_scl == REG || dcs->d_scl == AUTO) {
613 /* illegal storage class */
614 error(8);
615 dcs->d_scl = NOSCL;
616 }
617 } else if (dcs->d_kind == DLK_OLD_STYLE_ARGS ||
618 dcs->d_kind == DLK_PROTO_PARAMS) {
619 if (dcs->d_scl != NOSCL && dcs->d_scl != REG) {
620 /* only 'register' is valid as storage class ... */
621 error(9);
622 dcs->d_scl = NOSCL;
623 }
624 }
625 }
626
627 /*
628 * Merge the declaration specifiers from dcs into dcs->d_type.
629 *
630 * See C99 6.7.2 "Type specifiers".
631 */
632 static void
633 dcs_merge_declaration_specifiers(void)
634 {
635 tspec_t t = dcs->d_abstract_type;
636 tspec_t c = dcs->d_complex_mod;
637 tspec_t s = dcs->d_sign_mod;
638 tspec_t l = dcs->d_rank_mod;
639 type_t *tp = dcs->d_type;
640
641 if (tp != NULL) {
642 lint_assert(t == NO_TSPEC);
643 lint_assert(s == NO_TSPEC);
644 lint_assert(l == NO_TSPEC);
645 return;
646 }
647
648 debug_step("%s: %s", __func__, type_name(tp));
649
650 if (t == NO_TSPEC && s == NO_TSPEC && l == NO_TSPEC && c == NO_TSPEC)
651 dcs->d_no_type_specifier = true;
652 if (t == NO_TSPEC && s == NO_TSPEC && (l == NO_TSPEC || l == LONG))
653 t = c;
654
655 if (t == NO_TSPEC)
656 t = INT;
657 if (s == NO_TSPEC && t == INT)
658 s = SIGNED;
659 if (l != NO_TSPEC && t == CHAR) {
660 dcs->d_invalid_type_combination = true;
661 l = NO_TSPEC;
662 }
663 if (l == LONG && t == FLOAT) {
664 l = NO_TSPEC;
665 t = DOUBLE;
666 if (allow_c90)
667 /* use 'double' instead of 'long float' */
668 warning(6);
669 }
670 if ((l == LONG && t == DOUBLE) || t == LDOUBLE) {
671 l = NO_TSPEC;
672 t = LDOUBLE;
673 }
674 if (t == LDOUBLE && !allow_c90) {
675 /* 'long double' is illegal in traditional C */
676 warning(266);
677 }
678 if (l == LONG && t == DCOMPLEX) {
679 l = NO_TSPEC;
680 t = LCOMPLEX;
681 }
682
683 if (t != INT && t != CHAR && (s != NO_TSPEC || l != NO_TSPEC)) {
684 dcs->d_invalid_type_combination = true;
685 l = s = NO_TSPEC;
686 }
687 if (l != NO_TSPEC)
688 t = l;
689 dcs->d_type = gettyp(merge_signedness(t, s));
690 }
691
692 /* Create a type in 'dcs->d_type' from the information gathered in 'dcs'. */
693 void
694 dcs_end_type(void)
695 {
696
697 dcs_merge_declaration_specifiers();
698
699 if (dcs->d_multiple_storage_classes) {
700 /* only one storage class allowed */
701 error(7);
702 }
703 if (dcs->d_invalid_type_combination) {
704 /* illegal type combination */
705 error(4);
706 }
707
708 dcs_adjust_storage_class();
709
710 if (dcs->d_qual.tq_const && dcs->d_type->t_const
711 && !dcs->d_type->t_typeof) {
712 lint_assert(dcs->d_type->t_typedef);
713 /* typedef already qualified with '%s' */
714 warning(68, "const");
715 }
716 if (dcs->d_qual.tq_volatile && dcs->d_type->t_volatile &&
717 !dcs->d_type->t_typeof) {
718 lint_assert(dcs->d_type->t_typedef);
719 /* typedef already qualified with '%s' */
720 warning(68, "volatile");
721 }
722
723 if (dcs->d_qual.tq_const || dcs->d_qual.tq_volatile) {
724 dcs->d_type = block_dup_type(dcs->d_type);
725 dcs->d_type->t_const |= dcs->d_qual.tq_const;
726 dcs->d_type->t_volatile |= dcs->d_qual.tq_volatile;
727 }
728
729 debug_leave();
730 }
731
732 /*
733 * Return the length of a type in bits. For bit-fields, return the length of
734 * the underlying storage type.
735 *
736 * Printing a message if the outermost dimension of an array is 0 must
737 * be done by the caller. All other problems are reported by this function
738 * if name is not NULL.
739 */
740 int
741 length_in_bits(const type_t *tp, const char *name)
742 {
743
744 if (tp == NULL)
745 return -1;
746
747 unsigned int elem = 1;
748 while (tp->t_tspec == ARRAY) {
749 elem *= tp->t_dim;
750 tp = tp->t_subt;
751 }
752
753 if (is_struct_or_union(tp->t_tspec)) {
754 if (is_incomplete(tp) && name != NULL) {
755 /* '%s' has incomplete type '%s' */
756 error(31, name, type_name(tp));
757 }
758 return (int)(elem * tp->t_sou->sou_size_in_bits);
759 }
760
761 if (tp->t_tspec == ENUM && is_incomplete(tp) && name != NULL)
762 /* incomplete enum type '%s' */
763 warning(13, name);
764
765 lint_assert(tp->t_tspec != FUNC);
766
767 unsigned int elsz = size_in_bits(tp->t_tspec);
768 /*
769 * Workaround until the type parser (see add_function, add_array,
770 * add_pointer) does not construct the invalid intermediate declaration
771 * 'void b[4]' for the legitimate declaration 'void *b[4]'.
772 */
773 if (sytxerr > 0 && elsz == 0)
774 elsz = CHAR_SIZE;
775 lint_assert(elsz > 0);
776 return (int)(elem * elsz);
777 }
778
779 unsigned int
780 alignment_in_bits(const type_t *tp)
781 {
782
783 /* Super conservative so that it works for most systems. */
784 unsigned int worst_align_in_bits = 2 * LONG_SIZE;
785
786 while (tp->t_tspec == ARRAY)
787 tp = tp->t_subt;
788
789 tspec_t t = tp->t_tspec;
790 unsigned int a;
791 if (is_struct_or_union(t))
792 a = tp->t_sou->sou_align_in_bits;
793 else {
794 lint_assert(t != FUNC);
795 if ((a = size_in_bits(t)) == 0)
796 a = CHAR_SIZE;
797 else if (a > worst_align_in_bits)
798 a = worst_align_in_bits;
799 }
800 lint_assert(a >= CHAR_SIZE);
801 lint_assert(a <= worst_align_in_bits);
802 return a;
803 }
804
805 /*
806 * Concatenate two lists of symbols by s_next. Used by declarations of
807 * struct/union/enum elements and parameters.
808 */
809 sym_t *
810 concat_symbols(sym_t *l1, sym_t *l2)
811 {
812
813 if (l1 == NULL)
814 return l2;
815 sym_t *l = l1;
816 while (l->s_next != NULL)
817 l = l->s_next;
818 l->s_next = l2;
819 return l1;
820 }
821
822 /*
823 * Check if the type of the given symbol is valid.
824 *
825 * Invalid types are:
826 * - arrays of incomplete types or functions
827 * - functions returning arrays or functions
828 * - void types other than type of function or pointer
829 */
830 void
831 check_type(sym_t *sym)
832 {
833
834 type_t **tpp = &sym->s_type;
835 tspec_t to = NO_TSPEC;
836 while (*tpp != NULL) {
837 type_t *tp = *tpp;
838 tspec_t t = tp->t_tspec;
839 /*
840 * If this is the type of an old-style function definition,
841 * a better warning is printed in begin_function().
842 */
843 if (t == FUNC && !tp->t_proto &&
844 !(to == NO_TSPEC && sym->s_osdef)) {
845 /* TODO: Make this an error in C99 mode as well. */
846 if ((!allow_trad && !allow_c99) && hflag)
847 /* function declaration is not a prototype */
848 warning(287);
849 }
850 if (to == FUNC) {
851 if (t == FUNC || t == ARRAY) {
852 /* function returns illegal type '%s' */
853 error(15, type_name(tp));
854 *tpp = block_derive_type(
855 t == FUNC ? *tpp : (*tpp)->t_subt, PTR);
856 return;
857 }
858 if (tp->t_const || tp->t_volatile) {
859 /* TODO: Make this a warning in C99 mode as well. */
860 if (!allow_trad && !allow_c99) { /* XXX or better allow_c90? */
861 /* function cannot return const... */
862 warning(228);
863 }
864 }
865 } else if (to == ARRAY) {
866 if (t == FUNC) {
867 /* array of function is illegal */
868 error(16);
869 *tpp = gettyp(INT);
870 return;
871 }
872 if (t == ARRAY && tp->t_dim == 0) {
873 /* null dimension */
874 error(17);
875 return;
876 }
877 if (t == VOID) {
878 /* illegal use of 'void' */
879 error(18);
880 *tpp = gettyp(INT);
881 }
882 /*
883 * No need to check for incomplete types here as
884 * length_in_bits already does this.
885 */
886 } else if (to == NO_TSPEC && t == VOID) {
887 if (dcs->d_kind == DLK_PROTO_PARAMS) {
888 if (sym->s_scl != ABSTRACT) {
889 lint_assert(sym->s_name != unnamed);
890 /* void parameter '%s' cannot ... */
891 error(61, sym->s_name);
892 *tpp = gettyp(INT);
893 }
894 } else if (dcs->d_kind == DLK_ABSTRACT) {
895 /* ok */
896 } else if (sym->s_scl != TYPEDEF) {
897 /* void type for '%s' */
898 error(19, sym->s_name);
899 *tpp = gettyp(INT);
900 }
901 }
902 if (t == VOID && to != PTR) {
903 if (tp->t_const || tp->t_volatile) {
904 /* inappropriate qualifiers with 'void' */
905 warning(69);
906 tp->t_const = tp->t_volatile = false;
907 }
908 }
909 tpp = &tp->t_subt;
910 to = t;
911 }
912 }
913
914 /*
915 * In traditional C, the only portable type for bit-fields is unsigned int.
916 *
917 * In C90, the only allowed types for bit-fields are int, signed int and
918 * unsigned int (3.5.2.1). There is no mention of implementation-defined
919 * types.
920 *
921 * In C99, the only portable types for bit-fields are _Bool, signed int and
922 * unsigned int (6.7.2.1p4). In addition, C99 allows "or some other
923 * implementation-defined type".
924 */
925 static void
926 check_bit_field_type(sym_t *dsym, type_t **const inout_tp, tspec_t *inout_t)
927 {
928 type_t *tp = *inout_tp;
929 tspec_t t = *inout_t;
930
931 if (t == CHAR || t == UCHAR || t == SCHAR ||
932 t == SHORT || t == USHORT || t == ENUM) {
933 if (!suppress_bitfieldtype) {
934 /* TODO: Make this an error in C99 mode as well. */
935 if (!allow_trad && !allow_c99) {
936 type_t *btp = block_dup_type(tp);
937 btp->t_bitfield = false;
938 /* bit-field type '%s' invalid in ANSI C */
939 warning(273, type_name(btp));
940 } else if (pflag) {
941 type_t *btp = block_dup_type(tp);
942 btp->t_bitfield = false;
943 /* nonportable bit-field type '%s' */
944 warning(34, type_name(btp));
945 }
946 }
947 } else if (t == INT && dcs->d_sign_mod == NO_TSPEC) {
948 if (pflag && !suppress_bitfieldtype) {
949 /* bit-field of type plain 'int' has ... */
950 warning(344);
951 }
952 } else if (!(t == INT || t == UINT || t == BOOL
953 || (is_integer(t) && (suppress_bitfieldtype || allow_gcc)))) {
954
955 type_t *btp = block_dup_type(tp);
956 btp->t_bitfield = false;
957 /* illegal bit-field type '%s' */
958 warning(35, type_name(btp));
959
960 unsigned int width = tp->t_bit_field_width;
961 dsym->s_type = tp = block_dup_type(gettyp(t = INT));
962 if ((tp->t_bit_field_width = width) > size_in_bits(t))
963 tp->t_bit_field_width = size_in_bits(t);
964 *inout_t = t;
965 *inout_tp = tp;
966 }
967 }
968
969 static void
970 check_bit_field(sym_t *dsym, tspec_t *inout_t, type_t **const inout_tp)
971 {
972
973 check_bit_field_type(dsym, inout_tp, inout_t);
974
975 type_t *tp = *inout_tp;
976 tspec_t t = *inout_t;
977 unsigned int t_width = size_in_bits(t);
978 if (tp->t_bit_field_width > t_width) {
979 /* illegal bit-field size: %d */
980 error(36, (int)tp->t_bit_field_width);
981 tp->t_bit_field_width = t_width;
982 } else if (tp->t_bit_field_width == 0 && dsym->s_name != unnamed) {
983 /* zero size bit-field */
984 error(37);
985 tp->t_bit_field_width = t_width;
986 }
987 if (dsym->s_scl == UNION_MEMBER) {
988 /* bit-field in union is very unusual */
989 warning(41);
990 dsym->s_type->t_bitfield = false;
991 dsym->s_bitfield = false;
992 }
993 }
994
995 /* Aligns the next structure element as required. */
996 static void
997 dcs_align(unsigned int member_alignment, unsigned int bit_field_width)
998 {
999
1000 if (member_alignment > dcs->d_sou_align_in_bits)
1001 dcs->d_sou_align_in_bits = member_alignment;
1002
1003 unsigned int offset = (dcs->d_sou_size_in_bits + member_alignment - 1)
1004 & ~(member_alignment - 1);
1005 if (bit_field_width == 0
1006 || dcs->d_sou_size_in_bits + bit_field_width > offset)
1007 dcs->d_sou_size_in_bits = offset;
1008 }
1009
1010 /* Add a member to the struct or union type that is being built in 'dcs'. */
1011 static void
1012 dcs_add_member(sym_t *mem)
1013 {
1014 type_t *tp = mem->s_type;
1015
1016 unsigned int union_size = 0;
1017 if (dcs->d_kind == DLK_UNION) {
1018 union_size = dcs->d_sou_size_in_bits;
1019 dcs->d_sou_size_in_bits = 0;
1020 }
1021
1022 if (mem->s_bitfield) {
1023 dcs_align(alignment_in_bits(tp), tp->t_bit_field_width);
1024 // XXX: Why round down?
1025 mem->u.s_member.sm_offset_in_bits = dcs->d_sou_size_in_bits
1026 - dcs->d_sou_size_in_bits % size_in_bits(tp->t_tspec);
1027 tp->t_bit_field_offset = dcs->d_sou_size_in_bits
1028 - mem->u.s_member.sm_offset_in_bits;
1029 dcs->d_sou_size_in_bits += tp->t_bit_field_width;
1030 } else {
1031 dcs_align(alignment_in_bits(tp), 0);
1032 mem->u.s_member.sm_offset_in_bits = dcs->d_sou_size_in_bits;
1033 dcs->d_sou_size_in_bits += type_size_in_bits(tp);
1034 }
1035
1036 if (union_size > dcs->d_sou_size_in_bits)
1037 dcs->d_sou_size_in_bits = union_size;
1038 }
1039
1040 sym_t *
1041 declare_unnamed_member(void)
1042 {
1043
1044 sym_t *mem = block_zero_alloc(sizeof(*mem), "sym");
1045 mem->s_name = unnamed;
1046 mem->s_kind = FMEMBER;
1047 mem->s_scl = dcs->d_kind == DLK_STRUCT ? STRUCT_MEMBER : UNION_MEMBER;
1048 mem->s_block_level = -1;
1049 mem->s_type = dcs->d_type;
1050 mem->u.s_member.sm_containing_type = dcs->d_tag_type->t_sou;
1051
1052 dcs_add_member(mem);
1053 suppress_bitfieldtype = false;
1054 return mem;
1055 }
1056
1057 sym_t *
1058 declare_member(sym_t *dsym)
1059 {
1060
1061 lint_assert(is_member(dsym));
1062
1063 if (dcs->d_redeclared_symbol != NULL) {
1064 lint_assert(is_member(dcs->d_redeclared_symbol));
1065
1066 if (dsym->u.s_member.sm_containing_type ==
1067 dcs->d_redeclared_symbol->u.s_member.sm_containing_type) {
1068 /* duplicate member name '%s' */
1069 error(33, dsym->s_name);
1070 rmsym(dcs->d_redeclared_symbol);
1071 }
1072 }
1073
1074 check_type(dsym);
1075
1076 type_t *tp = dsym->s_type;
1077 tspec_t t = tp->t_tspec;
1078 if (dsym->s_bitfield)
1079 check_bit_field(dsym, &t, &tp);
1080 else if (t == FUNC) {
1081 /* function illegal in structure or union */
1082 error(38);
1083 dsym->s_type = tp = block_derive_type(tp, t = PTR);
1084 }
1085
1086 /*
1087 * bit-fields of length 0 are not warned about because length_in_bits
1088 * does not return the length of the bit-field but the length
1089 * of the type the bit-field is packed in (it's ok)
1090 */
1091 int sz = length_in_bits(dsym->s_type, dsym->s_name);
1092 if (sz == 0 && t == ARRAY && dsym->s_type->t_dim == 0) {
1093 /* zero-sized array '%s' in struct is a C99 extension */
1094 c99ism(39, dsym->s_name);
1095 }
1096
1097 dcs_add_member(dsym);
1098
1099 check_function_definition(dsym, false);
1100
1101 suppress_bitfieldtype = false;
1102
1103 return dsym;
1104 }
1105
1106 sym_t *
1107 set_bit_field_width(sym_t *dsym, int bit_field_width)
1108 {
1109
1110 if (dsym == NULL) {
1111 dsym = block_zero_alloc(sizeof(*dsym), "sym");
1112 dsym->s_name = unnamed;
1113 dsym->s_kind = FMEMBER;
1114 dsym->s_scl = STRUCT_MEMBER;
1115 dsym->s_type = gettyp(UINT);
1116 dsym->s_block_level = -1;
1117 }
1118 dsym->s_type = block_dup_type(dsym->s_type);
1119 dsym->s_type->t_bitfield = true;
1120 dsym->s_type->t_bit_field_width = bit_field_width;
1121 dsym->s_bitfield = true;
1122 return dsym;
1123 }
1124
1125 void
1126 add_type_qualifiers(type_qualifiers *dst, type_qualifiers src)
1127 {
1128
1129 if (src.tq_const && dst->tq_const)
1130 /* duplicate '%s' */
1131 warning(10, "const");
1132 if (src.tq_volatile && dst->tq_volatile)
1133 /* duplicate '%s' */
1134 warning(10, "volatile");
1135
1136 dst->tq_const = dst->tq_const | src.tq_const;
1137 dst->tq_restrict = dst->tq_restrict | src.tq_restrict;
1138 dst->tq_volatile = dst->tq_volatile | src.tq_volatile;
1139 dst->tq_atomic = dst->tq_atomic | src.tq_atomic;
1140 }
1141
1142 qual_ptr *
1143 append_qualified_pointer(qual_ptr *p1, qual_ptr *p2)
1144 {
1145
1146 qual_ptr *tail = p2;
1147 while (tail->p_next != NULL)
1148 tail = tail->p_next;
1149 tail->p_next = p1;
1150 return p2;
1151 }
1152
1153 static type_t *
1154 block_derive_pointer(type_t *stp, bool is_const, bool is_volatile)
1155 {
1156
1157 type_t *tp = block_derive_type(stp, PTR);
1158 tp->t_const = is_const;
1159 tp->t_volatile = is_volatile;
1160 return tp;
1161 }
1162
1163 /*
1164 * The following 3 functions extend the type of a declarator with
1165 * pointer, function and array types.
1166 *
1167 * The current type is the type built by dcs_end_type (dcs->d_type) and
1168 * pointer, function and array types already added for this
1169 * declarator. The new type extension is inserted between both.
1170 */
1171 sym_t *
1172 add_pointer(sym_t *decl, qual_ptr *p)
1173 {
1174
1175 debug_dcs(false);
1176
1177 type_t **tpp = &decl->s_type;
1178 while (*tpp != NULL && *tpp != dcs->d_type)
1179 tpp = &(*tpp)->t_subt;
1180 if (*tpp == NULL) {
1181 debug_step("add_pointer: unchanged '%s'",
1182 type_name(decl->s_type));
1183 return decl;
1184 }
1185
1186 while (p != NULL) {
1187 *tpp = block_derive_pointer(dcs->d_type,
1188 p->qualifiers.tq_const, p->qualifiers.tq_volatile);
1189
1190 tpp = &(*tpp)->t_subt;
1191
1192 qual_ptr *next = p->p_next;
1193 free(p);
1194 p = next;
1195 }
1196 debug_step("add_pointer: '%s'", type_name(decl->s_type));
1197 return decl;
1198 }
1199
1200 static type_t *
1201 block_derive_array(type_t *stp, bool dim, int len)
1202 {
1203
1204 type_t *tp = block_derive_type(stp, ARRAY);
1205 tp->t_dim = len;
1206
1207 #if 0
1208 /*
1209 * As of 2022-04-03, the implementation of the type parser (see
1210 * add_function, add_array, add_pointer) is strange. When it sees
1211 * the type 'void *b[4]', it first creates 'void b[4]' and only later
1212 * inserts the '*' in the middle of the type. Late modifications like
1213 * these should not be done at all, instead the parser should be fixed
1214 * to process the type names in the proper syntactical order.
1215 *
1216 * Since the intermediate type would be an array of void, but the
1217 * final type is valid, this check cannot be enabled yet.
1218 */
1219 if (stp->t_tspec == VOID) {
1220 /* array of incomplete type */
1221 error(301);
1222 tp->t_subt = gettyp(CHAR);
1223 }
1224 #endif
1225 if (len < 0) {
1226 /* negative array dimension (%d) */
1227 error(20, len);
1228 } else if (len == 0 && dim) {
1229 /* zero sized array is a C99 extension */
1230 c99ism(322);
1231 } else if (len == 0 && !dim)
1232 tp->t_incomplete_array = true;
1233
1234 return tp;
1235 }
1236
1237 /*
1238 * If a dimension was specified, dim is true, otherwise false
1239 * n is the specified dimension
1240 */
1241 sym_t *
1242 add_array(sym_t *decl, bool dim, int n)
1243 {
1244
1245 debug_dcs(false);
1246
1247 type_t **tpp = &decl->s_type;
1248 while (*tpp != NULL && *tpp != dcs->d_type)
1249 tpp = &(*tpp)->t_subt;
1250 if (*tpp == NULL) {
1251 debug_step("add_array: unchanged '%s'",
1252 type_name(decl->s_type));
1253 return decl;
1254 }
1255
1256 *tpp = block_derive_array(dcs->d_type, dim, n);
1257
1258 debug_step("add_array: '%s'", type_name(decl->s_type));
1259 return decl;
1260 }
1261
1262 static type_t *
1263 block_derive_function(type_t *ret, bool proto, sym_t *args, bool vararg)
1264 {
1265
1266 type_t *tp = block_derive_type(ret, FUNC);
1267 tp->t_proto = proto;
1268 if (proto)
1269 tp->t_args = args;
1270 tp->t_vararg = vararg;
1271 return tp;
1272 }
1273
1274 static void
1275 check_prototype_parameters(sym_t *args)
1276 {
1277
1278 for (sym_t *sym = dcs->d_first_dlsym;
1279 sym != NULL; sym = sym->s_level_next) {
1280 scl_t sc = sym->s_scl;
1281 if (sc == STRUCT_TAG || sc == UNION_TAG || sc == ENUM_TAG) {
1282 /* dubious tag declaration '%s %s' */
1283 warning(85, storage_class_name(sc), sym->s_name);
1284 }
1285 }
1286
1287 for (sym_t *arg = args; arg != NULL; arg = arg->s_next) {
1288 if (arg->s_type->t_tspec == VOID &&
1289 !(arg == args && arg->s_next == NULL)) {
1290 /* void must be sole parameter */
1291 error(60);
1292 arg->s_type = gettyp(INT);
1293 }
1294 }
1295 }
1296
1297 static void
1298 old_style_function(sym_t *decl, sym_t *args)
1299 {
1300
1301 /*
1302 * Remember the list of parameters only if this really seems to be a
1303 * function definition.
1304 */
1305 if (dcs->d_enclosing->d_kind == DLK_EXTERN &&
1306 decl->s_type == dcs->d_enclosing->d_type) {
1307 /*
1308 * Assume that this becomes a function definition. If not, it
1309 * will be corrected in check_function_definition.
1310 */
1311 if (args != NULL) {
1312 decl->s_osdef = true;
1313 decl->u.s_old_style_args = args;
1314 }
1315 } else {
1316 if (args != NULL)
1317 /* function prototype parameters must have types */
1318 warning(62);
1319 }
1320 }
1321
1322 sym_t *
1323 add_function(sym_t *decl, struct parameter_list params)
1324 {
1325
1326 debug_enter();
1327 debug_dcs(true);
1328 debug_sym("decl: ", decl, "\n");
1329 #ifdef DEBUG
1330 for (const sym_t *arg = params.first; arg != NULL; arg = arg->s_next)
1331 debug_sym("arg: ", arg, "\n");
1332 #endif
1333
1334 if (params.prototype) {
1335 if (!allow_c90)
1336 /* function prototypes are illegal in traditional C */
1337 warning(270);
1338 check_prototype_parameters(params.first);
1339 if (params.first != NULL
1340 && params.first->s_type->t_tspec == VOID)
1341 params.first = NULL;
1342 } else
1343 old_style_function(decl, params.first);
1344
1345 /*
1346 * The symbols are removed from the symbol table by
1347 * end_declaration_level after add_function. To be able to restore
1348 * them if this is a function definition, a pointer to the list of
1349 * all symbols is stored in dcs->d_enclosing->d_func_proto_syms. Also,
1350 * a list of the arguments (concatenated by s_next) is stored in
1351 * dcs->d_enclosing->d_func_args. (dcs->d_enclosing must be used
1352 * because *dcs is the declaration stack element created for the list
1353 * of params and is removed after add_function.)
1354 */
1355 if (dcs->d_enclosing->d_kind == DLK_EXTERN &&
1356 decl->s_type == dcs->d_enclosing->d_type) {
1357 dcs->d_enclosing->d_func_proto_syms = dcs->d_first_dlsym;
1358 dcs->d_enclosing->d_func_args = params.first;
1359 }
1360
1361 /*
1362 * XXX: What is this code doing on a semantic level, and why?
1363 * Returning decl leads to the wrong function types in msg_347.
1364 */
1365 type_t **tpp = &decl->s_type;
1366 if (*tpp == NULL)
1367 decl->s_type = dcs->d_enclosing->d_type;
1368 while (*tpp != NULL && *tpp != dcs->d_enclosing->d_type)
1369 /*
1370 * XXX: accessing INT->t_subt feels strange, even though it
1371 * may even be guaranteed to be NULL.
1372 */
1373 tpp = &(*tpp)->t_subt;
1374 if (*tpp == NULL) {
1375 debug_step("add_function: unchanged '%s'",
1376 type_name(decl->s_type));
1377 debug_leave();
1378 return decl; /* see msg_347 */
1379 }
1380
1381 *tpp = block_derive_function(dcs->d_enclosing->d_type,
1382 params.prototype, params.first, params.vararg);
1383
1384 debug_step("add_function: '%s'", type_name(decl->s_type));
1385 debug_dcs(true);
1386 debug_leave();
1387 return decl;
1388 }
1389
1390 /*
1391 * In a function declaration, a list of identifiers (as opposed to a list of
1392 * types) is allowed only if it's also a function definition.
1393 */
1394 void
1395 check_function_definition(sym_t *sym, bool msg)
1396 {
1397
1398 if (sym->s_osdef) {
1399 if (msg) {
1400 /* incomplete or misplaced function definition */
1401 error(22);
1402 }
1403 sym->s_osdef = false;
1404 sym->u.s_old_style_args = NULL;
1405 }
1406 }
1407
1408 /* The symbol gets a storage class and a definedness. */
1409 sym_t *
1410 declarator_name(sym_t *sym)
1411 {
1412 scl_t sc = NOSCL;
1413
1414 if (sym->s_scl == NOSCL)
1415 dcs->d_redeclared_symbol = NULL;
1416 else if (sym->s_defarg) {
1417 sym->s_defarg = false;
1418 dcs->d_redeclared_symbol = NULL;
1419 } else {
1420 dcs->d_redeclared_symbol = sym;
1421 sym = pushdown(sym);
1422 }
1423
1424 switch (dcs->d_kind) {
1425 case DLK_STRUCT:
1426 case DLK_UNION:
1427 sym->u.s_member.sm_containing_type = dcs->d_tag_type->t_sou;
1428 sym->s_def = DEF;
1429 sc = dcs->d_kind == DLK_STRUCT ? STRUCT_MEMBER : UNION_MEMBER;
1430 break;
1431 case DLK_EXTERN:
1432 /*
1433 * Symbols that are 'static' or without any storage class are
1434 * tentatively defined. Symbols that are tentatively defined or
1435 * declared may later become defined if an initializer is seen
1436 * or this is a function definition.
1437 */
1438 sc = dcs->d_scl;
1439 if (sc == NOSCL || sc == THREAD_LOCAL) {
1440 sc = EXTERN;
1441 sym->s_def = TDEF;
1442 } else if (sc == STATIC)
1443 sym->s_def = TDEF;
1444 else if (sc == TYPEDEF)
1445 sym->s_def = DEF;
1446 else {
1447 lint_assert(sc == EXTERN);
1448 sym->s_def = DECL;
1449 }
1450 break;
1451 case DLK_PROTO_PARAMS:
1452 sym->s_arg = true;
1453 /* FALLTHROUGH */
1454 case DLK_OLD_STYLE_ARGS:
1455 if ((sc = dcs->d_scl) == NOSCL)
1456 sc = AUTO;
1457 else {
1458 lint_assert(sc == REG);
1459 sym->s_register = true;
1460 sc = AUTO;
1461 }
1462 sym->s_def = DEF;
1463 break;
1464 case DLK_AUTO:
1465 if ((sc = dcs->d_scl) == NOSCL) {
1466 /*
1467 * XXX somewhat ugly because we don't know whether this
1468 * is AUTO or EXTERN (functions). If we are wrong, it
1469 * must be corrected in declare_local, when the
1470 * necessary type information is available.
1471 */
1472 sc = AUTO;
1473 sym->s_def = DEF;
1474 } else if (sc == AUTO || sc == STATIC || sc == TYPEDEF
1475 || sc == THREAD_LOCAL)
1476 sym->s_def = DEF;
1477 else if (sc == REG) {
1478 sym->s_register = true;
1479 sc = AUTO;
1480 sym->s_def = DEF;
1481 } else {
1482 lint_assert(sc == EXTERN);
1483 sym->s_def = DECL;
1484 }
1485 break;
1486 default:
1487 lint_assert(dcs->d_kind == DLK_ABSTRACT);
1488 /* try to continue after syntax errors */
1489 sc = NOSCL;
1490 }
1491 sym->s_scl = sc;
1492
1493 sym->s_type = dcs->d_type;
1494
1495 dcs->d_func_proto_syms = NULL;
1496
1497 return sym;
1498 }
1499
1500 sym_t *
1501 old_style_function_parameter_name(sym_t *sym)
1502 {
1503
1504 if (sym->s_scl != NOSCL) {
1505 if (block_level == sym->s_block_level) {
1506 /* redeclaration of formal parameter '%s' */
1507 error(21, sym->s_name);
1508 lint_assert(sym->s_defarg);
1509 }
1510 sym = pushdown(sym);
1511 }
1512 sym->s_type = gettyp(INT);
1513 sym->s_scl = AUTO;
1514 sym->s_def = DEF;
1515 sym->s_defarg = sym->s_arg = true;
1516 return sym;
1517 }
1518
1519 /*-
1520 * Checks all possible cases of tag redeclarations.
1521 *
1522 * decl whether T_LBRACE follows
1523 * semi whether T_SEMI follows
1524 */
1525 static sym_t *
1526 new_tag(sym_t *tag, scl_t scl, bool decl, bool semi)
1527 {
1528
1529 if (tag->s_block_level < block_level) {
1530 if (semi) {
1531 /* "struct a;" */
1532 if (allow_c90) {
1533 /* XXX: Why is this warning suppressed in C90 mode? */
1534 if (allow_trad || allow_c99)
1535 /* declaration of '%s %s' intro... */
1536 warning(44, storage_class_name(scl),
1537 tag->s_name);
1538 tag = pushdown(tag);
1539 } else if (tag->s_scl != scl) {
1540 /* base type is really '%s %s' */
1541 warning(45, storage_class_name(tag->s_scl),
1542 tag->s_name);
1543 }
1544 dcs->d_enclosing->d_nonempty_decl = true;
1545 } else if (decl) {
1546 /* "struct a { ... } " */
1547 if (hflag)
1548 /* redefinition of '%s' hides earlier one */
1549 warning(43, tag->s_name);
1550 tag = pushdown(tag);
1551 dcs->d_enclosing->d_nonempty_decl = true;
1552 } else if (tag->s_scl != scl) {
1553 /* base type is really '%s %s' */
1554 warning(45, storage_class_name(tag->s_scl),
1555 tag->s_name);
1556 /* XXX: Why is this warning suppressed in C90 mode? */
1557 if (allow_trad || allow_c99) {
1558 /* declaration of '%s %s' introduces ... */
1559 warning(44, storage_class_name(scl),
1560 tag->s_name);
1561 }
1562 tag = pushdown(tag);
1563 dcs->d_enclosing->d_nonempty_decl = true;
1564 }
1565 } else {
1566 if (tag->s_scl != scl ||
1567 (decl && !is_incomplete(tag->s_type))) {
1568 /* %s tag '%s' redeclared as %s */
1569 error(46, storage_class_name(tag->s_scl),
1570 tag->s_name, storage_class_name(scl));
1571 print_previous_declaration(tag);
1572 tag = pushdown(tag);
1573 dcs->d_enclosing->d_nonempty_decl = true;
1574 } else if (semi || decl)
1575 dcs->d_enclosing->d_nonempty_decl = true;
1576 }
1577 return tag;
1578 }
1579
1580 /*-
1581 * tag the symbol table entry of the tag
1582 * kind the kind of the tag (STRUCT/UNION/ENUM)
1583 * decl whether the tag type will be completed in this declaration
1584 * (when the following token is T_LBRACE)
1585 * semi whether the following token is T_SEMI
1586 */
1587 type_t *
1588 make_tag_type(sym_t *tag, tspec_t kind, bool decl, bool semi)
1589 {
1590 scl_t scl;
1591 type_t *tp;
1592
1593 if (kind == STRUCT)
1594 scl = STRUCT_TAG;
1595 else if (kind == UNION)
1596 scl = UNION_TAG;
1597 else {
1598 lint_assert(kind == ENUM);
1599 scl = ENUM_TAG;
1600 }
1601
1602 if (tag != NULL) {
1603 if (tag->s_scl != NOSCL)
1604 tag = new_tag(tag, scl, decl, semi);
1605 else {
1606 /* a new tag, no empty declaration */
1607 dcs->d_enclosing->d_nonempty_decl = true;
1608 if (scl == ENUM_TAG && !decl) {
1609 /* TODO: Make this an error in C99 mode as well. */
1610 if (allow_c90 &&
1611 ((!allow_trad && !allow_c99) || pflag))
1612 /* forward reference to enum type */
1613 warning(42);
1614 }
1615 }
1616 if (tag->s_scl == NOSCL) {
1617 tag->s_scl = scl;
1618 tag->s_type = tp =
1619 block_zero_alloc(sizeof(*tp), "type");
1620 tp->t_packed = dcs->d_packed;
1621 } else
1622 tp = tag->s_type;
1623
1624 } else {
1625 tag = block_zero_alloc(sizeof(*tag), "sym");
1626 tag->s_name = unnamed;
1627 tag->s_def_pos = unique_curr_pos();
1628 tag->s_kind = FTAG;
1629 tag->s_scl = scl;
1630 tag->s_block_level = -1;
1631 tag->s_type = tp = block_zero_alloc(sizeof(*tp), "type");
1632 tp->t_packed = dcs->d_packed;
1633 dcs->d_enclosing->d_nonempty_decl = true;
1634 }
1635
1636 if (tp->t_tspec == NO_TSPEC) {
1637 tp->t_tspec = kind;
1638 if (kind != ENUM) {
1639 tp->t_sou = block_zero_alloc(sizeof(*tp->t_sou),
1640 "struct_or_union");
1641 tp->t_sou->sou_align_in_bits = CHAR_SIZE;
1642 tp->t_sou->sou_tag = tag;
1643 tp->t_sou->sou_incomplete = true;
1644 } else {
1645 tp->t_is_enum = true;
1646 tp->t_enum = block_zero_alloc(sizeof(*tp->t_enum),
1647 "enumeration");
1648 tp->t_enum->en_tag = tag;
1649 tp->t_enum->en_incomplete = true;
1650 }
1651 }
1652 return tp;
1653 }
1654
1655 const char *
1656 storage_class_name(scl_t sc)
1657 {
1658 switch (sc) {
1659 case EXTERN: return "extern";
1660 case STATIC: return "static";
1661 case AUTO: return "auto";
1662 case REG: return "register";
1663 case TYPEDEF: return "typedef";
1664 case STRUCT_TAG:return "struct";
1665 case UNION_TAG: return "union";
1666 case ENUM_TAG: return "enum";
1667 default: lint_assert(/*CONSTCOND*/false);
1668 }
1669 /* NOTREACHED */
1670 }
1671
1672 static bool
1673 has_named_member(const type_t *tp)
1674 {
1675 for (const sym_t *mem = tp->t_sou->sou_first_member;
1676 mem != NULL; mem = mem->s_next) {
1677 if (mem->s_name != unnamed)
1678 return true;
1679 if (is_struct_or_union(mem->s_type->t_tspec)
1680 && has_named_member(mem->s_type))
1681 return true;
1682 }
1683 return false;
1684 }
1685
1686 type_t *
1687 complete_struct_or_union(sym_t *first_member)
1688 {
1689
1690 type_t *tp = dcs->d_tag_type;
1691 if (tp == NULL) /* in case of syntax errors */
1692 return gettyp(INT);
1693
1694 dcs_align(dcs->d_sou_align_in_bits, 0);
1695
1696 struct_or_union *sou = tp->t_sou;
1697 sou->sou_align_in_bits = dcs->d_sou_align_in_bits;
1698 sou->sou_incomplete = false;
1699 sou->sou_first_member = first_member;
1700 if (tp->t_packed)
1701 pack_struct_or_union(tp);
1702 else
1703 sou->sou_size_in_bits = dcs->d_sou_size_in_bits;
1704
1705 if (sou->sou_size_in_bits == 0) {
1706 /* zero sized %s is a C99 feature */
1707 c99ism(47, tspec_name(tp->t_tspec));
1708 } else if (!has_named_member(tp)) {
1709 /* '%s' has no named members */
1710 warning(65, type_name(tp));
1711 }
1712 return tp;
1713 }
1714
1715 type_t *
1716 complete_enum(sym_t *first_enumerator)
1717 {
1718
1719 type_t *tp = dcs->d_tag_type;
1720 tp->t_enum->en_incomplete = false;
1721 tp->t_enum->en_first_enumerator = first_enumerator;
1722 return tp;
1723 }
1724
1725 /*
1726 * Processes the name of an enumerator in an enum declaration.
1727 *
1728 * sym points to the enumerator
1729 * val is the value of the enumerator
1730 * impl is true if the value of the enumerator was not explicitly specified.
1731 */
1732 sym_t *
1733 enumeration_constant(sym_t *sym, int val, bool impl)
1734 {
1735
1736 if (sym->s_scl != NOSCL) {
1737 if (sym->s_block_level == block_level) {
1738 /* no hflag, because this is illegal */
1739 if (sym->s_arg) {
1740 /* enumeration constant '%s' hides parameter */
1741 warning(57, sym->s_name);
1742 } else {
1743 /* redeclaration of '%s' */
1744 error(27, sym->s_name);
1745 /*
1746 * Inside blocks, it should not be too
1747 * complicated to find the position of the
1748 * previous declaration
1749 */
1750 if (block_level == 0)
1751 print_previous_declaration(sym);
1752 }
1753 } else {
1754 if (hflag)
1755 /* redefinition of '%s' hides earlier one */
1756 warning(43, sym->s_name);
1757 }
1758 sym = pushdown(sym);
1759 }
1760
1761 sym->s_scl = ENUM_CONST;
1762 sym->s_type = dcs->d_tag_type;
1763 sym->u.s_enum_constant = val;
1764
1765 if (impl && val == TARG_INT_MIN) {
1766 /* enumeration value '%s' overflows */
1767 warning(48, sym->s_name);
1768 }
1769
1770 enumval = val == TARG_INT_MAX ? TARG_INT_MIN : val + 1;
1771 return sym;
1772 }
1773
1774 static bool
1775 ends_with(const char *s, const char *suffix)
1776 {
1777 size_t s_len = strlen(s);
1778 size_t suffix_len = strlen(suffix);
1779 return s_len >= suffix_len &&
1780 memcmp(s + s_len - suffix_len, suffix, suffix_len) == 0;
1781 }
1782
1783 void
1784 check_extern_declaration(const sym_t *sym)
1785 {
1786
1787 if (sym->s_scl == EXTERN &&
1788 dcs->d_redeclared_symbol == NULL &&
1789 ends_with(curr_pos.p_file, ".c") &&
1790 allow_c90 &&
1791 !ch_isdigit(sym->s_name[0]) && /* see mktempsym */
1792 strcmp(sym->s_name, "main") != 0) {
1793 /* missing%s header declaration for '%s' */
1794 warning(351, sym->s_type->t_tspec == FUNC ? "" : " 'extern'",
1795 sym->s_name);
1796 }
1797 if (any_query_enabled &&
1798 sym->s_type->t_tspec == FUNC &&
1799 sym->s_scl == EXTERN &&
1800 sym->s_def == DECL &&
1801 !in_system_header) {
1802 /* redundant 'extern' in function declaration of '%s' */
1803 query_message(13, sym->s_name);
1804 }
1805 }
1806
1807 /*
1808 * Check whether the symbol cannot be initialized due to type/storage class.
1809 * Return whether an error has been detected.
1810 */
1811 static bool
1812 check_init(sym_t *sym)
1813 {
1814
1815 if (sym->s_type->t_tspec == FUNC) {
1816 /* cannot initialize function '%s' */
1817 error(24, sym->s_name);
1818 return true;
1819 }
1820 if (sym->s_scl == TYPEDEF) {
1821 /* cannot initialize typedef '%s' */
1822 error(25, sym->s_name);
1823 return true;
1824 }
1825 if (sym->s_scl == EXTERN && sym->s_def == DECL) {
1826 if (dcs->d_kind == DLK_EXTERN) {
1827 /* cannot initialize extern declaration '%s' */
1828 warning(26, sym->s_name);
1829 } else {
1830 /* cannot initialize extern declaration '%s' */
1831 error(26, sym->s_name);
1832 return true;
1833 }
1834 }
1835
1836 return false;
1837 }
1838
1839 /*
1840 * Compares a prototype declaration with the remembered arguments of a previous
1841 * old-style function definition.
1842 */
1843 static bool
1844 check_old_style_definition(sym_t *rdsym, sym_t *dsym)
1845 {
1846
1847 sym_t *args = rdsym->u.s_old_style_args;
1848 sym_t *pargs = dsym->s_type->t_args;
1849
1850 bool msg = false;
1851
1852 int narg = 0;
1853 for (sym_t *arg = args; arg != NULL; arg = arg->s_next)
1854 narg++;
1855 int nparg = 0;
1856 for (sym_t *parg = pargs; parg != NULL; parg = parg->s_next)
1857 nparg++;
1858 if (narg != nparg) {
1859 /* prototype does not match old-style definition */
1860 error(63);
1861 msg = true;
1862 goto end;
1863 }
1864
1865 sym_t *arg = args;
1866 sym_t *parg = pargs;
1867 int n = 1;
1868 while (narg-- > 0) {
1869 bool dowarn = false;
1870 /*
1871 * If it does not match due to promotion and lint runs in
1872 * "traditional to C90" migration mode, print only a warning.
1873 *
1874 * XXX: Where is this "only a warning"?
1875 */
1876 if (!types_compatible(arg->s_type, parg->s_type,
1877 true, true, &dowarn) ||
1878 dowarn) {
1879 /* prototype does not match old-style ... */
1880 error(299, n);
1881 msg = true;
1882 }
1883 arg = arg->s_next;
1884 parg = parg->s_next;
1885 n++;
1886 }
1887
1888 end:
1889 if (msg && rflag) {
1890 /* old-style definition */
1891 message_at(300, &rdsym->s_def_pos);
1892 }
1893
1894 return msg;
1895 }
1896
1897 /* Process a single external or 'static' declarator. */
1898 static void
1899 declare_extern(sym_t *dsym, bool has_initializer, sbuf_t *renaming)
1900 {
1901
1902 if (renaming != NULL) {
1903 lint_assert(dsym->s_rename == NULL);
1904
1905 char *s = level_zero_alloc(1, renaming->sb_len + 1, "string");
1906 (void)memcpy(s, renaming->sb_name, renaming->sb_len + 1);
1907 dsym->s_rename = s;
1908 }
1909
1910 check_extern_declaration(dsym);
1911
1912 check_function_definition(dsym, true);
1913
1914 check_type(dsym);
1915
1916 if (has_initializer && !check_init(dsym))
1917 dsym->s_def = DEF;
1918
1919 /*
1920 * Declarations of functions are marked as "tentative" in
1921 * declarator_name(). This is wrong because there are no
1922 * tentative function definitions.
1923 */
1924 if (dsym->s_type->t_tspec == FUNC && dsym->s_def == TDEF)
1925 dsym->s_def = DECL;
1926
1927 if (dcs->d_inline) {
1928 if (dsym->s_type->t_tspec == FUNC) {
1929 dsym->s_inline = true;
1930 } else {
1931 /* variable '%s' declared inline */
1932 warning(268, dsym->s_name);
1933 }
1934 }
1935
1936 /* Write the declaration into the output file */
1937 if (plibflg && llibflg &&
1938 dsym->s_type->t_tspec == FUNC && dsym->s_type->t_proto) {
1939 /*
1940 * With both LINTLIBRARY and PROTOLIB the prototype is
1941 * written as a function definition to the output file.
1942 */
1943 bool rval = dsym->s_type->t_subt->t_tspec != VOID;
1944 outfdef(dsym, &dsym->s_def_pos, rval, false, NULL);
1945 } else if (!is_compiler_builtin(dsym->s_name)
1946 && !(has_initializer && dsym->s_type->t_incomplete_array)) {
1947 outsym(dsym, dsym->s_scl, dsym->s_def);
1948 }
1949
1950 sym_t *rdsym = dcs->d_redeclared_symbol;
1951 if (rdsym != NULL) {
1952
1953 /*
1954 * If the old symbol stems from an old-style function
1955 * definition, we have remembered the params in
1956 * rdsym->s_old_style_args and compare them with the params
1957 * of the prototype.
1958 */
1959 bool redec = rdsym->s_osdef && dsym->s_type->t_proto &&
1960 check_old_style_definition(rdsym, dsym);
1961
1962 bool dowarn = false;
1963 if (!redec && !check_redeclaration(dsym, &dowarn)) {
1964 if (dowarn) {
1965 /* TODO: Make this an error in C99 mode as well. */
1966 if (!allow_trad && !allow_c99)
1967 /* redeclaration of '%s' */
1968 error(27, dsym->s_name);
1969 else
1970 /* redeclaration of '%s' */
1971 warning(27, dsym->s_name);
1972 print_previous_declaration(rdsym);
1973 }
1974
1975 /*
1976 * Take over the remembered params if the new symbol
1977 * is not a prototype.
1978 */
1979 if (rdsym->s_osdef && !dsym->s_type->t_proto) {
1980 dsym->s_osdef = rdsym->s_osdef;
1981 dsym->u.s_old_style_args =
1982 rdsym->u.s_old_style_args;
1983 dsym->s_def_pos = rdsym->s_def_pos;
1984 }
1985
1986 if (rdsym->s_type->t_proto && !dsym->s_type->t_proto)
1987 dsym->s_def_pos = rdsym->s_def_pos;
1988 else if (rdsym->s_def == DEF && dsym->s_def != DEF)
1989 dsym->s_def_pos = rdsym->s_def_pos;
1990
1991 copy_usage_info(dsym, rdsym);
1992
1993 /* Once a name is defined, it remains defined. */
1994 if (rdsym->s_def == DEF)
1995 dsym->s_def = DEF;
1996
1997 /* once a function is inline, it remains inline */
1998 if (rdsym->s_inline)
1999 dsym->s_inline = true;
2000
2001 complete_type(dsym, rdsym);
2002 }
2003
2004 rmsym(rdsym);
2005 }
2006
2007 if (dsym->s_scl == TYPEDEF) {
2008 dsym->s_type = block_dup_type(dsym->s_type);
2009 dsym->s_type->t_typedef = true;
2010 set_first_typedef(dsym->s_type, dsym);
2011 }
2012 }
2013
2014 void
2015 declare(sym_t *decl, bool has_initializer, sbuf_t *renaming)
2016 {
2017
2018 if (dcs->d_kind == DLK_EXTERN)
2019 declare_extern(decl, has_initializer, renaming);
2020 else if (dcs->d_kind == DLK_OLD_STYLE_ARGS ||
2021 dcs->d_kind == DLK_PROTO_PARAMS) {
2022 if (renaming != NULL) {
2023 /* symbol renaming can't be used on function arguments */
2024 error(310);
2025 } else
2026 (void)declare_argument(decl, has_initializer);
2027 } else {
2028 lint_assert(dcs->d_kind == DLK_AUTO);
2029 if (renaming != NULL) {
2030 /* symbol renaming can't be used on automatic variables */
2031 error(311);
2032 } else
2033 declare_local(decl, has_initializer);
2034 }
2035 }
2036
2037 /*
2038 * Copies information about usage into a new symbol table entry of
2039 * the same symbol.
2040 */
2041 void
2042 copy_usage_info(sym_t *sym, sym_t *rdsym)
2043 {
2044
2045 sym->s_set_pos = rdsym->s_set_pos;
2046 sym->s_use_pos = rdsym->s_use_pos;
2047 sym->s_set = rdsym->s_set;
2048 sym->s_used = rdsym->s_used;
2049 }
2050
2051 /*
2052 * Prints an error and returns true if a symbol is redeclared/redefined.
2053 * Otherwise, returns false and, in some cases of minor problems, prints
2054 * a warning.
2055 */
2056 bool
2057 check_redeclaration(sym_t *dsym, bool *dowarn)
2058 {
2059
2060 sym_t *rdsym = dcs->d_redeclared_symbol;
2061 if (rdsym->s_scl == ENUM_CONST) {
2062 /* redeclaration of '%s' */
2063 error(27, dsym->s_name);
2064 print_previous_declaration(rdsym);
2065 return true;
2066 }
2067 if (rdsym->s_scl == TYPEDEF) {
2068 /* typedef '%s' redeclared */
2069 error(89, dsym->s_name);
2070 print_previous_declaration(rdsym);
2071 return true;
2072 }
2073 if (dsym->s_scl == TYPEDEF) {
2074 /* redeclaration of '%s' */
2075 error(27, dsym->s_name);
2076 print_previous_declaration(rdsym);
2077 return true;
2078 }
2079 if (rdsym->s_def == DEF && dsym->s_def == DEF) {
2080 /* redefinition of '%s' */
2081 error(28, dsym->s_name);
2082 print_previous_declaration(rdsym);
2083 return true;
2084 }
2085 if (!types_compatible(rdsym->s_type, dsym->s_type,
2086 false, false, dowarn)) {
2087 /* redeclaration of '%s' with type '%s', expected '%s' */
2088 error(347, dsym->s_name,
2089 type_name(dsym->s_type), type_name(rdsym->s_type));
2090 print_previous_declaration(rdsym);
2091 return true;
2092 }
2093 if (rdsym->s_scl == EXTERN && dsym->s_scl == EXTERN)
2094 return false;
2095 if (rdsym->s_scl == STATIC && dsym->s_scl == STATIC)
2096 return false;
2097 if (rdsym->s_scl == STATIC && dsym->s_def == DECL)
2098 return false;
2099 if (rdsym->s_scl == EXTERN && rdsym->s_def == DEF) {
2100 /*
2101 * All cases except "int a = 1; static int a;" are caught
2102 * above with or without a warning
2103 */
2104 /* redeclaration of '%s' */
2105 error(27, dsym->s_name);
2106 print_previous_declaration(rdsym);
2107 return true;
2108 }
2109 if (rdsym->s_scl == EXTERN) {
2110 /* '%s' was previously declared extern, becomes static */
2111 warning(29, dsym->s_name);
2112 print_previous_declaration(rdsym);
2113 return false;
2114 }
2115 /*
2116 * Now it's one of:
2117 * "static a; int a;", "static a; int a = 1;", "static a = 1; int a;"
2118 */
2119 /* TODO: Make this an error in C99 mode as well. */
2120 if (!allow_trad && !allow_c99) {
2121 /* redeclaration of '%s'; ANSI C requires static */
2122 warning(30, dsym->s_name);
2123 print_previous_declaration(rdsym);
2124 }
2125 dsym->s_scl = STATIC;
2126 return false;
2127 }
2128
2129 static bool
2130 qualifiers_correspond(const type_t *tp1, const type_t *tp2, bool ignqual)
2131 {
2132
2133 if (tp1->t_const != tp2->t_const && !ignqual && allow_c90)
2134 return false;
2135 if (tp1->t_volatile != tp2->t_volatile && !ignqual && allow_c90)
2136 return false;
2137 return true;
2138 }
2139
2140 bool
2141 pointer_types_are_compatible(const type_t *tp1, const type_t *tp2, bool ignqual)
2142 {
2143
2144 return tp1->t_tspec == VOID || tp2->t_tspec == VOID ||
2145 qualifiers_correspond(tp1, tp2, ignqual);
2146 }
2147
2148 static bool
2149 prototypes_compatible(const type_t *tp1, const type_t *tp2, bool *dowarn)
2150 {
2151
2152 if (tp1->t_vararg != tp2->t_vararg)
2153 return false;
2154
2155 sym_t *a1 = tp1->t_args;
2156 sym_t *a2 = tp2->t_args;
2157
2158 for (; a1 != NULL && a2 != NULL; a1 = a1->s_next, a2 = a2->s_next) {
2159 if (!types_compatible(a1->s_type, a2->s_type,
2160 true, false, dowarn))
2161 return false;
2162 }
2163 return a1 == a2;
2164 }
2165
2166 /*
2167 * Returns whether all parameters of a prototype are compatible with an
2168 * old-style function declaration.
2169 *
2170 * This is the case if the following conditions are met:
2171 * 1. the prototype has a fixed number of parameters
2172 * 2. no parameter is of type float
2173 * 3. no parameter is converted to another type if integer promotion
2174 * is applied on it
2175 */
2176 static bool
2177 matches_no_arg_function(const type_t *tp, bool *dowarn)
2178 {
2179
2180 if (tp->t_vararg && dowarn != NULL)
2181 *dowarn = true;
2182 for (sym_t *arg = tp->t_args; arg != NULL; arg = arg->s_next) {
2183 tspec_t t = arg->s_type->t_tspec;
2184 if (t == FLOAT ||
2185 t == CHAR || t == SCHAR || t == UCHAR ||
2186 t == SHORT || t == USHORT) {
2187 if (dowarn != NULL)
2188 *dowarn = true;
2189 }
2190 }
2191 /* FIXME: Always returning true cannot be correct. */
2192 return true;
2193 }
2194
2195 /*-
2196 * ignqual ignore type qualifiers; used for function parameters
2197 * promot promote the left type; used for comparison of parameters of
2198 * old-style function definitions with parameters of prototypes.
2199 * *dowarn is set to true if an old-style function declaration is not
2200 * compatible with a prototype
2201 */
2202 bool
2203 types_compatible(const type_t *tp1, const type_t *tp2,
2204 bool ignqual, bool promot, bool *dowarn)
2205 {
2206
2207 while (tp1 != NULL && tp2 != NULL) {
2208 tspec_t t = tp1->t_tspec;
2209 if (promot) {
2210 if (t == FLOAT)
2211 t = DOUBLE;
2212 else if (t == CHAR || t == SCHAR)
2213 t = INT;
2214 else if (t == UCHAR)
2215 t = allow_c90 ? INT : UINT;
2216 else if (t == SHORT)
2217 t = INT;
2218 else if (t == USHORT) {
2219 /* CONSTCOND */
2220 t = TARG_INT_MAX < TARG_USHRT_MAX || !allow_c90
2221 ? UINT : INT;
2222 }
2223 }
2224
2225 if (t != tp2->t_tspec)
2226 return false;
2227
2228 if (!qualifiers_correspond(tp1, tp2, ignqual))
2229 return false;
2230
2231 if (is_struct_or_union(t))
2232 return tp1->t_sou == tp2->t_sou;
2233
2234 if (t == ENUM && eflag)
2235 return tp1->t_enum == tp2->t_enum;
2236
2237 if (t == ARRAY && tp1->t_dim != tp2->t_dim) {
2238 if (tp1->t_dim != 0 && tp2->t_dim != 0)
2239 return false;
2240 }
2241
2242 /* don't check prototypes for traditional */
2243 if (t == FUNC && allow_c90) {
2244 if (tp1->t_proto && tp2->t_proto) {
2245 if (!prototypes_compatible(tp1, tp2, dowarn))
2246 return false;
2247 } else if (tp1->t_proto) {
2248 if (!matches_no_arg_function(tp1, dowarn))
2249 return false;
2250 } else if (tp2->t_proto) {
2251 if (!matches_no_arg_function(tp2, dowarn))
2252 return false;
2253 }
2254 }
2255
2256 tp1 = tp1->t_subt;
2257 tp2 = tp2->t_subt;
2258 ignqual = promot = false;
2259 }
2260
2261 return tp1 == tp2;
2262 }
2263
2264 /*
2265 * Completes a type by copying the dimension and prototype information from a
2266 * second compatible type.
2267 *
2268 * Following lines are legal:
2269 * "typedef a[]; a b; a b[10]; a c; a c[20];"
2270 * "typedef ft(); ft f; f(int); ft g; g(long);"
2271 * This means that, if a type is completed, the type structure must be
2272 * duplicated.
2273 */
2274 void
2275 complete_type(sym_t *dsym, sym_t *ssym)
2276 {
2277 type_t **dstp = &dsym->s_type;
2278 type_t *src = ssym->s_type;
2279
2280 while (*dstp != NULL) {
2281 type_t *dst = *dstp;
2282 lint_assert(src != NULL);
2283 lint_assert(dst->t_tspec == src->t_tspec);
2284 if (dst->t_tspec == ARRAY) {
2285 if (dst->t_dim == 0 && src->t_dim != 0) {
2286 *dstp = dst = block_dup_type(dst);
2287 dst->t_dim = src->t_dim;
2288 dst->t_incomplete_array = false;
2289 }
2290 } else if (dst->t_tspec == FUNC) {
2291 if (!dst->t_proto && src->t_proto) {
2292 *dstp = dst = block_dup_type(dst);
2293 dst->t_proto = true;
2294 dst->t_args = src->t_args;
2295 }
2296 }
2297 dstp = &dst->t_subt;
2298 src = src->t_subt;
2299 }
2300 }
2301
2302 /*
2303 * Completes the declaration of a single argument.
2304 */
2305 sym_t *
2306 declare_argument(sym_t *sym, bool has_initializer)
2307 {
2308
2309 check_function_definition(sym, true);
2310
2311 check_type(sym);
2312
2313 if (dcs->d_redeclared_symbol != NULL &&
2314 dcs->d_redeclared_symbol->s_block_level == block_level) {
2315 /* redeclaration of formal parameter '%s' */
2316 error(237, sym->s_name);
2317 rmsym(dcs->d_redeclared_symbol);
2318 sym->s_arg = true;
2319 }
2320
2321 if (!sym->s_arg) {
2322 /* declared argument '%s' is missing */
2323 error(53, sym->s_name);
2324 sym->s_arg = true;
2325 }
2326
2327 if (has_initializer) {
2328 /* cannot initialize parameter '%s' */
2329 error(52, sym->s_name);
2330 }
2331
2332 if (sym->s_type == NULL) /* for c(void()) */
2333 sym->s_type = gettyp(VOID);
2334
2335 tspec_t t = sym->s_type->t_tspec;
2336 if (t == ARRAY)
2337 sym->s_type = block_derive_type(sym->s_type->t_subt, PTR);
2338 if (t == FUNC) {
2339 if (!allow_c90)
2340 /* parameter '%s' has function type, should be ... */
2341 warning(50, sym->s_name);
2342 sym->s_type = block_derive_type(sym->s_type, PTR);
2343 }
2344 if (t == FLOAT && !allow_c90)
2345 sym->s_type = gettyp(DOUBLE);
2346
2347 if (dcs->d_inline)
2348 /* parameter '%s' declared inline */
2349 warning(269, sym->s_name);
2350
2351 /*
2352 * Arguments must have complete types. length_in_bits prints the
2353 * needed error messages (null dimension is impossible because arrays
2354 * are converted to pointers).
2355 */
2356 if (sym->s_type->t_tspec != VOID)
2357 (void)length_in_bits(sym->s_type, sym->s_name);
2358
2359 sym->s_used = dcs->d_used;
2360 mark_as_set(sym);
2361
2362 return sym;
2363 }
2364
2365 static bool
2366 is_character_pointer(const type_t *tp)
2367 {
2368 tspec_t st;
2369
2370 return tp->t_tspec == PTR &&
2371 (st = tp->t_subt->t_tspec,
2372 st == CHAR || st == SCHAR || st == UCHAR);
2373 }
2374
2375 void
2376 check_func_lint_directives(void)
2377 {
2378
2379 /* check for illegal combinations of lint directives */
2380 if (printflike_argnum != -1 && scanflike_argnum != -1) {
2381 /* ** PRINTFLIKE ** and ** SCANFLIKE ** cannot be combined */
2382 warning(289);
2383 printflike_argnum = scanflike_argnum = -1;
2384 }
2385 if (nvararg != -1 &&
2386 (printflike_argnum != -1 || scanflike_argnum != -1)) {
2387 /* dubious use of ** VARARGS ** with ** %s ** */
2388 warning(288,
2389 printflike_argnum != -1 ? "PRINTFLIKE" : "SCANFLIKE");
2390 nvararg = -1;
2391 }
2392
2393 /*
2394 * check if the argument of a lint directive is compatible with the
2395 * number of arguments.
2396 */
2397 int narg = 0;
2398 for (sym_t *arg = dcs->d_func_args; arg != NULL; arg = arg->s_next)
2399 narg++;
2400 if (nargusg > narg) {
2401 /* argument number mismatch in comment ** %s ** */
2402 warning(283, "ARGSUSED");
2403 nargusg = 0;
2404 }
2405 if (nvararg > narg) {
2406 /* argument number mismatch in comment ** %s ** */
2407 warning(283, "VARARGS");
2408 nvararg = 0;
2409 }
2410 if (printflike_argnum > narg) {
2411 /* argument number mismatch in comment ** %s ** */
2412 warning(283, "PRINTFLIKE");
2413 printflike_argnum = -1;
2414 } else if (printflike_argnum == 0) {
2415 printflike_argnum = -1;
2416 }
2417 if (scanflike_argnum > narg) {
2418 /* argument number mismatch in comment ** %s ** */
2419 warning(283, "SCANFLIKE");
2420 scanflike_argnum = -1;
2421 } else if (scanflike_argnum == 0) {
2422 scanflike_argnum = -1;
2423 }
2424 if (printflike_argnum != -1 || scanflike_argnum != -1) {
2425 narg = printflike_argnum != -1
2426 ? printflike_argnum : scanflike_argnum;
2427 sym_t *arg = dcs->d_func_args;
2428 for (int n = 1; n < narg; n++)
2429 arg = arg->s_next;
2430 if (!is_character_pointer(arg->s_type)) {
2431 /* argument %d must be 'char *' for PRINTFLIKE/... */
2432 warning(293, narg);
2433 printflike_argnum = scanflike_argnum = -1;
2434 }
2435 }
2436 }
2437
2438 /*
2439 * Checks compatibility of an old-style function definition with a previous
2440 * prototype declaration.
2441 * Returns true if the position of the previous declaration should be reported.
2442 */
2443 static bool
2444 check_prototype_declaration(sym_t *arg, sym_t *parg)
2445 {
2446 type_t *tp = arg->s_type;
2447 type_t *ptp = parg->s_type;
2448 bool dowarn = false;
2449
2450 if (!types_compatible(tp, ptp, true, true, &dowarn)) {
2451 if (types_compatible(tp, ptp, true, false, &dowarn)) {
2452 /* type of '%s' does not match prototype */
2453 return gnuism(58, arg->s_name);
2454 } else {
2455 /* type of '%s' does not match prototype */
2456 error(58, arg->s_name);
2457 return true;
2458 }
2459 }
2460 if (dowarn) {
2461 /* TODO: Make this an error in C99 mode as well. */
2462 if (!allow_trad && !allow_c99)
2463 /* type of '%s' does not match prototype */
2464 error(58, arg->s_name);
2465 else
2466 /* type of '%s' does not match prototype */
2467 warning(58, arg->s_name);
2468 return true;
2469 }
2470
2471 return false;
2472 }
2473
2474 /*
2475 * Warn about arguments in old-style function definitions that default to int.
2476 * Check that an old-style function definition is compatible to a previous
2477 * prototype.
2478 */
2479 void
2480 check_func_old_style_arguments(void)
2481 {
2482 int narg;
2483 int nparg;
2484 bool msg;
2485
2486 sym_t *args = funcsym->u.s_old_style_args;
2487 sym_t *pargs = funcsym->s_type->t_args;
2488
2489 /*
2490 * print a warning for each argument of an old-style function
2491 * definition which defaults to int
2492 */
2493 for (sym_t *arg = args; arg != NULL; arg = arg->s_next) {
2494 if (arg->s_defarg) {
2495 /* type of argument '%s' defaults to 'int' */
2496 warning(32, arg->s_name);
2497 arg->s_defarg = false;
2498 mark_as_set(arg);
2499 }
2500 }
2501
2502 /*
2503 * If this is an old-style function definition and a prototype
2504 * exists, compare the types of arguments.
2505 */
2506 if (funcsym->s_osdef && funcsym->s_type->t_proto) {
2507 /*
2508 * If the number of arguments does not match, we need not
2509 * continue.
2510 */
2511 narg = nparg = 0;
2512 msg = false;
2513 for (sym_t *parg = pargs; parg != NULL; parg = parg->s_next)
2514 nparg++;
2515 for (sym_t *arg = args; arg != NULL; arg = arg->s_next)
2516 narg++;
2517 if (narg != nparg) {
2518 /* parameter mismatch: %d declared, %d defined */
2519 error(51, nparg, narg);
2520 msg = true;
2521 } else {
2522 sym_t *parg = pargs;
2523 sym_t *arg = args;
2524 while (narg-- > 0) {
2525 msg |= check_prototype_declaration(arg, parg);
2526 parg = parg->s_next;
2527 arg = arg->s_next;
2528 }
2529 }
2530 if (msg && rflag) {
2531 /* prototype declaration */
2532 message_at(285, &dcs->d_redeclared_symbol->s_def_pos);
2533 }
2534
2535 /* from now on the prototype is valid */
2536 funcsym->s_osdef = false;
2537 funcsym->u.s_old_style_args = NULL;
2538 }
2539 }
2540
2541 static void
2542 check_local_hiding(const sym_t *dsym)
2543 {
2544 switch (dsym->s_scl) {
2545 case AUTO:
2546 /* automatic '%s' hides external declaration */
2547 warning(86, dsym->s_name);
2548 break;
2549 case STATIC:
2550 /* static '%s' hides external declaration */
2551 warning(87, dsym->s_name);
2552 break;
2553 case TYPEDEF:
2554 /* typedef '%s' hides external declaration */
2555 warning(88, dsym->s_name);
2556 break;
2557 case EXTERN:
2558 /* Already checked in declare_external_in_block. */
2559 break;
2560 default:
2561 lint_assert(/*CONSTCOND*/false);
2562 }
2563 }
2564
2565 static void
2566 check_local_redeclaration(const sym_t *dsym, sym_t *rdsym)
2567 {
2568 if (rdsym->s_block_level == 0) {
2569 if (hflag)
2570 check_local_hiding(dsym);
2571
2572 } else if (rdsym->s_block_level == block_level) {
2573
2574 /* no hflag, because it's illegal! */
2575 if (rdsym->s_arg) {
2576 /*
2577 * if allow_c90, a "redeclaration of '%s'" error
2578 * is produced below
2579 */
2580 if (!allow_c90) {
2581 if (hflag) {
2582 /* declaration of '%s' hides ... */
2583 warning(91, dsym->s_name);
2584 }
2585 rmsym(rdsym);
2586 }
2587 }
2588
2589 } else if (rdsym->s_block_level < block_level) {
2590 if (hflag) {
2591 /* declaration of '%s' hides earlier one */
2592 warning(95, dsym->s_name);
2593 }
2594 }
2595
2596 if (rdsym->s_block_level == block_level) {
2597 /* redeclaration of '%s' */
2598 error(27, dsym->s_name);
2599 rmsym(rdsym);
2600 }
2601 }
2602
2603 /* Processes (re)declarations of external symbols inside blocks. */
2604 static void
2605 declare_external_in_block(sym_t *dsym)
2606 {
2607
2608 /* look for a symbol with the same name */
2609 sym_t *esym = dcs->d_redeclared_symbol;
2610 while (esym != NULL && esym->s_block_level != 0) {
2611 while ((esym = esym->s_symtab_next) != NULL) {
2612 if (esym->s_kind != FVFT)
2613 continue;
2614 if (strcmp(dsym->s_name, esym->s_name) == 0)
2615 break;
2616 }
2617 }
2618 if (esym == NULL)
2619 return;
2620 if (esym->s_scl != EXTERN && esym->s_scl != STATIC) {
2621 /* gcc accepts this without a warning, pcc prints an error. */
2622 /* redeclaration of '%s' */
2623 warning(27, dsym->s_name);
2624 print_previous_declaration(esym);
2625 return;
2626 }
2627
2628 bool dowarn = false;
2629 bool compatible = types_compatible(esym->s_type, dsym->s_type,
2630 false, false, &dowarn);
2631
2632 if (!compatible || dowarn) {
2633 if (esym->s_scl == EXTERN) {
2634 /* inconsistent redeclaration of extern '%s' */
2635 warning(90, dsym->s_name);
2636 print_previous_declaration(esym);
2637 } else {
2638 /* inconsistent redeclaration of static '%s' */
2639 warning(92, dsym->s_name);
2640 print_previous_declaration(esym);
2641 }
2642 }
2643
2644 if (compatible) {
2645 /*
2646 * Remember the external symbol, so we can update usage
2647 * information at the end of the block.
2648 */
2649 dsym->s_ext_sym = esym;
2650 }
2651 }
2652
2653 /*
2654 * Completes a single local declaration/definition.
2655 */
2656 void
2657 declare_local(sym_t *dsym, bool has_initializer)
2658 {
2659
2660 /* Correct a mistake done in declarator_name(). */
2661 if (dsym->s_type->t_tspec == FUNC) {
2662 dsym->s_def = DECL;
2663 if (dcs->d_scl == NOSCL)
2664 dsym->s_scl = EXTERN;
2665 }
2666
2667 if (dsym->s_scl == EXTERN) {
2668 /* nested 'extern' declaration of '%s' */
2669 warning(352, dsym->s_name);
2670 }
2671
2672 if (dsym->s_type->t_tspec == FUNC) {
2673 if (dsym->s_scl == STATIC) {
2674 /* dubious static function '%s' at block level */
2675 warning(93, dsym->s_name);
2676 dsym->s_scl = EXTERN;
2677 } else if (dsym->s_scl != EXTERN && dsym->s_scl != TYPEDEF) {
2678 /* function '%s' has illegal storage class */
2679 error(94, dsym->s_name);
2680 dsym->s_scl = EXTERN;
2681 }
2682 }
2683
2684 /*
2685 * functions may be declared inline at local scope, although
2686 * this has no effect for a later definition of the same
2687 * function.
2688 * XXX it should have an effect if !allow_c90 is set. this would
2689 * also be the way gcc behaves.
2690 */
2691 if (dcs->d_inline) {
2692 if (dsym->s_type->t_tspec == FUNC)
2693 dsym->s_inline = true;
2694 else {
2695 /* variable '%s' declared inline */
2696 warning(268, dsym->s_name);
2697 }
2698 }
2699
2700 check_function_definition(dsym, true);
2701
2702 check_type(dsym);
2703
2704 if (dcs->d_redeclared_symbol != NULL && dsym->s_scl == EXTERN)
2705 declare_external_in_block(dsym);
2706
2707 if (dsym->s_scl == EXTERN) {
2708 /*
2709 * XXX if the static variable at level 0 is only defined
2710 * later, checking will be possible.
2711 */
2712 if (dsym->s_ext_sym == NULL)
2713 outsym(dsym, EXTERN, dsym->s_def);
2714 else
2715 outsym(dsym, dsym->s_ext_sym->s_scl, dsym->s_def);
2716 }
2717
2718 if (dcs->d_redeclared_symbol != NULL)
2719 check_local_redeclaration(dsym, dcs->d_redeclared_symbol);
2720
2721 if (has_initializer && !check_init(dsym)) {
2722 dsym->s_def = DEF;
2723 mark_as_set(dsym);
2724 }
2725
2726 if (dsym->s_scl == TYPEDEF) {
2727 dsym->s_type = block_dup_type(dsym->s_type);
2728 dsym->s_type->t_typedef = true;
2729 set_first_typedef(dsym->s_type, dsym);
2730 }
2731
2732 if (dsym->s_scl == STATIC && any_query_enabled) {
2733 /* static variable '%s' in function */
2734 query_message(11, dsym->s_name);
2735 }
2736 }
2737
2738 /* Create a symbol for an abstract declaration. */
2739 sym_t *
2740 abstract_name(void)
2741 {
2742
2743 lint_assert(dcs->d_kind == DLK_ABSTRACT
2744 || dcs->d_kind == DLK_PROTO_PARAMS);
2745
2746 sym_t *sym = block_zero_alloc(sizeof(*sym), "sym");
2747 sym->s_name = unnamed;
2748 sym->s_def = DEF;
2749 sym->s_scl = ABSTRACT;
2750 sym->s_block_level = -1;
2751 sym->s_arg = dcs->d_kind == DLK_PROTO_PARAMS;
2752
2753 /*
2754 * At this point, dcs->d_type contains only the basic type. That
2755 * type will be updated later, adding pointers, arrays and functions
2756 * as necessary.
2757 */
2758 /*
2759 * XXX: This is not the correct type. For example in msg_347, it is
2760 * the type of the last prototype parameter, but it should rather be
2761 * the return type of the function.
2762 */
2763 sym->s_type = dcs->d_type;
2764 dcs->d_redeclared_symbol = NULL;
2765
2766 return sym;
2767 }
2768
2769 /* Removes anything which has nothing to do on global level. */
2770 void
2771 global_clean_up(void)
2772 {
2773
2774 while (dcs->d_enclosing != NULL)
2775 end_declaration_level();
2776
2777 clean_up_after_error();
2778 block_level = 0;
2779 mem_block_level = 0;
2780 debug_step("%s: mem_block_level = %zu", __func__, mem_block_level);
2781 global_clean_up_decl(true);
2782 }
2783
2784 sym_t *
2785 declare_abstract_type(sym_t *sym)
2786 {
2787
2788 check_function_definition(sym, true);
2789 check_type(sym);
2790 return sym;
2791 }
2792
2793 /* Checks size after declarations of variables and their initialization. */
2794 void
2795 check_size(sym_t *dsym)
2796 {
2797
2798 if (dsym->s_def == DEF &&
2799 dsym->s_scl != TYPEDEF &&
2800 dsym->s_type->t_tspec != FUNC &&
2801 length_in_bits(dsym->s_type, dsym->s_name) == 0 &&
2802 dsym->s_type->t_tspec == ARRAY &&
2803 dsym->s_type->t_dim == 0) {
2804 if (!allow_c90)
2805 /* empty array declaration for '%s' */
2806 warning(190, dsym->s_name);
2807 else
2808 /* empty array declaration for '%s' */
2809 error(190, dsym->s_name);
2810 }
2811 }
2812
2813 /* Mark an object as set if it is not already. */
2814 void
2815 mark_as_set(sym_t *sym)
2816 {
2817
2818 if (!sym->s_set) {
2819 sym->s_set = true;
2820 sym->s_set_pos = unique_curr_pos();
2821 }
2822 }
2823
2824 /* Mark an object as used if it is not already. */
2825 void
2826 mark_as_used(sym_t *sym, bool fcall, bool szof)
2827 {
2828
2829 if (!sym->s_used) {
2830 sym->s_used = true;
2831 sym->s_use_pos = unique_curr_pos();
2832 }
2833 /*
2834 * For function calls, another record is written.
2835 *
2836 * XXX: Should symbols used in sizeof() be treated as used or not?
2837 * Probably not, because there is no point in declaring an external
2838 * variable only to get its size.
2839 */
2840 if (!fcall && !szof && sym->s_kind == FVFT && sym->s_scl == EXTERN)
2841 outusg(sym);
2842 }
2843
2844 /* Warns about variables and labels that are not used or only set. */
2845 void
2846 check_usage(decl_level *dl)
2847 {
2848 /* for this warning LINTED has no effect */
2849 int saved_lwarn = lwarn;
2850 lwarn = LWARN_ALL;
2851
2852 debug_step("begin lwarn %d", lwarn);
2853 for (sym_t *sym = dl->d_first_dlsym;
2854 sym != NULL; sym = sym->s_level_next)
2855 check_usage_sym(dl->d_asm, sym);
2856 lwarn = saved_lwarn;
2857 debug_step("end lwarn %d", lwarn);
2858 }
2859
2860 static void
2861 check_argument_usage(bool novar, sym_t *arg)
2862 {
2863
2864 lint_assert(arg->s_set);
2865
2866 if (novar)
2867 return;
2868
2869 if (!arg->s_used && !vflag) {
2870 /* parameter '%s' unused in function '%s' */
2871 warning_at(231, &arg->s_def_pos, arg->s_name, funcsym->s_name);
2872 }
2873 }
2874
2875 static void
2876 check_variable_usage(bool novar, sym_t *sym)
2877 {
2878
2879 lint_assert(block_level != 0);
2880
2881 /* example at file scope: int c = ({ return 3; }); */
2882 if (sym->s_block_level == 0 && ch_isdigit(sym->s_name[0]))
2883 return;
2884
2885 /* errors in expressions easily cause lots of these warnings */
2886 if (seen_error)
2887 return;
2888
2889 /*
2890 * XXX Only variables are checked, although types should
2891 * probably also be checked
2892 */
2893 scl_t sc = sym->s_scl;
2894 if (sc != EXTERN && sc != STATIC && sc != AUTO && sc != REG)
2895 return;
2896
2897 if (novar)
2898 return;
2899
2900 if (sc == EXTERN) {
2901 if (!sym->s_used && !sym->s_set) {
2902 /* '%s' unused in function '%s' */
2903 warning_at(192, &sym->s_def_pos,
2904 sym->s_name, funcsym->s_name);
2905 }
2906 } else {
2907 if (sym->s_set && !sym->s_used) {
2908 /* '%s' set but not used in function '%s' */
2909 warning_at(191, &sym->s_set_pos,
2910 sym->s_name, funcsym->s_name);
2911 } else if (!sym->s_used) {
2912 /* '%s' unused in function '%s' */
2913 warning_at(192, &sym->s_def_pos,
2914 sym->s_name, funcsym->s_name);
2915 }
2916 }
2917
2918 if (sc == EXTERN) {
2919 /*
2920 * information about usage is taken over into the symbol
2921 * table entry at level 0 if the symbol was locally declared
2922 * as an external symbol.
2923 *
2924 * XXX This is wrong for symbols declared static at level 0
2925 * if the usage information stems from sizeof(). This is
2926 * because symbols at level 0 only used in sizeof() are
2927 * considered to not be used.
2928 */
2929 sym_t *xsym = sym->s_ext_sym;
2930 if (xsym != NULL) {
2931 if (sym->s_used && !xsym->s_used) {
2932 xsym->s_used = true;
2933 xsym->s_use_pos = sym->s_use_pos;
2934 }
2935 if (sym->s_set && !xsym->s_set) {
2936 xsym->s_set = true;
2937 xsym->s_set_pos = sym->s_set_pos;
2938 }
2939 }
2940 }
2941 }
2942
2943 static void
2944 check_label_usage(sym_t *lab)
2945 {
2946
2947 lint_assert(block_level == 1);
2948 lint_assert(lab->s_block_level == 1);
2949
2950 if (funcsym == NULL)
2951 /* syntax error '%s' */
2952 error(249, "labels are only valid inside a function");
2953 else if (lab->s_set && !lab->s_used)
2954 /* label '%s' unused in function '%s' */
2955 warning_at(232, &lab->s_set_pos, lab->s_name, funcsym->s_name);
2956 else if (!lab->s_set)
2957 /* undefined label '%s' */
2958 warning_at(23, &lab->s_use_pos, lab->s_name);
2959 }
2960
2961 static void
2962 check_tag_usage(sym_t *sym)
2963 {
2964
2965 if (!is_incomplete(sym->s_type))
2966 return;
2967
2968 /* always complain about incomplete tags declared inside blocks */
2969 if (zflag || dcs->d_kind != DLK_EXTERN)
2970 return;
2971
2972 switch (sym->s_type->t_tspec) {
2973 case STRUCT:
2974 /* struct '%s' never defined */
2975 warning_at(233, &sym->s_def_pos, sym->s_name);
2976 break;
2977 case UNION:
2978 /* union '%s' never defined */
2979 warning_at(234, &sym->s_def_pos, sym->s_name);
2980 break;
2981 default:
2982 lint_assert(sym->s_type->t_tspec == ENUM);
2983 /* enum '%s' never defined */
2984 warning_at(235, &sym->s_def_pos, sym->s_name);
2985 break;
2986 }
2987 }
2988
2989 /* Warns about a variable or a label that is not used or only set. */
2990 void
2991 check_usage_sym(bool novar, sym_t *sym)
2992 {
2993
2994 if (sym->s_block_level == -1)
2995 return;
2996
2997 if (sym->s_kind == FVFT && sym->s_arg)
2998 check_argument_usage(novar, sym);
2999 else if (sym->s_kind == FVFT)
3000 check_variable_usage(novar, sym);
3001 else if (sym->s_kind == FLABEL)
3002 check_label_usage(sym);
3003 else if (sym->s_kind == FTAG)
3004 check_tag_usage(sym);
3005 }
3006
3007 static void
3008 check_global_variable_size(const sym_t *sym)
3009 {
3010
3011 if (sym->s_def != TDEF)
3012 return;
3013 if (sym->s_type->t_tspec == FUNC) {
3014 /* Maybe a syntax error after a function declaration. */
3015 return;
3016 }
3017 if (sym->s_def == TDEF && sym->s_type->t_tspec == VOID) {
3018 /* Prevent an internal error in length_in_bits below. */
3019 return;
3020 }
3021
3022 pos_t cpos = curr_pos;
3023 curr_pos = sym->s_def_pos;
3024 int len_in_bits = length_in_bits(sym->s_type, sym->s_name);
3025 curr_pos = cpos;
3026
3027 if (len_in_bits == 0 &&
3028 sym->s_type->t_tspec == ARRAY && sym->s_type->t_dim == 0) {
3029 /* TODO: C99 6.7.5.2p1 defines this as an error as well. */
3030 if (!allow_c90 ||
3031 (sym->s_scl == EXTERN && (allow_trad || allow_c99))) {
3032 /* empty array declaration for '%s' */
3033 warning_at(190, &sym->s_def_pos, sym->s_name);
3034 } else {
3035 /* empty array declaration for '%s' */
3036 error_at(190, &sym->s_def_pos, sym->s_name);
3037 }
3038 }
3039 }
3040
3041 static void
3042 check_unused_static_global_variable(const sym_t *sym)
3043 {
3044 if (sym->s_type->t_tspec == FUNC) {
3045 if (sym->s_def == DEF) {
3046 if (!sym->s_inline)
3047 /* static function '%s' unused */
3048 warning_at(236, &sym->s_def_pos, sym->s_name);
3049 } else {
3050 /* static function '%s' declared but not defined */
3051 warning_at(290, &sym->s_def_pos, sym->s_name);
3052 }
3053 } else if (!sym->s_set) {
3054 /* static variable '%s' unused */
3055 warning_at(226, &sym->s_def_pos, sym->s_name);
3056 } else {
3057 /* static variable '%s' set but not used */
3058 warning_at(307, &sym->s_def_pos, sym->s_name);
3059 }
3060 }
3061
3062 static void
3063 check_static_global_variable(const sym_t *sym)
3064 {
3065 if (sym->s_type->t_tspec == FUNC && sym->s_used && sym->s_def != DEF) {
3066 /* static function '%s' called but not defined */
3067 error_at(225, &sym->s_use_pos, sym->s_name);
3068 }
3069
3070 if (!sym->s_used)
3071 check_unused_static_global_variable(sym);
3072
3073 if (allow_c90 && sym->s_def == TDEF && sym->s_type->t_const) {
3074 /* const object '%s' should have initializer */
3075 warning_at(227, &sym->s_def_pos, sym->s_name);
3076 }
3077 }
3078
3079 static void
3080 check_global_variable(const sym_t *sym)
3081 {
3082 scl_t scl = sym->s_scl;
3083
3084 if (scl == TYPEDEF || scl == BOOL_CONST || scl == ENUM_CONST)
3085 return;
3086
3087 if (scl == NOSCL)
3088 return; /* May be caused by a syntax error. */
3089
3090 lint_assert(scl == EXTERN || scl == STATIC);
3091
3092 check_global_variable_size(sym);
3093
3094 if (scl == STATIC)
3095 check_static_global_variable(sym);
3096 }
3097
3098 /*
3099 * Called after the entire translation unit has been parsed.
3100 * Changes tentative definitions into definitions.
3101 * Performs some tests on global symbols. Detected problems are:
3102 * - defined variables of incomplete type
3103 * - constant variables which are not initialized
3104 * - static symbols which are never used
3105 */
3106 void
3107 check_global_symbols(void)
3108 {
3109 sym_t *sym;
3110
3111 if (block_level != 0 || dcs->d_enclosing != NULL)
3112 norecover();
3113
3114 for (sym = dcs->d_first_dlsym; sym != NULL; sym = sym->s_level_next) {
3115 if (sym->s_block_level == -1)
3116 continue;
3117 if (sym->s_kind == FVFT)
3118 check_global_variable(sym);
3119 else if (sym->s_kind == FTAG)
3120 check_tag_usage(sym);
3121 else
3122 lint_assert(sym->s_kind == FMEMBER);
3123 }
3124 }
3125
3126 /*
3127 * Prints information about location of previous definition/declaration.
3128 */
3129 void
3130 print_previous_declaration(const sym_t *psym)
3131 {
3132
3133 if (!rflag)
3134 return;
3135
3136 if (psym->s_def == DEF || psym->s_def == TDEF) {
3137 /* previous definition of '%s' */
3138 message_at(261, &psym->s_def_pos, psym->s_name);
3139 } else {
3140 /* previous declaration of '%s' */
3141 message_at(260, &psym->s_def_pos, psym->s_name);
3142 }
3143 }
3144
3145 /*
3146 * Gets a node for a constant and returns the value of this constant
3147 * as integer.
3148 *
3149 * If the node is not constant or too large for int or of type float,
3150 * a warning will be printed.
3151 *
3152 * to_int_constant() should be used only inside declarations. If it is used in
3153 * expressions, it frees the memory used for the expression.
3154 */
3155 int
3156 to_int_constant(tnode_t *tn, bool required)
3157 {
3158
3159 if (tn == NULL)
3160 return 1;
3161
3162 val_t *v = integer_constant(tn, required);
3163 bool is_unsigned = is_uinteger(v->v_tspec);
3164 int64_t val = v->u.integer;
3165 free(v);
3166
3167 /*
3168 * Abstract declarations are used inside expression. To free
3169 * the memory would be a fatal error.
3170 * We don't free blocks that are inside casts because these
3171 * will be used later to match types.
3172 */
3173 if (tn->tn_op != CON && dcs->d_kind != DLK_ABSTRACT)
3174 expr_free_all();
3175
3176 bool out_of_bounds = is_unsigned
3177 ? (uint64_t)val > (uint64_t)TARG_INT_MAX
3178 : val > (int64_t)TARG_INT_MAX || val < (int64_t)TARG_INT_MIN;
3179 if (out_of_bounds)
3180 /* integral constant too large */
3181 warning(56);
3182 return (int)val;
3183 }
3184