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