xref: /netbsd-src/usr.bin/xlint/lint1/func.c (revision 70f7362772ba52b749c976fb5e86e39a8b2c9afc)
1 /*	$NetBSD: func.c,v 1.186 2024/03/29 08:35:32 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.186 2024/03/29 08:35:32 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 	while (cstmt->c_kind != kind)
160 		cstmt = cstmt->c_surrounding;
161 
162 	control_statement *cs = cstmt;
163 	cstmt = cs->c_surrounding;
164 
165 	free(cs->c_case_labels.vals);
166 	free(cs->c_switch_type);
167 	free(cs);
168 }
169 
170 static void
171 set_reached(bool new_reached)
172 {
173 	debug_step("%s -> %s",
174 	    reached ? "reachable" : "unreachable",
175 	    new_reached ? "reachable" : "unreachable");
176 	reached = new_reached;
177 	warn_about_unreachable = true;
178 }
179 
180 /*
181  * Prints a warning if a statement cannot be reached.
182  */
183 void
184 check_statement_reachable(void)
185 {
186 	if (!reached && warn_about_unreachable) {
187 		/* statement not reached */
188 		warning(193);
189 		warn_about_unreachable = false;
190 	}
191 }
192 
193 /*
194  * Called after a function declaration which introduces a function definition
195  * and before an (optional) old-style parameter declaration list.
196  *
197  * Puts all symbols declared in the prototype or in an old-style parameter
198  * list back to the symbol table.
199  *
200  * Does the usual checking of storage class, type (return value),
201  * redeclaration, etc.
202  */
203 void
204 begin_function(sym_t *fsym)
205 {
206 	funcsym = fsym;
207 
208 	/*
209 	 * Put all symbols declared in the parameter list back to the symbol
210 	 * table.
211 	 */
212 	for (sym_t *sym = dcs->d_func_proto_syms; sym != NULL;
213 	    sym = sym->s_level_next) {
214 		if (sym->s_block_level != -1) {
215 			lint_assert(sym->s_block_level == 1);
216 			inssym(1, sym);
217 		}
218 	}
219 
220 	/*
221 	 * In old_style_function() we did not know whether it is an old style
222 	 * function definition or only an old-style declaration, if there are
223 	 * no parameters inside the parameter list ("f()").
224 	 */
225 	if (!fsym->s_type->t_proto && fsym->u.s_old_style_params == NULL)
226 		fsym->s_osdef = true;
227 
228 	check_type(fsym);
229 
230 	/*
231 	 * check_type() checks for almost all possible errors, but not for
232 	 * incomplete return values (these are allowed in declarations)
233 	 */
234 	if (fsym->s_type->t_subt->t_tspec != VOID &&
235 	    is_incomplete(fsym->s_type->t_subt)) {
236 		/* cannot return incomplete type */
237 		error(67);
238 	}
239 
240 	fsym->s_def = DEF;
241 
242 	if (fsym->s_scl == TYPEDEF) {
243 		fsym->s_scl = EXTERN;
244 		/* illegal storage class */
245 		error(8);
246 	}
247 
248 	if (dcs->d_inline)
249 		fsym->s_inline = true;
250 
251 	/*
252 	 * Parameters in new-style function declarations need a name. ('void'
253 	 * is already removed from the list of parameters.)
254 	 */
255 	int n = 1;
256 	for (const sym_t *param = fsym->s_type->u.params;
257 	    param != NULL; param = param->s_next) {
258 		if (param->s_scl == ABSTRACT) {
259 			lint_assert(param->s_name == unnamed);
260 			/* formal parameter #%d lacks name */
261 			error(59, n);
262 		} else {
263 			lint_assert(param->s_name != unnamed);
264 		}
265 		n++;
266 	}
267 
268 	/*
269 	 * We must also remember the position. s_def_pos is overwritten if this
270 	 * is an old-style definition, and we had already a prototype.
271 	 */
272 	dcs->d_func_def_pos = fsym->s_def_pos;
273 
274 	sym_t *rdsym = dcs->d_redeclared_symbol;
275 	if (rdsym != NULL) {
276 		bool dowarn = false;
277 		if (!check_redeclaration(fsym, &dowarn)) {
278 
279 			/*
280 			 * Print nothing if the newly defined function is
281 			 * defined in old style. A better warning will be
282 			 * printed in check_func_lint_directives().
283 			 */
284 			if (dowarn && !fsym->s_osdef) {
285 				/* TODO: error in C99 mode as well? */
286 				if (!allow_trad && !allow_c99)
287 					/* redeclaration of '%s' */
288 					error(27, fsym->s_name);
289 				else
290 					/* redeclaration of '%s' */
291 					warning(27, fsym->s_name);
292 				print_previous_declaration(rdsym);
293 			}
294 
295 			copy_usage_info(fsym, rdsym);
296 
297 			/*
298 			 * If the old symbol was a prototype and the new one is
299 			 * none, overtake the position of the declaration of
300 			 * the prototype.
301 			 */
302 			if (fsym->s_osdef && rdsym->s_type->t_proto)
303 				fsym->s_def_pos = rdsym->s_def_pos;
304 
305 			complete_type(fsym, rdsym);
306 
307 			if (rdsym->s_inline)
308 				fsym->s_inline = true;
309 		}
310 
311 		symtab_remove_forever(rdsym);
312 	}
313 
314 	if (fsym->s_osdef && !fsym->s_type->t_proto) {
315 		/* TODO: Make this an error in C99 mode as well. */
316 		if (!allow_trad && !allow_c99 && hflag &&
317 		    strcmp(fsym->s_name, "main") != 0)
318 			/* function definition is not a prototype */
319 			warning(286);
320 	}
321 
322 	if (dcs->d_no_type_specifier)
323 		fsym->s_return_type_implicit_int = true;
324 
325 	set_reached(true);
326 }
327 
328 static void
329 check_missing_return_value(void)
330 {
331 	if (funcsym->s_type->t_subt->t_tspec == VOID)
332 		return;
333 	if (funcsym->s_return_type_implicit_int)
334 		return;
335 
336 	/* C99 5.1.2.2.3 "Program termination" p1 */
337 	if (allow_c99 && strcmp(funcsym->s_name, "main") == 0)
338 		return;
339 
340 	/* function '%s' falls off bottom without returning value */
341 	warning(217, funcsym->s_name);
342 }
343 
344 void
345 end_function(void)
346 {
347 	if (reached) {
348 		cstmt->c_had_return_noval = true;
349 		check_missing_return_value();
350 	}
351 
352 	if (cstmt->c_had_return_noval && cstmt->c_had_return_value &&
353 	    funcsym->s_return_type_implicit_int)
354 		/* function '%s' has 'return expr' and 'return' */
355 		warning(216, funcsym->s_name);
356 
357 	/* Warn about unused parameters. */
358 	int n = nargusg;
359 	nargusg = -1;
360 	for (const sym_t *param = dcs->d_func_params;
361 	    param != NULL && n != 0; param = param->s_next, n--)
362 		check_usage_sym(dcs->d_asm, param);
363 
364 	if (dcs->d_scl == EXTERN && funcsym->s_inline)
365 		outsym(funcsym, funcsym->s_scl, DECL);
366 	else
367 		outfdef(funcsym, &dcs->d_func_def_pos,
368 		    cstmt->c_had_return_value, funcsym->s_osdef,
369 		    dcs->d_func_params);
370 
371 	/* clean up after syntax errors, see test stmt_for.c. */
372 	while (dcs->d_enclosing != NULL)
373 		dcs = dcs->d_enclosing;
374 
375 	lint_assert(dcs->d_enclosing == NULL);
376 	lint_assert(dcs->d_kind == DLK_EXTERN);
377 	symtab_remove_level(dcs->d_func_proto_syms);
378 
379 	/* must be set on level 0 */
380 	set_reached(true);
381 
382 	funcsym = NULL;
383 }
384 
385 void
386 named_label(sym_t *sym)
387 {
388 
389 	if (sym->s_set)
390 		/* label '%s' redefined */
391 		error(194, sym->s_name);
392 	else
393 		mark_as_set(sym);
394 
395 	/* XXX: Assuming that each label is reachable is wrong. */
396 	set_reached(true);
397 }
398 
399 static void
400 check_case_label_bitand(const tnode_t *case_expr, const tnode_t *switch_expr)
401 {
402 	if (switch_expr->tn_op != BITAND ||
403 	    switch_expr->u.ops.right->tn_op != CON)
404 		return;
405 
406 	lint_assert(case_expr->tn_op == CON);
407 	uint64_t case_value = (uint64_t)case_expr->u.value.u.integer;
408 	uint64_t mask = (uint64_t)switch_expr->u.ops.right->u.value.u.integer;
409 
410 	if ((case_value & ~mask) != 0)
411 		/* statement not reached */
412 		warning(193);
413 }
414 
415 static void
416 check_case_label_enum(const tnode_t *tn, const control_statement *cs)
417 {
418 	/* similar to typeok_enum in tree.c */
419 
420 	if (!(tn->tn_type->t_is_enum || cs->c_switch_type->t_is_enum))
421 		return;
422 	if (tn->tn_type->t_is_enum && cs->c_switch_type->t_is_enum &&
423 	    tn->tn_type->u.enumer == cs->c_switch_type->u.enumer)
424 		return;
425 
426 #if 0 /* not yet ready, see msg_130.c */
427 	/* enum type mismatch: '%s' '%s' '%s' */
428 	warning(130, type_name(cs->c_switch_type), op_name(EQ),
429 	    type_name(tn->tn_type));
430 #endif
431 }
432 
433 static bool
434 check_duplicate_case_label(control_statement *cs, const val_t *nv)
435 {
436 	case_labels *labels = &cs->c_case_labels;
437 	size_t i = 0, n = labels->len;
438 
439 	while (i < n && labels->vals[i].u.integer != nv->u.integer)
440 		i++;
441 
442 	if (i < n) {
443 		if (is_uinteger(nv->v_tspec))
444 			/* duplicate case '%ju' in switch */
445 			error(200, (uintmax_t)nv->u.integer);
446 		else
447 			/* duplicate case '%jd' in switch */
448 			error(199, (intmax_t)nv->u.integer);
449 		return false;
450 	}
451 
452 	if (labels->len >= labels->cap) {
453 		labels->cap = 16 + 2 * labels->cap;
454 		labels->vals = xrealloc(labels->vals,
455 		    sizeof(*labels->vals) * labels->cap);
456 	}
457 	labels->vals[labels->len++] = *nv;
458 	return true;
459 }
460 
461 static void
462 check_case_label(tnode_t *tn)
463 {
464 	control_statement *cs;
465 	for (cs = cstmt; cs != NULL && !cs->c_switch; cs = cs->c_surrounding)
466 		continue;
467 
468 	if (cs == NULL) {
469 		/* case not in switch */
470 		error(195);
471 		return;
472 	}
473 
474 	if (tn == NULL)
475 		return;
476 
477 	if (tn->tn_op != CON) {
478 		/* non-constant case expression */
479 		error(197);
480 		return;
481 	}
482 
483 	if (!is_integer(tn->tn_type->t_tspec)) {
484 		/* non-integral case expression */
485 		error(198);
486 		return;
487 	}
488 
489 	check_case_label_bitand(tn, cs->c_switch_expr);
490 	check_case_label_enum(tn, cs);
491 
492 	lint_assert(cs->c_switch_type != NULL);
493 
494 	if (reached && !suppress_fallthrough) {
495 		if (hflag)
496 			/* fallthrough on case statement */
497 			warning(220);
498 	}
499 
500 	tspec_t t = tn->tn_type->t_tspec;
501 	if ((t == LONG || t == ULONG || t == LLONG || t == ULLONG)
502 	    && !allow_c90)
503 		/* case label must be of type 'int' in traditional C */
504 		warning(203);
505 
506 	val_t *v = integer_constant(tn, true);
507 	val_t nv;
508 	(void)memset(&nv, 0, sizeof(nv));
509 	convert_constant(CASE, 0, cs->c_switch_type, &nv, v);
510 	free(v);
511 
512 	if (check_duplicate_case_label(cs, &nv))
513 		check_getopt_case_label(nv.u.integer);
514 }
515 
516 void
517 case_label(tnode_t *tn)
518 {
519 	check_case_label(tn);
520 	expr_free_all();
521 	set_reached(true);
522 }
523 
524 void
525 default_label(void)
526 {
527 	/* find the innermost switch statement */
528 	control_statement *cs;
529 	for (cs = cstmt; cs != NULL && !cs->c_switch; cs = cs->c_surrounding)
530 		continue;
531 
532 	if (cs == NULL)
533 		/* default outside switch */
534 		error(201);
535 	else if (cs->c_default)
536 		/* duplicate default in switch */
537 		error(202);
538 	else {
539 		if (reached && !suppress_fallthrough) {
540 			if (hflag)
541 				/* fallthrough on default statement */
542 				warning(284);
543 		}
544 		cs->c_default = true;
545 	}
546 
547 	set_reached(true);
548 }
549 
550 static tnode_t *
551 check_controlling_expression(tnode_t *tn)
552 {
553 	tn = cconv(tn);
554 	if (tn != NULL)
555 		tn = promote(NOOP, false, tn);
556 
557 	if (tn != NULL && !is_scalar(tn->tn_type->t_tspec)) {
558 		/* C99 6.5.15p4 for the ?: operator; see typeok:QUEST */
559 		/* C99 6.8.4.1p1 for if statements */
560 		/* C99 6.8.5p2 for while, do and for loops */
561 		/* controlling expressions must have scalar type */
562 		error(204);
563 		return NULL;
564 	}
565 
566 	if (tn != NULL && Tflag && !is_typeok_bool_compares_with_zero(tn)) {
567 		/* controlling expression must be bool, not '%s' */
568 		error(333, tn->tn_type->t_is_enum ? type_name(tn->tn_type)
569 		    : tspec_name(tn->tn_type->t_tspec));
570 	}
571 
572 	return tn;
573 }
574 
575 void
576 stmt_if_expr(tnode_t *tn)
577 {
578 	if (tn != NULL)
579 		tn = check_controlling_expression(tn);
580 	if (tn != NULL)
581 		expr(tn, false, true, false, false);
582 	begin_control_statement(CS_IF);
583 
584 	if (tn != NULL && tn->tn_op == CON && !tn->tn_system_dependent) {
585 		/* XXX: what if inside 'if (0)'? */
586 		set_reached(constant_is_nonzero(tn));
587 		/* XXX: what about always_else? */
588 		cstmt->c_always_then = reached;
589 	}
590 }
591 
592 void
593 stmt_if_then_stmt(void)
594 {
595 	cstmt->c_reached_end_of_then = reached;
596 	/* XXX: what if inside 'if (0)'? */
597 	set_reached(!cstmt->c_always_then);
598 }
599 
600 void
601 stmt_if_else_stmt(bool els)
602 {
603 	if (cstmt->c_reached_end_of_then)
604 		set_reached(true);
605 	else if (cstmt->c_always_then)
606 		set_reached(false);
607 	else if (!els)
608 		set_reached(true);
609 
610 	end_control_statement(CS_IF);
611 }
612 
613 void
614 stmt_switch_expr(tnode_t *tn)
615 {
616 	if (tn != NULL)
617 		tn = cconv(tn);
618 	if (tn != NULL)
619 		tn = promote(NOOP, false, tn);
620 	if (tn != NULL && !is_integer(tn->tn_type->t_tspec)) {
621 		/* switch expression must have integral type */
622 		error(205);
623 		tn = NULL;
624 	}
625 	if (tn != NULL && !allow_c90) {
626 		tspec_t t = tn->tn_type->t_tspec;
627 		if (t == LONG || t == ULONG || t == LLONG || t == ULLONG)
628 			/* switch expression must be of type 'int' in ... */
629 			warning(271);
630 	}
631 
632 	/*
633 	 * Remember the type of the expression. Because it's possible that
634 	 * (*tp) is allocated on tree memory, the type must be duplicated. This
635 	 * is not too complicated because it is only an integer type.
636 	 */
637 	type_t *tp = xcalloc(1, sizeof(*tp));
638 	if (tn != NULL) {
639 		tp->t_tspec = tn->tn_type->t_tspec;
640 		if ((tp->t_is_enum = tn->tn_type->t_is_enum) != false)
641 			tp->u.enumer = tn->tn_type->u.enumer;
642 	} else {
643 		tp->t_tspec = INT;
644 	}
645 
646 	/* leak the memory, for check_case_label_bitand */
647 	(void)expr_save_memory();
648 
649 	check_getopt_begin_switch();
650 	expr(tn, true, false, false, false);
651 
652 	begin_control_statement(CS_SWITCH);
653 	cstmt->c_switch = true;
654 	cstmt->c_switch_type = tp;
655 	cstmt->c_switch_expr = tn;
656 
657 	set_reached(false);
658 	suppress_fallthrough = true;
659 }
660 
661 void
662 stmt_switch_expr_stmt(void)
663 {
664 	int nenum = 0, nclab = 0;
665 	sym_t *esym;
666 
667 	lint_assert(cstmt->c_switch_type != NULL);
668 
669 	if (cstmt->c_switch_type->t_is_enum) {
670 		/*
671 		 * Warn if the number of case labels is different from the
672 		 * number of enumerators.
673 		 */
674 		nenum = nclab = 0;
675 		lint_assert(cstmt->c_switch_type->u.enumer != NULL);
676 		for (esym = cstmt->c_switch_type->u.enumer->en_first_enumerator;
677 		    esym != NULL; esym = esym->s_next) {
678 			nenum++;
679 		}
680 		nclab = (int)cstmt->c_case_labels.len;
681 		if (hflag && eflag && nclab < nenum && !cstmt->c_default)
682 			/* enumeration value(s) not handled in switch */
683 			warning(206);
684 	}
685 
686 	check_getopt_end_switch();
687 
688 	if (cstmt->c_break) {
689 		/*
690 		 * The end of the switch statement is always reached since
691 		 * c_break is only set if a break statement can actually be
692 		 * reached.
693 		 */
694 		set_reached(true);
695 	} else if (cstmt->c_default ||
696 		   (hflag && cstmt->c_switch_type->t_is_enum &&
697 		    nenum == nclab)) {
698 		/*
699 		 * The end of the switch statement is reached if the end of the
700 		 * last statement inside it is reached.
701 		 */
702 	} else {
703 		/*
704 		 * There are possible values that are not handled in the switch
705 		 * statement.
706 		 */
707 		set_reached(true);
708 	}
709 
710 	end_control_statement(CS_SWITCH);
711 }
712 
713 void
714 stmt_while_expr(tnode_t *tn)
715 {
716 	if (!reached) {
717 		/* loop not entered at top */
718 		warning(207);
719 		/* FIXME: that's plain wrong. */
720 		set_reached(true);
721 	}
722 
723 	if (tn != NULL)
724 		tn = check_controlling_expression(tn);
725 
726 	begin_control_statement(CS_WHILE);
727 	cstmt->c_loop = true;
728 	cstmt->c_maybe_endless = is_nonzero(tn);
729 	bool body_reached = !is_zero(tn);
730 
731 	check_getopt_begin_while(tn);
732 	expr(tn, false, true, true, false);
733 
734 	set_reached(body_reached);
735 }
736 
737 void
738 stmt_while_expr_stmt(void)
739 {
740 	set_reached(!cstmt->c_maybe_endless || cstmt->c_break);
741 	check_getopt_end_while();
742 	end_control_statement(CS_WHILE);
743 }
744 
745 void
746 stmt_do(void)
747 {
748 	if (!reached) {
749 		/* loop not entered at top */
750 		warning(207);
751 		set_reached(true);
752 	}
753 
754 	begin_control_statement(CS_DO_WHILE);
755 	cstmt->c_loop = true;
756 }
757 
758 void
759 stmt_do_while_expr(tnode_t *tn)
760 {
761 	if (cstmt->c_continue)
762 		set_reached(true);
763 
764 	if (tn != NULL)
765 		tn = check_controlling_expression(tn);
766 
767 	if (tn != NULL && tn->tn_op == CON) {
768 		cstmt->c_maybe_endless = constant_is_nonzero(tn);
769 		if (!cstmt->c_maybe_endless && cstmt->c_continue)
770 			/* continue in 'do ... while (0)' loop */
771 			error(323);
772 	}
773 
774 	expr(tn, false, true, true, true);
775 
776 	if (cstmt->c_maybe_endless)
777 		set_reached(false);
778 	if (cstmt->c_break)
779 		set_reached(true);
780 
781 	end_control_statement(CS_DO_WHILE);
782 }
783 
784 void
785 stmt_for_exprs(tnode_t *tn1, tnode_t *tn2, tnode_t *tn3)
786 {
787 	/*
788 	 * If there is no initialization expression it is possible that it is
789 	 * intended not to enter the loop at top.
790 	 */
791 	if (tn1 != NULL && !reached) {
792 		/* loop not entered at top */
793 		warning(207);
794 		set_reached(true);
795 	}
796 
797 	begin_control_statement(CS_FOR);
798 	cstmt->c_loop = true;
799 
800 	/*
801 	 * Store the tree memory for the reinitialization expression. Also
802 	 * remember this expression itself. We must check it at the end of the
803 	 * loop to get "used but not set" warnings correct.
804 	 */
805 	cstmt->c_for_expr3_mem = expr_save_memory();
806 	cstmt->c_for_expr3 = tn3;
807 	cstmt->c_for_expr3_pos = curr_pos;
808 	cstmt->c_for_expr3_csrc_pos = csrc_pos;
809 
810 	if (tn1 != NULL)
811 		expr(tn1, false, false, true, false);
812 
813 	if (tn2 != NULL)
814 		tn2 = check_controlling_expression(tn2);
815 	if (tn2 != NULL)
816 		expr(tn2, false, true, true, false);
817 
818 	cstmt->c_maybe_endless = tn2 == NULL || is_nonzero(tn2);
819 
820 	/* The tn3 expression is checked in stmt_for_exprs_stmt. */
821 
822 	set_reached(!is_zero(tn2));
823 }
824 
825 void
826 stmt_for_exprs_stmt(void)
827 {
828 	if (cstmt->c_continue)
829 		set_reached(true);
830 
831 	expr_restore_memory(cstmt->c_for_expr3_mem);
832 	tnode_t *tn3 = cstmt->c_for_expr3;
833 
834 	pos_t saved_curr_pos = curr_pos;
835 	pos_t saved_csrc_pos = csrc_pos;
836 	curr_pos = cstmt->c_for_expr3_pos;
837 	csrc_pos = cstmt->c_for_expr3_csrc_pos;
838 
839 	/* simply "statement not reached" would be confusing */
840 	if (!reached && warn_about_unreachable) {
841 		/* end-of-loop code not reached */
842 		warning(223);
843 		set_reached(true);
844 	}
845 
846 	if (tn3 != NULL)
847 		expr(tn3, false, false, true, false);
848 	else
849 		expr_free_all();
850 
851 	curr_pos = saved_curr_pos;
852 	csrc_pos = saved_csrc_pos;
853 
854 	set_reached(cstmt->c_break || !cstmt->c_maybe_endless);
855 
856 	end_control_statement(CS_FOR);
857 }
858 
859 void
860 stmt_goto(sym_t *lab)
861 {
862 	mark_as_used(lab, false, false);
863 	check_statement_reachable();
864 	set_reached(false);
865 }
866 
867 void
868 stmt_break(void)
869 {
870 	control_statement *cs = cstmt;
871 	while (cs != NULL && !cs->c_loop && !cs->c_switch)
872 		cs = cs->c_surrounding;
873 
874 	if (cs == NULL)
875 		/* break outside loop or switch */
876 		error(208);
877 	else if (reached)
878 		cs->c_break = true;
879 
880 	if (bflag)
881 		check_statement_reachable();
882 
883 	set_reached(false);
884 }
885 
886 void
887 stmt_continue(void)
888 {
889 	control_statement *cs;
890 
891 	for (cs = cstmt; cs != NULL && !cs->c_loop; cs = cs->c_surrounding)
892 		continue;
893 
894 	if (cs == NULL)
895 		/* continue outside loop */
896 		error(209);
897 	else
898 		/* TODO: only if reachable, for symmetry with c_break */
899 		cs->c_continue = true;
900 
901 	check_statement_reachable();
902 
903 	set_reached(false);
904 }
905 
906 static bool
907 is_parenthesized(const tnode_t *tn)
908 {
909 	while (!tn->tn_parenthesized && tn->tn_op == COMMA)
910 		tn = tn->u.ops.right;
911 	return tn->tn_parenthesized && !tn->tn_sys;
912 }
913 
914 static void
915 check_return_value(bool sys, tnode_t *tn)
916 {
917 	if (any_query_enabled && is_parenthesized(tn)) {
918 		/* parenthesized return value */
919 		query_message(9);
920 	}
921 
922 	/* Create a temporary node for the left side */
923 	tnode_t *ln = expr_zero_alloc(sizeof(*ln), "tnode");
924 	ln->tn_op = NAME;
925 	ln->tn_type = expr_unqualified_type(funcsym->s_type->t_subt);
926 	ln->tn_lvalue = true;
927 	ln->u.sym = funcsym;	/* better than nothing */
928 
929 	tnode_t *retn = build_binary(ln, RETURN, sys, tn);
930 
931 	if (retn != NULL) {
932 		const tnode_t *rn = retn->u.ops.right;
933 		while (rn->tn_op == CVT || rn->tn_op == PLUS)
934 			rn = rn->u.ops.left;
935 		if (rn->tn_op == ADDR && rn->u.ops.left->tn_op == NAME &&
936 		    rn->u.ops.left->u.sym->s_scl == AUTO)
937 			/* '%s' returns pointer to automatic object */
938 			warning(302, funcsym->s_name);
939 	}
940 
941 	expr(retn, true, false, true, false);
942 }
943 
944 void
945 stmt_return(bool sys, tnode_t *tn)
946 {
947 	control_statement *cs = cstmt;
948 
949 	if (cs == NULL) {
950 		/* syntax error '%s' */
951 		error(249, "return outside function");
952 		return;
953 	}
954 
955 	for (; cs->c_surrounding != NULL; cs = cs->c_surrounding)
956 		continue;
957 
958 	if (tn != NULL)
959 		cs->c_had_return_value = true;
960 	else
961 		cs->c_had_return_noval = true;
962 
963 	if (tn != NULL && funcsym->s_type->t_subt->t_tspec == VOID) {
964 		/* void function '%s' cannot return value */
965 		error(213, funcsym->s_name);
966 		expr_free_all();
967 		tn = NULL;
968 	}
969 	if (tn == NULL && funcsym->s_type->t_subt->t_tspec != VOID
970 	    && !funcsym->s_return_type_implicit_int) {
971 		if (allow_c99)
972 			/* function '%s' expects to return value */
973 			error(214, funcsym->s_name);
974 		else
975 			/* function '%s' expects to return value */
976 			warning(214, funcsym->s_name);
977 	}
978 
979 	if (tn != NULL)
980 		check_return_value(sys, tn);
981 	else
982 		check_statement_reachable();
983 
984 	set_reached(false);
985 }
986 
987 void
988 global_clean_up_decl(bool silent)
989 {
990 	if (nargusg != -1) {
991 		if (!silent)
992 			/* comment ** %s ** must precede function definition */
993 			warning_at(282, &argsused_pos, "ARGSUSED");
994 		nargusg = -1;
995 	}
996 	if (nvararg != -1) {
997 		if (!silent)
998 			/* comment ** %s ** must precede function definition */
999 			warning_at(282, &vapos, "VARARGS");
1000 		nvararg = -1;
1001 	}
1002 	if (printflike_argnum != -1) {
1003 		if (!silent)
1004 			/* comment ** %s ** must precede function definition */
1005 			warning_at(282, &printflike_pos, "PRINTFLIKE");
1006 		printflike_argnum = -1;
1007 	}
1008 	if (scanflike_argnum != -1) {
1009 		if (!silent)
1010 			/* comment ** %s ** must precede function definition */
1011 			warning_at(282, &scanflike_pos, "SCANFLIKE");
1012 		scanflike_argnum = -1;
1013 	}
1014 
1015 	dcs->d_asm = false;
1016 
1017 	/*
1018 	 * Needed for BSD yacc in case of parse errors; GNU Bison 3.0.4 is
1019 	 * fine.  See test gcc_attribute.c, function_with_unknown_attribute.
1020 	 */
1021 	in_gcc_attribute = false;
1022 	while (dcs->d_enclosing != NULL)
1023 		end_declaration_level();
1024 }
1025 
1026 /*
1027  * Only the first n parameters of the following function are checked for usage.
1028  * A missing argument is taken to be 0.
1029  */
1030 static void
1031 argsused(int n)
1032 {
1033 	if (dcs->d_kind != DLK_EXTERN) {
1034 		/* comment ** %s ** must be outside function */
1035 		warning(280, "ARGSUSED");
1036 		return;
1037 	}
1038 	if (nargusg != -1)
1039 		/* duplicate comment ** %s ** */
1040 		warning(281, "ARGSUSED");
1041 	nargusg = n != -1 ? n : 0;
1042 	argsused_pos = curr_pos;
1043 }
1044 
1045 static void
1046 varargs(int n)
1047 {
1048 	if (dcs->d_kind != DLK_EXTERN) {
1049 		/* comment ** %s ** must be outside function */
1050 		warning(280, "VARARGS");
1051 		return;
1052 	}
1053 	if (nvararg != -1)
1054 		/* duplicate comment ** %s ** */
1055 		warning(281, "VARARGS");
1056 	nvararg = n != -1 ? n : 0;
1057 	vapos = curr_pos;
1058 }
1059 
1060 /*
1061  * Check all parameters until the (n-1)-th as usual. The n-th argument is
1062  * used to check the types of the remaining arguments.
1063  */
1064 static void
1065 printflike(int n)
1066 {
1067 	if (dcs->d_kind != DLK_EXTERN) {
1068 		/* comment ** %s ** must be outside function */
1069 		warning(280, "PRINTFLIKE");
1070 		return;
1071 	}
1072 	if (printflike_argnum != -1)
1073 		/* duplicate comment ** %s ** */
1074 		warning(281, "PRINTFLIKE");
1075 	printflike_argnum = n != -1 ? n : 0;
1076 	printflike_pos = curr_pos;
1077 }
1078 
1079 /*
1080  * Check all parameters until the (n-1)-th as usual. The n-th argument is
1081  * used the check the types of remaining arguments.
1082  */
1083 static void
1084 scanflike(int n)
1085 {
1086 	if (dcs->d_kind != DLK_EXTERN) {
1087 		/* comment ** %s ** must be outside function */
1088 		warning(280, "SCANFLIKE");
1089 		return;
1090 	}
1091 	if (scanflike_argnum != -1)
1092 		/* duplicate comment ** %s ** */
1093 		warning(281, "SCANFLIKE");
1094 	scanflike_argnum = n != -1 ? n : 0;
1095 	scanflike_pos = curr_pos;
1096 }
1097 
1098 static void
1099 lintlib(void)
1100 {
1101 	if (dcs->d_kind != DLK_EXTERN) {
1102 		/* comment ** %s ** must be outside function */
1103 		warning(280, "LINTLIBRARY");
1104 		return;
1105 	}
1106 	llibflg = true;
1107 	vflag = true;
1108 }
1109 
1110 /*
1111  * PROTOLIB in conjunction with LINTLIBRARY can be used to handle
1112  * prototypes like function definitions. This is done if the argument
1113  * to PROTOLIB is nonzero. Otherwise, prototypes are handled normally.
1114  */
1115 static void
1116 protolib(int n)
1117 {
1118 	if (dcs->d_kind != DLK_EXTERN) {
1119 		/* comment ** %s ** must be outside function */
1120 		warning(280, "PROTOLIB");
1121 		return;
1122 	}
1123 	plibflg = n != 0;
1124 }
1125 
1126 void
1127 handle_lint_comment(lint_comment comment, int arg)
1128 {
1129 	switch (comment) {
1130 	case LC_ARGSUSED:	argsused(arg);			break;
1131 	case LC_BITFIELDTYPE:	suppress_bitfieldtype = true;	break;
1132 	case LC_CONSTCOND:	suppress_constcond = true;	break;
1133 	case LC_FALLTHROUGH:	suppress_fallthrough = true;	break;
1134 	case LC_LINTLIBRARY:	lintlib();			break;
1135 	case LC_LINTED:		debug_step("set lwarn %d", arg);
1136 				lwarn = arg;			break;
1137 	case LC_LONGLONG:	suppress_longlong = true;	break;
1138 	case LC_NOTREACHED:	set_reached(false);
1139 				warn_about_unreachable = false;	break;
1140 	case LC_PRINTFLIKE:	printflike(arg);		break;
1141 	case LC_PROTOLIB:	protolib(arg);			break;
1142 	case LC_SCANFLIKE:	scanflike(arg);			break;
1143 	case LC_VARARGS:	varargs(arg);			break;
1144 	}
1145 }
1146