1 /* $NetBSD: func.c,v 1.196 2025/09/14 11:14:00 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.196 2025/09/14 11:14:00 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 ? expr_type_name(tn) 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 /* FIXME: that's plain wrong. */ 715 set_reached(true); 716 } 717 718 if (tn != NULL) 719 tn = check_controlling_expression(tn, false); 720 721 begin_control_statement(CS_WHILE); 722 cstmt->c_loop = true; 723 cstmt->c_maybe_endless = is_nonzero(tn); 724 bool body_reached = !is_zero(tn); 725 726 check_getopt_begin_while(tn); 727 expr(tn, false, true, true, false, "while"); 728 729 set_reached(body_reached); 730 } 731 732 void 733 stmt_while_expr_stmt(void) 734 { 735 set_reached(!cstmt->c_maybe_endless || cstmt->c_break); 736 check_getopt_end_while(); 737 end_control_statement(CS_WHILE); 738 } 739 740 void 741 stmt_do(void) 742 { 743 if (!reached) 744 set_reached(true); 745 746 begin_control_statement(CS_DO_WHILE); 747 cstmt->c_loop = true; 748 } 749 750 void 751 stmt_do_while_expr(tnode_t *tn) 752 { 753 if (cstmt->c_continue) 754 set_reached(true); 755 756 if (tn != NULL) 757 tn = check_controlling_expression(tn, true); 758 759 if (tn != NULL && tn->tn_op == CON) { 760 cstmt->c_maybe_endless = constant_is_nonzero(tn); 761 if (!cstmt->c_maybe_endless && cstmt->c_continue) 762 /* continue in 'do ... while (0)' loop */ 763 error(323); 764 } 765 766 expr(tn, false, true, true, true, "do-while"); 767 768 if (cstmt->c_maybe_endless) 769 set_reached(false); 770 if (cstmt->c_break) 771 set_reached(true); 772 773 end_control_statement(CS_DO_WHILE); 774 } 775 776 void 777 stmt_for_exprs(tnode_t *tn1, tnode_t *tn2, tnode_t *tn3) 778 { 779 /* 780 * If there is no initialization expression it is possible that it is 781 * intended not to enter the loop at top. 782 */ 783 if (tn1 != NULL && !reached) 784 set_reached(true); 785 786 begin_control_statement(CS_FOR); 787 cstmt->c_loop = true; 788 789 /* 790 * Store the tree memory for the reinitialization expression. Also 791 * remember this expression itself. We must check it at the end of the 792 * loop to get "used but not set" warnings correct. 793 */ 794 cstmt->c_for_expr3_mem = expr_save_memory(); 795 cstmt->c_for_expr3 = tn3; 796 cstmt->c_for_expr3_pos = curr_pos; 797 cstmt->c_for_expr3_csrc_pos = csrc_pos; 798 799 if (tn1 != NULL) 800 expr(tn1, false, false, true, false, "for"); 801 802 if (tn2 != NULL) 803 tn2 = check_controlling_expression(tn2, false); 804 if (tn2 != NULL) 805 expr(tn2, false, true, true, false, "for"); 806 807 cstmt->c_maybe_endless = tn2 == NULL || is_nonzero(tn2); 808 809 /* The tn3 expression is checked in stmt_for_exprs_stmt. */ 810 811 set_reached(!is_zero(tn2)); 812 } 813 814 void 815 stmt_for_exprs_stmt(void) 816 { 817 if (cstmt->c_continue) 818 set_reached(true); 819 820 expr_restore_memory(cstmt->c_for_expr3_mem); 821 tnode_t *tn3 = cstmt->c_for_expr3; 822 823 pos_t saved_curr_pos = curr_pos; 824 pos_t saved_csrc_pos = csrc_pos; 825 curr_pos = cstmt->c_for_expr3_pos; 826 csrc_pos = cstmt->c_for_expr3_csrc_pos; 827 828 /* simply "statement not reached" would be confusing */ 829 if (!reached && warn_about_unreachable) { 830 /* end-of-loop code not reached */ 831 warning(223); 832 set_reached(true); 833 } 834 835 if (tn3 != NULL) 836 expr(tn3, false, false, true, false, "for continuation"); 837 else 838 expr_free_all(); 839 840 curr_pos = saved_curr_pos; 841 csrc_pos = saved_csrc_pos; 842 843 set_reached(cstmt->c_break || !cstmt->c_maybe_endless); 844 845 end_control_statement(CS_FOR); 846 } 847 848 void 849 stmt_goto(sym_t *lab) 850 { 851 mark_as_used(lab, false, false); 852 check_statement_reachable("goto"); 853 set_reached(false); 854 } 855 856 void 857 stmt_break(void) 858 { 859 control_statement *cs = cstmt; 860 while (cs != NULL && !cs->c_loop && !cs->c_switch) 861 cs = cs->c_surrounding; 862 863 if (cs == NULL) 864 /* break outside loop or switch */ 865 error(208); 866 else if (reached) 867 cs->c_break = true; 868 869 if (bflag) 870 check_statement_reachable("break"); 871 872 set_reached(false); 873 } 874 875 void 876 stmt_continue(void) 877 { 878 control_statement *cs; 879 880 for (cs = cstmt; cs != NULL && !cs->c_loop; cs = cs->c_surrounding) 881 continue; 882 883 if (cs == NULL) 884 /* continue outside loop */ 885 error(209); 886 else 887 /* TODO: only if reachable, for symmetry with c_break */ 888 cs->c_continue = true; 889 890 check_statement_reachable("continue"); 891 892 set_reached(false); 893 } 894 895 void 896 stmt_call_noreturn(void) 897 { 898 set_reached(false); 899 } 900 901 static bool 902 is_parenthesized(const tnode_t *tn) 903 { 904 while (!tn->tn_parenthesized && tn->tn_op == COMMA) 905 tn = tn->u.ops.right; 906 return tn->tn_parenthesized && !tn->tn_sys; 907 } 908 909 static void 910 check_return_value(bool sys, tnode_t *tn) 911 { 912 if (any_query_enabled && is_parenthesized(tn)) 913 /* parenthesized return value */ 914 query_message(9); 915 916 /* Create a temporary node for the left side */ 917 tnode_t *ln = expr_zero_alloc(sizeof(*ln), "tnode"); 918 ln->tn_op = NAME; 919 ln->tn_type = expr_unqualified_type(funcsym->s_type->t_subt); 920 ln->tn_lvalue = true; 921 ln->u.sym = funcsym; /* better than nothing */ 922 923 tnode_t *retn = build_binary(ln, RETURN, sys, tn); 924 925 if (retn != NULL) { 926 const tnode_t *rn = retn->u.ops.right; 927 while (rn->tn_op == CVT || rn->tn_op == PLUS) 928 rn = rn->u.ops.left; 929 if (rn->tn_op == ADDR && rn->u.ops.left->tn_op == NAME && 930 rn->u.ops.left->u.sym->s_scl == AUTO) 931 /* '%s' returns pointer to automatic object */ 932 warning(302, funcsym->s_name); 933 } 934 935 expr(retn, true, false, true, false, "return"); 936 } 937 938 void 939 stmt_return(bool sys, tnode_t *tn) 940 { 941 control_statement *cs = cstmt; 942 943 if (cs == NULL) { 944 /* syntax error '%s' */ 945 error(249, "return outside function"); 946 return; 947 } 948 949 for (; cs->c_surrounding != NULL; cs = cs->c_surrounding) 950 continue; 951 952 if (tn != NULL) 953 cs->c_had_return_value = true; 954 else 955 cs->c_had_return_noval = true; 956 957 if (tn != NULL && funcsym->s_type->t_subt->t_tspec == VOID) { 958 /* void function '%s' cannot return value */ 959 error(213, funcsym->s_name); 960 expr_free_all(); 961 tn = NULL; 962 } 963 if (tn == NULL && funcsym->s_type->t_subt->t_tspec != VOID 964 && !funcsym->s_return_type_implicit_int) { 965 if (allow_c99) 966 /* function '%s' expects to return value */ 967 error(214, funcsym->s_name); 968 else 969 /* function '%s' expects to return value */ 970 warning(214, funcsym->s_name); 971 } 972 973 if (tn != NULL) 974 check_return_value(sys, tn); 975 else 976 check_statement_reachable("return"); 977 978 set_reached(false); 979 } 980 981 void 982 global_clean_up_decl(bool silent) 983 { 984 if (nargusg != -1) { 985 if (!silent) 986 /* comment ** %s ** must precede function definition */ 987 warning_at(282, &argsused_pos, "ARGSUSED"); 988 nargusg = -1; 989 } 990 if (nvararg != -1) { 991 if (!silent) 992 /* comment ** %s ** must precede function definition */ 993 warning_at(282, &vapos, "VARARGS"); 994 nvararg = -1; 995 } 996 if (printflike_argnum != -1) { 997 if (!silent) 998 /* comment ** %s ** must precede function definition */ 999 warning_at(282, &printflike_pos, "PRINTFLIKE"); 1000 printflike_argnum = -1; 1001 } 1002 if (scanflike_argnum != -1) { 1003 if (!silent) 1004 /* comment ** %s ** must precede function definition */ 1005 warning_at(282, &scanflike_pos, "SCANFLIKE"); 1006 scanflike_argnum = -1; 1007 } 1008 1009 dcs->d_asm = false; 1010 1011 /* 1012 * Needed for BSD yacc in case of parse errors; GNU Bison 3.0.4 is 1013 * fine. See test gcc_attribute.c, function_with_unknown_attribute. 1014 */ 1015 in_gcc_attribute = false; 1016 while (dcs->d_enclosing != NULL) 1017 end_declaration_level(); 1018 } 1019 1020 /* 1021 * Only the first n parameters of the following function are checked for usage. 1022 * A missing argument is taken to be 0. 1023 */ 1024 static void 1025 argsused(int n) 1026 { 1027 if (dcs->d_kind != DLK_EXTERN) { 1028 /* comment ** %s ** must be outside function */ 1029 warning(280, "ARGSUSED"); 1030 return; 1031 } 1032 if (nargusg != -1) 1033 /* duplicate comment ** %s ** */ 1034 warning(281, "ARGSUSED"); 1035 nargusg = n != -1 ? n : 0; 1036 argsused_pos = curr_pos; 1037 } 1038 1039 static void 1040 varargs(int n) 1041 { 1042 if (dcs->d_kind != DLK_EXTERN) { 1043 /* comment ** %s ** must be outside function */ 1044 warning(280, "VARARGS"); 1045 return; 1046 } 1047 if (nvararg != -1) 1048 /* duplicate comment ** %s ** */ 1049 warning(281, "VARARGS"); 1050 nvararg = n != -1 ? n : 0; 1051 vapos = curr_pos; 1052 } 1053 1054 /* 1055 * Check all parameters until the (n-1)-th as usual. The n-th argument is 1056 * used to check the types of the remaining arguments. 1057 */ 1058 static void 1059 printflike(int n) 1060 { 1061 if (dcs->d_kind != DLK_EXTERN) { 1062 /* comment ** %s ** must be outside function */ 1063 warning(280, "PRINTFLIKE"); 1064 return; 1065 } 1066 if (printflike_argnum != -1) 1067 /* duplicate comment ** %s ** */ 1068 warning(281, "PRINTFLIKE"); 1069 printflike_argnum = n != -1 ? n : 0; 1070 printflike_pos = curr_pos; 1071 } 1072 1073 /* 1074 * Check all parameters until the (n-1)-th as usual. The n-th argument is 1075 * used the check the types of remaining arguments. 1076 */ 1077 static void 1078 scanflike(int n) 1079 { 1080 if (dcs->d_kind != DLK_EXTERN) { 1081 /* comment ** %s ** must be outside function */ 1082 warning(280, "SCANFLIKE"); 1083 return; 1084 } 1085 if (scanflike_argnum != -1) 1086 /* duplicate comment ** %s ** */ 1087 warning(281, "SCANFLIKE"); 1088 scanflike_argnum = n != -1 ? n : 0; 1089 scanflike_pos = curr_pos; 1090 } 1091 1092 static void 1093 lintlib(void) 1094 { 1095 if (dcs->d_kind != DLK_EXTERN) { 1096 /* comment ** %s ** must be outside function */ 1097 warning(280, "LINTLIBRARY"); 1098 return; 1099 } 1100 llibflg = true; 1101 vflag = true; 1102 } 1103 1104 /* 1105 * PROTOLIB in conjunction with LINTLIBRARY can be used to handle 1106 * prototypes like function definitions. This is done if the argument 1107 * to PROTOLIB is nonzero. Otherwise, prototypes are handled normally. 1108 */ 1109 static void 1110 protolib(int n) 1111 { 1112 if (dcs->d_kind != DLK_EXTERN) { 1113 /* comment ** %s ** must be outside function */ 1114 warning(280, "PROTOLIB"); 1115 return; 1116 } 1117 plibflg = n != 0; 1118 } 1119 1120 void 1121 handle_lint_comment(lint_comment comment, int arg) 1122 { 1123 switch (comment) { 1124 case LC_ARGSUSED: argsused(arg); break; 1125 case LC_BITFIELDTYPE: suppress_bitfieldtype = true; break; 1126 case LC_FALLTHROUGH: suppress_fallthrough = true; break; 1127 case LC_LINTLIBRARY: lintlib(); break; 1128 case LC_LINTED: debug_step("set lwarn %d", arg); 1129 lwarn = arg; break; 1130 case LC_LONGLONG: suppress_longlong = true; break; 1131 case LC_NOTREACHED: set_reached(false); 1132 warn_about_unreachable = false; break; 1133 case LC_PRINTFLIKE: printflike(arg); break; 1134 case LC_PROTOLIB: protolib(arg); break; 1135 case LC_SCANFLIKE: scanflike(arg); break; 1136 case LC_VARARGS: varargs(arg); break; 1137 } 1138 } 1139