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
begin_control_statement(control_statement_kind kind)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
end_control_statement(control_statement_kind kind)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
set_reached(bool new_reached)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
check_statement_reachable(const char * stmt_kind)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
begin_function(sym_t * fsym)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
check_missing_return_value(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
end_function(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
named_label(sym_t * sym)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
check_case_label_bitand(const tnode_t * case_expr,const tnode_t * switch_expr)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
check_case_label_enum(const tnode_t * tn,const control_statement * cs)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
check_duplicate_case_label(control_statement * cs,const val_t * nv)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
check_case_label(tnode_t * tn)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
case_label(tnode_t * tn)513 case_label(tnode_t *tn)
514 {
515           check_case_label(tn);
516           expr_free_all();
517           set_reached(true);
518 }
519 
520 void
default_label(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 *
check_controlling_expression(tnode_t * tn,bool is_do_while)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
stmt_if_expr(tnode_t * tn)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
stmt_if_then_stmt(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
stmt_if_else_stmt(bool els)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
stmt_switch_expr(tnode_t * tn)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
stmt_switch_expr_stmt(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
stmt_while_expr(tnode_t * tn)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
stmt_while_expr_stmt(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
stmt_do(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
stmt_do_while_expr(tnode_t * tn)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
stmt_for_exprs(tnode_t * tn1,tnode_t * tn2,tnode_t * tn3)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
stmt_for_exprs_stmt(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
stmt_goto(sym_t * lab)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
stmt_break(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
stmt_continue(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
stmt_call_noreturn(void)904 stmt_call_noreturn(void)
905 {
906           set_reached(false);
907 }
908 
909 static bool
is_parenthesized(const tnode_t * tn)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
check_return_value(bool sys,tnode_t * tn)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
stmt_return(bool sys,tnode_t * tn)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
global_clean_up_decl(bool silent)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
argsused(int n)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
varargs(int n)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
printflike(int n)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
scanflike(int n)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
lintlib(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
protolib(int n)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
handle_lint_comment(lint_comment comment,int arg)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