1 /* $NetBSD: func.c,v 1.14 2001/05/28 12:40:37 lukem 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 #include <sys/cdefs.h> 35 #ifndef lint 36 __RCSID("$NetBSD: func.c,v 1.14 2001/05/28 12:40:37 lukem Exp $"); 37 #endif 38 39 #include <stdlib.h> 40 #include <string.h> 41 42 #include "lint1.h" 43 #include "cgram.h" 44 45 /* 46 * Contains a pointer to the symbol table entry of the current function 47 * definition. 48 */ 49 sym_t *funcsym; 50 51 /* Is set as long as a statement can be reached. Must be set at level 0. */ 52 int reached = 1; 53 54 /* 55 * Is set as long as NOTREACHED is in effect. 56 * Is reset everywhere where reached can become 0. 57 */ 58 int rchflg; 59 60 /* 61 * In conjunction with reached ontrols printing of "fallthrough on ..." 62 * warnings. 63 * Reset by each statement and set by FALLTHROUGH, switch (switch1()) 64 * and case (label()). 65 * 66 * Control statements if, for, while and switch do not reset ftflg because 67 * this must be done by the controled statement. At least for if this is 68 * important because ** FALLTHROUGH ** after "if (expr) stmnt" is evaluated 69 * befor the following token, wich causes reduction of above, is read. 70 * This means that ** FALLTHROUGH ** after "if ..." would always be ignored. 71 */ 72 int ftflg; 73 74 /* Top element of stack for control statements */ 75 cstk_t *cstk; 76 77 /* 78 * Number of arguments which will be checked for usage in following 79 * function definition. -1 stands for all arguments. 80 * 81 * The position of the last ARGSUSED comment is stored in aupos. 82 */ 83 int nargusg = -1; 84 pos_t aupos; 85 86 /* 87 * Number of arguments of the following function definition whose types 88 * shall be checked by lint2. -1 stands for all arguments. 89 * 90 * The position of the last VARARGS comment is stored in vapos. 91 */ 92 int nvararg = -1; 93 pos_t vapos; 94 95 /* 96 * Both prflstr and scflstrg contain the number of the argument which 97 * shall be used to check the types of remaining arguments (for PRINTFLIKE 98 * and SCANFLIKE). 99 * 100 * prflpos and scflpos are the positions of the last PRINTFLIKE or 101 * SCANFLIKE comment. 102 */ 103 int prflstrg = -1; 104 int scflstrg = -1; 105 pos_t prflpos; 106 pos_t scflpos; 107 108 /* 109 * Are both plibflg and llibflg set, prototypes are writen as function 110 * definitions to the output file. 111 */ 112 int plibflg; 113 114 /* 115 * Nonzero means that no warnings about constands in conditional 116 * context are printed. 117 */ 118 int ccflg; 119 120 /* 121 * llibflg is set if a lint library shall be created. The effect of 122 * llibflg is that all defined symbols are treated as used. 123 * (The LINTLIBRARY comment also resets vflag.) 124 */ 125 int llibflg; 126 127 /* 128 * Nonzero if warnings are suppressed by a LINTED directive 129 */ 130 int nowarn; 131 132 /* 133 * Nonzero if complaints about use of "long long" are suppressed in 134 * the next statement or declaration. 135 */ 136 int quadflg; 137 138 /* 139 * Puts a new element at the top of the stack used for control statements. 140 */ 141 void 142 pushctrl(int env) 143 { 144 cstk_t *ci; 145 146 ci = xcalloc(1, sizeof (cstk_t)); 147 ci->c_env = env; 148 ci->c_nxt = cstk; 149 cstk = ci; 150 } 151 152 /* 153 * Removes the top element of the stack used for control statements. 154 */ 155 void 156 popctrl(int env) 157 { 158 cstk_t *ci; 159 clst_t *cl; 160 161 if (cstk == NULL || cstk->c_env != env) 162 lerror("popctrl() 1"); 163 164 cstk = (ci = cstk)->c_nxt; 165 166 while ((cl = ci->c_clst) != NULL) { 167 ci->c_clst = cl->cl_nxt; 168 free(cl); 169 } 170 171 if (ci->c_swtype != NULL) 172 free(ci->c_swtype); 173 174 free(ci); 175 } 176 177 /* 178 * Prints a warning if a statement cannot be reached. 179 */ 180 void 181 chkreach(void) 182 { 183 if (!reached && !rchflg) { 184 /* statement not reached */ 185 warning(193); 186 reached = 1; 187 } 188 } 189 190 /* 191 * Called after a function declaration which introduces a function definition 192 * and before an (optional) old style argument declaration list. 193 * 194 * Puts all symbols declared in the Prototype or in an old style argument 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 funcdef(sym_t *fsym) 202 { 203 int n, warn; 204 sym_t *arg, *sym, *rdsym; 205 206 funcsym = fsym; 207 208 /* 209 * Put all symbols declared in the argument list back to the 210 * symbol table. 211 */ 212 for (sym = dcs->d_fpsyms; sym != NULL; sym = sym->s_dlnxt) { 213 if (sym->s_blklev != -1) { 214 if (sym->s_blklev != 1) 215 lerror("funcdef() 1"); 216 inssym(1, sym); 217 } 218 } 219 220 /* 221 * In osfunc() we did not know whether it is an old style function 222 * definition or only an old style declaration, if there are no 223 * arguments inside the argument list ("f()"). 224 */ 225 if (!fsym->s_type->t_proto && fsym->s_args == NULL) 226 fsym->s_osdef = 1; 227 228 chktyp(fsym); 229 230 /* 231 * chktyp() checks for almost all possible errors, but not for 232 * incomplete return values (these are allowed in declarations) 233 */ 234 if (fsym->s_type->t_subt->t_tspec != VOID && 235 incompl(fsym->s_type->t_subt)) { 236 /* cannot return incomplete type */ 237 error(67); 238 } 239 240 fsym->s_def = DEF; 241 242 if (fsym->s_scl == TYPEDEF) { 243 fsym->s_scl = EXTERN; 244 /* illegal storage class */ 245 error(8); 246 } 247 248 if (dcs->d_inline) 249 fsym->s_inline = 1; 250 251 /* 252 * Arguments in new style function declarations need a name. 253 * (void is already removed from the list of arguments) 254 */ 255 n = 1; 256 for (arg = fsym->s_type->t_args; arg != NULL; arg = arg->s_nxt) { 257 if (arg->s_scl == ABSTRACT) { 258 if (arg->s_name != unnamed) 259 lerror("funcdef() 2"); 260 /* formal parameter lacks name: param #%d */ 261 error(59, n); 262 } else { 263 if (arg->s_name == unnamed) 264 lerror("funcdef() 3"); 265 } 266 n++; 267 } 268 269 /* 270 * We must also remember the position. s_dpos is overwritten 271 * if this is an old style definition and we had already a 272 * prototype. 273 */ 274 STRUCT_ASSIGN(dcs->d_fdpos, fsym->s_dpos); 275 276 if ((rdsym = dcs->d_rdcsym) != NULL) { 277 278 if (!isredec(fsym, (warn = 0, &warn))) { 279 280 /* 281 * Print nothing if the newly defined function 282 * is defined in old style. A better warning will 283 * be printed in cluparg(). 284 */ 285 if (warn && !fsym->s_osdef) { 286 /* redeclaration of %s */ 287 (*(sflag ? error : warning))(27, fsym->s_name); 288 prevdecl(-1, rdsym); 289 } 290 291 /* copy usage information */ 292 cpuinfo(fsym, rdsym); 293 294 /* 295 * If the old symbol was a prototype and the new 296 * one is none, overtake the position of the 297 * declaration of the prototype. 298 */ 299 if (fsym->s_osdef && rdsym->s_type->t_proto) 300 STRUCT_ASSIGN(fsym->s_dpos, rdsym->s_dpos); 301 302 /* complete the type */ 303 compltyp(fsym, rdsym); 304 305 /* once a function is inline it remains inline */ 306 if (rdsym->s_inline) 307 fsym->s_inline = 1; 308 309 } 310 311 /* remove the old symbol from the symbol table */ 312 rmsym(rdsym); 313 314 } 315 316 if (fsym->s_osdef && !fsym->s_type->t_proto) { 317 if (sflag && hflag && strcmp(fsym->s_name, "main") != 0) 318 /* function definition is not a prototyp */ 319 warning(286); 320 } 321 322 if (dcs->d_notyp) 323 /* return value is implicitly declared to be int */ 324 fsym->s_rimpl = 1; 325 326 reached = 1; 327 } 328 329 /* 330 * Called at the end of a function definition. 331 */ 332 void 333 funcend(void) 334 { 335 sym_t *arg; 336 int n; 337 338 if (reached) { 339 cstk->c_noretval = 1; 340 if (funcsym->s_type->t_subt->t_tspec != VOID && 341 !funcsym->s_rimpl) { 342 /* func. %s falls off bottom without returning value */ 343 warning(217, funcsym->s_name); 344 } 345 } 346 347 /* 348 * This warning is printed only if the return value was implizitly 349 * declared to be int. Otherwise the wrong return statement 350 * has already printed a warning. 351 */ 352 if (cstk->c_noretval && cstk->c_retval && funcsym->s_rimpl) 353 /* function %s has return (e); and return; */ 354 warning(216, funcsym->s_name); 355 356 /* Print warnings for unused arguments */ 357 arg = dcs->d_fargs; 358 n = 0; 359 while (arg != NULL && (nargusg == -1 || n < nargusg)) { 360 chkusg1(dcs->d_asm, arg); 361 arg = arg->s_nxt; 362 n++; 363 } 364 nargusg = -1; 365 366 /* 367 * write the information about the function definition to the 368 * output file 369 * inline functions explicitely declared extern are written as 370 * declarations only. 371 */ 372 if (dcs->d_scl == EXTERN && funcsym->s_inline) { 373 outsym(funcsym, funcsym->s_scl, DECL); 374 } else { 375 outfdef(funcsym, &dcs->d_fdpos, cstk->c_retval, 376 funcsym->s_osdef, dcs->d_fargs); 377 } 378 379 /* 380 * remove all symbols declared during argument declaration from 381 * the symbol table 382 */ 383 if (dcs->d_nxt != NULL || dcs->d_ctx != EXTERN) 384 lerror("funcend() 1"); 385 rmsyms(dcs->d_fpsyms); 386 387 /* must be set on level 0 */ 388 reached = 1; 389 } 390 391 /* 392 * Process a label. 393 * 394 * typ type of the label (T_NAME, T_DEFAULT or T_CASE). 395 * sym symbol table entry of label if typ == T_NAME 396 * tn expression if typ == T_CASE 397 */ 398 void 399 label(int typ, sym_t *sym, tnode_t *tn) 400 { 401 cstk_t *ci; 402 clst_t *cl; 403 val_t *v; 404 val_t nv; 405 tspec_t t; 406 407 switch (typ) { 408 409 case T_NAME: 410 if (sym->s_set) { 411 /* label %s redefined */ 412 error(194, sym->s_name); 413 } else { 414 setsflg(sym); 415 } 416 break; 417 418 case T_CASE: 419 420 /* find the stack entry for the innermost switch statement */ 421 for (ci = cstk; ci != NULL && !ci->c_switch; ci = ci->c_nxt) 422 continue; 423 424 if (ci == NULL) { 425 /* case not in switch */ 426 error(195); 427 tn = NULL; 428 } else if (tn != NULL && tn->tn_op != CON) { 429 /* non-constant case expression */ 430 error(197); 431 tn = NULL; 432 } else if (tn != NULL && !isityp(tn->tn_type->t_tspec)) { 433 /* non-integral case expression */ 434 error(198); 435 tn = NULL; 436 } 437 438 if (tn != NULL) { 439 440 if (ci->c_swtype == NULL) 441 lerror("label() 1"); 442 443 if (reached && !ftflg) { 444 if (hflag) 445 /* fallthrough on case statement */ 446 warning(220); 447 } 448 449 t = tn->tn_type->t_tspec; 450 if (t == LONG || t == ULONG || 451 t == QUAD || t == UQUAD) { 452 if (tflag) 453 /* case label must be of type ... */ 454 warning(203); 455 } 456 457 /* 458 * get the value of the expression and convert it 459 * to the type of the switch expression 460 */ 461 v = constant(tn); 462 (void) memset(&nv, 0, sizeof nv); 463 cvtcon(CASE, 0, ci->c_swtype, &nv, v); 464 free(v); 465 466 /* look if we had this value already */ 467 for (cl = ci->c_clst; cl != NULL; cl = cl->cl_nxt) { 468 if (cl->cl_val.v_quad == nv.v_quad) 469 break; 470 } 471 if (cl != NULL && isutyp(nv.v_tspec)) { 472 /* duplicate case in switch, %lu */ 473 error(200, (u_long)nv.v_quad); 474 } else if (cl != NULL) { 475 /* duplicate case in switch, %ld */ 476 error(199, (long)nv.v_quad); 477 } else { 478 /* 479 * append the value to the list of 480 * case values 481 */ 482 cl = xcalloc(1, sizeof (clst_t)); 483 STRUCT_ASSIGN(cl->cl_val, nv); 484 cl->cl_nxt = ci->c_clst; 485 ci->c_clst = cl; 486 } 487 } 488 tfreeblk(); 489 break; 490 491 case T_DEFAULT: 492 493 /* find the stack entry for the innermost switch statement */ 494 for (ci = cstk; ci != NULL && !ci->c_switch; ci = ci->c_nxt) 495 continue; 496 497 if (ci == NULL) { 498 /* default outside switch */ 499 error(201); 500 } else if (ci->c_default) { 501 /* duplicate default in switch */ 502 error(202); 503 } else { 504 if (reached && !ftflg) { 505 if (hflag) 506 /* fallthrough on default statement */ 507 warning(284); 508 } 509 ci->c_default = 1; 510 } 511 break; 512 }; 513 reached = 1; 514 } 515 516 /* 517 * T_IF T_LPARN expr T_RPARN 518 */ 519 void 520 if1(tnode_t *tn) 521 { 522 523 if (tn != NULL) 524 tn = cconv(tn); 525 if (tn != NULL) 526 tn = promote(NOOP, 0, tn); 527 expr(tn, 0, 1); 528 pushctrl(T_IF); 529 } 530 531 /* 532 * if_without_else 533 * if_without_else T_ELSE 534 */ 535 void 536 if2(void) 537 { 538 539 cstk->c_rchif = reached ? 1 : 0; 540 reached = 1; 541 } 542 543 /* 544 * if_without_else 545 * if_without_else T_ELSE stmnt 546 */ 547 void 548 if3(int els) 549 { 550 551 if (els) { 552 reached |= cstk->c_rchif; 553 } else { 554 reached = 1; 555 } 556 popctrl(T_IF); 557 } 558 559 /* 560 * T_SWITCH T_LPARN expr T_RPARN 561 */ 562 void 563 switch1(tnode_t *tn) 564 { 565 tspec_t t; 566 type_t *tp; 567 568 if (tn != NULL) 569 tn = cconv(tn); 570 if (tn != NULL) 571 tn = promote(NOOP, 0, tn); 572 if (tn != NULL && !isityp(tn->tn_type->t_tspec)) { 573 /* switch expression must have integral type */ 574 error(205); 575 tn = NULL; 576 } 577 if (tn != NULL && tflag) { 578 t = tn->tn_type->t_tspec; 579 if (t == LONG || t == ULONG || t == QUAD || t == UQUAD) { 580 /* switch expr. must be of type `int' in trad. C */ 581 warning(271); 582 } 583 } 584 585 /* 586 * Remember the type of the expression. Because its possible 587 * that (*tp) is allocated on tree memory the type must be 588 * duplicated. This is not too complicated because it is 589 * only an integer type. 590 */ 591 tp = xcalloc(1, sizeof (type_t)); 592 if (tn != NULL) { 593 tp->t_tspec = tn->tn_type->t_tspec; 594 if ((tp->t_isenum = tn->tn_type->t_isenum) != 0) 595 tp->t_enum = tn->tn_type->t_enum; 596 } else { 597 tp->t_tspec = INT; 598 } 599 600 expr(tn, 1, 0); 601 602 pushctrl(T_SWITCH); 603 cstk->c_switch = 1; 604 cstk->c_swtype = tp; 605 606 reached = rchflg = 0; 607 ftflg = 1; 608 } 609 610 /* 611 * switch_expr stmnt 612 */ 613 void 614 switch2(void) 615 { 616 int nenum = 0, nclab = 0; 617 sym_t *esym; 618 clst_t *cl; 619 620 if (cstk->c_swtype == NULL) 621 lerror("switch2() 1"); 622 623 /* 624 * If the switch expression was of type enumeration, count the case 625 * labels and the number of enumerators. If both counts are not 626 * equal print a warning. 627 */ 628 if (cstk->c_swtype->t_isenum) { 629 nenum = nclab = 0; 630 if (cstk->c_swtype->t_enum == NULL) 631 lerror("switch2() 2"); 632 for (esym = cstk->c_swtype->t_enum->elem; 633 esym != NULL; esym = esym->s_nxt) { 634 nenum++; 635 } 636 for (cl = cstk->c_clst; cl != NULL; cl = cl->cl_nxt) 637 nclab++; 638 if (hflag && eflag && nenum != nclab && !cstk->c_default) { 639 /* enumeration value(s) not handled in switch */ 640 warning(206); 641 } 642 } 643 644 if (cstk->c_break) { 645 /* 646 * end of switch alway reached (c_break is only set if the 647 * break statement can be reached). 648 */ 649 reached = 1; 650 } else if (!cstk->c_default && 651 (!hflag || !cstk->c_swtype->t_isenum || nenum != nclab)) { 652 /* 653 * there are possible values which are not handled in 654 * switch 655 */ 656 reached = 1; 657 } /* 658 * otherwise the end of the switch expression is reached 659 * if the end of the last statement inside it is reached. 660 */ 661 662 popctrl(T_SWITCH); 663 } 664 665 /* 666 * T_WHILE T_LPARN expr T_RPARN 667 */ 668 void 669 while1(tnode_t *tn) 670 { 671 672 if (!reached) { 673 /* loop not entered at top */ 674 warning(207); 675 reached = 1; 676 } 677 678 if (tn != NULL) 679 tn = cconv(tn); 680 if (tn != NULL) 681 tn = promote(NOOP, 0, tn); 682 if (tn != NULL && !issclt(tn->tn_type->t_tspec)) { 683 /* controlling expressions must have scalar type */ 684 error(204); 685 tn = NULL; 686 } 687 688 pushctrl(T_WHILE); 689 cstk->c_loop = 1; 690 if (tn != NULL && tn->tn_op == CON) { 691 if (isityp(tn->tn_type->t_tspec)) { 692 cstk->c_infinite = tn->tn_val->v_quad != 0; 693 } else { 694 cstk->c_infinite = tn->tn_val->v_ldbl != 0.0; 695 } 696 } 697 698 expr(tn, 0, 1); 699 } 700 701 /* 702 * while_expr stmnt 703 * while_expr error 704 */ 705 void 706 while2(void) 707 { 708 709 /* 710 * The end of the loop can be reached if it is no endless loop 711 * or there was a break statement which was reached. 712 */ 713 reached = !cstk->c_infinite || cstk->c_break; 714 rchflg = 0; 715 716 popctrl(T_WHILE); 717 } 718 719 /* 720 * T_DO 721 */ 722 void 723 do1(void) 724 { 725 726 if (!reached) { 727 /* loop not entered at top */ 728 warning(207); 729 reached = 1; 730 } 731 732 pushctrl(T_DO); 733 cstk->c_loop = 1; 734 } 735 736 /* 737 * do stmnt do_while_expr 738 * do error 739 */ 740 void 741 do2(tnode_t *tn) 742 { 743 744 /* 745 * If there was a continue statement the expression controlling the 746 * loop is reached. 747 */ 748 if (cstk->c_cont) 749 reached = 1; 750 751 if (tn != NULL) 752 tn = cconv(tn); 753 if (tn != NULL) 754 tn = promote(NOOP, 0, tn); 755 if (tn != NULL && !issclt(tn->tn_type->t_tspec)) { 756 /* controlling expressions must have scalar type */ 757 error(204); 758 tn = NULL; 759 } 760 761 if (tn != NULL && tn->tn_op == CON) { 762 if (isityp(tn->tn_type->t_tspec)) { 763 cstk->c_infinite = tn->tn_val->v_quad != 0; 764 } else { 765 cstk->c_infinite = tn->tn_val->v_ldbl != 0.0; 766 } 767 } 768 769 expr(tn, 0, 1); 770 771 /* 772 * The end of the loop is only reached if it is no endless loop 773 * or there was a break statement which could be reached. 774 */ 775 reached = !cstk->c_infinite || cstk->c_break; 776 rchflg = 0; 777 778 popctrl(T_DO); 779 } 780 781 /* 782 * T_FOR T_LPARN opt_expr T_SEMI opt_expr T_SEMI opt_expr T_RPARN 783 */ 784 void 785 for1(tnode_t *tn1, tnode_t *tn2, tnode_t *tn3) 786 { 787 788 /* 789 * If there is no initialisation expression it is possible that 790 * it is intended not to enter the loop at top. 791 */ 792 if (tn1 != NULL && !reached) { 793 /* loop not entered at top */ 794 warning(207); 795 reached = 1; 796 } 797 798 pushctrl(T_FOR); 799 cstk->c_loop = 1; 800 801 /* 802 * Store the tree memory for the reinitialisation expression. 803 * Also remember this expression itself. We must check it at 804 * the end of the loop to get "used but not set" warnings correct. 805 */ 806 cstk->c_fexprm = tsave(); 807 cstk->c_f3expr = tn3; 808 STRUCT_ASSIGN(cstk->c_fpos, curr_pos); 809 STRUCT_ASSIGN(cstk->c_cfpos, csrc_pos); 810 811 if (tn1 != NULL) 812 expr(tn1, 0, 0); 813 814 if (tn2 != NULL) 815 tn2 = cconv(tn2); 816 if (tn2 != NULL) 817 tn2 = promote(NOOP, 0, tn2); 818 if (tn2 != NULL && !issclt(tn2->tn_type->t_tspec)) { 819 /* controlling expressions must have scalar type */ 820 error(204); 821 tn2 = NULL; 822 } 823 if (tn2 != NULL) 824 expr(tn2, 0, 1); 825 826 if (tn2 == NULL) { 827 cstk->c_infinite = 1; 828 } else if (tn2->tn_op == CON) { 829 if (isityp(tn2->tn_type->t_tspec)) { 830 cstk->c_infinite = tn2->tn_val->v_quad != 0; 831 } else { 832 cstk->c_infinite = tn2->tn_val->v_ldbl != 0.0; 833 } 834 } 835 836 /* Checking the reinitialisation expression is done in for2() */ 837 838 reached = 1; 839 } 840 841 /* 842 * for_exprs stmnt 843 * for_exprs error 844 */ 845 void 846 for2(void) 847 { 848 pos_t cpos, cspos; 849 tnode_t *tn3; 850 851 if (cstk->c_cont) 852 reached = 1; 853 854 STRUCT_ASSIGN(cpos, curr_pos); 855 STRUCT_ASSIGN(cspos, csrc_pos); 856 857 /* Restore the tree memory for the reinitialisation expression */ 858 trestor(cstk->c_fexprm); 859 tn3 = cstk->c_f3expr; 860 STRUCT_ASSIGN(curr_pos, cstk->c_fpos); 861 STRUCT_ASSIGN(csrc_pos, cstk->c_cfpos); 862 863 /* simply "statement not reached" would be confusing */ 864 if (!reached && !rchflg) { 865 /* end-of-loop code not reached */ 866 warning(223); 867 reached = 1; 868 } 869 870 if (tn3 != NULL) { 871 expr(tn3, 0, 0); 872 } else { 873 tfreeblk(); 874 } 875 876 STRUCT_ASSIGN(curr_pos, cpos); 877 STRUCT_ASSIGN(csrc_pos, cspos); 878 879 /* An endless loop without break will never terminate */ 880 reached = cstk->c_break || !cstk->c_infinite; 881 rchflg = 0; 882 883 popctrl(T_FOR); 884 } 885 886 /* 887 * T_GOTO identifier T_SEMI 888 * T_GOTO error T_SEMI 889 */ 890 void 891 dogoto(sym_t *lab) 892 { 893 894 setuflg(lab, 0, 0); 895 896 chkreach(); 897 898 reached = rchflg = 0; 899 } 900 901 /* 902 * T_BREAK T_SEMI 903 */ 904 void 905 dobreak(void) 906 { 907 cstk_t *ci; 908 909 ci = cstk; 910 while (ci != NULL && !ci->c_loop && !ci->c_switch) 911 ci = ci->c_nxt; 912 913 if (ci == NULL) { 914 /* break outside loop or switch */ 915 error(208); 916 } else { 917 if (reached) 918 ci->c_break = 1; 919 } 920 921 if (bflag) 922 chkreach(); 923 924 reached = rchflg = 0; 925 } 926 927 /* 928 * T_CONTINUE T_SEMI 929 */ 930 void 931 docont(void) 932 { 933 cstk_t *ci; 934 935 for (ci = cstk; ci != NULL && !ci->c_loop; ci = ci->c_nxt) 936 continue; 937 938 if (ci == NULL) { 939 /* continue outside loop */ 940 error(209); 941 } else { 942 ci->c_cont = 1; 943 } 944 945 chkreach(); 946 947 reached = rchflg = 0; 948 } 949 950 /* 951 * T_RETURN T_SEMI 952 * T_RETURN expr T_SEMI 953 */ 954 void 955 doreturn(tnode_t *tn) 956 { 957 tnode_t *ln, *rn; 958 cstk_t *ci; 959 op_t op; 960 961 for (ci = cstk; ci->c_nxt != NULL; ci = ci->c_nxt) 962 continue; 963 964 if (tn != NULL) { 965 ci->c_retval = 1; 966 } else { 967 ci->c_noretval = 1; 968 } 969 970 if (tn != NULL && funcsym->s_type->t_subt->t_tspec == VOID) { 971 /* void function %s cannot return value */ 972 error(213, funcsym->s_name); 973 tfreeblk(); 974 tn = NULL; 975 } else if (tn == NULL && funcsym->s_type->t_subt->t_tspec != VOID) { 976 /* 977 * Assume that the function has a return value only if it 978 * is explicitly declared. 979 */ 980 if (!funcsym->s_rimpl) 981 /* function %s expects to return value */ 982 warning(214, funcsym->s_name); 983 } 984 985 if (tn != NULL) { 986 987 /* Create a temporary node for the left side */ 988 ln = tgetblk(sizeof (tnode_t)); 989 ln->tn_op = NAME; 990 ln->tn_type = tduptyp(funcsym->s_type->t_subt); 991 ln->tn_type->t_const = 0; 992 ln->tn_lvalue = 1; 993 ln->tn_sym = funcsym; /* better than nothing */ 994 995 tn = build(RETURN, ln, tn); 996 997 if (tn != NULL) { 998 rn = tn->tn_right; 999 while ((op = rn->tn_op) == CVT || op == PLUS) 1000 rn = rn->tn_left; 1001 if (rn->tn_op == AMPER && rn->tn_left->tn_op == NAME && 1002 rn->tn_left->tn_sym->s_scl == AUTO) { 1003 /* %s returns pointer to automatic object */ 1004 warning(302, funcsym->s_name); 1005 } 1006 } 1007 1008 expr(tn, 1, 0); 1009 1010 } else { 1011 1012 chkreach(); 1013 1014 } 1015 1016 reached = rchflg = 0; 1017 } 1018 1019 /* 1020 * Do some cleanup after a global declaration or definition. 1021 * Especially remove informations about unused lint comments. 1022 */ 1023 void 1024 glclup(int silent) 1025 { 1026 pos_t cpos; 1027 1028 STRUCT_ASSIGN(cpos, curr_pos); 1029 1030 if (nargusg != -1) { 1031 if (!silent) { 1032 STRUCT_ASSIGN(curr_pos, aupos); 1033 /* must precede function definition: %s */ 1034 warning(282, "ARGSUSED"); 1035 } 1036 nargusg = -1; 1037 } 1038 if (nvararg != -1) { 1039 if (!silent) { 1040 STRUCT_ASSIGN(curr_pos, vapos); 1041 /* must precede function definition: %s */ 1042 warning(282, "VARARGS"); 1043 } 1044 nvararg = -1; 1045 } 1046 if (prflstrg != -1) { 1047 if (!silent) { 1048 STRUCT_ASSIGN(curr_pos, prflpos); 1049 /* must precede function definition: %s */ 1050 warning(282, "PRINTFLIKE"); 1051 } 1052 prflstrg = -1; 1053 } 1054 if (scflstrg != -1) { 1055 if (!silent) { 1056 STRUCT_ASSIGN(curr_pos, scflpos); 1057 /* must precede function definition: %s */ 1058 warning(282, "SCANFLIKE"); 1059 } 1060 scflstrg = -1; 1061 } 1062 1063 STRUCT_ASSIGN(curr_pos, cpos); 1064 1065 dcs->d_asm = 0; 1066 } 1067 1068 /* 1069 * ARGSUSED comment 1070 * 1071 * Only the first n arguments of the following function are checked 1072 * for usage. A missing argument is taken to be 0. 1073 */ 1074 void 1075 argsused(int n) 1076 { 1077 1078 if (n == -1) 1079 n = 0; 1080 1081 if (dcs->d_ctx != EXTERN) { 1082 /* must be outside function: ** %s ** */ 1083 warning(280, "ARGSUSED"); 1084 return; 1085 } 1086 if (nargusg != -1) { 1087 /* duplicate use of ** %s ** */ 1088 warning(281, "ARGSUSED"); 1089 } 1090 nargusg = n; 1091 STRUCT_ASSIGN(aupos, curr_pos); 1092 } 1093 1094 /* 1095 * VARARGS comment 1096 * 1097 * Makes that lint2 checks only the first n arguments for compatibility 1098 * to the function definition. A missing argument is taken to be 0. 1099 */ 1100 void 1101 varargs(int n) 1102 { 1103 1104 if (n == -1) 1105 n = 0; 1106 1107 if (dcs->d_ctx != EXTERN) { 1108 /* must be outside function: ** %s ** */ 1109 warning(280, "VARARGS"); 1110 return; 1111 } 1112 if (nvararg != -1) { 1113 /* duplicate use of ** %s ** */ 1114 warning(281, "VARARGS"); 1115 } 1116 nvararg = n; 1117 STRUCT_ASSIGN(vapos, curr_pos); 1118 } 1119 1120 /* 1121 * PRINTFLIKE comment 1122 * 1123 * Check all arguments until the (n-1)-th as usual. The n-th argument is 1124 * used the check the types of remaining arguments. 1125 */ 1126 void 1127 printflike(int n) 1128 { 1129 1130 if (n == -1) 1131 n = 0; 1132 1133 if (dcs->d_ctx != EXTERN) { 1134 /* must be outside function: ** %s ** */ 1135 warning(280, "PRINTFLIKE"); 1136 return; 1137 } 1138 if (prflstrg != -1) { 1139 /* duplicate use of ** %s ** */ 1140 warning(281, "PRINTFLIKE"); 1141 } 1142 prflstrg = n; 1143 STRUCT_ASSIGN(prflpos, curr_pos); 1144 } 1145 1146 /* 1147 * SCANFLIKE comment 1148 * 1149 * Check all arguments until the (n-1)-th as usual. The n-th argument is 1150 * used the check the types of remaining arguments. 1151 */ 1152 void 1153 scanflike(int n) 1154 { 1155 1156 if (n == -1) 1157 n = 0; 1158 1159 if (dcs->d_ctx != EXTERN) { 1160 /* must be outside function: ** %s ** */ 1161 warning(280, "SCANFLIKE"); 1162 return; 1163 } 1164 if (scflstrg != -1) { 1165 /* duplicate use of ** %s ** */ 1166 warning(281, "SCANFLIKE"); 1167 } 1168 scflstrg = n; 1169 STRUCT_ASSIGN(scflpos, curr_pos); 1170 } 1171 1172 /* 1173 * Set the linenumber for a CONSTCOND comment. At this and the following 1174 * line no warnings about constants in conditional contexts are printed. 1175 */ 1176 /* ARGSUSED */ 1177 void 1178 constcond(int n) 1179 { 1180 1181 ccflg = 1; 1182 } 1183 1184 /* 1185 * Suppress printing of "fallthrough on ..." warnings until next 1186 * statement. 1187 */ 1188 /* ARGSUSED */ 1189 void 1190 fallthru(int n) 1191 { 1192 1193 ftflg = 1; 1194 } 1195 1196 /* 1197 * Stop warnings about statements which cannot be reached. Also tells lint 1198 * that the following statements cannot be reached (e.g. after exit()). 1199 */ 1200 /* ARGSUSED */ 1201 void 1202 notreach(int n) 1203 { 1204 1205 reached = 0; 1206 rchflg = 1; 1207 } 1208 1209 /* ARGSUSED */ 1210 void 1211 lintlib(int n) 1212 { 1213 1214 if (dcs->d_ctx != EXTERN) { 1215 /* must be outside function: ** %s ** */ 1216 warning(280, "LINTLIBRARY"); 1217 return; 1218 } 1219 llibflg = 1; 1220 vflag = 0; 1221 } 1222 1223 /* 1224 * Suppress most warnings at the current and the following line. 1225 */ 1226 /* ARGSUSED */ 1227 void 1228 linted(int n) 1229 { 1230 1231 #ifdef DEBUG 1232 printf("%s, %d: nowarn = 1\n", curr_pos.p_file, curr_pos.p_line); 1233 #endif 1234 nowarn = 1; 1235 } 1236 1237 /* 1238 * PROTOTLIB in conjunction with LINTLIBRARY can be used to handle 1239 * prototypes like function definitions. This is done if the argument 1240 * to PROTOLIB is nonzero. Otherwise prototypes are handled normaly. 1241 */ 1242 void 1243 protolib(int n) 1244 { 1245 1246 if (dcs->d_ctx != EXTERN) { 1247 /* must be outside function: ** %s ** */ 1248 warning(280, "PROTOLIB"); 1249 return; 1250 } 1251 plibflg = n == 0 ? 0 : 1; 1252 } 1253 1254 /* 1255 * Set quadflg to nonzero which means that the next statement/declaration 1256 * may use "long long" without an error or warning. 1257 */ 1258 /* ARGSUSED */ 1259 void 1260 longlong(int n) 1261 { 1262 1263 quadflg = 1; 1264 } 1265