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