1 1.196 rillig /* $NetBSD: func.c,v 1.196 2025/09/14 11:14:00 rillig Exp $ */ 2 1.2 cgd 3 1.1 cgd /* 4 1.1 cgd * Copyright (c) 1994, 1995 Jochen Pohl 5 1.1 cgd * All Rights Reserved. 6 1.1 cgd * 7 1.1 cgd * Redistribution and use in source and binary forms, with or without 8 1.1 cgd * modification, are permitted provided that the following conditions 9 1.1 cgd * are met: 10 1.1 cgd * 1. Redistributions of source code must retain the above copyright 11 1.1 cgd * notice, this list of conditions and the following disclaimer. 12 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 cgd * notice, this list of conditions and the following disclaimer in the 14 1.1 cgd * documentation and/or other materials provided with the distribution. 15 1.1 cgd * 3. All advertising materials mentioning features or use of this software 16 1.1 cgd * must display the following acknowledgement: 17 1.170 rillig * This product includes software developed by Jochen Pohl for 18 1.1 cgd * The NetBSD Project. 19 1.1 cgd * 4. The name of the author may not be used to endorse or promote products 20 1.1 cgd * derived from this software without specific prior written permission. 21 1.1 cgd * 22 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 1.1 cgd * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 1.1 cgd * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 1.1 cgd * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 1.1 cgd * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 1.1 cgd * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 1.1 cgd * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 1.1 cgd * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 1.1 cgd * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 1.1 cgd * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 1.1 cgd */ 33 1.1 cgd 34 1.21 jmc #if HAVE_NBTOOL_CONFIG_H 35 1.21 jmc #include "nbtool_config.h" 36 1.21 jmc #endif 37 1.21 jmc 38 1.8 christos #include <sys/cdefs.h> 39 1.136 rillig #if defined(__RCSID) 40 1.196 rillig __RCSID("$NetBSD: func.c,v 1.196 2025/09/14 11:14:00 rillig Exp $"); 41 1.1 cgd #endif 42 1.1 cgd 43 1.1 cgd #include <stdlib.h> 44 1.1 cgd #include <string.h> 45 1.1 cgd 46 1.1 cgd #include "lint1.h" 47 1.10 tv #include "cgram.h" 48 1.1 cgd 49 1.1 cgd /* 50 1.1 cgd * Contains a pointer to the symbol table entry of the current function 51 1.1 cgd * definition. 52 1.1 cgd */ 53 1.178 rillig sym_t *funcsym; 54 1.1 cgd 55 1.1 cgd /* Is set as long as a statement can be reached. Must be set at level 0. */ 56 1.178 rillig bool reached = true; 57 1.1 cgd 58 1.1 cgd /* 59 1.94 rillig * Is true by default, can be cleared by NOTREACHED. 60 1.94 rillig * Is reset to true whenever 'reached' changes. 61 1.1 cgd */ 62 1.178 rillig bool warn_about_unreachable; 63 1.1 cgd 64 1.1 cgd /* 65 1.63 rillig * In conjunction with 'reached', controls printing of "fallthrough on ..." 66 1.1 cgd * warnings. 67 1.158 rillig * Reset by each statement and set by FALLTHROUGH, stmt_switch_expr and 68 1.158 rillig * case_label. 69 1.1 cgd * 70 1.168 rillig * The control statements 'if', 'for', 'while' and 'switch' do not reset 71 1.168 rillig * suppress_fallthrough because this must be done by the controlled statement. 72 1.168 rillig * At least for 'if', this is important because ** FALLTHROUGH ** after "if 73 1.168 rillig * (expr) statement" is evaluated before the following token, which causes 74 1.168 rillig * reduction of above. This means that ** FALLTHROUGH ** after "if ..." would 75 1.168 rillig * always be ignored. 76 1.1 cgd */ 77 1.178 rillig bool suppress_fallthrough; 78 1.1 cgd 79 1.48 rillig /* The innermost control statement */ 80 1.150 rillig static control_statement *cstmt; 81 1.1 cgd 82 1.1 cgd /* 83 1.173 rillig * Number of parameters which will be checked for usage in following 84 1.173 rillig * function definition. -1 stands for all parameters. 85 1.1 cgd * 86 1.31 rillig * The position of the last ARGSUSED comment is stored in argsused_pos. 87 1.1 cgd */ 88 1.178 rillig int nargusg = -1; 89 1.178 rillig pos_t argsused_pos; 90 1.1 cgd 91 1.1 cgd /* 92 1.173 rillig * Number of parameters of the following function definition whose types 93 1.173 rillig * shall be checked by lint2. -1 stands for all parameters. 94 1.1 cgd * 95 1.1 cgd * The position of the last VARARGS comment is stored in vapos. 96 1.1 cgd */ 97 1.178 rillig int nvararg = -1; 98 1.178 rillig pos_t vapos; 99 1.1 cgd 100 1.1 cgd /* 101 1.49 rillig * Both printflike_argnum and scanflike_argnum contain the 1-based number 102 1.173 rillig * of the string parameter which shall be used to check the types of remaining 103 1.49 rillig * arguments (for PRINTFLIKE and SCANFLIKE). 104 1.1 cgd * 105 1.31 rillig * printflike_pos and scanflike_pos are the positions of the last PRINTFLIKE 106 1.31 rillig * or SCANFLIKE comment. 107 1.1 cgd */ 108 1.178 rillig int printflike_argnum = -1; 109 1.178 rillig int scanflike_argnum = -1; 110 1.178 rillig pos_t printflike_pos; 111 1.178 rillig pos_t scanflike_pos; 112 1.1 cgd 113 1.1 cgd /* 114 1.28 rillig * If both plibflg and llibflg are set, prototypes are written as function 115 1.1 cgd * definitions to the output file. 116 1.1 cgd */ 117 1.178 rillig bool plibflg; 118 1.1 cgd 119 1.1 cgd /* 120 1.138 rillig * Whether a lint library shall be created. The effect of this flag is that 121 1.138 rillig * all defined symbols are treated as used. 122 1.1 cgd * (The LINTLIBRARY comment also resets vflag.) 123 1.1 cgd */ 124 1.178 rillig bool llibflg; 125 1.1 cgd 126 1.1 cgd /* 127 1.138 rillig * Determines the warnings that are suppressed by a LINTED directive. For 128 1.138 rillig * globally suppressed warnings, see 'msgset'. 129 1.138 rillig * 130 1.138 rillig * LWARN_ALL: all warnings are enabled 131 1.138 rillig * LWARN_NONE: all warnings are suppressed 132 1.138 rillig * n >= 0: warning n is ignored, the others are active 133 1.1 cgd */ 134 1.178 rillig int lwarn = LWARN_ALL; 135 1.6 jpo 136 1.168 rillig /* Temporarily suppress warnings about wrong types for bit-fields. */ 137 1.178 rillig bool suppress_bitfieldtype; 138 1.16 thorpej 139 1.168 rillig /* Temporarily suppress warnings about use of 'long long'. */ 140 1.178 rillig bool suppress_longlong; 141 1.1 cgd 142 1.1 cgd void 143 1.96 rillig begin_control_statement(control_statement_kind kind) 144 1.1 cgd { 145 1.115 rillig control_statement *cs; 146 1.1 cgd 147 1.115 rillig cs = xcalloc(1, sizeof(*cs)); 148 1.115 rillig cs->c_kind = kind; 149 1.115 rillig cs->c_surrounding = cstmt; 150 1.115 rillig cstmt = cs; 151 1.1 cgd } 152 1.1 cgd 153 1.1 cgd void 154 1.96 rillig end_control_statement(control_statement_kind kind) 155 1.1 cgd { 156 1.110 rillig while (cstmt->c_kind != kind) 157 1.110 rillig cstmt = cstmt->c_surrounding; 158 1.1 cgd 159 1.180 rillig control_statement *cs = cstmt; 160 1.115 rillig cstmt = cs->c_surrounding; 161 1.1 cgd 162 1.182 rillig free(cs->c_case_labels.vals); 163 1.115 rillig free(cs->c_switch_type); 164 1.115 rillig free(cs); 165 1.1 cgd } 166 1.1 cgd 167 1.93 rillig static void 168 1.93 rillig set_reached(bool new_reached) 169 1.93 rillig { 170 1.118 rillig debug_step("%s -> %s", 171 1.106 rillig reached ? "reachable" : "unreachable", 172 1.106 rillig new_reached ? "reachable" : "unreachable"); 173 1.93 rillig reached = new_reached; 174 1.94 rillig warn_about_unreachable = true; 175 1.93 rillig } 176 1.93 rillig 177 1.1 cgd /* 178 1.1 cgd * Prints a warning if a statement cannot be reached. 179 1.1 cgd */ 180 1.1 cgd void 181 1.189 rillig check_statement_reachable(const char *stmt_kind) 182 1.1 cgd { 183 1.94 rillig if (!reached && warn_about_unreachable) { 184 1.189 rillig /* '%s' statement not reached */ 185 1.189 rillig warning(193, stmt_kind); 186 1.95 rillig warn_about_unreachable = false; 187 1.1 cgd } 188 1.1 cgd } 189 1.1 cgd 190 1.1 cgd /* 191 1.1 cgd * Called after a function declaration which introduces a function definition 192 1.173 rillig * and before an (optional) old-style parameter declaration list. 193 1.1 cgd * 194 1.173 rillig * Puts all symbols declared in the prototype or in an old-style parameter 195 1.1 cgd * list back to the symbol table. 196 1.1 cgd * 197 1.1 cgd * Does the usual checking of storage class, type (return value), 198 1.28 rillig * redeclaration, etc. 199 1.1 cgd */ 200 1.1 cgd void 201 1.146 rillig begin_function(sym_t *fsym) 202 1.1 cgd { 203 1.1 cgd funcsym = fsym; 204 1.1 cgd 205 1.1 cgd /* 206 1.177 rillig * Put all symbols declared in the parameter list back to the symbol 207 1.177 rillig * table. 208 1.1 cgd */ 209 1.180 rillig for (sym_t *sym = dcs->d_func_proto_syms; sym != NULL; 210 1.128 rillig sym = sym->s_level_next) { 211 1.77 rillig if (sym->s_block_level != -1) { 212 1.77 rillig lint_assert(sym->s_block_level == 1); 213 1.1 cgd inssym(1, sym); 214 1.1 cgd } 215 1.1 cgd } 216 1.1 cgd 217 1.1 cgd /* 218 1.177 rillig * In old_style_function() we did not know whether it is an old style 219 1.177 rillig * function definition or only an old-style declaration, if there are 220 1.177 rillig * no parameters inside the parameter list ("f()"). 221 1.1 cgd */ 222 1.173 rillig if (!fsym->s_type->t_proto && fsym->u.s_old_style_params == NULL) 223 1.59 rillig fsym->s_osdef = true; 224 1.1 cgd 225 1.29 rillig check_type(fsym); 226 1.1 cgd 227 1.1 cgd /* 228 1.29 rillig * check_type() checks for almost all possible errors, but not for 229 1.1 cgd * incomplete return values (these are allowed in declarations) 230 1.1 cgd */ 231 1.1 cgd if (fsym->s_type->t_subt->t_tspec != VOID && 232 1.66 rillig is_incomplete(fsym->s_type->t_subt)) { 233 1.1 cgd /* cannot return incomplete type */ 234 1.1 cgd error(67); 235 1.1 cgd } 236 1.1 cgd 237 1.4 jpo fsym->s_def = DEF; 238 1.1 cgd 239 1.1 cgd if (fsym->s_scl == TYPEDEF) { 240 1.1 cgd fsym->s_scl = EXTERN; 241 1.194 rillig /* invalid storage class */ 242 1.1 cgd error(8); 243 1.1 cgd } 244 1.1 cgd 245 1.4 jpo if (dcs->d_inline) 246 1.59 rillig fsym->s_inline = true; 247 1.4 jpo 248 1.1 cgd /* 249 1.177 rillig * Parameters in new-style function declarations need a name. ('void' 250 1.177 rillig * is already removed from the list of parameters.) 251 1.1 cgd */ 252 1.180 rillig int n = 1; 253 1.183 rillig for (const sym_t *param = fsym->s_type->u.params; 254 1.176 rillig param != NULL; param = param->s_next) { 255 1.173 rillig if (param->s_scl == ABSTRACT) { 256 1.173 rillig lint_assert(param->s_name == unnamed); 257 1.141 rillig /* formal parameter #%d lacks name */ 258 1.1 cgd error(59, n); 259 1.1 cgd } else { 260 1.173 rillig lint_assert(param->s_name != unnamed); 261 1.1 cgd } 262 1.1 cgd n++; 263 1.1 cgd } 264 1.1 cgd 265 1.1 cgd /* 266 1.177 rillig * We must also remember the position. s_def_pos is overwritten if this 267 1.177 rillig * is an old-style definition, and we had already a prototype. 268 1.1 cgd */ 269 1.81 rillig dcs->d_func_def_pos = fsym->s_def_pos; 270 1.1 cgd 271 1.180 rillig sym_t *rdsym = dcs->d_redeclared_symbol; 272 1.180 rillig if (rdsym != NULL) { 273 1.180 rillig bool dowarn = false; 274 1.180 rillig if (!check_redeclaration(fsym, &dowarn)) { 275 1.1 cgd 276 1.1 cgd /* 277 1.177 rillig * Print nothing if the newly defined function is 278 1.177 rillig * defined in old style. A better warning will be 279 1.177 rillig * printed in check_func_lint_directives(). 280 1.1 cgd */ 281 1.24 dholland if (dowarn && !fsym->s_osdef) { 282 1.135 rillig /* TODO: error in C99 mode as well? */ 283 1.135 rillig if (!allow_trad && !allow_c99) 284 1.139 rillig /* redeclaration of '%s' */ 285 1.50 rillig error(27, fsym->s_name); 286 1.50 rillig else 287 1.139 rillig /* redeclaration of '%s' */ 288 1.50 rillig warning(27, fsym->s_name); 289 1.144 rillig print_previous_declaration(rdsym); 290 1.1 cgd } 291 1.1 cgd 292 1.29 rillig copy_usage_info(fsym, rdsym); 293 1.1 cgd 294 1.1 cgd /* 295 1.177 rillig * If the old symbol was a prototype and the new one is 296 1.177 rillig * none, overtake the position of the declaration of 297 1.177 rillig * the prototype. 298 1.1 cgd */ 299 1.1 cgd if (fsym->s_osdef && rdsym->s_type->t_proto) 300 1.36 rillig fsym->s_def_pos = rdsym->s_def_pos; 301 1.1 cgd 302 1.29 rillig complete_type(fsym, rdsym); 303 1.1 cgd 304 1.4 jpo if (rdsym->s_inline) 305 1.59 rillig fsym->s_inline = true; 306 1.1 cgd } 307 1.1 cgd 308 1.186 rillig symtab_remove_forever(rdsym); 309 1.1 cgd } 310 1.1 cgd 311 1.1 cgd if (fsym->s_osdef && !fsym->s_type->t_proto) { 312 1.192 rillig if (!allow_trad && hflag && 313 1.192 rillig (allow_c99 || strcmp(fsym->s_name, "main") != 0)) 314 1.28 rillig /* function definition is not a prototype */ 315 1.1 cgd warning(286); 316 1.1 cgd } 317 1.1 cgd 318 1.159 rillig if (dcs->d_no_type_specifier) 319 1.69 rillig fsym->s_return_type_implicit_int = true; 320 1.1 cgd 321 1.93 rillig set_reached(true); 322 1.1 cgd } 323 1.1 cgd 324 1.72 rillig static void 325 1.72 rillig check_missing_return_value(void) 326 1.72 rillig { 327 1.72 rillig if (funcsym->s_type->t_subt->t_tspec == VOID) 328 1.72 rillig return; 329 1.72 rillig if (funcsym->s_return_type_implicit_int) 330 1.72 rillig return; 331 1.72 rillig 332 1.72 rillig /* C99 5.1.2.2.3 "Program termination" p1 */ 333 1.133 rillig if (allow_c99 && strcmp(funcsym->s_name, "main") == 0) 334 1.72 rillig return; 335 1.72 rillig 336 1.142 rillig /* function '%s' falls off bottom without returning value */ 337 1.72 rillig warning(217, funcsym->s_name); 338 1.72 rillig } 339 1.72 rillig 340 1.1 cgd void 341 1.146 rillig end_function(void) 342 1.1 cgd { 343 1.1 cgd if (reached) { 344 1.63 rillig cstmt->c_had_return_noval = true; 345 1.72 rillig check_missing_return_value(); 346 1.1 cgd } 347 1.1 cgd 348 1.63 rillig if (cstmt->c_had_return_noval && cstmt->c_had_return_value && 349 1.69 rillig funcsym->s_return_type_implicit_int) 350 1.142 rillig /* function '%s' has 'return expr' and 'return' */ 351 1.1 cgd warning(216, funcsym->s_name); 352 1.1 cgd 353 1.172 rillig /* Warn about unused parameters. */ 354 1.172 rillig int n = nargusg; 355 1.172 rillig nargusg = -1; 356 1.173 rillig for (const sym_t *param = dcs->d_func_params; 357 1.176 rillig param != NULL && n != 0; param = param->s_next, n--) 358 1.173 rillig check_usage_sym(dcs->d_asm, param); 359 1.1 cgd 360 1.180 rillig if (dcs->d_scl == EXTERN && funcsym->s_inline) 361 1.4 jpo outsym(funcsym, funcsym->s_scl, DECL); 362 1.180 rillig else 363 1.81 rillig outfdef(funcsym, &dcs->d_func_def_pos, 364 1.81 rillig cstmt->c_had_return_value, funcsym->s_osdef, 365 1.173 rillig dcs->d_func_params); 366 1.1 cgd 367 1.111 rillig /* clean up after syntax errors, see test stmt_for.c. */ 368 1.129 rillig while (dcs->d_enclosing != NULL) 369 1.129 rillig dcs = dcs->d_enclosing; 370 1.111 rillig 371 1.129 rillig lint_assert(dcs->d_enclosing == NULL); 372 1.160 rillig lint_assert(dcs->d_kind == DLK_EXTERN); 373 1.162 rillig symtab_remove_level(dcs->d_func_proto_syms); 374 1.1 cgd 375 1.1 cgd /* must be set on level 0 */ 376 1.93 rillig set_reached(true); 377 1.147 rillig 378 1.147 rillig funcsym = NULL; 379 1.1 cgd } 380 1.1 cgd 381 1.1 cgd void 382 1.42 rillig named_label(sym_t *sym) 383 1.42 rillig { 384 1.42 rillig 385 1.180 rillig if (sym->s_set) 386 1.142 rillig /* label '%s' redefined */ 387 1.42 rillig error(194, sym->s_name); 388 1.180 rillig else 389 1.42 rillig mark_as_set(sym); 390 1.42 rillig 391 1.149 rillig /* XXX: Assuming that each label is reachable is wrong. */ 392 1.93 rillig set_reached(true); 393 1.42 rillig } 394 1.42 rillig 395 1.43 rillig static void 396 1.108 rillig check_case_label_bitand(const tnode_t *case_expr, const tnode_t *switch_expr) 397 1.108 rillig { 398 1.108 rillig if (switch_expr->tn_op != BITAND || 399 1.184 rillig switch_expr->u.ops.right->tn_op != CON) 400 1.108 rillig return; 401 1.108 rillig 402 1.108 rillig lint_assert(case_expr->tn_op == CON); 403 1.184 rillig uint64_t case_value = (uint64_t)case_expr->u.value.u.integer; 404 1.184 rillig uint64_t mask = (uint64_t)switch_expr->u.ops.right->u.value.u.integer; 405 1.108 rillig 406 1.180 rillig if ((case_value & ~mask) != 0) 407 1.189 rillig /* '%s' statement not reached */ 408 1.189 rillig warning(193, "case"); 409 1.108 rillig } 410 1.108 rillig 411 1.108 rillig static void 412 1.115 rillig check_case_label_enum(const tnode_t *tn, const control_statement *cs) 413 1.75 rillig { 414 1.75 rillig /* similar to typeok_enum in tree.c */ 415 1.75 rillig 416 1.115 rillig if (!(tn->tn_type->t_is_enum || cs->c_switch_type->t_is_enum)) 417 1.75 rillig return; 418 1.115 rillig if (tn->tn_type->t_is_enum && cs->c_switch_type->t_is_enum && 419 1.183 rillig tn->tn_type->u.enumer == cs->c_switch_type->u.enumer) 420 1.75 rillig return; 421 1.75 rillig 422 1.76 rillig #if 0 /* not yet ready, see msg_130.c */ 423 1.75 rillig /* enum type mismatch: '%s' '%s' '%s' */ 424 1.115 rillig warning(130, type_name(cs->c_switch_type), op_name(EQ), 425 1.75 rillig type_name(tn->tn_type)); 426 1.76 rillig #endif 427 1.75 rillig } 428 1.75 rillig 429 1.182 rillig static bool 430 1.182 rillig check_duplicate_case_label(control_statement *cs, const val_t *nv) 431 1.182 rillig { 432 1.182 rillig case_labels *labels = &cs->c_case_labels; 433 1.182 rillig size_t i = 0, n = labels->len; 434 1.182 rillig 435 1.182 rillig while (i < n && labels->vals[i].u.integer != nv->u.integer) 436 1.182 rillig i++; 437 1.182 rillig 438 1.182 rillig if (i < n) { 439 1.182 rillig if (is_uinteger(nv->v_tspec)) 440 1.185 rillig /* duplicate case '%ju' in switch */ 441 1.185 rillig error(200, (uintmax_t)nv->u.integer); 442 1.182 rillig else 443 1.185 rillig /* duplicate case '%jd' in switch */ 444 1.185 rillig error(199, (intmax_t)nv->u.integer); 445 1.182 rillig return false; 446 1.182 rillig } 447 1.182 rillig 448 1.182 rillig if (labels->len >= labels->cap) { 449 1.182 rillig labels->cap = 16 + 2 * labels->cap; 450 1.182 rillig labels->vals = xrealloc(labels->vals, 451 1.182 rillig sizeof(*labels->vals) * labels->cap); 452 1.182 rillig } 453 1.182 rillig labels->vals[labels->len++] = *nv; 454 1.182 rillig return true; 455 1.182 rillig } 456 1.182 rillig 457 1.75 rillig static void 458 1.180 rillig check_case_label(tnode_t *tn) 459 1.1 cgd { 460 1.180 rillig control_statement *cs; 461 1.180 rillig for (cs = cstmt; cs != NULL && !cs->c_switch; cs = cs->c_surrounding) 462 1.180 rillig continue; 463 1.1 cgd 464 1.115 rillig if (cs == NULL) { 465 1.42 rillig /* case not in switch */ 466 1.42 rillig error(195); 467 1.43 rillig return; 468 1.43 rillig } 469 1.43 rillig 470 1.149 rillig if (tn == NULL) 471 1.149 rillig return; 472 1.149 rillig 473 1.149 rillig if (tn->tn_op != CON) { 474 1.42 rillig /* non-constant case expression */ 475 1.42 rillig error(197); 476 1.43 rillig return; 477 1.43 rillig } 478 1.43 rillig 479 1.149 rillig if (!is_integer(tn->tn_type->t_tspec)) { 480 1.42 rillig /* non-integral case expression */ 481 1.42 rillig error(198); 482 1.43 rillig return; 483 1.42 rillig } 484 1.1 cgd 485 1.115 rillig check_case_label_bitand(tn, cs->c_switch_expr); 486 1.115 rillig check_case_label_enum(tn, cs); 487 1.75 rillig 488 1.115 rillig lint_assert(cs->c_switch_type != NULL); 489 1.1 cgd 490 1.168 rillig if (reached && !suppress_fallthrough) { 491 1.43 rillig if (hflag) 492 1.43 rillig /* fallthrough on case statement */ 493 1.43 rillig warning(220); 494 1.43 rillig } 495 1.1 cgd 496 1.180 rillig tspec_t t = tn->tn_type->t_tspec; 497 1.180 rillig if ((t == LONG || t == ULONG || t == LLONG || t == ULLONG) 498 1.180 rillig && !allow_c90) 499 1.180 rillig /* case label must be of type 'int' in traditional C */ 500 1.180 rillig warning(203); 501 1.1 cgd 502 1.180 rillig val_t *v = integer_constant(tn, true); 503 1.180 rillig val_t nv; 504 1.101 rillig (void)memset(&nv, 0, sizeof(nv)); 505 1.115 rillig convert_constant(CASE, 0, cs->c_switch_type, &nv, v); 506 1.43 rillig free(v); 507 1.43 rillig 508 1.182 rillig if (check_duplicate_case_label(cs, &nv)) 509 1.163 rillig check_getopt_case_label(nv.u.integer); 510 1.43 rillig } 511 1.43 rillig 512 1.43 rillig void 513 1.43 rillig case_label(tnode_t *tn) 514 1.43 rillig { 515 1.180 rillig check_case_label(tn); 516 1.99 rillig expr_free_all(); 517 1.93 rillig set_reached(true); 518 1.42 rillig } 519 1.42 rillig 520 1.42 rillig void 521 1.42 rillig default_label(void) 522 1.42 rillig { 523 1.180 rillig /* find the innermost switch statement */ 524 1.115 rillig control_statement *cs; 525 1.115 rillig for (cs = cstmt; cs != NULL && !cs->c_switch; cs = cs->c_surrounding) 526 1.42 rillig continue; 527 1.1 cgd 528 1.180 rillig if (cs == NULL) 529 1.42 rillig /* default outside switch */ 530 1.42 rillig error(201); 531 1.180 rillig else if (cs->c_default) 532 1.42 rillig /* duplicate default in switch */ 533 1.42 rillig error(202); 534 1.180 rillig else { 535 1.168 rillig if (reached && !suppress_fallthrough) { 536 1.42 rillig if (hflag) 537 1.42 rillig /* fallthrough on default statement */ 538 1.42 rillig warning(284); 539 1.1 cgd } 540 1.115 rillig cs->c_default = true; 541 1.42 rillig } 542 1.42 rillig 543 1.93 rillig set_reached(true); 544 1.1 cgd } 545 1.1 cgd 546 1.39 rillig static tnode_t * 547 1.187 rillig check_controlling_expression(tnode_t *tn, bool is_do_while) 548 1.39 rillig { 549 1.124 rillig tn = cconv(tn); 550 1.39 rillig if (tn != NULL) 551 1.60 rillig tn = promote(NOOP, false, tn); 552 1.39 rillig 553 1.55 rillig if (tn != NULL && !is_scalar(tn->tn_type->t_tspec)) { 554 1.39 rillig /* C99 6.5.15p4 for the ?: operator; see typeok:QUEST */ 555 1.39 rillig /* C99 6.8.4.1p1 for if statements */ 556 1.39 rillig /* C99 6.8.5p2 for while, do and for loops */ 557 1.39 rillig /* controlling expressions must have scalar type */ 558 1.39 rillig error(204); 559 1.39 rillig return NULL; 560 1.39 rillig } 561 1.39 rillig 562 1.187 rillig if (tn != NULL && Tflag 563 1.187 rillig && !is_typeok_bool_compares_with_zero(tn, is_do_while)) { 564 1.57 rillig /* controlling expression must be bool, not '%s' */ 565 1.196 rillig error(333, tn->tn_type->t_is_enum ? expr_type_name(tn) 566 1.154 rillig : tspec_name(tn->tn_type->t_tspec)); 567 1.57 rillig } 568 1.57 rillig 569 1.39 rillig return tn; 570 1.39 rillig } 571 1.39 rillig 572 1.1 cgd void 573 1.158 rillig stmt_if_expr(tnode_t *tn) 574 1.1 cgd { 575 1.1 cgd if (tn != NULL) 576 1.187 rillig tn = check_controlling_expression(tn, false); 577 1.1 cgd if (tn != NULL) 578 1.189 rillig expr(tn, false, true, false, false, "if"); 579 1.96 rillig begin_control_statement(CS_IF); 580 1.88 rillig 581 1.88 rillig if (tn != NULL && tn->tn_op == CON && !tn->tn_system_dependent) { 582 1.93 rillig /* XXX: what if inside 'if (0)'? */ 583 1.93 rillig set_reached(constant_is_nonzero(tn)); 584 1.93 rillig /* XXX: what about always_else? */ 585 1.88 rillig cstmt->c_always_then = reached; 586 1.88 rillig } 587 1.1 cgd } 588 1.1 cgd 589 1.1 cgd void 590 1.158 rillig stmt_if_then_stmt(void) 591 1.1 cgd { 592 1.87 rillig cstmt->c_reached_end_of_then = reached; 593 1.93 rillig /* XXX: what if inside 'if (0)'? */ 594 1.93 rillig set_reached(!cstmt->c_always_then); 595 1.1 cgd } 596 1.1 cgd 597 1.1 cgd void 598 1.158 rillig stmt_if_else_stmt(bool els) 599 1.1 cgd { 600 1.90 rillig if (cstmt->c_reached_end_of_then) 601 1.93 rillig set_reached(true); 602 1.90 rillig else if (cstmt->c_always_then) 603 1.93 rillig set_reached(false); 604 1.90 rillig else if (!els) 605 1.93 rillig set_reached(true); 606 1.14 lukem 607 1.96 rillig end_control_statement(CS_IF); 608 1.1 cgd } 609 1.1 cgd 610 1.1 cgd void 611 1.158 rillig stmt_switch_expr(tnode_t *tn) 612 1.1 cgd { 613 1.1 cgd if (tn != NULL) 614 1.1 cgd tn = cconv(tn); 615 1.1 cgd if (tn != NULL) 616 1.60 rillig tn = promote(NOOP, false, tn); 617 1.55 rillig if (tn != NULL && !is_integer(tn->tn_type->t_tspec)) { 618 1.1 cgd /* switch expression must have integral type */ 619 1.1 cgd error(205); 620 1.1 cgd tn = NULL; 621 1.1 cgd } 622 1.134 rillig if (tn != NULL && !allow_c90) { 623 1.180 rillig tspec_t t = tn->tn_type->t_tspec; 624 1.181 rillig if (t == LONG || t == ULONG || t == LLONG || t == ULLONG) 625 1.123 rillig /* switch expression must be of type 'int' in ... */ 626 1.1 cgd warning(271); 627 1.1 cgd } 628 1.1 cgd 629 1.1 cgd /* 630 1.177 rillig * Remember the type of the expression. Because it's possible that 631 1.177 rillig * (*tp) is allocated on tree memory, the type must be duplicated. This 632 1.177 rillig * is not too complicated because it is only an integer type. 633 1.1 cgd */ 634 1.180 rillig type_t *tp = xcalloc(1, sizeof(*tp)); 635 1.1 cgd if (tn != NULL) { 636 1.1 cgd tp->t_tspec = tn->tn_type->t_tspec; 637 1.71 rillig if ((tp->t_is_enum = tn->tn_type->t_is_enum) != false) 638 1.183 rillig tp->u.enumer = tn->tn_type->u.enumer; 639 1.1 cgd } else { 640 1.1 cgd tp->t_tspec = INT; 641 1.1 cgd } 642 1.1 cgd 643 1.108 rillig /* leak the memory, for check_case_label_bitand */ 644 1.122 rillig (void)expr_save_memory(); 645 1.108 rillig 646 1.68 rillig check_getopt_begin_switch(); 647 1.189 rillig expr(tn, true, false, false, false, "switch"); 648 1.1 cgd 649 1.96 rillig begin_control_statement(CS_SWITCH); 650 1.59 rillig cstmt->c_switch = true; 651 1.97 rillig cstmt->c_switch_type = tp; 652 1.108 rillig cstmt->c_switch_expr = tn; 653 1.1 cgd 654 1.93 rillig set_reached(false); 655 1.168 rillig suppress_fallthrough = true; 656 1.1 cgd } 657 1.1 cgd 658 1.1 cgd void 659 1.158 rillig stmt_switch_expr_stmt(void) 660 1.1 cgd { 661 1.155 rillig int nenum = 0, nclab = 0; 662 1.155 rillig sym_t *esym; 663 1.1 cgd 664 1.97 rillig lint_assert(cstmt->c_switch_type != NULL); 665 1.1 cgd 666 1.97 rillig if (cstmt->c_switch_type->t_is_enum) { 667 1.112 rillig /* 668 1.112 rillig * Warn if the number of case labels is different from the 669 1.112 rillig * number of enumerators. 670 1.112 rillig */ 671 1.1 cgd nenum = nclab = 0; 672 1.183 rillig lint_assert(cstmt->c_switch_type->u.enumer != NULL); 673 1.183 rillig for (esym = cstmt->c_switch_type->u.enumer->en_first_enumerator; 674 1.176 rillig esym != NULL; esym = esym->s_next) { 675 1.1 cgd nenum++; 676 1.1 cgd } 677 1.182 rillig nclab = (int)cstmt->c_case_labels.len; 678 1.181 rillig if (hflag && eflag && nclab < nenum && !cstmt->c_default) 679 1.1 cgd /* enumeration value(s) not handled in switch */ 680 1.1 cgd warning(206); 681 1.1 cgd } 682 1.1 cgd 683 1.68 rillig check_getopt_end_switch(); 684 1.68 rillig 685 1.48 rillig if (cstmt->c_break) { 686 1.1 cgd /* 687 1.112 rillig * The end of the switch statement is always reached since 688 1.177 rillig * c_break is only set if a break statement can actually be 689 1.177 rillig * reached. 690 1.1 cgd */ 691 1.93 rillig set_reached(true); 692 1.112 rillig } else if (cstmt->c_default || 693 1.112 rillig (hflag && cstmt->c_switch_type->t_is_enum && 694 1.112 rillig nenum == nclab)) { 695 1.1 cgd /* 696 1.177 rillig * The end of the switch statement is reached if the end of the 697 1.177 rillig * last statement inside it is reached. 698 1.112 rillig */ 699 1.112 rillig } else { 700 1.112 rillig /* 701 1.177 rillig * There are possible values that are not handled in the switch 702 1.177 rillig * statement. 703 1.1 cgd */ 704 1.93 rillig set_reached(true); 705 1.112 rillig } 706 1.1 cgd 707 1.96 rillig end_control_statement(CS_SWITCH); 708 1.1 cgd } 709 1.1 cgd 710 1.1 cgd void 711 1.158 rillig stmt_while_expr(tnode_t *tn) 712 1.1 cgd { 713 1.1 cgd if (!reached) { 714 1.93 rillig /* FIXME: that's plain wrong. */ 715 1.93 rillig set_reached(true); 716 1.1 cgd } 717 1.1 cgd 718 1.1 cgd if (tn != NULL) 719 1.187 rillig tn = check_controlling_expression(tn, false); 720 1.1 cgd 721 1.96 rillig begin_control_statement(CS_WHILE); 722 1.59 rillig cstmt->c_loop = true; 723 1.92 rillig cstmt->c_maybe_endless = is_nonzero(tn); 724 1.180 rillig bool body_reached = !is_zero(tn); 725 1.1 cgd 726 1.68 rillig check_getopt_begin_while(tn); 727 1.189 rillig expr(tn, false, true, true, false, "while"); 728 1.92 rillig 729 1.93 rillig set_reached(body_reached); 730 1.1 cgd } 731 1.1 cgd 732 1.1 cgd void 733 1.158 rillig stmt_while_expr_stmt(void) 734 1.1 cgd { 735 1.93 rillig set_reached(!cstmt->c_maybe_endless || cstmt->c_break); 736 1.68 rillig check_getopt_end_while(); 737 1.96 rillig end_control_statement(CS_WHILE); 738 1.1 cgd } 739 1.1 cgd 740 1.1 cgd void 741 1.158 rillig stmt_do(void) 742 1.1 cgd { 743 1.195 rillig if (!reached) 744 1.93 rillig set_reached(true); 745 1.1 cgd 746 1.96 rillig begin_control_statement(CS_DO_WHILE); 747 1.59 rillig cstmt->c_loop = true; 748 1.1 cgd } 749 1.1 cgd 750 1.1 cgd void 751 1.158 rillig stmt_do_while_expr(tnode_t *tn) 752 1.1 cgd { 753 1.85 rillig if (cstmt->c_continue) 754 1.93 rillig set_reached(true); 755 1.1 cgd 756 1.1 cgd if (tn != NULL) 757 1.187 rillig tn = check_controlling_expression(tn, true); 758 1.1 cgd 759 1.1 cgd if (tn != NULL && tn->tn_op == CON) { 760 1.84 rillig cstmt->c_maybe_endless = constant_is_nonzero(tn); 761 1.85 rillig if (!cstmt->c_maybe_endless && cstmt->c_continue) 762 1.46 rillig /* continue in 'do ... while (0)' loop */ 763 1.46 rillig error(323); 764 1.1 cgd } 765 1.1 cgd 766 1.189 rillig expr(tn, false, true, true, true, "do-while"); 767 1.1 cgd 768 1.84 rillig if (cstmt->c_maybe_endless) 769 1.93 rillig set_reached(false); 770 1.83 rillig if (cstmt->c_break) 771 1.93 rillig set_reached(true); 772 1.1 cgd 773 1.96 rillig end_control_statement(CS_DO_WHILE); 774 1.1 cgd } 775 1.1 cgd 776 1.1 cgd void 777 1.158 rillig stmt_for_exprs(tnode_t *tn1, tnode_t *tn2, tnode_t *tn3) 778 1.1 cgd { 779 1.1 cgd /* 780 1.177 rillig * If there is no initialization expression it is possible that it is 781 1.177 rillig * intended not to enter the loop at top. 782 1.1 cgd */ 783 1.195 rillig if (tn1 != NULL && !reached) 784 1.93 rillig set_reached(true); 785 1.1 cgd 786 1.96 rillig begin_control_statement(CS_FOR); 787 1.59 rillig cstmt->c_loop = true; 788 1.1 cgd 789 1.1 cgd /* 790 1.177 rillig * Store the tree memory for the reinitialization expression. Also 791 1.177 rillig * remember this expression itself. We must check it at the end of the 792 1.177 rillig * loop to get "used but not set" warnings correct. 793 1.1 cgd */ 794 1.99 rillig cstmt->c_for_expr3_mem = expr_save_memory(); 795 1.97 rillig cstmt->c_for_expr3 = tn3; 796 1.97 rillig cstmt->c_for_expr3_pos = curr_pos; 797 1.97 rillig cstmt->c_for_expr3_csrc_pos = csrc_pos; 798 1.1 cgd 799 1.1 cgd if (tn1 != NULL) 800 1.189 rillig expr(tn1, false, false, true, false, "for"); 801 1.1 cgd 802 1.1 cgd if (tn2 != NULL) 803 1.187 rillig tn2 = check_controlling_expression(tn2, false); 804 1.1 cgd if (tn2 != NULL) 805 1.189 rillig expr(tn2, false, true, true, false, "for"); 806 1.1 cgd 807 1.91 rillig cstmt->c_maybe_endless = tn2 == NULL || is_nonzero(tn2); 808 1.1 cgd 809 1.158 rillig /* The tn3 expression is checked in stmt_for_exprs_stmt. */ 810 1.1 cgd 811 1.93 rillig set_reached(!is_zero(tn2)); 812 1.1 cgd } 813 1.1 cgd 814 1.1 cgd void 815 1.158 rillig stmt_for_exprs_stmt(void) 816 1.1 cgd { 817 1.85 rillig if (cstmt->c_continue) 818 1.93 rillig set_reached(true); 819 1.1 cgd 820 1.180 rillig expr_restore_memory(cstmt->c_for_expr3_mem); 821 1.180 rillig tnode_t *tn3 = cstmt->c_for_expr3; 822 1.1 cgd 823 1.180 rillig pos_t saved_curr_pos = curr_pos; 824 1.180 rillig pos_t saved_csrc_pos = csrc_pos; 825 1.97 rillig curr_pos = cstmt->c_for_expr3_pos; 826 1.97 rillig csrc_pos = cstmt->c_for_expr3_csrc_pos; 827 1.1 cgd 828 1.1 cgd /* simply "statement not reached" would be confusing */ 829 1.94 rillig if (!reached && warn_about_unreachable) { 830 1.1 cgd /* end-of-loop code not reached */ 831 1.1 cgd warning(223); 832 1.93 rillig set_reached(true); 833 1.1 cgd } 834 1.1 cgd 835 1.180 rillig if (tn3 != NULL) 836 1.189 rillig expr(tn3, false, false, true, false, "for continuation"); 837 1.180 rillig else 838 1.99 rillig expr_free_all(); 839 1.1 cgd 840 1.180 rillig curr_pos = saved_curr_pos; 841 1.180 rillig csrc_pos = saved_csrc_pos; 842 1.1 cgd 843 1.93 rillig set_reached(cstmt->c_break || !cstmt->c_maybe_endless); 844 1.1 cgd 845 1.96 rillig end_control_statement(CS_FOR); 846 1.1 cgd } 847 1.1 cgd 848 1.1 cgd void 849 1.158 rillig stmt_goto(sym_t *lab) 850 1.1 cgd { 851 1.60 rillig mark_as_used(lab, false, false); 852 1.189 rillig check_statement_reachable("goto"); 853 1.93 rillig set_reached(false); 854 1.1 cgd } 855 1.1 cgd 856 1.1 cgd void 857 1.158 rillig stmt_break(void) 858 1.1 cgd { 859 1.180 rillig control_statement *cs = cstmt; 860 1.115 rillig while (cs != NULL && !cs->c_loop && !cs->c_switch) 861 1.115 rillig cs = cs->c_surrounding; 862 1.1 cgd 863 1.180 rillig if (cs == NULL) 864 1.1 cgd /* break outside loop or switch */ 865 1.1 cgd error(208); 866 1.180 rillig else if (reached) 867 1.180 rillig cs->c_break = true; 868 1.1 cgd 869 1.1 cgd if (bflag) 870 1.189 rillig check_statement_reachable("break"); 871 1.1 cgd 872 1.93 rillig set_reached(false); 873 1.1 cgd } 874 1.1 cgd 875 1.1 cgd void 876 1.158 rillig stmt_continue(void) 877 1.1 cgd { 878 1.115 rillig control_statement *cs; 879 1.1 cgd 880 1.115 rillig for (cs = cstmt; cs != NULL && !cs->c_loop; cs = cs->c_surrounding) 881 1.14 lukem continue; 882 1.1 cgd 883 1.180 rillig if (cs == NULL) 884 1.1 cgd /* continue outside loop */ 885 1.1 cgd error(209); 886 1.180 rillig else 887 1.85 rillig /* TODO: only if reachable, for symmetry with c_break */ 888 1.115 rillig cs->c_continue = true; 889 1.1 cgd 890 1.189 rillig check_statement_reachable("continue"); 891 1.1 cgd 892 1.93 rillig set_reached(false); 893 1.1 cgd } 894 1.1 cgd 895 1.188 rillig void 896 1.188 rillig stmt_call_noreturn(void) 897 1.188 rillig { 898 1.188 rillig set_reached(false); 899 1.188 rillig } 900 1.188 rillig 901 1.153 rillig static bool 902 1.153 rillig is_parenthesized(const tnode_t *tn) 903 1.153 rillig { 904 1.153 rillig while (!tn->tn_parenthesized && tn->tn_op == COMMA) 905 1.184 rillig tn = tn->u.ops.right; 906 1.153 rillig return tn->tn_parenthesized && !tn->tn_sys; 907 1.153 rillig } 908 1.153 rillig 909 1.152 rillig static void 910 1.152 rillig check_return_value(bool sys, tnode_t *tn) 911 1.152 rillig { 912 1.191 rillig if (any_query_enabled && is_parenthesized(tn)) 913 1.153 rillig /* parenthesized return value */ 914 1.153 rillig query_message(9); 915 1.153 rillig 916 1.152 rillig /* Create a temporary node for the left side */ 917 1.171 rillig tnode_t *ln = expr_zero_alloc(sizeof(*ln), "tnode"); 918 1.152 rillig ln->tn_op = NAME; 919 1.152 rillig ln->tn_type = expr_unqualified_type(funcsym->s_type->t_subt); 920 1.152 rillig ln->tn_lvalue = true; 921 1.184 rillig ln->u.sym = funcsym; /* better than nothing */ 922 1.152 rillig 923 1.152 rillig tnode_t *retn = build_binary(ln, RETURN, sys, tn); 924 1.152 rillig 925 1.152 rillig if (retn != NULL) { 926 1.184 rillig const tnode_t *rn = retn->u.ops.right; 927 1.152 rillig while (rn->tn_op == CVT || rn->tn_op == PLUS) 928 1.184 rillig rn = rn->u.ops.left; 929 1.184 rillig if (rn->tn_op == ADDR && rn->u.ops.left->tn_op == NAME && 930 1.184 rillig rn->u.ops.left->u.sym->s_scl == AUTO) 931 1.152 rillig /* '%s' returns pointer to automatic object */ 932 1.152 rillig warning(302, funcsym->s_name); 933 1.152 rillig } 934 1.152 rillig 935 1.189 rillig expr(retn, true, false, true, false, "return"); 936 1.152 rillig } 937 1.152 rillig 938 1.1 cgd void 939 1.158 rillig stmt_return(bool sys, tnode_t *tn) 940 1.1 cgd { 941 1.152 rillig control_statement *cs = cstmt; 942 1.1 cgd 943 1.115 rillig if (cs == NULL) { 944 1.109 rillig /* syntax error '%s' */ 945 1.109 rillig error(249, "return outside function"); 946 1.109 rillig return; 947 1.109 rillig } 948 1.109 rillig 949 1.115 rillig for (; cs->c_surrounding != NULL; cs = cs->c_surrounding) 950 1.14 lukem continue; 951 1.1 cgd 952 1.82 rillig if (tn != NULL) 953 1.115 rillig cs->c_had_return_value = true; 954 1.82 rillig else 955 1.115 rillig cs->c_had_return_noval = true; 956 1.1 cgd 957 1.1 cgd if (tn != NULL && funcsym->s_type->t_subt->t_tspec == VOID) { 958 1.142 rillig /* void function '%s' cannot return value */ 959 1.1 cgd error(213, funcsym->s_name); 960 1.99 rillig expr_free_all(); 961 1.1 cgd tn = NULL; 962 1.174 rillig } 963 1.174 rillig if (tn == NULL && funcsym->s_type->t_subt->t_tspec != VOID 964 1.174 rillig && !funcsym->s_return_type_implicit_int) { 965 1.174 rillig if (allow_c99) 966 1.174 rillig /* function '%s' expects to return value */ 967 1.174 rillig error(214, funcsym->s_name); 968 1.174 rillig else 969 1.119 rillig /* function '%s' expects to return value */ 970 1.1 cgd warning(214, funcsym->s_name); 971 1.1 cgd } 972 1.1 cgd 973 1.152 rillig if (tn != NULL) 974 1.152 rillig check_return_value(sys, tn); 975 1.152 rillig else 976 1.189 rillig check_statement_reachable("return"); 977 1.1 cgd 978 1.93 rillig set_reached(false); 979 1.1 cgd } 980 1.1 cgd 981 1.1 cgd void 982 1.59 rillig global_clean_up_decl(bool silent) 983 1.1 cgd { 984 1.1 cgd if (nargusg != -1) { 985 1.181 rillig if (!silent) 986 1.142 rillig /* comment ** %s ** must precede function definition */ 987 1.105 rillig warning_at(282, &argsused_pos, "ARGSUSED"); 988 1.1 cgd nargusg = -1; 989 1.1 cgd } 990 1.1 cgd if (nvararg != -1) { 991 1.181 rillig if (!silent) 992 1.142 rillig /* comment ** %s ** must precede function definition */ 993 1.105 rillig warning_at(282, &vapos, "VARARGS"); 994 1.1 cgd nvararg = -1; 995 1.1 cgd } 996 1.49 rillig if (printflike_argnum != -1) { 997 1.181 rillig if (!silent) 998 1.142 rillig /* comment ** %s ** must precede function definition */ 999 1.105 rillig warning_at(282, &printflike_pos, "PRINTFLIKE"); 1000 1.49 rillig printflike_argnum = -1; 1001 1.1 cgd } 1002 1.49 rillig if (scanflike_argnum != -1) { 1003 1.181 rillig if (!silent) 1004 1.143 rillig /* comment ** %s ** must precede function definition */ 1005 1.105 rillig warning_at(282, &scanflike_pos, "SCANFLIKE"); 1006 1.49 rillig scanflike_argnum = -1; 1007 1.1 cgd } 1008 1.1 cgd 1009 1.59 rillig dcs->d_asm = false; 1010 1.107 rillig 1011 1.107 rillig /* 1012 1.107 rillig * Needed for BSD yacc in case of parse errors; GNU Bison 3.0.4 is 1013 1.125 rillig * fine. See test gcc_attribute.c, function_with_unknown_attribute. 1014 1.107 rillig */ 1015 1.125 rillig in_gcc_attribute = false; 1016 1.130 rillig while (dcs->d_enclosing != NULL) 1017 1.130 rillig end_declaration_level(); 1018 1.1 cgd } 1019 1.1 cgd 1020 1.1 cgd /* 1021 1.173 rillig * Only the first n parameters of the following function are checked for usage. 1022 1.169 rillig * A missing argument is taken to be 0. 1023 1.1 cgd */ 1024 1.169 rillig static void 1025 1.14 lukem argsused(int n) 1026 1.1 cgd { 1027 1.160 rillig if (dcs->d_kind != DLK_EXTERN) { 1028 1.142 rillig /* comment ** %s ** must be outside function */ 1029 1.1 cgd warning(280, "ARGSUSED"); 1030 1.1 cgd return; 1031 1.1 cgd } 1032 1.181 rillig if (nargusg != -1) 1033 1.142 rillig /* duplicate comment ** %s ** */ 1034 1.1 cgd warning(281, "ARGSUSED"); 1035 1.180 rillig nargusg = n != -1 ? n : 0; 1036 1.36 rillig argsused_pos = curr_pos; 1037 1.1 cgd } 1038 1.1 cgd 1039 1.169 rillig static void 1040 1.14 lukem varargs(int n) 1041 1.1 cgd { 1042 1.160 rillig if (dcs->d_kind != DLK_EXTERN) { 1043 1.142 rillig /* comment ** %s ** must be outside function */ 1044 1.1 cgd warning(280, "VARARGS"); 1045 1.1 cgd return; 1046 1.1 cgd } 1047 1.181 rillig if (nvararg != -1) 1048 1.142 rillig /* duplicate comment ** %s ** */ 1049 1.1 cgd warning(281, "VARARGS"); 1050 1.180 rillig nvararg = n != -1 ? n : 0; 1051 1.36 rillig vapos = curr_pos; 1052 1.1 cgd } 1053 1.1 cgd 1054 1.1 cgd /* 1055 1.173 rillig * Check all parameters until the (n-1)-th as usual. The n-th argument is 1056 1.173 rillig * used to check the types of the remaining arguments. 1057 1.1 cgd */ 1058 1.169 rillig static void 1059 1.14 lukem printflike(int n) 1060 1.1 cgd { 1061 1.160 rillig if (dcs->d_kind != DLK_EXTERN) { 1062 1.142 rillig /* comment ** %s ** must be outside function */ 1063 1.1 cgd warning(280, "PRINTFLIKE"); 1064 1.1 cgd return; 1065 1.1 cgd } 1066 1.181 rillig if (printflike_argnum != -1) 1067 1.142 rillig /* duplicate comment ** %s ** */ 1068 1.1 cgd warning(281, "PRINTFLIKE"); 1069 1.180 rillig printflike_argnum = n != -1 ? n : 0; 1070 1.36 rillig printflike_pos = curr_pos; 1071 1.1 cgd } 1072 1.1 cgd 1073 1.1 cgd /* 1074 1.173 rillig * Check all parameters until the (n-1)-th as usual. The n-th argument is 1075 1.1 cgd * used the check the types of remaining arguments. 1076 1.1 cgd */ 1077 1.169 rillig static void 1078 1.14 lukem scanflike(int n) 1079 1.1 cgd { 1080 1.160 rillig if (dcs->d_kind != DLK_EXTERN) { 1081 1.142 rillig /* comment ** %s ** must be outside function */ 1082 1.1 cgd warning(280, "SCANFLIKE"); 1083 1.1 cgd return; 1084 1.1 cgd } 1085 1.181 rillig if (scanflike_argnum != -1) 1086 1.142 rillig /* duplicate comment ** %s ** */ 1087 1.1 cgd warning(281, "SCANFLIKE"); 1088 1.180 rillig scanflike_argnum = n != -1 ? n : 0; 1089 1.36 rillig scanflike_pos = curr_pos; 1090 1.1 cgd } 1091 1.1 cgd 1092 1.169 rillig static void 1093 1.169 rillig lintlib(void) 1094 1.1 cgd { 1095 1.160 rillig if (dcs->d_kind != DLK_EXTERN) { 1096 1.142 rillig /* comment ** %s ** must be outside function */ 1097 1.1 cgd warning(280, "LINTLIBRARY"); 1098 1.1 cgd return; 1099 1.1 cgd } 1100 1.59 rillig llibflg = true; 1101 1.165 rillig vflag = true; 1102 1.1 cgd } 1103 1.1 cgd 1104 1.1 cgd /* 1105 1.28 rillig * PROTOLIB in conjunction with LINTLIBRARY can be used to handle 1106 1.1 cgd * prototypes like function definitions. This is done if the argument 1107 1.156 rillig * to PROTOLIB is nonzero. Otherwise, prototypes are handled normally. 1108 1.1 cgd */ 1109 1.169 rillig static void 1110 1.14 lukem protolib(int n) 1111 1.1 cgd { 1112 1.160 rillig if (dcs->d_kind != DLK_EXTERN) { 1113 1.142 rillig /* comment ** %s ** must be outside function */ 1114 1.1 cgd warning(280, "PROTOLIB"); 1115 1.1 cgd return; 1116 1.1 cgd } 1117 1.59 rillig plibflg = n != 0; 1118 1.6 jpo } 1119 1.6 jpo 1120 1.6 jpo void 1121 1.169 rillig handle_lint_comment(lint_comment comment, int arg) 1122 1.6 jpo { 1123 1.169 rillig switch (comment) { 1124 1.169 rillig case LC_ARGSUSED: argsused(arg); break; 1125 1.169 rillig case LC_BITFIELDTYPE: suppress_bitfieldtype = true; break; 1126 1.169 rillig case LC_FALLTHROUGH: suppress_fallthrough = true; break; 1127 1.169 rillig case LC_LINTLIBRARY: lintlib(); break; 1128 1.169 rillig case LC_LINTED: debug_step("set lwarn %d", arg); 1129 1.169 rillig lwarn = arg; break; 1130 1.169 rillig case LC_LONGLONG: suppress_longlong = true; break; 1131 1.169 rillig case LC_NOTREACHED: set_reached(false); 1132 1.169 rillig warn_about_unreachable = false; break; 1133 1.169 rillig case LC_PRINTFLIKE: printflike(arg); break; 1134 1.169 rillig case LC_PROTOLIB: protolib(arg); break; 1135 1.169 rillig case LC_SCANFLIKE: scanflike(arg); break; 1136 1.169 rillig case LC_VARARGS: varargs(arg); break; 1137 1.169 rillig } 1138 1.1 cgd } 1139