1 /* $NetBSD: func.c,v 1.7 1995/10/02 17:31:40 jpo 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 #ifndef lint 35 static char rcsid[] = "$NetBSD: func.c,v 1.7 1995/10/02 17:31:40 jpo Exp $"; 36 #endif 37 38 #include <stdlib.h> 39 #include <string.h> 40 41 #include "lint1.h" 42 #include "y.tab.h" 43 44 /* 45 * Contains a pointer to the symbol table entry of the current function 46 * definition. 47 */ 48 sym_t *funcsym; 49 50 /* Is set as long as a statement can be reached. Must be set at level 0. */ 51 int reached = 1; 52 53 /* 54 * Is set as long as NOTREACHED is in effect. 55 * Is reset everywhere where reached can become 0. 56 */ 57 int rchflg; 58 59 /* 60 * In conjunction with reached ontrols printing of "fallthrough on ..." 61 * warnings. 62 * Reset by each statement and set by FALLTHROUGH, switch (switch1()) 63 * and case (label()). 64 * 65 * Control statements if, for, while and switch do not reset ftflg because 66 * this must be done by the controled statement. At least for if this is 67 * important because ** FALLTHROUGH ** after "if (expr) stmnt" is evaluated 68 * befor the following token, wich causes reduction of above, is read. 69 * This means that ** FALLTHROUGH ** after "if ..." would always be ignored. 70 */ 71 int ftflg; 72 73 /* Top element of stack for control statements */ 74 cstk_t *cstk; 75 76 /* 77 * Number of arguments which will be checked for usage in following 78 * function definition. -1 stands for all arguments. 79 * 80 * The position of the last ARGSUSED comment is stored in aupos. 81 */ 82 int nargusg = -1; 83 pos_t aupos; 84 85 /* 86 * Number of arguments of the following function definition whose types 87 * shall be checked by lint2. -1 stands for all arguments. 88 * 89 * The position of the last VARARGS comment is stored in vapos. 90 */ 91 int nvararg = -1; 92 pos_t vapos; 93 94 /* 95 * Both prflstr and scflstrg contain the number of the argument which 96 * shall be used to check the types of remaining arguments (for PRINTFLIKE 97 * and SCANFLIKE). 98 * 99 * prflpos and scflpos are the positions of the last PRINTFLIKE or 100 * SCANFLIKE comment. 101 */ 102 int prflstrg = -1; 103 int scflstrg = -1; 104 pos_t prflpos; 105 pos_t scflpos; 106 107 /* 108 * Are both plibflg and llibflg set, prototypes are writen as function 109 * definitions to the output file. 110 */ 111 int plibflg; 112 113 /* 114 * Nonzero means that no warnings about constands in conditional 115 * context are printed. 116 */ 117 int ccflg; 118 119 /* 120 * llibflg is set if a lint library shall be created. The effect of 121 * llibflg is that all defined symbols are treated as used. 122 * (The LINTLIBRARY comment also resets vflag.) 123 */ 124 int llibflg; 125 126 /* 127 * Nonzero if warnings are suppressed by a LINTED directive 128 */ 129 int nowarn; 130 131 /* 132 * Nonzero if complaints about use of "long long" are suppressed in 133 * the next statement or declaration. 134 */ 135 int quadflg; 136 137 /* 138 * Puts a new element at the top of the stack used for control statements. 139 */ 140 void 141 pushctrl(env) 142 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(env) 157 int env; 158 { 159 cstk_t *ci; 160 clst_t *cl; 161 162 if (cstk == NULL || cstk->c_env != env) 163 lerror("popctrl() 1"); 164 165 cstk = (ci = cstk)->c_nxt; 166 167 while ((cl = ci->c_clst) != NULL) { 168 ci->c_clst = cl->cl_nxt; 169 free(cl); 170 } 171 172 if (ci->c_swtype != NULL) 173 free(ci->c_swtype); 174 175 free(ci); 176 } 177 178 /* 179 * Prints a warning if a statement cannot be reached. 180 */ 181 void 182 chkreach() 183 { 184 if (!reached && !rchflg) { 185 /* statement not reached */ 186 warning(193); 187 reached = 1; 188 } 189 } 190 191 /* 192 * Called after a function declaration which introduces a function definition 193 * and before an (optional) old style argument declaration list. 194 * 195 * Puts all symbols declared in the Prototype or in an old style argument 196 * list back to the symbol table. 197 * 198 * Does the usual checking of storage class, type (return value), 199 * redeclaration etc.. 200 */ 201 void 202 funcdef(fsym) 203 sym_t *fsym; 204 { 205 int n, warn; 206 sym_t *arg, *sym, *rdsym; 207 208 funcsym = fsym; 209 210 /* 211 * Put all symbols declared in the argument list back to the 212 * symbol table. 213 */ 214 for (sym = dcs->d_fpsyms; sym != NULL; sym = sym->s_dlnxt) { 215 if (sym->s_blklev != -1) { 216 if (sym->s_blklev != 1) 217 lerror("funcdef() 1"); 218 inssym(1, sym); 219 } 220 } 221 222 /* 223 * In osfunc() we did not know whether it is an old style function 224 * definition or only an old style declaration, if there are no 225 * arguments inside the argument list ("f()"). 226 */ 227 if (!fsym->s_type->t_proto && fsym->s_args == NULL) 228 fsym->s_osdef = 1; 229 230 chktyp(fsym); 231 232 /* 233 * chktyp() checks for almost all possible errors, but not for 234 * incomplete return values (these are allowed in declarations) 235 */ 236 if (fsym->s_type->t_subt->t_tspec != VOID && 237 incompl(fsym->s_type->t_subt)) { 238 /* cannot return incomplete type */ 239 error(67); 240 } 241 242 fsym->s_def = DEF; 243 244 if (fsym->s_scl == TYPEDEF) { 245 fsym->s_scl = EXTERN; 246 /* illegal storage class */ 247 error(8); 248 } 249 250 if (dcs->d_inline) 251 fsym->s_inline = 1; 252 253 /* 254 * Arguments in new style function declarations need a name. 255 * (void is already removed from the list of arguments) 256 */ 257 n = 1; 258 for (arg = fsym->s_type->t_args; arg != NULL; arg = arg->s_nxt) { 259 if (arg->s_scl == ABSTRACT) { 260 if (arg->s_name != unnamed) 261 lerror("funcdef() 2"); 262 /* formal parameter lacks name: param #%d */ 263 error(59, n); 264 } else { 265 if (arg->s_name == unnamed) 266 lerror("funcdef() 3"); 267 } 268 n++; 269 } 270 271 /* 272 * We must also remember the position. s_dpos is overwritten 273 * if this is an old style definition and we had already a 274 * prototype. 275 */ 276 STRUCT_ASSIGN(dcs->d_fdpos, fsym->s_dpos); 277 278 if ((rdsym = dcs->d_rdcsym) != NULL) { 279 280 if (!isredec(fsym, (warn = 0, &warn))) { 281 282 /* 283 * Print nothing if the newly defined function 284 * is defined in old style. A better warning will 285 * be printed in cluparg(). 286 */ 287 if (warn && !fsym->s_osdef) { 288 /* redeclaration of %s */ 289 (*(sflag ? error : warning))(27, fsym->s_name); 290 prevdecl(-1, rdsym); 291 } 292 293 /* copy usage information */ 294 cpuinfo(fsym, rdsym); 295 296 /* 297 * If the old symbol was a prototype and the new 298 * one is none, overtake the position of the 299 * declaration of the prototype. 300 */ 301 if (fsym->s_osdef && rdsym->s_type->t_proto) 302 STRUCT_ASSIGN(fsym->s_dpos, rdsym->s_dpos); 303 304 /* complete the type */ 305 compltyp(fsym, rdsym); 306 307 /* once a function is inline it remains inline */ 308 if (rdsym->s_inline) 309 fsym->s_inline = 1; 310 311 } 312 313 /* remove the old symbol from the symbol table */ 314 rmsym(rdsym); 315 316 } 317 318 if (fsym->s_osdef && !fsym->s_type->t_proto) { 319 if (sflag && hflag && strcmp(fsym->s_name, "main") != 0) 320 /* function definition is not a prototyp */ 321 warning(286); 322 } 323 324 if (dcs->d_notyp) 325 /* return value is implizitly declared to be int */ 326 fsym->s_rimpl = 1; 327 328 reached = 1; 329 } 330 331 /* 332 * Called at the end of a function definition. 333 */ 334 void 335 funcend() 336 { 337 sym_t *arg; 338 int n; 339 340 if (reached) { 341 cstk->c_noretval = 1; 342 if (funcsym->s_type->t_subt->t_tspec != VOID && 343 !funcsym->s_rimpl) { 344 /* func. %s falls off bottom without returning value */ 345 warning(217, funcsym->s_name); 346 } 347 } 348 349 /* 350 * This warning is printed only if the return value was implizitly 351 * declared to be int. Otherwise the wrong return statement 352 * has already printed a warning. 353 */ 354 if (cstk->c_noretval && cstk->c_retval && funcsym->s_rimpl) 355 /* function %s has return (e); and return; */ 356 warning(216, funcsym->s_name); 357 358 /* Print warnings for unused arguments */ 359 arg = dcs->d_fargs; 360 n = 0; 361 while (arg != NULL && (nargusg == -1 || n < nargusg)) { 362 chkusg1(dcs->d_asm, arg); 363 arg = arg->s_nxt; 364 n++; 365 } 366 nargusg = -1; 367 368 /* 369 * write the information about the function definition to the 370 * output file 371 * inline functions explicitely declared extern are written as 372 * declarations only. 373 */ 374 if (dcs->d_scl == EXTERN && funcsym->s_inline) { 375 outsym(funcsym, funcsym->s_scl, DECL); 376 } else { 377 outfdef(funcsym, &dcs->d_fdpos, cstk->c_retval, 378 funcsym->s_osdef, dcs->d_fargs); 379 } 380 381 /* 382 * remove all symbols declared during argument declaration from 383 * the symbol table 384 */ 385 if (dcs->d_nxt != NULL || dcs->d_ctx != EXTERN) 386 lerror("funcend() 1"); 387 rmsyms(dcs->d_fpsyms); 388 389 /* must be set on level 0 */ 390 reached = 1; 391 } 392 393 /* 394 * Process a label. 395 * 396 * typ type of the label (T_NAME, T_DEFAULT or T_CASE). 397 * sym symbol table entry of label if typ == T_NAME 398 * tn expression if typ == T_CASE 399 */ 400 void 401 label(typ, sym, tn) 402 int typ; 403 sym_t *sym; 404 tnode_t *tn; 405 { 406 cstk_t *ci; 407 clst_t *cl; 408 val_t *v, *nv; 409 tspec_t t; 410 411 switch (typ) { 412 413 case T_NAME: 414 if (sym->s_set) { 415 /* label %s redefined */ 416 error(194, sym->s_name); 417 } else { 418 setsflg(sym); 419 } 420 break; 421 422 case T_CASE: 423 424 /* find the stack entry for the innermost switch statement */ 425 for (ci = cstk; ci != NULL && !ci->c_switch; ci = ci->c_nxt) ; 426 427 if (ci == NULL) { 428 /* case not in switch */ 429 error(195); 430 tn = NULL; 431 } else if (tn != NULL && tn->tn_op != CON) { 432 /* non-constant case expression */ 433 error(197); 434 tn = NULL; 435 } else if (tn != NULL && !isityp(tn->tn_type->t_tspec)) { 436 /* non-integral case expression */ 437 error(198); 438 tn = NULL; 439 } 440 441 if (tn != NULL) { 442 443 if (ci->c_swtype == NULL) 444 lerror("label() 1"); 445 446 if (reached && !ftflg) { 447 if (hflag) 448 /* fallthrough on case statement */ 449 warning(220); 450 } 451 452 t = tn->tn_type->t_tspec; 453 if (t == LONG || t == ULONG || 454 t == QUAD || t == UQUAD) { 455 if (tflag) 456 /* case label must be of type ... */ 457 warning(203); 458 } 459 460 /* 461 * get the value of the expression and convert it 462 * to the type of the switch expression 463 */ 464 v = constant(tn); 465 nv = xcalloc(1, sizeof (val_t)); 466 cvtcon(CASE, 0, ci->c_swtype, nv, v); 467 free(v); 468 469 /* look if we had this value already */ 470 for (cl = ci->c_clst; cl != NULL; cl = cl->cl_nxt) { 471 if (cl->cl_val.v_quad == nv->v_quad) 472 break; 473 } 474 if (cl != NULL && isutyp(nv->v_tspec)) { 475 /* duplicate case in switch, %lu */ 476 error(200, (u_long)nv->v_quad); 477 } else if (cl != NULL) { 478 /* duplicate case in switch, %ld */ 479 error(199, (long)nv->v_quad); 480 } else { 481 /* 482 * append the value to the list of 483 * case values 484 */ 485 cl = xcalloc(1, sizeof (clst_t)); 486 STRUCT_ASSIGN(cl->cl_val, *nv); 487 cl->cl_nxt = ci->c_clst; 488 ci->c_clst = cl; 489 } 490 } 491 tfreeblk(); 492 break; 493 494 case T_DEFAULT: 495 496 /* find the stack entry for the innermost switch statement */ 497 for (ci = cstk; ci != NULL && !ci->c_switch; ci = ci->c_nxt) ; 498 499 if (ci == NULL) { 500 /* default outside switch */ 501 error(201); 502 } else if (ci->c_default) { 503 /* duplicate default in switch */ 504 error(202); 505 } else { 506 if (reached && !ftflg) { 507 if (hflag) 508 /* fallthrough on default statement */ 509 warning(284); 510 } 511 ci->c_default = 1; 512 } 513 break; 514 }; 515 reached = 1; 516 } 517 518 /* 519 * T_IF T_LPARN expr T_RPARN 520 */ 521 void 522 if1(tn) 523 tnode_t *tn; 524 { 525 if (tn != NULL) 526 tn = cconv(tn); 527 if (tn != NULL) 528 tn = promote(NOOP, 0, tn); 529 expr(tn, 0, 1); 530 pushctrl(T_IF); 531 } 532 533 /* 534 * if_without_else 535 * if_without_else T_ELSE 536 */ 537 void 538 if2() 539 { 540 cstk->c_rchif = reached ? 1 : 0; 541 reached = 1; 542 } 543 544 /* 545 * if_without_else 546 * if_without_else T_ELSE stmnt 547 */ 548 void 549 if3(els) 550 int els; 551 { 552 if (els) { 553 reached |= cstk->c_rchif; 554 } else { 555 reached = 1; 556 } 557 popctrl(T_IF); 558 } 559 560 /* 561 * T_SWITCH T_LPARN expr T_RPARN 562 */ 563 void 564 switch1(tn) 565 tnode_t *tn; 566 { 567 tspec_t t; 568 type_t *tp; 569 570 if (tn != NULL) 571 tn = cconv(tn); 572 if (tn != NULL) 573 tn = promote(NOOP, 0, tn); 574 if (tn != NULL && !isityp(tn->tn_type->t_tspec)) { 575 /* switch expression must have integral type */ 576 error(205); 577 tn = NULL; 578 } 579 if (tn != NULL && tflag) { 580 t = tn->tn_type->t_tspec; 581 if (t == LONG || t == ULONG || t == QUAD || t == UQUAD) { 582 /* switch expr. must be of type `int' in trad. C */ 583 warning(271); 584 } 585 } 586 587 /* 588 * Remember the type of the expression. Because its possible 589 * that (*tp) is allocated on tree memory the type must be 590 * duplicated. This is not too complicated because it is 591 * only an integer type. 592 */ 593 tp = xcalloc(1, sizeof (type_t)); 594 if (tn != NULL) { 595 tp->t_tspec = tn->tn_type->t_tspec; 596 if ((tp->t_isenum = tn->tn_type->t_isenum) != 0) 597 tp->t_enum = tn->tn_type->t_enum; 598 } else { 599 tp->t_tspec = INT; 600 } 601 602 expr(tn, 1, 0); 603 604 pushctrl(T_SWITCH); 605 cstk->c_switch = 1; 606 cstk->c_swtype = tp; 607 608 reached = rchflg = 0; 609 ftflg = 1; 610 } 611 612 /* 613 * switch_expr stmnt 614 */ 615 void 616 switch2() 617 { 618 int nenum, nclab; 619 sym_t *esym; 620 clst_t *cl; 621 622 if (cstk->c_swtype == NULL) 623 lerror("switch2() 1"); 624 625 /* 626 * If the switch expression was of type enumeration, count the case 627 * labels and the number of enumerators. If both counts are not 628 * equal print a warning. 629 */ 630 if (cstk->c_swtype->t_isenum) { 631 nenum = nclab = 0; 632 if (cstk->c_swtype->t_enum == NULL) 633 lerror("switch2() 2"); 634 for (esym = cstk->c_swtype->t_enum->elem; 635 esym != NULL; esym = esym->s_nxt) { 636 nenum++; 637 } 638 for (cl = cstk->c_clst; cl != NULL; cl = cl->cl_nxt) 639 nclab++; 640 if (hflag && eflag && nenum != nclab && !cstk->c_default) { 641 /* enumeration value(s) not handled in switch */ 642 warning(206); 643 } 644 } 645 646 if (cstk->c_break) { 647 /* 648 * end of switch alway reached (c_break is only set if the 649 * break statement can be reached). 650 */ 651 reached = 1; 652 } else if (!cstk->c_default && 653 (!hflag || !cstk->c_swtype->t_isenum || nenum != nclab)) { 654 /* 655 * there are possible values which are not handled in 656 * switch 657 */ 658 reached = 1; 659 } /* 660 * otherwise the end of the switch expression is reached 661 * if the end of the last statement inside it is reached. 662 */ 663 664 popctrl(T_SWITCH); 665 } 666 667 /* 668 * T_WHILE T_LPARN expr T_RPARN 669 */ 670 void 671 while1(tn) 672 tnode_t *tn; 673 { 674 if (!reached) { 675 /* loop not entered at top */ 676 warning(207); 677 reached = 1; 678 } 679 680 if (tn != NULL) 681 tn = cconv(tn); 682 if (tn != NULL) 683 tn = promote(NOOP, 0, tn); 684 if (tn != NULL && !issclt(tn->tn_type->t_tspec)) { 685 /* controlling expressions must have scalar type */ 686 error(204); 687 tn = NULL; 688 } 689 690 pushctrl(T_WHILE); 691 cstk->c_loop = 1; 692 if (tn != NULL && tn->tn_op == CON) { 693 if (isityp(tn->tn_type->t_tspec)) { 694 cstk->c_infinite = tn->tn_val->v_quad != 0; 695 } else { 696 cstk->c_infinite = tn->tn_val->v_ldbl != 0.0; 697 } 698 } 699 700 expr(tn, 0, 1); 701 } 702 703 /* 704 * while_expr stmnt 705 * while_expr error 706 */ 707 void 708 while2() 709 { 710 /* 711 * The end of the loop can be reached if it is no endless loop 712 * or there was a break statement which was reached. 713 */ 714 reached = !cstk->c_infinite || cstk->c_break; 715 rchflg = 0; 716 717 popctrl(T_WHILE); 718 } 719 720 /* 721 * T_DO 722 */ 723 void 724 do1() 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(tn) 742 tnode_t *tn; 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(tn1, tn2, tn3) 786 tnode_t *tn1, *tn2, *tn3; 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() 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(lab) 892 sym_t *lab; 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() 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() 932 { 933 cstk_t *ci; 934 935 for (ci = cstk; ci != NULL && !ci->c_loop; ci = ci->c_nxt) ; 936 937 if (ci == NULL) { 938 /* continue outside loop */ 939 error(209); 940 } else { 941 ci->c_cont = 1; 942 } 943 944 chkreach(); 945 946 reached = rchflg = 0; 947 } 948 949 /* 950 * T_RETURN T_SEMI 951 * T_RETURN expr T_SEMI 952 */ 953 void 954 doreturn(tn) 955 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 963 if (tn != NULL) { 964 ci->c_retval = 1; 965 } else { 966 ci->c_noretval = 1; 967 } 968 969 if (tn != NULL && funcsym->s_type->t_subt->t_tspec == VOID) { 970 /* void function %s cannot return value */ 971 error(213, funcsym->s_name); 972 tfreeblk(); 973 tn = NULL; 974 } else if (tn == NULL && funcsym->s_type->t_subt->t_tspec != VOID) { 975 /* 976 * Assume that the function has a return value only if it 977 * is explicitly declared. 978 */ 979 if (!funcsym->s_rimpl) 980 /* function %s expects to return value */ 981 warning(214, funcsym->s_name); 982 } 983 984 if (tn != NULL) { 985 986 /* Create a temporary node for the left side */ 987 ln = tgetblk(sizeof (tnode_t)); 988 ln->tn_op = NAME; 989 ln->tn_type = tduptyp(funcsym->s_type->t_subt); 990 ln->tn_type->t_const = 0; 991 ln->tn_lvalue = 1; 992 ln->tn_sym = funcsym; /* better than nothing */ 993 994 tn = build(RETURN, ln, tn); 995 996 if (tn != NULL) { 997 rn = tn->tn_right; 998 while ((op = rn->tn_op) == CVT || op == PLUS) 999 rn = rn->tn_left; 1000 if (rn->tn_op == AMPER && rn->tn_left->tn_op == NAME && 1001 rn->tn_left->tn_sym->s_scl == AUTO) { 1002 /* %s returns pointer to automatic object */ 1003 warning(302, funcsym->s_name); 1004 } 1005 } 1006 1007 expr(tn, 1, 0); 1008 1009 } else { 1010 1011 chkreach(); 1012 1013 } 1014 1015 reached = rchflg = 0; 1016 } 1017 1018 /* 1019 * Do some cleanup after a global declaration or definition. 1020 * Especially remove informations about unused lint comments. 1021 */ 1022 void 1023 glclup(silent) 1024 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(n) 1076 int n; 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(n) 1102 int n; 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(n) 1128 int n; 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(n) 1154 int n; 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(n) 1179 int n; 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(n) 1191 int n; 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(n) 1203 int n; 1204 { 1205 reached = 0; 1206 rchflg = 1; 1207 } 1208 1209 /* ARGSUSED */ 1210 void 1211 lintlib(n) 1212 int n; 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(n) 1229 int n; 1230 { 1231 nowarn = 1; 1232 } 1233 1234 /* 1235 * PROTOTLIB in conjunction with LINTLIBRARY can be used to handle 1236 * prototypes like function definitions. This is done if the argument 1237 * to PROTOLIB is nonzero. Otherwise prototypes are handled normaly. 1238 */ 1239 void 1240 protolib(n) 1241 int n; 1242 { 1243 if (dcs->d_ctx != EXTERN) { 1244 /* must be outside function: ** %s ** */ 1245 warning(280, "PROTOLIB"); 1246 return; 1247 } 1248 plibflg = n == 0 ? 0 : 1; 1249 } 1250 1251 /* 1252 * Set quadflg to nonzero which means that the next statement/declaration 1253 * may use "long long" without an error or warning. 1254 */ 1255 /* ARGSUSED */ 1256 void 1257 longlong(n) 1258 int n; 1259 { 1260 quadflg = 1; 1261 } 1262