1 /* $NetBSD: func.c,v 1.197 2026/01/10 19:50:40 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.197 2026/01/10 19:50:40 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 == NULL || 399 switch_expr->tn_op != BITAND || 400 switch_expr->u.ops.right->tn_op != CON) 401 return; 402 403 lint_assert(case_expr->tn_op == CON); 404 uint64_t case_value = (uint64_t)case_expr->u.value.u.integer; 405 uint64_t mask = (uint64_t)switch_expr->u.ops.right->u.value.u.integer; 406 407 if ((case_value & ~mask) != 0) 408 /* '%s' statement not reached */ 409 warning(193, "case"); 410 } 411 412 static void 413 check_case_label_enum(const tnode_t *tn, const control_statement *cs) 414 { 415 /* similar to typeok_enum in tree.c */ 416 417 if (!(tn->tn_type->t_is_enum || cs->c_switch_type->t_is_enum)) 418 return; 419 if (tn->tn_type->t_is_enum && cs->c_switch_type->t_is_enum && 420 tn->tn_type->u.enumer == cs->c_switch_type->u.enumer) 421 return; 422 423 #if 0 /* not yet ready, see msg_130.c */ 424 /* enum type mismatch: '%s' '%s' '%s' */ 425 warning(130, type_name(cs->c_switch_type), op_name(EQ), 426 type_name(tn->tn_type)); 427 #endif 428 } 429 430 static bool 431 check_duplicate_case_label(control_statement *cs, const val_t *nv) 432 { 433 case_labels *labels = &cs->c_case_labels; 434 size_t i = 0, n = labels->len; 435 436 while (i < n && labels->vals[i].u.integer != nv->u.integer) 437 i++; 438 439 if (i < n) { 440 if (is_uinteger(nv->v_tspec)) 441 /* duplicate case '%ju' in switch */ 442 error(200, (uintmax_t)nv->u.integer); 443 else 444 /* duplicate case '%jd' in switch */ 445 error(199, (intmax_t)nv->u.integer); 446 return false; 447 } 448 449 if (labels->len >= labels->cap) { 450 labels->cap = 16 + 2 * labels->cap; 451 labels->vals = xrealloc(labels->vals, 452 sizeof(*labels->vals) * labels->cap); 453 } 454 labels->vals[labels->len++] = *nv; 455 return true; 456 } 457 458 static void 459 check_case_label(tnode_t *tn) 460 { 461 control_statement *cs; 462 for (cs = cstmt; cs != NULL && !cs->c_switch; cs = cs->c_surrounding) 463 continue; 464 465 if (cs == NULL) { 466 /* case not in switch */ 467 error(195); 468 return; 469 } 470 471 if (tn == NULL) 472 return; 473 474 if (tn->tn_op != CON) { 475 /* non-constant case expression */ 476 error(197); 477 return; 478 } 479 480 if (!is_integer(tn->tn_type->t_tspec)) { 481 /* non-integral case expression */ 482 error(198); 483 return; 484 } 485 486 check_case_label_bitand(tn, cs->c_switch_expr); 487 check_case_label_enum(tn, cs); 488 489 lint_assert(cs->c_switch_type != NULL); 490 491 if (reached && !suppress_fallthrough) { 492 if (hflag) 493 /* fallthrough on case statement */ 494 warning(220); 495 } 496 497 tspec_t t = tn->tn_type->t_tspec; 498 if ((t == LONG || t == ULONG || t == LLONG || t == ULLONG) 499 && !allow_c90) 500 /* case label must be of type 'int' in traditional C */ 501 warning(203); 502 503 val_t *v = integer_constant(tn, true); 504 val_t nv; 505 (void)memset(&nv, 0, sizeof(nv)); 506 convert_constant(CASE, 0, cs->c_switch_type, &nv, v); 507 free(v); 508 509 if (check_duplicate_case_label(cs, &nv)) 510 check_getopt_case_label(nv.u.integer); 511 } 512 513 void 514 case_label(tnode_t *tn) 515 { 516 check_case_label(tn); 517 expr_free_all(); 518 set_reached(true); 519 } 520 521 void 522 default_label(void) 523 { 524 /* find the innermost switch statement */ 525 control_statement *cs; 526 for (cs = cstmt; cs != NULL && !cs->c_switch; cs = cs->c_surrounding) 527 continue; 528 529 if (cs == NULL) 530 /* default outside switch */ 531 error(201); 532 else if (cs->c_default) 533 /* duplicate default in switch */ 534 error(202); 535 else { 536 if (reached && !suppress_fallthrough) { 537 if (hflag) 538 /* fallthrough on default statement */ 539 warning(284); 540 } 541 cs->c_default = true; 542 } 543 544 set_reached(true); 545 } 546 547 static tnode_t * 548 check_controlling_expression(tnode_t *tn, bool is_do_while) 549 { 550 tn = cconv(tn); 551 if (tn != NULL) 552 tn = promote(NOOP, false, tn); 553 554 if (tn != NULL && !is_scalar(tn->tn_type->t_tspec)) { 555 /* C99 6.5.15p4 for the ?: operator; see typeok:QUEST */ 556 /* C99 6.8.4.1p1 for if statements */ 557 /* C99 6.8.5p2 for while, do and for loops */ 558 /* controlling expressions must have scalar type */ 559 error(204); 560 return NULL; 561 } 562 563 if (tn != NULL && Tflag 564 && !is_typeok_bool_compares_with_zero(tn, is_do_while)) { 565 /* controlling expression must be bool, not '%s' */ 566 error(333, tn->tn_type->t_is_enum ? expr_type_name(tn) 567 : tspec_name(tn->tn_type->t_tspec)); 568 } 569 570 return tn; 571 } 572 573 void 574 stmt_if_expr(tnode_t *tn) 575 { 576 if (tn != NULL) 577 tn = check_controlling_expression(tn, false); 578 if (tn != NULL) 579 expr(tn, false, true, false, false, "if"); 580 begin_control_statement(CS_IF); 581 582 if (tn != NULL && tn->tn_op == CON && !tn->tn_system_dependent) { 583 /* XXX: what if inside 'if (0)'? */ 584 set_reached(constant_is_nonzero(tn)); 585 /* XXX: what about always_else? */ 586 cstmt->c_always_then = reached; 587 } 588 } 589 590 void 591 stmt_if_then_stmt(void) 592 { 593 cstmt->c_reached_end_of_then = reached; 594 /* XXX: what if inside 'if (0)'? */ 595 set_reached(!cstmt->c_always_then); 596 } 597 598 void 599 stmt_if_else_stmt(bool els) 600 { 601 if (cstmt->c_reached_end_of_then) 602 set_reached(true); 603 else if (cstmt->c_always_then) 604 set_reached(false); 605 else if (!els) 606 set_reached(true); 607 608 end_control_statement(CS_IF); 609 } 610 611 void 612 stmt_switch_expr(tnode_t *tn) 613 { 614 if (tn != NULL) 615 tn = cconv(tn); 616 if (tn != NULL) 617 tn = promote(NOOP, false, tn); 618 if (tn != NULL && !is_integer(tn->tn_type->t_tspec)) { 619 /* switch expression must have integral type, not '%s' */ 620 error(205, type_name(tn->tn_type)); 621 tn = NULL; 622 } 623 if (tn != NULL && !allow_c90) { 624 tspec_t t = tn->tn_type->t_tspec; 625 if (t == LONG || t == ULONG || t == LLONG || t == ULLONG) 626 /* switch expression must be of type 'int' in ... */ 627 warning(271); 628 } 629 630 /* 631 * Remember the type of the expression. Because it's possible that 632 * (*tp) is allocated on tree memory, the type must be duplicated. This 633 * is not too complicated because it is only an integer type. 634 */ 635 type_t *tp = xcalloc(1, sizeof(*tp)); 636 if (tn != NULL) { 637 tp->t_tspec = tn->tn_type->t_tspec; 638 if ((tp->t_is_enum = tn->tn_type->t_is_enum) != false) 639 tp->u.enumer = tn->tn_type->u.enumer; 640 } else { 641 tp->t_tspec = INT; 642 } 643 644 /* leak the memory, for check_case_label_bitand */ 645 (void)expr_save_memory(); 646 647 check_getopt_begin_switch(); 648 expr(tn, true, false, false, false, "switch"); 649 650 begin_control_statement(CS_SWITCH); 651 cstmt->c_switch = true; 652 cstmt->c_switch_type = tp; 653 cstmt->c_switch_expr = tn; 654 655 set_reached(false); 656 suppress_fallthrough = true; 657 } 658 659 void 660 stmt_switch_expr_stmt(void) 661 { 662 int nenum = 0, nclab = 0; 663 sym_t *esym; 664 665 lint_assert(cstmt->c_switch_type != NULL); 666 667 if (cstmt->c_switch_type->t_is_enum) { 668 /* 669 * Warn if the number of case labels is different from the 670 * number of enumerators. 671 */ 672 nenum = nclab = 0; 673 lint_assert(cstmt->c_switch_type->u.enumer != NULL); 674 for (esym = cstmt->c_switch_type->u.enumer->en_first_enumerator; 675 esym != NULL; esym = esym->s_next) { 676 nenum++; 677 } 678 nclab = (int)cstmt->c_case_labels.len; 679 if (hflag && eflag && nclab < nenum && !cstmt->c_default) 680 /* enumeration value(s) not handled in switch */ 681 warning(206); 682 } 683 684 check_getopt_end_switch(); 685 686 if (cstmt->c_break) { 687 /* 688 * The end of the switch statement is always reached since 689 * c_break is only set if a break statement can actually be 690 * reached. 691 */ 692 set_reached(true); 693 } else if (cstmt->c_default || 694 (hflag && cstmt->c_switch_type->t_is_enum && 695 nenum == nclab)) { 696 /* 697 * The end of the switch statement is reached if the end of the 698 * last statement inside it is reached. 699 */ 700 } else { 701 /* 702 * There are possible values that are not handled in the switch 703 * statement. 704 */ 705 set_reached(true); 706 } 707 708 end_control_statement(CS_SWITCH); 709 } 710 711 void 712 stmt_while_expr(tnode_t *tn) 713 { 714 if (!reached) { 715 /* FIXME: that's plain wrong. */ 716 set_reached(true); 717 } 718 719 if (tn != NULL) 720 tn = check_controlling_expression(tn, false); 721 722 begin_control_statement(CS_WHILE); 723 cstmt->c_loop = true; 724 cstmt->c_maybe_endless = is_nonzero(tn); 725 bool body_reached = !is_zero(tn); 726 727 check_getopt_begin_while(tn); 728 expr(tn, false, true, true, false, "while"); 729 730 set_reached(body_reached); 731 } 732 733 void 734 stmt_while_expr_stmt(void) 735 { 736 set_reached(!cstmt->c_maybe_endless || cstmt->c_break); 737 check_getopt_end_while(); 738 end_control_statement(CS_WHILE); 739 } 740 741 void 742 stmt_do(void) 743 { 744 if (!reached) 745 set_reached(true); 746 747 begin_control_statement(CS_DO_WHILE); 748 cstmt->c_loop = true; 749 } 750 751 void 752 stmt_do_while_expr(tnode_t *tn) 753 { 754 if (cstmt->c_continue) 755 set_reached(true); 756 757 if (tn != NULL) 758 tn = check_controlling_expression(tn, true); 759 760 if (tn != NULL && tn->tn_op == CON) { 761 cstmt->c_maybe_endless = constant_is_nonzero(tn); 762 if (!cstmt->c_maybe_endless && cstmt->c_continue) 763 /* continue in 'do ... while (0)' loop */ 764 error(323); 765 } 766 767 expr(tn, false, true, true, true, "do-while"); 768 769 if (cstmt->c_maybe_endless) 770 set_reached(false); 771 if (cstmt->c_break) 772 set_reached(true); 773 774 end_control_statement(CS_DO_WHILE); 775 } 776 777 void 778 stmt_for_exprs(tnode_t *tn1, tnode_t *tn2, tnode_t *tn3) 779 { 780 /* 781 * If there is no initialization expression it is possible that it is 782 * intended not to enter the loop at top. 783 */ 784 if (tn1 != NULL && !reached) 785 set_reached(true); 786 787 begin_control_statement(CS_FOR); 788 cstmt->c_loop = true; 789 790 /* 791 * Store the tree memory for the reinitialization expression. Also 792 * remember this expression itself. We must check it at the end of the 793 * loop to get "used but not set" warnings correct. 794 */ 795 cstmt->c_for_expr3_mem = expr_save_memory(); 796 cstmt->c_for_expr3 = tn3; 797 cstmt->c_for_expr3_pos = curr_pos; 798 cstmt->c_for_expr3_csrc_pos = csrc_pos; 799 800 if (tn1 != NULL) 801 expr(tn1, false, false, true, false, "for"); 802 803 if (tn2 != NULL) 804 tn2 = check_controlling_expression(tn2, false); 805 if (tn2 != NULL) 806 expr(tn2, false, true, true, false, "for"); 807 808 cstmt->c_maybe_endless = tn2 == NULL || is_nonzero(tn2); 809 810 /* The tn3 expression is checked in stmt_for_exprs_stmt. */ 811 812 set_reached(!is_zero(tn2)); 813 } 814 815 void 816 stmt_for_exprs_stmt(void) 817 { 818 if (cstmt->c_continue) 819 set_reached(true); 820 821 expr_restore_memory(cstmt->c_for_expr3_mem); 822 tnode_t *tn3 = cstmt->c_for_expr3; 823 824 pos_t saved_curr_pos = curr_pos; 825 pos_t saved_csrc_pos = csrc_pos; 826 curr_pos = cstmt->c_for_expr3_pos; 827 csrc_pos = cstmt->c_for_expr3_csrc_pos; 828 829 /* simply "statement not reached" would be confusing */ 830 if (!reached && warn_about_unreachable) { 831 /* end-of-loop code not reached */ 832 warning(223); 833 set_reached(true); 834 } 835 836 if (tn3 != NULL) 837 expr(tn3, false, false, true, false, "for continuation"); 838 else 839 expr_free_all(); 840 841 curr_pos = saved_curr_pos; 842 csrc_pos = saved_csrc_pos; 843 844 set_reached(cstmt->c_break || !cstmt->c_maybe_endless); 845 846 end_control_statement(CS_FOR); 847 } 848 849 void 850 stmt_goto(sym_t *lab) 851 { 852 mark_as_used(lab, false, false); 853 check_statement_reachable("goto"); 854 set_reached(false); 855 } 856 857 void 858 stmt_break(void) 859 { 860 control_statement *cs = cstmt; 861 while (cs != NULL && !cs->c_loop && !cs->c_switch) 862 cs = cs->c_surrounding; 863 864 if (cs == NULL) 865 /* break outside loop or switch */ 866 error(208); 867 else if (reached) 868 cs->c_break = true; 869 870 if (bflag) 871 check_statement_reachable("break"); 872 873 set_reached(false); 874 } 875 876 void 877 stmt_continue(void) 878 { 879 control_statement *cs; 880 881 for (cs = cstmt; cs != NULL && !cs->c_loop; cs = cs->c_surrounding) 882 continue; 883 884 if (cs == NULL) 885 /* continue outside loop */ 886 error(209); 887 else 888 /* TODO: only if reachable, for symmetry with c_break */ 889 cs->c_continue = true; 890 891 check_statement_reachable("continue"); 892 893 set_reached(false); 894 } 895 896 void 897 stmt_call_noreturn(void) 898 { 899 set_reached(false); 900 } 901 902 static bool 903 is_parenthesized(const tnode_t *tn) 904 { 905 while (!tn->tn_parenthesized && tn->tn_op == COMMA) 906 tn = tn->u.ops.right; 907 return tn->tn_parenthesized && !tn->tn_sys; 908 } 909 910 static void 911 check_return_value(bool sys, tnode_t *tn) 912 { 913 if (any_query_enabled && is_parenthesized(tn)) 914 /* parenthesized return value */ 915 query_message(9); 916 917 /* Create a temporary node for the left side */ 918 tnode_t *ln = expr_zero_alloc(sizeof(*ln), "tnode"); 919 ln->tn_op = NAME; 920 ln->tn_type = expr_unqualified_type(funcsym->s_type->t_subt); 921 ln->tn_lvalue = true; 922 ln->u.sym = funcsym; /* better than nothing */ 923 924 tnode_t *retn = build_binary(ln, RETURN, sys, tn); 925 926 if (retn != NULL) { 927 const tnode_t *rn = retn->u.ops.right; 928 while (rn->tn_op == CVT || rn->tn_op == PLUS) 929 rn = rn->u.ops.left; 930 if (rn->tn_op == ADDR && rn->u.ops.left->tn_op == NAME && 931 rn->u.ops.left->u.sym->s_scl == AUTO) 932 /* '%s' returns pointer to automatic object */ 933 warning(302, funcsym->s_name); 934 } 935 936 expr(retn, true, false, true, false, "return"); 937 } 938 939 void 940 stmt_return(bool sys, tnode_t *tn) 941 { 942 control_statement *cs = cstmt; 943 944 if (cs == NULL) { 945 /* syntax error '%s' */ 946 error(249, "return outside function"); 947 return; 948 } 949 950 for (; cs->c_surrounding != NULL; cs = cs->c_surrounding) 951 continue; 952 953 if (tn != NULL) 954 cs->c_had_return_value = true; 955 else 956 cs->c_had_return_noval = true; 957 958 if (tn != NULL && funcsym->s_type->t_subt->t_tspec == VOID) { 959 /* void function '%s' cannot return value */ 960 error(213, funcsym->s_name); 961 expr_free_all(); 962 tn = NULL; 963 } 964 if (tn == NULL && funcsym->s_type->t_subt->t_tspec != VOID 965 && !funcsym->s_return_type_implicit_int) { 966 if (allow_c99) 967 /* function '%s' expects to return value */ 968 error(214, funcsym->s_name); 969 else 970 /* function '%s' expects to return value */ 971 warning(214, funcsym->s_name); 972 } 973 974 if (tn != NULL) 975 check_return_value(sys, tn); 976 else 977 check_statement_reachable("return"); 978 979 set_reached(false); 980 } 981 982 void 983 global_clean_up_decl(bool silent) 984 { 985 if (nargusg != -1) { 986 if (!silent) 987 /* comment ** %s ** must precede function definition */ 988 warning_at(282, &argsused_pos, "ARGSUSED"); 989 nargusg = -1; 990 } 991 if (nvararg != -1) { 992 if (!silent) 993 /* comment ** %s ** must precede function definition */ 994 warning_at(282, &vapos, "VARARGS"); 995 nvararg = -1; 996 } 997 if (printflike_argnum != -1) { 998 if (!silent) 999 /* comment ** %s ** must precede function definition */ 1000 warning_at(282, &printflike_pos, "PRINTFLIKE"); 1001 printflike_argnum = -1; 1002 } 1003 if (scanflike_argnum != -1) { 1004 if (!silent) 1005 /* comment ** %s ** must precede function definition */ 1006 warning_at(282, &scanflike_pos, "SCANFLIKE"); 1007 scanflike_argnum = -1; 1008 } 1009 1010 dcs->d_asm = false; 1011 1012 /* 1013 * Needed for BSD yacc in case of parse errors; GNU Bison 3.0.4 is 1014 * fine. See test gcc_attribute.c, function_with_unknown_attribute. 1015 */ 1016 in_gcc_attribute = false; 1017 while (dcs->d_enclosing != NULL) 1018 end_declaration_level(); 1019 } 1020 1021 /* 1022 * Only the first n parameters of the following function are checked for usage. 1023 * A missing argument is taken to be 0. 1024 */ 1025 static void 1026 argsused(int n) 1027 { 1028 if (dcs->d_kind != DLK_EXTERN) { 1029 /* comment ** %s ** must be outside function */ 1030 warning(280, "ARGSUSED"); 1031 return; 1032 } 1033 if (nargusg != -1) 1034 /* duplicate comment ** %s ** */ 1035 warning(281, "ARGSUSED"); 1036 nargusg = n != -1 ? n : 0; 1037 argsused_pos = curr_pos; 1038 } 1039 1040 static void 1041 varargs(int n) 1042 { 1043 if (dcs->d_kind != DLK_EXTERN) { 1044 /* comment ** %s ** must be outside function */ 1045 warning(280, "VARARGS"); 1046 return; 1047 } 1048 if (nvararg != -1) 1049 /* duplicate comment ** %s ** */ 1050 warning(281, "VARARGS"); 1051 nvararg = n != -1 ? n : 0; 1052 vapos = curr_pos; 1053 } 1054 1055 /* 1056 * Check all parameters until the (n-1)-th as usual. The n-th argument is 1057 * used to check the types of the remaining arguments. 1058 */ 1059 static void 1060 printflike(int n) 1061 { 1062 if (dcs->d_kind != DLK_EXTERN) { 1063 /* comment ** %s ** must be outside function */ 1064 warning(280, "PRINTFLIKE"); 1065 return; 1066 } 1067 if (printflike_argnum != -1) 1068 /* duplicate comment ** %s ** */ 1069 warning(281, "PRINTFLIKE"); 1070 printflike_argnum = n != -1 ? n : 0; 1071 printflike_pos = curr_pos; 1072 } 1073 1074 /* 1075 * Check all parameters until the (n-1)-th as usual. The n-th argument is 1076 * used the check the types of remaining arguments. 1077 */ 1078 static void 1079 scanflike(int n) 1080 { 1081 if (dcs->d_kind != DLK_EXTERN) { 1082 /* comment ** %s ** must be outside function */ 1083 warning(280, "SCANFLIKE"); 1084 return; 1085 } 1086 if (scanflike_argnum != -1) 1087 /* duplicate comment ** %s ** */ 1088 warning(281, "SCANFLIKE"); 1089 scanflike_argnum = n != -1 ? n : 0; 1090 scanflike_pos = curr_pos; 1091 } 1092 1093 static void 1094 lintlib(void) 1095 { 1096 if (dcs->d_kind != DLK_EXTERN) { 1097 /* comment ** %s ** must be outside function */ 1098 warning(280, "LINTLIBRARY"); 1099 return; 1100 } 1101 llibflg = true; 1102 vflag = true; 1103 } 1104 1105 /* 1106 * PROTOLIB in conjunction with LINTLIBRARY can be used to handle 1107 * prototypes like function definitions. This is done if the argument 1108 * to PROTOLIB is nonzero. Otherwise, prototypes are handled normally. 1109 */ 1110 static void 1111 protolib(int n) 1112 { 1113 if (dcs->d_kind != DLK_EXTERN) { 1114 /* comment ** %s ** must be outside function */ 1115 warning(280, "PROTOLIB"); 1116 return; 1117 } 1118 plibflg = n != 0; 1119 } 1120 1121 void 1122 handle_lint_comment(lint_comment comment, int arg) 1123 { 1124 switch (comment) { 1125 case LC_ARGSUSED: argsused(arg); break; 1126 case LC_BITFIELDTYPE: suppress_bitfieldtype = true; break; 1127 case LC_FALLTHROUGH: suppress_fallthrough = true; break; 1128 case LC_LINTLIBRARY: lintlib(); break; 1129 case LC_LINTED: debug_step("set lwarn %d", arg); 1130 lwarn = arg; break; 1131 case LC_LONGLONG: suppress_longlong = true; break; 1132 case LC_NOTREACHED: set_reached(false); 1133 warn_about_unreachable = false; break; 1134 case LC_PRINTFLIKE: printflike(arg); break; 1135 case LC_PROTOLIB: protolib(arg); break; 1136 case LC_SCANFLIKE: scanflike(arg); break; 1137 case LC_VARARGS: varargs(arg); break; 1138 } 1139 } 1140