[BACK]Return to func.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / usr.bin / xlint / lint1

Annotation of src/usr.bin/xlint/lint1/func.c, Revision 1.142

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

CVSweb <webmaster@jp.NetBSD.org>