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