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