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