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