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