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

Annotation of src/usr.bin/xlint/lint1/decl.c, Revision 1.114

1.114   ! rillig      1: /* $NetBSD: decl.c,v 1.113 2021/01/09 14:10:15 rillig Exp $ */
1.2       cgd         2:
1.1       cgd         3: /*
1.12      cgd         4:  * Copyright (c) 1996 Christopher G. Demetriou.  All Rights Reserved.
1.1       cgd         5:  * Copyright (c) 1994, 1995 Jochen Pohl
                      6:  * All Rights Reserved.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  * 3. All advertising materials mentioning features or use of this software
                     17:  *    must display the following acknowledgement:
                     18:  *      This product includes software developed by Jochen Pohl for
                     19:  *     The NetBSD Project.
                     20:  * 4. The name of the author may not be used to endorse or promote products
                     21:  *    derived from this software without specific prior written permission.
                     22:  *
                     23:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     24:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     25:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     26:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     27:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     28:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     29:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     30:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     31:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     32:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     33:  */
                     34:
1.33      jmc        35: #if HAVE_NBTOOL_CONFIG_H
                     36: #include "nbtool_config.h"
                     37: #endif
                     38:
1.13      christos   39: #include <sys/cdefs.h>
1.30      tv         40: #if defined(__RCSID) && !defined(lint)
1.114   ! rillig     41: __RCSID("$NetBSD: decl.c,v 1.113 2021/01/09 14:10:15 rillig Exp $");
1.1       cgd        42: #endif
                     43:
                     44: #include <sys/param.h>
                     45: #include <limits.h>
                     46: #include <stdlib.h>
                     47: #include <string.h>
                     48:
                     49: #include "lint1.h"
                     50:
                     51: const  char *unnamed = "<unnamed>";
                     52:
1.111     rillig     53: /* shared type structures for arithmetic types and void */
1.1       cgd        54: static type_t  *typetab;
                     55:
                     56: /* value of next enumerator during declaration of enum types */
                     57: int    enumval;
                     58:
                     59: /*
1.73      rillig     60:  * pointer to top element of a stack which contains information local
1.1       cgd        61:  * to nested declarations
                     62:  */
                     63: dinfo_t        *dcs;
                     64:
1.22      lukem      65: static type_t  *tdeferr(type_t *, tspec_t);
                     66: static void    settdsym(type_t *, sym_t *);
1.77      rillig     67: static tspec_t merge_type_specifiers(tspec_t, tspec_t);
1.22      lukem      68: static void    align(int, int);
                     69: static sym_t   *newtag(sym_t *, scl_t, int, int);
                     70: static int     eqargs(type_t *, type_t *, int *);
                     71: static int     mnoarg(type_t *, int *);
1.75      rillig     72: static int     check_old_style_definition(sym_t *, sym_t *);
                     73: static int     check_prototype_declaration(sym_t *, sym_t *);
                     74: static sym_t   *new_style_function(sym_t *, sym_t *);
                     75: static void    old_style_function(sym_t *, sym_t *);
1.22      lukem      76: static void    ledecl(sym_t *);
1.75      rillig     77: static int     check_init(sym_t *);
                     78: static void    check_argument_usage(int, sym_t *);
                     79: static void    check_variable_usage(int, sym_t *);
                     80: static void    check_label_usage(sym_t *);
                     81: static void    check_tag_usage(sym_t *);
                     82: static void    check_global_variable(sym_t *);
                     83: static void    check_global_variable_size(sym_t *);
1.1       cgd        84:
                     85: /*
                     86:  * initializes all global vars used in declarations
                     87:  */
                     88: void
1.22      lukem      89: initdecl(void)
1.1       cgd        90: {
1.29      thorpej    91:        int i;
1.1       cgd        92:
                     93:        /* declaration stack */
                     94:        dcs = xcalloc(1, sizeof (dinfo_t));
1.3       jpo        95:        dcs->d_ctx = EXTERN;
                     96:        dcs->d_ldlsym = &dcs->d_dlsyms;
1.1       cgd        97:
                     98:        /* type information and classification */
1.29      thorpej    99:        inittyp();
1.22      lukem     100:
1.1       cgd       101:        /* shared type structures */
                    102:        typetab = xcalloc(NTSPEC, sizeof (type_t));
                    103:        for (i = 0; i < NTSPEC; i++)
                    104:                typetab[i].t_tspec = NOTSPEC;
1.34      yamt      105:        typetab[BOOL].t_tspec = BOOL;
1.1       cgd       106:        typetab[CHAR].t_tspec = CHAR;
                    107:        typetab[SCHAR].t_tspec = SCHAR;
                    108:        typetab[UCHAR].t_tspec = UCHAR;
                    109:        typetab[SHORT].t_tspec = SHORT;
                    110:        typetab[USHORT].t_tspec = USHORT;
                    111:        typetab[INT].t_tspec = INT;
                    112:        typetab[UINT].t_tspec = UINT;
                    113:        typetab[LONG].t_tspec = LONG;
                    114:        typetab[ULONG].t_tspec = ULONG;
                    115:        typetab[QUAD].t_tspec = QUAD;
                    116:        typetab[UQUAD].t_tspec = UQUAD;
                    117:        typetab[FLOAT].t_tspec = FLOAT;
                    118:        typetab[DOUBLE].t_tspec = DOUBLE;
                    119:        typetab[LDOUBLE].t_tspec = LDOUBLE;
1.39      christos  120:        typetab[FCOMPLEX].t_tspec = FCOMPLEX;
                    121:        typetab[DCOMPLEX].t_tspec = DCOMPLEX;
1.42      matt      122:        typetab[LCOMPLEX].t_tspec = LCOMPLEX;
1.39      christos  123:        typetab[COMPLEX].t_tspec = COMPLEX;
1.1       cgd       124:        typetab[VOID].t_tspec = VOID;
                    125:        /*
                    126:         * Next two are not real types. They are only used by the parser
                    127:         * to return keywords "signed" and "unsigned"
                    128:         */
                    129:        typetab[SIGNED].t_tspec = SIGNED;
                    130:        typetab[UNSIGN].t_tspec = UNSIGN;
                    131: }
                    132:
                    133: /*
1.73      rillig    134:  * Returns a shared type structure for arithmetic types and void.
1.1       cgd       135:  *
1.80      rillig    136:  * It's important to duplicate this structure (using duptyp() or tduptyp())
1.1       cgd       137:  * if it is to be modified (adding qualifiers or anything else).
                    138:  */
                    139: type_t *
1.22      lukem     140: gettyp(tspec_t t)
1.1       cgd       141: {
1.22      lukem     142:
1.76      rillig    143:        return &typetab[t];
1.1       cgd       144: }
                    145:
                    146: type_t *
1.22      lukem     147: duptyp(const type_t *tp)
1.1       cgd       148: {
                    149:        type_t  *ntp;
                    150:
                    151:        ntp = getblk(sizeof (type_t));
1.85      rillig    152:        *ntp = *tp;
1.76      rillig    153:        return ntp;
1.1       cgd       154: }
                    155:
                    156: /*
                    157:  * Use tduptyp() instead of duptyp() inside expressions (if the
                    158:  * allocated memory should be freed after the expr).
                    159:  */
                    160: type_t *
1.22      lukem     161: tduptyp(const type_t *tp)
1.1       cgd       162: {
                    163:        type_t  *ntp;
                    164:
                    165:        ntp = tgetblk(sizeof (type_t));
1.85      rillig    166:        *ntp = *tp;
1.76      rillig    167:        return ntp;
1.1       cgd       168: }
                    169:
                    170: /*
                    171:  * Returns 1 if the argument is void or an incomplete array,
                    172:  * struct, union or enum type.
                    173:  */
                    174: int
1.22      lukem     175: incompl(type_t *tp)
1.1       cgd       176: {
                    177:        tspec_t t;
                    178:
                    179:        if ((t = tp->t_tspec) == VOID) {
1.76      rillig    180:                return 1;
1.1       cgd       181:        } else if (t == ARRAY) {
1.76      rillig    182:                return tp->t_aincompl;
1.1       cgd       183:        } else if (t == STRUCT || t == UNION) {
1.76      rillig    184:                return tp->t_str->sincompl;
1.1       cgd       185:        } else if (t == ENUM) {
1.76      rillig    186:                return tp->t_enum->eincompl;
1.1       cgd       187:        }
1.76      rillig    188:        return 0;
1.1       cgd       189: }
                    190:
                    191: /*
1.74      rillig    192:  * Mark an array, struct, union or enum type as complete or incomplete.
1.1       cgd       193:  */
                    194: void
1.74      rillig    195: setcomplete(type_t *tp, int complete)
1.1       cgd       196: {
                    197:        tspec_t t;
                    198:
                    199:        if ((t = tp->t_tspec) == ARRAY) {
1.74      rillig    200:                tp->t_aincompl = !complete;
1.1       cgd       201:        } else if (t == STRUCT || t == UNION) {
1.74      rillig    202:                tp->t_str->sincompl = !complete;
1.1       cgd       203:        } else {
1.92      rillig    204:                lint_assert(t == ENUM);
1.74      rillig    205:                tp->t_enum->eincompl = !complete;
1.1       cgd       206:        }
                    207: }
                    208:
                    209: /*
1.3       jpo       210:  * Remember the storage class of the current declaration in dcs->d_scl
1.1       cgd       211:  * (the top element of the declaration stack) and detect multiple
                    212:  * storage classes.
                    213:  */
                    214: void
1.77      rillig    215: add_storage_class(scl_t sc)
1.1       cgd       216: {
1.22      lukem     217:
1.4       jpo       218:        if (sc == INLINE) {
                    219:                if (dcs->d_inline)
                    220:                        /* duplicate '%s' */
                    221:                        warning(10, "inline");
                    222:                dcs->d_inline = 1;
                    223:                return;
                    224:        }
1.3       jpo       225:        if (dcs->d_type != NULL || dcs->d_atyp != NOTSPEC ||
                    226:            dcs->d_smod != NOTSPEC || dcs->d_lmod != NOTSPEC) {
1.1       cgd       227:                /* storage class after type is obsolescent */
                    228:                warning(83);
                    229:        }
1.3       jpo       230:        if (dcs->d_scl == NOSCL) {
                    231:                dcs->d_scl = sc;
1.1       cgd       232:        } else {
                    233:                /*
                    234:                 * multiple storage classes. An error will be reported in
                    235:                 * deftyp().
                    236:                 */
1.3       jpo       237:                dcs->d_mscl = 1;
1.1       cgd       238:        }
                    239: }
                    240:
                    241: /*
                    242:  * Remember the type, modifier or typedef name returned by the parser
                    243:  * in *dcs (top element of decl stack). This information is used in
                    244:  * deftyp() to build the type used for all declarators in this
                    245:  * declaration.
                    246:  *
1.73      rillig    247:  * If tp->t_typedef is 1, the type comes from a previously defined typename.
1.1       cgd       248:  * Otherwise it comes from a type specifier (int, long, ...) or a
                    249:  * struct/union/enum tag.
                    250:  */
                    251: void
1.77      rillig    252: add_type(type_t *tp)
1.1       cgd       253: {
                    254:        tspec_t t;
1.49      christos  255: #ifdef DEBUG
1.98      rillig    256:        printf("%s: %s\n", __func__, type_name(tp));
1.49      christos  257: #endif
1.1       cgd       258:        if (tp->t_typedef) {
1.92      rillig    259:                /*
                    260:                 * something like "typedef int a; int a b;"
                    261:                 * This should not happen with current grammar.
                    262:                 */
                    263:                lint_assert(dcs->d_type == NULL);
                    264:                lint_assert(dcs->d_atyp == NOTSPEC);
                    265:                lint_assert(dcs->d_lmod == NOTSPEC);
                    266:                lint_assert(dcs->d_smod == NOTSPEC);
                    267:
1.3       jpo       268:                dcs->d_type = tp;
1.1       cgd       269:                return;
                    270:        }
                    271:
                    272:        t = tp->t_tspec;
                    273:
                    274:        if (t == STRUCT || t == UNION || t == ENUM) {
                    275:                /*
                    276:                 * something like "int struct a ..."
                    277:                 * struct/union/enum with anything else is not allowed
                    278:                 */
1.3       jpo       279:                if (dcs->d_type != NULL || dcs->d_atyp != NOTSPEC ||
                    280:                    dcs->d_lmod != NOTSPEC || dcs->d_smod != NOTSPEC) {
1.1       cgd       281:                        /*
                    282:                         * remember that an error must be reported in
                    283:                         * deftyp().
                    284:                         */
1.3       jpo       285:                        dcs->d_terr = 1;
                    286:                        dcs->d_atyp = dcs->d_lmod = dcs->d_smod = NOTSPEC;
1.1       cgd       287:                }
1.3       jpo       288:                dcs->d_type = tp;
1.1       cgd       289:                return;
                    290:        }
                    291:
1.3       jpo       292:        if (dcs->d_type != NULL && !dcs->d_type->t_typedef) {
1.1       cgd       293:                /*
                    294:                 * something like "struct a int"
                    295:                 * struct/union/enum with anything else is not allowed
                    296:                 */
1.3       jpo       297:                dcs->d_terr = 1;
1.1       cgd       298:                return;
                    299:        }
                    300:
1.39      christos  301:        if (t == COMPLEX) {
                    302:                if (dcs->d_cmod == FLOAT)
                    303:                        t = FCOMPLEX;
1.94      rillig    304:                else if (dcs->d_cmod == DOUBLE)
1.39      christos  305:                        t = DCOMPLEX;
1.100     rillig    306:                else {
1.104     rillig    307:                        /* invalid type for _Complex */
1.100     rillig    308:                        error(308);
                    309:                        t = DCOMPLEX; /* just as a fallback */
                    310:                }
1.39      christos  311:                dcs->d_cmod = NOTSPEC;
                    312:        }
                    313:
1.3       jpo       314:        if (t == LONG && dcs->d_lmod == LONG) {
1.1       cgd       315:                /* "long long" or "long ... long" */
                    316:                t = QUAD;
1.3       jpo       317:                dcs->d_lmod = NOTSPEC;
1.9       jpo       318:                if (!quadflg)
                    319:                        /* %s C does not support 'long long' */
1.106     rillig    320:                        c99ism(265, tflag ? "traditional" : "c89");
1.1       cgd       321:        }
                    322:
1.3       jpo       323:        if (dcs->d_type != NULL && dcs->d_type->t_typedef) {
1.1       cgd       324:                /* something like "typedef int a; a long ..." */
1.3       jpo       325:                dcs->d_type = tdeferr(dcs->d_type, t);
1.1       cgd       326:                return;
                    327:        }
                    328:
                    329:        /* now it can be only a combination of arithmetic types and void */
                    330:        if (t == SIGNED || t == UNSIGN) {
1.43      dholland  331:                /* remember specifiers "signed" & "unsigned" in dcs->d_smod */
1.3       jpo       332:                if (dcs->d_smod != NOTSPEC)
1.1       cgd       333:                        /*
1.25      wiz       334:                         * more than one "signed" and/or "unsigned"; print
1.1       cgd       335:                         * an error in deftyp()
                    336:                         */
1.3       jpo       337:                        dcs->d_terr = 1;
                    338:                dcs->d_smod = t;
1.1       cgd       339:        } else if (t == SHORT || t == LONG || t == QUAD) {
                    340:                /*
                    341:                 * remember specifiers "short", "long" and "long long" in
1.3       jpo       342:                 * dcs->d_lmod
1.1       cgd       343:                 */
1.3       jpo       344:                if (dcs->d_lmod != NOTSPEC)
1.1       cgd       345:                        /* more than one, print error in deftyp() */
1.3       jpo       346:                        dcs->d_terr = 1;
                    347:                dcs->d_lmod = t;
1.39      christos  348:        } else if (t == FLOAT || t == DOUBLE) {
1.42      matt      349:                if (dcs->d_lmod == NOTSPEC || dcs->d_lmod == LONG) {
                    350:                        if (dcs->d_cmod != NOTSPEC
                    351:                            || (t == FLOAT && dcs->d_lmod == LONG))
1.40      christos  352:                                dcs->d_terr = 1;
                    353:                        dcs->d_cmod = t;
                    354:                } else {
                    355:                        if (dcs->d_atyp != NOTSPEC)
                    356:                                dcs->d_terr = 1;
                    357:                        dcs->d_atyp = t;
                    358:                }
1.68      christos  359:        } else if (t == PTR) {
                    360:                dcs->d_type = tp;
1.1       cgd       361:        } else {
                    362:                /*
1.39      christos  363:                 * remember specifiers "void", "char", "int",
                    364:                 * or "_Complex" int dcs->d_atyp
1.1       cgd       365:                 */
1.3       jpo       366:                if (dcs->d_atyp != NOTSPEC)
1.1       cgd       367:                        /* more than one, print error in deftyp() */
1.3       jpo       368:                        dcs->d_terr = 1;
                    369:                dcs->d_atyp = t;
1.1       cgd       370:        }
                    371: }
                    372:
                    373: /*
                    374:  * called if a list of declaration specifiers contains a typedef name
                    375:  * and other specifiers (except struct, union, enum, typedef name)
                    376:  */
                    377: static type_t *
1.22      lukem     378: tdeferr(type_t *td, tspec_t t)
1.1       cgd       379: {
                    380:        tspec_t t2;
                    381:
                    382:        t2 = td->t_tspec;
                    383:
                    384:        switch (t) {
                    385:        case SIGNED:
                    386:        case UNSIGN:
                    387:                if (t2 == CHAR || t2 == SHORT || t2 == INT || t2 == LONG ||
                    388:                    t2 == QUAD) {
                    389:                        if (!tflag)
1.101     rillig    390:                                /* modifying typedef with '%s'; only ... */
1.1       cgd       391:                                warning(5, ttab[t].tt_name);
1.77      rillig    392:                        td = duptyp(gettyp(merge_type_specifiers(t2, t)));
1.1       cgd       393:                        td->t_typedef = 1;
1.76      rillig    394:                        return td;
1.1       cgd       395:                }
                    396:                break;
                    397:        case SHORT:
                    398:                if (t2 == INT || t2 == UINT) {
1.101     rillig    399:                        /* modifying typedef with '%s'; only qualifiers ... */
1.1       cgd       400:                        warning(5, "short");
                    401:                        td = duptyp(gettyp(t2 == INT ? SHORT : USHORT));
                    402:                        td->t_typedef = 1;
1.76      rillig    403:                        return td;
1.1       cgd       404:                }
                    405:                break;
                    406:        case LONG:
                    407:                if (t2 == INT || t2 == UINT || t2 == LONG || t2 == ULONG ||
1.42      matt      408:                    t2 == FLOAT || t2 == DOUBLE || t2 == DCOMPLEX) {
1.1       cgd       409:                        /* modifying typedef with ... */
                    410:                        warning(5, "long");
                    411:                        if (t2 == INT) {
                    412:                                td = gettyp(LONG);
                    413:                        } else if (t2 == UINT) {
                    414:                                td = gettyp(ULONG);
                    415:                        } else if (t2 == LONG) {
                    416:                                td = gettyp(QUAD);
                    417:                        } else if (t2 == ULONG) {
                    418:                                td = gettyp(UQUAD);
                    419:                        } else if (t2 == FLOAT) {
                    420:                                td = gettyp(DOUBLE);
                    421:                        } else if (t2 == DOUBLE) {
                    422:                                td = gettyp(LDOUBLE);
1.42      matt      423:                        } else if (t2 == DCOMPLEX) {
                    424:                                td = gettyp(LCOMPLEX);
1.1       cgd       425:                        }
                    426:                        td = duptyp(td);
                    427:                        td->t_typedef = 1;
1.76      rillig    428:                        return td;
1.1       cgd       429:                }
                    430:                break;
1.57      christos  431:                /* LINTED206: (enumeration values not handled in switch) */
1.13      christos  432:        case NOTSPEC:
                    433:        case USHORT:
                    434:        case UCHAR:
                    435:        case SCHAR:
                    436:        case CHAR:
1.34      yamt      437:        case BOOL:
1.13      christos  438:        case FUNC:
                    439:        case ARRAY:
                    440:        case PTR:
                    441:        case ENUM:
                    442:        case UNION:
                    443:        case STRUCT:
                    444:        case VOID:
                    445:        case LDOUBLE:
1.39      christos  446:        case FLOAT:
1.13      christos  447:        case DOUBLE:
                    448:        case UQUAD:
                    449:        case QUAD:
1.69      christos  450: #ifdef INT128_SIZE
                    451:        case UINT128:
                    452:        case INT128:
                    453: #endif
1.13      christos  454:        case ULONG:
                    455:        case UINT:
                    456:        case INT:
1.39      christos  457:        case FCOMPLEX:
                    458:        case DCOMPLEX:
1.42      matt      459:        case LCOMPLEX:
1.39      christos  460:        case COMPLEX:
1.28      thorpej   461:                break;
1.1       cgd       462:        }
                    463:
                    464:        /* Anything other is not accepted. */
                    465:
1.3       jpo       466:        dcs->d_terr = 1;
1.76      rillig    467:        return td;
1.1       cgd       468: }
                    469:
                    470: /*
                    471:  * Remember the symbol of a typedef name (2nd arg) in a struct, union
                    472:  * or enum tag if the typedef name is the first defined for this tag.
                    473:  *
                    474:  * If the tag is unnamed, the typdef name is used for identification
1.86      rillig    475:  * of this tag in lint2. Although it's possible that more than one typedef
1.1       cgd       476:  * name is defined for one tag, the first name defined should be unique
                    477:  * if the tag is unnamed.
                    478:  */
                    479: static void
1.22      lukem     480: settdsym(type_t *tp, sym_t *sym)
1.1       cgd       481: {
                    482:        tspec_t t;
                    483:
                    484:        if ((t = tp->t_tspec) == STRUCT || t == UNION) {
                    485:                if (tp->t_str->stdef == NULL)
                    486:                        tp->t_str->stdef = sym;
                    487:        } else if (t == ENUM) {
                    488:                if (tp->t_enum->etdef == NULL)
                    489:                        tp->t_enum->etdef = sym;
                    490:        }
                    491: }
                    492:
1.65      christos  493: static size_t
                    494: bitfieldsize(sym_t **mem)
                    495: {
                    496:        size_t len = (*mem)->s_type->t_flen;
1.108     rillig    497:        while (*mem && (*mem)->s_type->t_bitfield) {
1.65      christos  498:                len += (*mem)->s_type->t_flen;
1.80      rillig    499:                *mem = (*mem)->s_next;
1.65      christos  500:        }
                    501:        return ((len + INT_SIZE - 1) / INT_SIZE) * INT_SIZE;
                    502: }
                    503:
1.48      christos  504: static void
                    505: setpackedsize(type_t *tp)
1.47      christos  506: {
                    507:        str_t *sp;
                    508:        sym_t *mem;
                    509:
                    510:        switch (tp->t_tspec) {
                    511:        case STRUCT:
                    512:        case UNION:
                    513:                sp = tp->t_str;
                    514:                sp->size = 0;
1.80      rillig    515:                for (mem = sp->memb; mem != NULL; mem = mem->s_next) {
1.108     rillig    516:                        if (mem->s_type->t_bitfield) {
1.65      christos  517:                                sp->size += bitfieldsize(&mem);
1.51      christos  518:                                if (mem == NULL)
                    519:                                        break;
                    520:                        }
1.50      christos  521:                        size_t x = (size_t)tsize(mem->s_type);
1.51      christos  522:                        if (tp->t_tspec == STRUCT)
                    523:                                sp->size += x;
                    524:                        else if (x > sp->size)
1.47      christos  525:                                sp->size = x;
                    526:                }
                    527:                break;
                    528:        default:
1.94      rillig    529:                /* %s attribute ignored for %s */
1.98      rillig    530:                warning(326, "packed", type_name(tp));
1.47      christos  531:                break;
                    532:        }
                    533: }
                    534:
1.48      christos  535: void
                    536: addpacked(void)
                    537: {
1.49      christos  538:        if (dcs->d_type == NULL)
1.109     rillig    539:                dcs->d_packed = 1;
1.49      christos  540:        else
1.48      christos  541:                setpackedsize(dcs->d_type);
                    542: }
                    543:
1.67      christos  544: void
1.77      rillig    545: add_attr_used(void)
1.67      christos  546: {
                    547:        dcs->d_used = 1;
                    548: }
                    549:
1.1       cgd       550: /*
                    551:  * Remember a qualifier which is part of the declaration specifiers
                    552:  * (and not the declarator) in the top element of the declaration stack.
                    553:  * Also detect multiple qualifiers of the same kind.
                    554:
1.21      lukem     555:  * The remembered qualifier is used by deftyp() to construct the type
1.1       cgd       556:  * for all declarators.
                    557:  */
                    558: void
1.77      rillig    559: add_qualifier(tqual_t q)
1.1       cgd       560: {
1.22      lukem     561:
1.1       cgd       562:        if (q == CONST) {
1.3       jpo       563:                if (dcs->d_const) {
1.88      rillig    564:                        /* duplicate '%s' */
1.1       cgd       565:                        warning(10, "const");
                    566:                }
1.3       jpo       567:                dcs->d_const = 1;
1.1       cgd       568:        } else {
1.70      christos  569:                if (q == THREAD)
                    570:                        return;
1.92      rillig    571:                lint_assert(q == VOLATILE);
1.3       jpo       572:                if (dcs->d_volatile) {
1.88      rillig    573:                        /* duplicate '%s' */
1.1       cgd       574:                        warning(10, "volatile");
                    575:                }
1.3       jpo       576:                dcs->d_volatile = 1;
1.1       cgd       577:        }
                    578: }
                    579:
                    580: /*
                    581:  * Go to the next declaration level (structs, nested structs, blocks,
                    582:  * argument declaration lists ...)
                    583:  */
                    584: void
1.22      lukem     585: pushdecl(scl_t sc)
1.1       cgd       586: {
                    587:        dinfo_t *di;
                    588:
                    589:        /* put a new element on the declaration stack */
                    590:        di = xcalloc(1, sizeof (dinfo_t));
1.82      rillig    591:        di->d_next = dcs;
1.1       cgd       592:        dcs = di;
1.3       jpo       593:        di->d_ctx = sc;
                    594:        di->d_ldlsym = &di->d_dlsyms;
1.47      christos  595:        if (dflag)
                    596:                (void)printf("pushdecl(%p %d)\n", dcs, (int)sc);
                    597:
1.1       cgd       598: }
                    599:
                    600: /*
                    601:  * Go back to previous declaration level
                    602:  */
                    603: void
1.22      lukem     604: popdecl(void)
1.1       cgd       605: {
                    606:        dinfo_t *di;
                    607:
                    608:        if (dflag)
1.47      christos  609:                (void)printf("popdecl(%p %d)\n", dcs, (int)dcs->d_ctx);
1.1       cgd       610:
1.92      rillig    611:        lint_assert(dcs->d_next != NULL);
1.1       cgd       612:        di = dcs;
1.82      rillig    613:        dcs = di->d_next;
1.3       jpo       614:        switch (di->d_ctx) {
1.1       cgd       615:        case MOS:
                    616:        case MOU:
                    617:        case ENUMCON:
                    618:                /*
                    619:                 * Symbols declared in (nested) structs or enums are
                    620:                 * part of the next level (they are removed from the
                    621:                 * symbol table if the symbols of the outher level are
1.73      rillig    622:                 * removed).
1.1       cgd       623:                 */
1.3       jpo       624:                if ((*dcs->d_ldlsym = di->d_dlsyms) != NULL)
                    625:                        dcs->d_ldlsym = di->d_ldlsym;
1.1       cgd       626:                break;
                    627:        case ARG:
                    628:                /*
1.3       jpo       629:                 * All symbols in dcs->d_dlsyms are introduced in old style
1.1       cgd       630:                 * argument declarations (it's not clean, but possible).
                    631:                 * They are appended to the list of symbols declared in
                    632:                 * an old style argument identifier list or a new style
                    633:                 * parameter type list.
                    634:                 */
1.3       jpo       635:                if (di->d_dlsyms != NULL) {
                    636:                        *di->d_ldlsym = dcs->d_fpsyms;
                    637:                        dcs->d_fpsyms = di->d_dlsyms;
1.1       cgd       638:                }
                    639:                break;
                    640:        case ABSTRACT:
                    641:                /*
                    642:                 * casts and sizeof
                    643:                 * Append all symbols declared in the abstract declaration
1.73      rillig    644:                 * to the list of symbols declared in the surrounding
                    645:                 * declaration or block.
1.1       cgd       646:                 * XXX I'm not sure whether they should be removed from the
                    647:                 * symbol table now or later.
                    648:                 */
1.3       jpo       649:                if ((*dcs->d_ldlsym = di->d_dlsyms) != NULL)
                    650:                        dcs->d_ldlsym = di->d_ldlsym;
1.1       cgd       651:                break;
                    652:        case AUTO:
                    653:                /* check usage of local vars */
1.75      rillig    654:                check_usage(di);
1.1       cgd       655:                /* FALLTHROUGH */
                    656:        case PARG:
                    657:                /* usage of arguments will be checked by funcend() */
1.3       jpo       658:                rmsyms(di->d_dlsyms);
1.1       cgd       659:                break;
1.97      rillig    660:        case EXTERN:
                    661:                /* there is nothing after external declarations */
                    662:                /* FALLTHROUGH */
1.1       cgd       663:        default:
1.102     rillig    664:                lint_assert(/*CONSTCOND*/0);
1.1       cgd       665:        }
                    666:        free(di);
                    667: }
                    668:
                    669: /*
1.10      jpo       670:  * Set flag d_asm in all declaration stack elements up to the
                    671:  * outermost one.
                    672:  *
                    673:  * This is used to mark compound statements which have, possibly in
                    674:  * nested compound statements, asm statements. For these compound
1.111     rillig    675:  * statements no warnings about unused or uninitialized variables are
1.10      jpo       676:  * printed.
                    677:  *
                    678:  * There is no need to clear d_asm in dinfo structs with context AUTO,
                    679:  * because these structs are freed at the end of the compound statement.
1.62      dholland  680:  * But it must be cleared in the outermost dinfo struct, which has
1.10      jpo       681:  * context EXTERN. This could be done in clrtyp() and would work for
                    682:  * C, but not for C++ (due to mixed statements and declarations). Thus
1.77      rillig    683:  * we clear it in global_clean_up_decl(), which is used to do some cleanup
                    684:  * after global declarations/definitions.
1.10      jpo       685:  */
                    686: void
1.22      lukem     687: setasm(void)
1.10      jpo       688: {
                    689:        dinfo_t *di;
                    690:
1.82      rillig    691:        for (di = dcs; di != NULL; di = di->d_next)
1.10      jpo       692:                di->d_asm = 1;
                    693: }
                    694:
                    695: /*
1.1       cgd       696:  * Clean all elements of the top element of declaration stack which
                    697:  * will be used by the next declaration
                    698:  */
                    699: void
1.22      lukem     700: clrtyp(void)
1.1       cgd       701: {
1.22      lukem     702:
1.39      christos  703:        dcs->d_atyp = dcs->d_cmod = dcs->d_smod = dcs->d_lmod = NOTSPEC;
1.3       jpo       704:        dcs->d_scl = NOSCL;
                    705:        dcs->d_type = NULL;
                    706:        dcs->d_const = dcs->d_volatile = 0;
1.4       jpo       707:        dcs->d_inline = 0;
1.3       jpo       708:        dcs->d_mscl = dcs->d_terr = 0;
                    709:        dcs->d_nedecl = 0;
1.7       jpo       710:        dcs->d_notyp = 0;
1.1       cgd       711: }
                    712:
                    713: /*
1.73      rillig    714:  * Create a type structure from the information gathered in
1.1       cgd       715:  * the declaration stack.
                    716:  * Complain about storage classes which are not possible in current
                    717:  * context.
                    718:  */
                    719: void
1.22      lukem     720: deftyp(void)
1.1       cgd       721: {
1.39      christos  722:        tspec_t t, s, l, c;
1.1       cgd       723:        type_t  *tp;
                    724:        scl_t   scl;
                    725:
1.39      christos  726:        t = dcs->d_atyp;        /* BOOL, CHAR, INT, COMPLEX, VOID */
1.34      yamt      727:        s = dcs->d_smod;        /* SIGNED, UNSIGNED */
                    728:        l = dcs->d_lmod;        /* SHORT, LONG, QUAD */
1.39      christos  729:        c = dcs->d_cmod;        /* FLOAT, DOUBLE */
1.3       jpo       730:        tp = dcs->d_type;
                    731:        scl = dcs->d_scl;
1.1       cgd       732:
1.68      christos  733: #ifdef DEBUG
1.98      rillig    734:        printf("%s: %s\n", __func__, type_name(tp));
1.68      christos  735: #endif
1.39      christos  736:        if (t == NOTSPEC && s == NOTSPEC && l == NOTSPEC && c == NOTSPEC &&
                    737:            tp == NULL)
                    738:                dcs->d_notyp = 1;
1.43      dholland  739:        if (t == NOTSPEC && s == NOTSPEC && (l == NOTSPEC || l == LONG) &&
                    740:            tp == NULL)
1.39      christos  741:                t = c;
1.1       cgd       742:
1.92      rillig    743:        if (tp != NULL) {
                    744:                lint_assert(t == NOTSPEC);
                    745:                lint_assert(s == NOTSPEC);
                    746:                lint_assert(l == NOTSPEC);
1.1       cgd       747:        }
                    748:
                    749:        if (tp == NULL) {
                    750:                switch (t) {
1.34      yamt      751:                case BOOL:
                    752:                        break;
1.1       cgd       753:                case NOTSPEC:
                    754:                        t = INT;
                    755:                        /* FALLTHROUGH */
                    756:                case INT:
                    757:                        if (s == NOTSPEC)
                    758:                                s = SIGNED;
                    759:                        break;
                    760:                case CHAR:
                    761:                        if (l != NOTSPEC) {
1.3       jpo       762:                                dcs->d_terr = 1;
1.1       cgd       763:                                l = NOTSPEC;
                    764:                        }
                    765:                        break;
                    766:                case FLOAT:
                    767:                        if (l == LONG) {
                    768:                                l = NOTSPEC;
                    769:                                t = DOUBLE;
                    770:                                if (!tflag)
1.88      rillig    771:                                        /* use 'double' instead of 'long ... */
1.1       cgd       772:                                        warning(6);
                    773:                        }
                    774:                        break;
                    775:                case DOUBLE:
                    776:                        if (l == LONG) {
1.59      christos  777:                case LDOUBLE:
1.1       cgd       778:                                l = NOTSPEC;
                    779:                                t = LDOUBLE;
                    780:                                if (tflag)
                    781:                                        /* 'long double' is illegal in ... */
                    782:                                        warning(266);
                    783:                        }
                    784:                        break;
1.42      matt      785:                case DCOMPLEX:
                    786:                        if (l == LONG) {
                    787:                                l = NOTSPEC;
                    788:                                t = LCOMPLEX;
                    789:                                if (tflag)
                    790:                                        /* 'long double' is illegal in ... */
                    791:                                        warning(266);
                    792:                        }
                    793:                        break;
1.1       cgd       794:                case VOID:
1.39      christos  795:                case FCOMPLEX:
1.42      matt      796:                case LCOMPLEX:
1.1       cgd       797:                        break;
                    798:                default:
1.91      rillig    799:                        LERROR("deftyp(%s)", tspec_name(t));
1.1       cgd       800:                }
                    801:                if (t != INT && t != CHAR && (s != NOTSPEC || l != NOTSPEC)) {
1.3       jpo       802:                        dcs->d_terr = 1;
1.1       cgd       803:                        l = s = NOTSPEC;
                    804:                }
                    805:                if (l != NOTSPEC)
                    806:                        t = l;
1.77      rillig    807:                dcs->d_type = gettyp(merge_type_specifiers(t, s));
1.1       cgd       808:        }
                    809:
1.3       jpo       810:        if (dcs->d_mscl) {
1.1       cgd       811:                /* only one storage class allowed */
                    812:                error(7);
                    813:        }
1.3       jpo       814:        if (dcs->d_terr) {
1.1       cgd       815:                /* illegal type combination */
                    816:                error(4);
                    817:        }
                    818:
1.3       jpo       819:        if (dcs->d_ctx == EXTERN) {
1.1       cgd       820:                if (scl == REG || scl == AUTO) {
                    821:                        /* illegal storage class */
                    822:                        error(8);
                    823:                        scl = NOSCL;
                    824:                }
1.3       jpo       825:        } else if (dcs->d_ctx == ARG || dcs->d_ctx == PARG) {
1.1       cgd       826:                if (scl != NOSCL && scl != REG) {
1.88      rillig    827:                        /* only register valid ... */
1.1       cgd       828:                        error(9);
                    829:                        scl = NOSCL;
                    830:                }
                    831:        }
                    832:
1.3       jpo       833:        dcs->d_scl = scl;
1.1       cgd       834:
1.3       jpo       835:        if (dcs->d_const && dcs->d_type->t_const) {
1.92      rillig    836:                lint_assert(dcs->d_type->t_typedef);
1.88      rillig    837:                /* typedef already qualified with '%s' */
1.1       cgd       838:                warning(68, "const");
                    839:        }
1.3       jpo       840:        if (dcs->d_volatile && dcs->d_type->t_volatile) {
1.92      rillig    841:                lint_assert(dcs->d_type->t_typedef);
1.88      rillig    842:                /* typedef already qualified with '%s' */
1.1       cgd       843:                warning(68, "volatile");
                    844:        }
                    845:
1.3       jpo       846:        if (dcs->d_const || dcs->d_volatile) {
                    847:                dcs->d_type = duptyp(dcs->d_type);
                    848:                dcs->d_type->t_const |= dcs->d_const;
                    849:                dcs->d_type->t_volatile |= dcs->d_volatile;
1.1       cgd       850:        }
                    851: }
                    852:
                    853: /*
                    854:  * Merge type specifiers (char, ..., long long, signed, unsigned).
                    855:  */
                    856: static tspec_t
1.77      rillig    857: merge_type_specifiers(tspec_t t, tspec_t s)
1.1       cgd       858: {
1.22      lukem     859:
1.1       cgd       860:        if (s == SIGNED || s == UNSIGN) {
                    861:                if (t == CHAR) {
                    862:                        t = s == SIGNED ? SCHAR : UCHAR;
                    863:                } else if (t == SHORT) {
                    864:                        t = s == SIGNED ? SHORT : USHORT;
                    865:                } else if (t == INT) {
                    866:                        t = s == SIGNED ? INT : UINT;
                    867:                } else if (t == LONG) {
                    868:                        t = s == SIGNED ? LONG : ULONG;
                    869:                } else if (t == QUAD) {
                    870:                        t = s == SIGNED ? QUAD : UQUAD;
                    871:                }
                    872:        }
                    873:
1.76      rillig    874:        return t;
1.1       cgd       875: }
                    876:
                    877: /*
1.73      rillig    878:  * Return the length of a type in bits.
1.1       cgd       879:  *
1.111     rillig    880:  * Printing a message if the outermost dimension of an array is 0 must
1.1       cgd       881:  * be done by the caller. All other problems are reported by length()
                    882:  * if name is not NULL.
                    883:  */
                    884: int
1.22      lukem     885: length(type_t *tp, const char *name)
1.1       cgd       886: {
                    887:        int     elem, elsz;
                    888:
                    889:        elem = 1;
1.18      christos  890:        while (tp && tp->t_tspec == ARRAY) {
1.1       cgd       891:                elem *= tp->t_dim;
                    892:                tp = tp->t_subt;
                    893:        }
1.18      christos  894:        if (tp == NULL)
                    895:                return -1;
                    896:
1.1       cgd       897:        switch (tp->t_tspec) {
                    898:        case FUNC:
                    899:                /* compiler takes size of function */
1.52      joerg     900:                LERROR("%s", msgs[12]);
1.1       cgd       901:                /* NOTREACHED */
                    902:        case STRUCT:
                    903:        case UNION:
                    904:                if (incompl(tp) && name != NULL) {
                    905:                        /* incomplete structure or union %s: %s */
                    906:                        error(31, tp->t_str->stag->s_name, name);
                    907:                }
                    908:                elsz = tp->t_str->size;
                    909:                break;
                    910:        case ENUM:
                    911:                if (incompl(tp) && name != NULL) {
                    912:                        /* incomplete enum type: %s */
                    913:                        warning(13, name);
                    914:                }
                    915:                /* FALLTHROUGH */
                    916:        default:
                    917:                elsz = size(tp->t_tspec);
                    918:                if (elsz <= 0)
1.61      christos  919:                        LERROR("length(%d)", elsz);
1.1       cgd       920:                break;
                    921:        }
1.76      rillig    922:        return elem * elsz;
1.1       cgd       923: }
                    924:
                    925: /*
                    926:  * Get the alignment of the given Type in bits.
                    927:  */
                    928: int
1.22      lukem     929: getbound(type_t *tp)
1.1       cgd       930: {
1.46      christos  931:        size_t  a;
1.1       cgd       932:        tspec_t t;
                    933:
1.18      christos  934:        while (tp && tp->t_tspec == ARRAY)
1.1       cgd       935:                tp = tp->t_subt;
                    936:
1.18      christos  937:        if (tp == NULL)
                    938:                return -1;
                    939:
1.1       cgd       940:        if ((t = tp->t_tspec) == STRUCT || t == UNION) {
                    941:                a = tp->t_str->align;
                    942:        } else if (t == FUNC) {
                    943:                /* compiler takes alignment of function */
                    944:                error(14);
1.113     rillig    945:                a = WORST_ALIGN(1) * CHAR_SIZE;
1.1       cgd       946:        } else {
                    947:                if ((a = size(t)) == 0) {
1.113     rillig    948:                        a = CHAR_SIZE;
                    949:                } else if (a > WORST_ALIGN(1) * CHAR_SIZE) {
                    950:                        a = WORST_ALIGN(1) * CHAR_SIZE;
1.1       cgd       951:                }
                    952:        }
1.113     rillig    953:        lint_assert(a >= CHAR_SIZE);
                    954:        lint_assert(a <= WORST_ALIGN(1) * CHAR_SIZE);
1.76      rillig    955:        return a;
1.1       cgd       956: }
                    957:
                    958: /*
1.80      rillig    959:  * Concatenate two lists of symbols by s_next. Used by declarations of
1.1       cgd       960:  * struct/union/enum elements and parameters.
                    961:  */
                    962: sym_t *
1.22      lukem     963: lnklst(sym_t *l1, sym_t *l2)
1.1       cgd       964: {
                    965:        sym_t   *l;
                    966:
                    967:        if ((l = l1) == NULL)
1.76      rillig    968:                return l2;
1.80      rillig    969:        while (l1->s_next != NULL)
                    970:                l1 = l1->s_next;
                    971:        l1->s_next = l2;
1.76      rillig    972:        return l;
1.1       cgd       973: }
                    974:
                    975: /*
                    976:  * Check if the type of the given symbol is valid and print an error
                    977:  * message if it is not.
                    978:  *
                    979:  * Invalid types are:
1.111     rillig    980:  * - arrays of incomplete types or functions
1.1       cgd       981:  * - functions returning arrays or functions
                    982:  * - void types other than type of function or pointer
                    983:  */
                    984: void
1.75      rillig    985: check_type(sym_t *sym)
1.1       cgd       986: {
                    987:        tspec_t to, t;
                    988:        type_t  **tpp, *tp;
                    989:
                    990:        tpp = &sym->s_type;
                    991:        to = NOTSPEC;
                    992:        while ((tp = *tpp) != NULL) {
                    993:                t = tp->t_tspec;
                    994:                /*
                    995:                 * If this is the type of an old style function definition,
                    996:                 * a better warning is printed in funcdef().
                    997:                 */
                    998:                if (t == FUNC && !tp->t_proto &&
                    999:                    !(to == NOTSPEC && sym->s_osdef)) {
                   1000:                        if (sflag && hflag)
                   1001:                                /* function declaration is not a prototype */
                   1002:                                warning(287);
                   1003:                }
                   1004:                if (to == FUNC) {
                   1005:                        if (t == FUNC || t == ARRAY) {
                   1006:                                /* function returns illegal type */
                   1007:                                error(15);
                   1008:                                if (t == FUNC) {
                   1009:                                        *tpp = incref(*tpp, PTR);
                   1010:                                } else {
                   1011:                                        *tpp = incref((*tpp)->t_subt, PTR);
                   1012:                                }
                   1013:                                return;
                   1014:                        } else if (tp->t_const || tp->t_volatile) {
                   1015:                                if (sflag) {    /* XXX oder better !tflag ? */
                   1016:                                        /* function cannot return const... */
                   1017:                                        warning(228);
                   1018:                                }
                   1019:                        }
                   1020:                } if (to == ARRAY) {
                   1021:                        if (t == FUNC) {
                   1022:                                /* array of function is illegal */
                   1023:                                error(16);
                   1024:                                *tpp = gettyp(INT);
                   1025:                                return;
                   1026:                        } else if (t == ARRAY && tp->t_dim == 0) {
                   1027:                                /* null dimension */
                   1028:                                error(17);
                   1029:                                return;
                   1030:                        } else if (t == VOID) {
1.88      rillig   1031:                                /* illegal use of 'void' */
1.1       cgd      1032:                                error(18);
                   1033:                                *tpp = gettyp(INT);
                   1034: #if 0  /* errors are produced by length() */
                   1035:                        } else if (incompl(tp)) {
                   1036:                                /* array of incomplete type */
                   1037:                                if (sflag) {
1.94      rillig   1038:                                        /* array of incomplete type */
1.1       cgd      1039:                                        error(301);
                   1040:                                } else {
1.94      rillig   1041:                                        /* array of incomplete type */
1.1       cgd      1042:                                        warning(301);
                   1043:                                }
                   1044: #endif
                   1045:                        }
                   1046:                } else if (to == NOTSPEC && t == VOID) {
1.3       jpo      1047:                        if (dcs->d_ctx == PARG) {
1.1       cgd      1048:                                if (sym->s_scl != ABSTRACT) {
1.92      rillig   1049:                                        lint_assert(sym->s_name != unnamed);
1.88      rillig   1050:                                        /* void param. cannot have name: %s */
1.1       cgd      1051:                                        error(61, sym->s_name);
                   1052:                                        *tpp = gettyp(INT);
                   1053:                                }
1.3       jpo      1054:                        } else if (dcs->d_ctx == ABSTRACT) {
1.1       cgd      1055:                                /* ok */
                   1056:                        } else if (sym->s_scl != TYPEDEF) {
                   1057:                                /* void type for %s */
                   1058:                                error(19, sym->s_name);
                   1059:                                *tpp = gettyp(INT);
                   1060:                        }
                   1061:                }
                   1062:                if (t == VOID && to != PTR) {
                   1063:                        if (tp->t_const || tp->t_volatile) {
1.88      rillig   1064:                                /* inappropriate qualifiers with 'void' */
1.1       cgd      1065:                                warning(69);
                   1066:                                tp->t_const = tp->t_volatile = 0;
                   1067:                        }
                   1068:                }
                   1069:                tpp = &tp->t_subt;
                   1070:                to = t;
                   1071:        }
                   1072: }
                   1073:
                   1074: /*
                   1075:  * Process the declarator of a struct/union element.
                   1076:  */
                   1077: sym_t *
1.75      rillig   1078: declarator_1_struct_union(sym_t *dsym)
1.1       cgd      1079: {
                   1080:        type_t  *tp;
                   1081:        tspec_t t;
1.13      christos 1082:        int     sz, len;
                   1083:        int     o = 0;  /* Appease gcc */
1.1       cgd      1084:        scl_t   sc;
                   1085:
1.92      rillig   1086:        lint_assert((sc = dsym->s_scl) == MOS || sc == MOU);
1.1       cgd      1087:
1.3       jpo      1088:        if (dcs->d_rdcsym != NULL) {
1.92      rillig   1089:                /* should be ensured by storesym() */
                   1090:                lint_assert((sc = dcs->d_rdcsym->s_scl) == MOS || sc == MOU);
1.3       jpo      1091:                if (dsym->s_styp == dcs->d_rdcsym->s_styp) {
1.1       cgd      1092:                        /* duplicate member name: %s */
                   1093:                        error(33, dsym->s_name);
1.3       jpo      1094:                        rmsym(dcs->d_rdcsym);
1.1       cgd      1095:                }
                   1096:        }
                   1097:
1.75      rillig   1098:        check_type(dsym);
1.1       cgd      1099:
                   1100:        t = (tp = dsym->s_type)->t_tspec;
                   1101:
1.83      rillig   1102:        if (dsym->s_bitfield) {
1.1       cgd      1103:                /*
1.73      rillig   1104:                 * only unsigned and signed int are portable bit-field types
1.1       cgd      1105:                 *(at least in ANSI C, in traditional C only unsigned int)
                   1106:                 */
                   1107:                if (t == CHAR || t == UCHAR || t == SCHAR ||
                   1108:                    t == SHORT || t == USHORT || t == ENUM) {
1.103     rillig   1109:                        if (!bitfieldtype_ok) {
1.26      thorpej  1110:                                if (sflag) {
1.94      rillig   1111:                                        /* bit-field type '%s' invalid ... */
1.98      rillig   1112:                                        warning(273, type_name(tp));
1.26      thorpej  1113:                                } else if (pflag) {
                   1114:                                        /* nonportable bit-field type */
                   1115:                                        warning(34);
                   1116:                                }
1.1       cgd      1117:                        }
1.3       jpo      1118:                } else if (t == INT && dcs->d_smod == NOTSPEC) {
1.103     rillig   1119:                        if (pflag && !bitfieldtype_ok) {
1.1       cgd      1120:                                /* nonportable bit-field type */
                   1121:                                warning(34);
                   1122:                        }
1.99      rillig   1123:                } else if (t != INT && t != UINT && t != BOOL) {
1.26      thorpej  1124:                        /*
                   1125:                         * Non-integer types are always illegal for
                   1126:                         * bitfields, regardless of BITFIELDTYPE.
1.27      thorpej  1127:                         * Integer types not dealt with above are
                   1128:                         * okay only if BITFIELDTYPE is in effect.
1.26      thorpej  1129:                         */
1.114   ! rillig   1130:                        if (!bitfieldtype_ok || !is_integer(t)) {
1.26      thorpej  1131:                                /* illegal bit-field type */
1.58      christos 1132:                                warning(35);
1.26      thorpej  1133:                                sz = tp->t_flen;
                   1134:                                dsym->s_type = tp = duptyp(gettyp(t = INT));
                   1135:                                if ((tp->t_flen = sz) > size(t))
                   1136:                                        tp->t_flen = size(t);
                   1137:                        }
1.1       cgd      1138:                }
1.46      christos 1139:                if ((len = tp->t_flen) < 0 || len > (ssize_t)size(t)) {
1.88      rillig   1140:                        /* illegal bit-field size: %d */
1.71      christos 1141:                        error(36, len);
1.1       cgd      1142:                        tp->t_flen = size(t);
                   1143:                } else if (len == 0 && dsym->s_name != unnamed) {
                   1144:                        /* zero size bit-field */
                   1145:                        error(37);
                   1146:                        tp->t_flen = size(t);
                   1147:                }
                   1148:                if (dsym->s_scl == MOU) {
                   1149:                        /* illegal use of bit-field */
                   1150:                        error(41);
1.108     rillig   1151:                        dsym->s_type->t_bitfield = false;
1.83      rillig   1152:                        dsym->s_bitfield = 0;
1.1       cgd      1153:                }
                   1154:        } else if (t == FUNC) {
                   1155:                /* function illegal in structure or union */
                   1156:                error(38);
                   1157:                dsym->s_type = tp = incref(tp, t = PTR);
                   1158:        }
                   1159:
                   1160:        /*
                   1161:         * bit-fields of length 0 are not warned about because length()
                   1162:         * does not return the length of the bit-field but the length
1.86      rillig   1163:         * of the type the bit-field is packed in (it's ok)
1.1       cgd      1164:         */
                   1165:        if ((sz = length(dsym->s_type, dsym->s_name)) == 0) {
1.36      christos 1166:                if (t == ARRAY && dsym->s_type->t_dim == 0) {
1.89      rillig   1167:                        /* zero sized array in struct is a C99 extension: %s */
1.36      christos 1168:                        c99ism(39, dsym->s_name);
1.1       cgd      1169:                }
                   1170:        }
                   1171:
1.3       jpo      1172:        if (dcs->d_ctx == MOU) {
                   1173:                o = dcs->d_offset;
                   1174:                dcs->d_offset = 0;
1.1       cgd      1175:        }
1.83      rillig   1176:        if (dsym->s_bitfield) {
1.1       cgd      1177:                align(getbound(tp), tp->t_flen);
1.3       jpo      1178:                dsym->s_value.v_quad = (dcs->d_offset / size(t)) * size(t);
                   1179:                tp->t_foffs = dcs->d_offset - (int)dsym->s_value.v_quad;
                   1180:                dcs->d_offset += tp->t_flen;
1.1       cgd      1181:        } else {
                   1182:                align(getbound(tp), 0);
1.3       jpo      1183:                dsym->s_value.v_quad = dcs->d_offset;
                   1184:                dcs->d_offset += sz;
1.1       cgd      1185:        }
1.3       jpo      1186:        if (dcs->d_ctx == MOU) {
                   1187:                if (o > dcs->d_offset)
                   1188:                        dcs->d_offset = o;
1.1       cgd      1189:        }
                   1190:
1.75      rillig   1191:        check_function_definition(dsym, 0);
1.26      thorpej  1192:
                   1193:        /*
                   1194:         * Clear the BITFIELDTYPE indicator after processing each
                   1195:         * structure element.
                   1196:         */
1.103     rillig   1197:        bitfieldtype_ok = false;
1.1       cgd      1198:
1.76      rillig   1199:        return dsym;
1.1       cgd      1200: }
                   1201:
                   1202: /*
                   1203:  * Aligns next structure element as required.
                   1204:  *
                   1205:  * al contains the required alignment, len the length of a bit-field.
                   1206:  */
                   1207: static void
1.22      lukem    1208: align(int al, int len)
1.1       cgd      1209: {
                   1210:        int     no;
                   1211:
                   1212:        /*
                   1213:         * The alignment of the current element becomes the alignment of
                   1214:         * the struct/union if it is larger than the current alignment
                   1215:         * of the struct/union.
                   1216:         */
1.3       jpo      1217:        if (al > dcs->d_stralign)
                   1218:                dcs->d_stralign = al;
1.22      lukem    1219:
1.3       jpo      1220:        no = (dcs->d_offset + (al - 1)) & ~(al - 1);
                   1221:        if (len == 0 || dcs->d_offset + len > no)
                   1222:                dcs->d_offset = no;
1.1       cgd      1223: }
                   1224:
                   1225: /*
                   1226:  * Remember the width of the field in its type structure.
                   1227:  */
                   1228: sym_t *
1.22      lukem    1229: bitfield(sym_t *dsym, int len)
1.1       cgd      1230: {
1.22      lukem    1231:
1.1       cgd      1232:        if (dsym == NULL) {
                   1233:                dsym = getblk(sizeof (sym_t));
                   1234:                dsym->s_name = unnamed;
1.81      rillig   1235:                dsym->s_kind = FMEMBER;
1.1       cgd      1236:                dsym->s_scl = MOS;
1.20      sommerfe 1237:                dsym->s_type = gettyp(UINT);
1.1       cgd      1238:                dsym->s_blklev = -1;
                   1239:        }
                   1240:        dsym->s_type = duptyp(dsym->s_type);
1.108     rillig   1241:        dsym->s_type->t_bitfield = true;
1.1       cgd      1242:        dsym->s_type->t_flen = len;
1.83      rillig   1243:        dsym->s_bitfield = 1;
1.76      rillig   1244:        return dsym;
1.1       cgd      1245: }
                   1246:
                   1247: /*
1.79      rillig   1248:  * Collect information about a sequence of asterisks and qualifiers in a
                   1249:  * list of type pqinf_t.
                   1250:  * Qualifiers always refer to the left asterisk.
                   1251:  * The rightmost asterisk will be at the top of the list.
1.1       cgd      1252:  */
                   1253: pqinf_t *
1.75      rillig   1254: merge_pointers_and_qualifiers(pqinf_t *p1, pqinf_t *p2)
1.1       cgd      1255: {
                   1256:        pqinf_t *p;
                   1257:
                   1258:        if (p2->p_pcnt != 0) {
                   1259:                /* left '*' at the end of the list */
1.82      rillig   1260:                for (p = p2; p->p_next != NULL; p = p->p_next)
1.22      lukem    1261:                        continue;
1.82      rillig   1262:                p->p_next = p1;
1.76      rillig   1263:                return p2;
1.1       cgd      1264:        } else {
                   1265:                if (p2->p_const) {
                   1266:                        if (p1->p_const) {
1.88      rillig   1267:                                /* duplicate '%s' */
1.1       cgd      1268:                                warning(10, "const");
                   1269:                        }
                   1270:                        p1->p_const = 1;
                   1271:                }
                   1272:                if (p2->p_volatile) {
                   1273:                        if (p1->p_volatile) {
1.88      rillig   1274:                                /* duplicate '%s' */
1.1       cgd      1275:                                warning(10, "volatile");
                   1276:                        }
                   1277:                        p1->p_volatile = 1;
                   1278:                }
                   1279:                free(p2);
1.76      rillig   1280:                return p1;
1.1       cgd      1281:        }
                   1282: }
                   1283:
                   1284: /*
1.73      rillig   1285:  * The following 3 functions extend the type of a declarator with
1.1       cgd      1286:  * pointer, function and array types.
                   1287:  *
1.3       jpo      1288:  * The current type is the Type built by deftyp() (dcs->d_type) and
1.1       cgd      1289:  * pointer, function and array types already added for this
                   1290:  * declarator. The new type extension is inserted between both.
                   1291:  */
                   1292: sym_t *
1.75      rillig   1293: add_pointer(sym_t *decl, pqinf_t *pi)
1.1       cgd      1294: {
                   1295:        type_t  **tpp, *tp;
                   1296:        pqinf_t *npi;
                   1297:
                   1298:        tpp = &decl->s_type;
1.18      christos 1299:        while (*tpp && *tpp != dcs->d_type)
1.1       cgd      1300:                tpp = &(*tpp)->t_subt;
1.18      christos 1301:        if (*tpp == NULL)
                   1302:                return decl;
1.1       cgd      1303:
                   1304:        while (pi != NULL) {
                   1305:                *tpp = tp = getblk(sizeof (type_t));
                   1306:                tp->t_tspec = PTR;
                   1307:                tp->t_const = pi->p_const;
                   1308:                tp->t_volatile = pi->p_volatile;
1.3       jpo      1309:                *(tpp = &tp->t_subt) = dcs->d_type;
1.82      rillig   1310:                npi = pi->p_next;
1.1       cgd      1311:                free(pi);
                   1312:                pi = npi;
                   1313:        }
1.76      rillig   1314:        return decl;
1.1       cgd      1315: }
                   1316:
                   1317: /*
                   1318:  * If a dimension was specified, dim is 1, otherwise 0
                   1319:  * n is the specified dimension
                   1320:  */
                   1321: sym_t *
1.75      rillig   1322: add_array(sym_t *decl, int dim, int n)
1.1       cgd      1323: {
                   1324:        type_t  **tpp, *tp;
                   1325:
                   1326:        tpp = &decl->s_type;
1.18      christos 1327:        while (*tpp && *tpp != dcs->d_type)
1.1       cgd      1328:                tpp = &(*tpp)->t_subt;
1.18      christos 1329:        if (*tpp == NULL)
                   1330:            return decl;
1.1       cgd      1331:
                   1332:        *tpp = tp = getblk(sizeof (type_t));
                   1333:        tp->t_tspec = ARRAY;
1.3       jpo      1334:        tp->t_subt = dcs->d_type;
1.1       cgd      1335:        tp->t_dim = n;
                   1336:
                   1337:        if (n < 0) {
1.88      rillig   1338:                /* negative array dimension (%d) */
1.36      christos 1339:                error(20, n);
1.1       cgd      1340:                n = 0;
                   1341:        } else if (n == 0 && dim) {
1.89      rillig   1342:                /* zero sized array is a C99 extension */
1.90      rillig   1343:                c99ism(322);
1.1       cgd      1344:        } else if (n == 0 && !dim) {
1.74      rillig   1345:                setcomplete(tp, 0);
1.1       cgd      1346:        }
                   1347:
1.76      rillig   1348:        return decl;
1.1       cgd      1349: }
                   1350:
                   1351: sym_t *
1.75      rillig   1352: add_function(sym_t *decl, sym_t *args)
1.1       cgd      1353: {
                   1354:        type_t  **tpp, *tp;
                   1355:
1.3       jpo      1356:        if (dcs->d_proto) {
1.1       cgd      1357:                if (tflag)
                   1358:                        /* function prototypes are illegal in traditional C */
                   1359:                        warning(270);
1.75      rillig   1360:                args = new_style_function(decl, args);
1.1       cgd      1361:        } else {
1.75      rillig   1362:                old_style_function(decl, args);
1.1       cgd      1363:        }
                   1364:
                   1365:        /*
                   1366:         * The symbols are removed from the symbol table by popdecl() after
1.75      rillig   1367:         * add_function(). To be able to restore them if this is a function
1.1       cgd      1368:         * definition, a pointer to the list of all symbols is stored in
1.82      rillig   1369:         * dcs->d_next->d_fpsyms. Also a list of the arguments (concatenated
                   1370:         * by s_next) is stored in dcs->d_next->d_fargs.
                   1371:         * (dcs->d_next must be used because *dcs is the declaration stack
1.1       cgd      1372:         * element created for the list of params and is removed after
1.75      rillig   1373:         * add_function())
1.1       cgd      1374:         */
1.82      rillig   1375:        if (dcs->d_next->d_ctx == EXTERN &&
                   1376:            decl->s_type == dcs->d_next->d_type) {
                   1377:                dcs->d_next->d_fpsyms = dcs->d_dlsyms;
                   1378:                dcs->d_next->d_fargs = args;
1.1       cgd      1379:        }
                   1380:
                   1381:        tpp = &decl->s_type;
1.82      rillig   1382:        while (*tpp && *tpp != dcs->d_next->d_type)
1.1       cgd      1383:                tpp = &(*tpp)->t_subt;
1.18      christos 1384:        if (*tpp == NULL)
                   1385:            return decl;
1.1       cgd      1386:
                   1387:        *tpp = tp = getblk(sizeof (type_t));
                   1388:        tp->t_tspec = FUNC;
1.82      rillig   1389:        tp->t_subt = dcs->d_next->d_type;
1.3       jpo      1390:        if ((tp->t_proto = dcs->d_proto) != 0)
1.1       cgd      1391:                tp->t_args = args;
1.3       jpo      1392:        tp->t_vararg = dcs->d_vararg;
1.1       cgd      1393:
1.76      rillig   1394:        return decl;
1.1       cgd      1395: }
                   1396:
                   1397: /*
                   1398:  * Called for new style function declarations.
                   1399:  */
                   1400: /* ARGSUSED */
                   1401: static sym_t *
1.75      rillig   1402: new_style_function(sym_t *decl, sym_t *args)
1.1       cgd      1403: {
                   1404:        sym_t   *arg, *sym;
                   1405:        scl_t   sc;
                   1406:        int     n;
                   1407:
                   1408:        /*
                   1409:         * Declarations of structs/unions/enums in param lists are legal,
                   1410:         * but senseless.
                   1411:         */
1.3       jpo      1412:        for (sym = dcs->d_dlsyms; sym != NULL; sym = sym->s_dlnxt) {
1.1       cgd      1413:                sc = sym->s_scl;
                   1414:                if (sc == STRTAG || sc == UNIONTAG || sc == ENUMTAG) {
                   1415:                        /* dubious tag declaration: %s %s */
1.77      rillig   1416:                        warning(85, storage_class_name(sc), sym->s_name);
1.1       cgd      1417:                }
                   1418:        }
                   1419:
                   1420:        n = 1;
1.80      rillig   1421:        for (arg = args; arg != NULL; arg = arg->s_next) {
1.1       cgd      1422:                if (arg->s_type->t_tspec == VOID) {
1.80      rillig   1423:                        if (n > 1 || arg->s_next != NULL) {
1.88      rillig   1424:                                /* void must be sole parameter */
1.1       cgd      1425:                                error(60);
                   1426:                                arg->s_type = gettyp(INT);
                   1427:                        }
                   1428:                }
                   1429:                n++;
                   1430:        }
                   1431:
                   1432:        /* return NULL if first param is VOID */
1.76      rillig   1433:        return args != NULL && args->s_type->t_tspec != VOID ? args : NULL;
1.1       cgd      1434: }
                   1435:
                   1436: /*
                   1437:  * Called for old style function declarations.
                   1438:  */
                   1439: static void
1.75      rillig   1440: old_style_function(sym_t *decl, sym_t *args)
1.1       cgd      1441: {
1.22      lukem    1442:
1.1       cgd      1443:        /*
                   1444:         * Remember list of params only if this is really seams to be
                   1445:         * a function definition.
                   1446:         */
1.82      rillig   1447:        if (dcs->d_next->d_ctx == EXTERN &&
                   1448:            decl->s_type == dcs->d_next->d_type) {
1.1       cgd      1449:                /*
                   1450:                 * We assume that this becomes a function definition. If
1.86      rillig   1451:                 * we are wrong, it's corrected in check_function_definition().
1.1       cgd      1452:                 */
                   1453:                if (args != NULL) {
                   1454:                        decl->s_osdef = 1;
                   1455:                        decl->s_args = args;
                   1456:                }
                   1457:        } else {
                   1458:                if (args != NULL)
                   1459:                        /* function prototype parameters must have types */
                   1460:                        warning(62);
                   1461:        }
                   1462: }
                   1463:
                   1464: /*
                   1465:  * Lists of Identifiers in functions declarations are allowed only if
1.86      rillig   1466:  * it's also a function definition. If this is not the case, print a
1.1       cgd      1467:  * error message.
                   1468:  */
                   1469: void
1.75      rillig   1470: check_function_definition(sym_t *sym, int msg)
1.1       cgd      1471: {
1.22      lukem    1472:
1.1       cgd      1473:        if (sym->s_osdef) {
                   1474:                if (msg) {
                   1475:                        /* incomplete or misplaced function definition */
                   1476:                        error(22);
                   1477:                }
                   1478:                sym->s_osdef = 0;
                   1479:                sym->s_args = NULL;
                   1480:        }
                   1481: }
                   1482:
                   1483: /*
                   1484:  * Process the name in a declarator.
1.73      rillig   1485:  * The symbol gets one of the storage classes EXTERN, STATIC, AUTO or
1.1       cgd      1486:  * TYPEDEF.
1.75      rillig   1487:  * s_def and s_reg are valid after declarator_name().
1.1       cgd      1488:  */
                   1489: sym_t *
1.75      rillig   1490: declarator_name(sym_t *sym)
1.1       cgd      1491: {
1.14      mycroft  1492:        scl_t   sc = NOSCL;
1.1       cgd      1493:
                   1494:        if (sym->s_scl == NOSCL) {
1.3       jpo      1495:                dcs->d_rdcsym = NULL;
1.1       cgd      1496:        } else if (sym->s_defarg) {
                   1497:                sym->s_defarg = 0;
1.3       jpo      1498:                dcs->d_rdcsym = NULL;
1.1       cgd      1499:        } else {
1.3       jpo      1500:                dcs->d_rdcsym = sym;
1.1       cgd      1501:                sym = pushdown(sym);
                   1502:        }
                   1503:
1.3       jpo      1504:        switch (dcs->d_ctx) {
1.1       cgd      1505:        case MOS:
                   1506:        case MOU:
1.73      rillig   1507:                /* Set parent */
1.3       jpo      1508:                sym->s_styp = dcs->d_tagtyp->t_str;
1.1       cgd      1509:                sym->s_def = DEF;
                   1510:                sym->s_value.v_tspec = INT;
1.3       jpo      1511:                sc = dcs->d_ctx;
1.1       cgd      1512:                break;
                   1513:        case EXTERN:
                   1514:                /*
                   1515:                 * static and external symbols without "extern" are
                   1516:                 * considered to be tentative defined, external
                   1517:                 * symbols with "extern" are declared, and typedef names
                   1518:                 * are defined. Tentative defined and declared symbols
                   1519:                 * may become defined if an initializer is present or
                   1520:                 * this is a function definition.
                   1521:                 */
1.3       jpo      1522:                if ((sc = dcs->d_scl) == NOSCL) {
1.1       cgd      1523:                        sc = EXTERN;
                   1524:                        sym->s_def = TDEF;
                   1525:                } else if (sc == STATIC) {
                   1526:                        sym->s_def = TDEF;
                   1527:                } else if (sc == TYPEDEF) {
                   1528:                        sym->s_def = DEF;
1.93      rillig   1529:                } else {
                   1530:                        lint_assert(sc == EXTERN);
1.1       cgd      1531:                        sym->s_def = DECL;
                   1532:                }
                   1533:                break;
                   1534:        case PARG:
                   1535:                sym->s_arg = 1;
                   1536:                /* FALLTHROUGH */
                   1537:        case ARG:
1.3       jpo      1538:                if ((sc = dcs->d_scl) == NOSCL) {
1.1       cgd      1539:                        sc = AUTO;
1.93      rillig   1540:                } else {
                   1541:                        lint_assert(sc == REG);
1.1       cgd      1542:                        sym->s_reg = 1;
                   1543:                        sc = AUTO;
                   1544:                }
                   1545:                sym->s_def = DEF;
                   1546:                break;
                   1547:        case AUTO:
1.3       jpo      1548:                if ((sc = dcs->d_scl) == NOSCL) {
1.1       cgd      1549:                        /*
                   1550:                         * XXX somewhat ugly because we dont know whether
                   1551:                         * this is AUTO or EXTERN (functions). If we are
                   1552:                         * wrong it must be corrected in decl1loc(), where
1.23      wiz      1553:                         * we have the necessary type information.
1.1       cgd      1554:                         */
                   1555:                        sc = AUTO;
                   1556:                        sym->s_def = DEF;
                   1557:                } else if (sc == AUTO || sc == STATIC || sc == TYPEDEF) {
                   1558:                        sym->s_def = DEF;
                   1559:                } else if (sc == REG) {
                   1560:                        sym->s_reg = 1;
                   1561:                        sc = AUTO;
                   1562:                        sym->s_def = DEF;
1.93      rillig   1563:                } else {
                   1564:                        lint_assert(sc == EXTERN);
1.1       cgd      1565:                        sym->s_def = DECL;
                   1566:                }
                   1567:                break;
                   1568:        default:
1.102     rillig   1569:                lint_assert(/*CONSTCOND*/0);
1.1       cgd      1570:        }
                   1571:        sym->s_scl = sc;
                   1572:
1.3       jpo      1573:        sym->s_type = dcs->d_type;
1.1       cgd      1574:
1.3       jpo      1575:        dcs->d_fpsyms = NULL;
1.1       cgd      1576:
1.76      rillig   1577:        return sym;
1.1       cgd      1578: }
                   1579:
                   1580: /*
                   1581:  * Process a name in the list of formal params in an old style function
                   1582:  * definition.
                   1583:  */
                   1584: sym_t *
1.75      rillig   1585: old_style_function_name(sym_t *sym)
1.1       cgd      1586: {
1.22      lukem    1587:
1.1       cgd      1588:        if (sym->s_scl != NOSCL) {
                   1589:                if (blklev == sym->s_blklev) {
                   1590:                        /* redeclaration of formal parameter %s */
                   1591:                        error(21, sym->s_name);
1.92      rillig   1592:                        lint_assert(sym->s_defarg);
1.1       cgd      1593:                }
                   1594:                sym = pushdown(sym);
                   1595:        }
                   1596:        sym->s_type = gettyp(INT);
                   1597:        sym->s_scl = AUTO;
                   1598:        sym->s_def = DEF;
                   1599:        sym->s_defarg = sym->s_arg = 1;
1.76      rillig   1600:        return sym;
1.1       cgd      1601: }
                   1602:
                   1603: /*
                   1604:  * Create the type of a tag.
                   1605:  *
                   1606:  * tag points to the symbol table entry of the tag
                   1607:  * kind is the kind of the tag (STRUCT/UNION/ENUM)
                   1608:  * decl is 1 if the type of the tag will be completed in this declaration
                   1609:  * (the following token is T_LBRACE)
                   1610:  * semi is 1 if the following token is T_SEMI
                   1611:  */
                   1612: type_t *
1.22      lukem    1613: mktag(sym_t *tag, tspec_t kind, int decl, int semi)
1.1       cgd      1614: {
1.14      mycroft  1615:        scl_t   scl = NOSCL;
1.1       cgd      1616:        type_t  *tp;
                   1617:
                   1618:        if (kind == STRUCT) {
                   1619:                scl = STRTAG;
                   1620:        } else if (kind == UNION) {
                   1621:                scl = UNIONTAG;
1.92      rillig   1622:        } else {
                   1623:                lint_assert(kind == ENUM);
1.1       cgd      1624:                scl = ENUMTAG;
                   1625:        }
                   1626:
                   1627:        if (tag != NULL) {
                   1628:                if (tag->s_scl != NOSCL) {
                   1629:                        tag = newtag(tag, scl, decl, semi);
                   1630:                } else {
                   1631:                        /* a new tag, no empty declaration */
1.82      rillig   1632:                        dcs->d_next->d_nedecl = 1;
1.1       cgd      1633:                        if (scl == ENUMTAG && !decl) {
                   1634:                                if (!tflag && (sflag || pflag))
                   1635:                                        /* forward reference to enum type */
                   1636:                                        warning(42);
                   1637:                        }
                   1638:                }
                   1639:                if (tag->s_scl == NOSCL) {
                   1640:                        tag->s_scl = scl;
                   1641:                        tag->s_type = tp = getblk(sizeof (type_t));
1.109     rillig   1642:                        tp->t_packed = dcs->d_packed;
1.1       cgd      1643:                } else {
                   1644:                        tp = tag->s_type;
                   1645:                }
                   1646:        } else {
                   1647:                tag = getblk(sizeof (sym_t));
                   1648:                tag->s_name = unnamed;
1.84      rillig   1649:                UNIQUE_CURR_POS(tag->s_def_pos);
1.1       cgd      1650:                tag->s_kind = FTAG;
                   1651:                tag->s_scl = scl;
                   1652:                tag->s_blklev = -1;
                   1653:                tag->s_type = tp = getblk(sizeof (type_t));
1.109     rillig   1654:                tp->t_packed = dcs->d_packed;
1.82      rillig   1655:                dcs->d_next->d_nedecl = 1;
1.1       cgd      1656:        }
                   1657:
                   1658:        if (tp->t_tspec == NOTSPEC) {
                   1659:                tp->t_tspec = kind;
                   1660:                if (kind != ENUM) {
                   1661:                        tp->t_str = getblk(sizeof (str_t));
1.113     rillig   1662:                        tp->t_str->align = CHAR_SIZE;
1.1       cgd      1663:                        tp->t_str->stag = tag;
                   1664:                } else {
                   1665:                        tp->t_isenum = 1;
1.55      christos 1666:                        tp->t_enum = getblk(sizeof(*tp->t_enum));
1.1       cgd      1667:                        tp->t_enum->etag = tag;
                   1668:                }
1.74      rillig   1669:                setcomplete(tp, 0);
1.1       cgd      1670:        }
1.76      rillig   1671:        return tp;
1.1       cgd      1672: }
                   1673:
                   1674: /*
                   1675:  * Checks all possible cases of tag redeclarations.
                   1676:  * decl is 1 if T_LBRACE follows
                   1677:  * semi is 1 if T_SEMI follows
                   1678:  */
                   1679: static sym_t *
1.22      lukem    1680: newtag(sym_t *tag, scl_t scl, int decl, int semi)
1.1       cgd      1681: {
1.22      lukem    1682:
1.1       cgd      1683:        if (tag->s_blklev < blklev) {
                   1684:                if (semi) {
                   1685:                        /* "struct a;" */
                   1686:                        if (!tflag) {
                   1687:                                if (!sflag)
                   1688:                                        /* decl. introduces new type ... */
1.77      rillig   1689:                                        warning(44, storage_class_name(scl),
                   1690:                                            tag->s_name);
1.1       cgd      1691:                                tag = pushdown(tag);
                   1692:                        } else if (tag->s_scl != scl) {
1.88      rillig   1693:                                /* base type is really '%s %s' */
1.77      rillig   1694:                                warning(45, storage_class_name(tag->s_scl),
                   1695:                                    tag->s_name);
1.1       cgd      1696:                        }
1.82      rillig   1697:                        dcs->d_next->d_nedecl = 1;
1.1       cgd      1698:                } else if (decl) {
1.22      lukem    1699:                        /* "struct a { ... } " */
1.1       cgd      1700:                        if (hflag)
                   1701:                                /* redefinition hides earlier one: %s */
                   1702:                                warning(43, tag->s_name);
                   1703:                        tag = pushdown(tag);
1.82      rillig   1704:                        dcs->d_next->d_nedecl = 1;
1.1       cgd      1705:                } else if (tag->s_scl != scl) {
1.88      rillig   1706:                        /* base type is really '%s %s' */
1.77      rillig   1707:                        warning(45, storage_class_name(tag->s_scl),
                   1708:                            tag->s_name);
1.1       cgd      1709:                        /* declaration introduces new type in ANSI C: %s %s */
1.77      rillig   1710:                        if (!sflag) {
1.94      rillig   1711:                                /* decl. introduces new type in ANSI C: %s %s */
1.77      rillig   1712:                                warning(44, storage_class_name(scl),
                   1713:                                    tag->s_name);
                   1714:                        }
1.1       cgd      1715:                        tag = pushdown(tag);
1.82      rillig   1716:                        dcs->d_next->d_nedecl = 1;
1.1       cgd      1717:                }
                   1718:        } else {
                   1719:                if (tag->s_scl != scl) {
                   1720:                        /* (%s) tag redeclared */
1.77      rillig   1721:                        error(46, storage_class_name(tag->s_scl));
1.75      rillig   1722:                        print_previous_declaration(-1, tag);
1.1       cgd      1723:                        tag = pushdown(tag);
1.82      rillig   1724:                        dcs->d_next->d_nedecl = 1;
1.1       cgd      1725:                } else if (decl && !incompl(tag->s_type)) {
                   1726:                        /* (%s) tag redeclared */
1.77      rillig   1727:                        error(46, storage_class_name(tag->s_scl));
1.75      rillig   1728:                        print_previous_declaration(-1, tag);
1.1       cgd      1729:                        tag = pushdown(tag);
1.82      rillig   1730:                        dcs->d_next->d_nedecl = 1;
1.1       cgd      1731:                } else if (semi || decl) {
1.82      rillig   1732:                        dcs->d_next->d_nedecl = 1;
1.1       cgd      1733:                }
                   1734:        }
1.76      rillig   1735:        return tag;
1.1       cgd      1736: }
                   1737:
                   1738: const char *
1.77      rillig   1739: storage_class_name(scl_t sc)
1.1       cgd      1740: {
                   1741:        const   char *s;
                   1742:
                   1743:        switch (sc) {
                   1744:        case EXTERN:    s = "extern";   break;
                   1745:        case STATIC:    s = "static";   break;
                   1746:        case AUTO:      s = "auto";     break;
                   1747:        case REG:       s = "register"; break;
                   1748:        case TYPEDEF:   s = "typedef";  break;
                   1749:        case STRTAG:    s = "struct";   break;
                   1750:        case UNIONTAG:  s = "union";    break;
                   1751:        case ENUMTAG:   s = "enum";     break;
1.102     rillig   1752:        default:        lint_assert(/*CONSTCOND*/0);
1.1       cgd      1753:        }
1.76      rillig   1754:        return s;
1.1       cgd      1755: }
                   1756:
                   1757: /*
1.78      rillig   1758:  * tp points to the type of the tag, fmem to the list of members.
1.1       cgd      1759:  */
                   1760: type_t *
1.78      rillig   1761: complete_tag_struct_or_union(type_t *tp, sym_t *fmem)
1.1       cgd      1762: {
                   1763:        tspec_t t;
                   1764:        str_t   *sp;
                   1765:        int     n;
                   1766:        sym_t   *mem;
                   1767:
1.74      rillig   1768:        setcomplete(tp, 1);
1.1       cgd      1769:
1.78      rillig   1770:        t = tp->t_tspec;
                   1771:        align(dcs->d_stralign, 0);
                   1772:        sp = tp->t_str;
                   1773:        sp->align = dcs->d_stralign;
                   1774:        sp->memb = fmem;
1.109     rillig   1775:        if (tp->t_packed)
1.78      rillig   1776:                setpackedsize(tp);
                   1777:        else
                   1778:                sp->size = dcs->d_offset;
                   1779:
                   1780:        if (sp->size == 0) {
1.106     rillig   1781:                /* zero sized %s is a C9X feature */
                   1782:                c99ism(47, ttab[t].tt_name);
1.78      rillig   1783:        }
1.63      christos 1784:
1.78      rillig   1785:        n = 0;
1.80      rillig   1786:        for (mem = fmem; mem != NULL; mem = mem->s_next) {
1.78      rillig   1787:                /* bind anonymous members to the structure */
                   1788:                if (mem->s_styp == NULL) {
                   1789:                        mem->s_styp = sp;
1.108     rillig   1790:                        if (mem->s_type->t_bitfield) {
1.78      rillig   1791:                                sp->size += bitfieldsize(&mem);
                   1792:                                if (mem == NULL)
                   1793:                                        break;
1.63      christos 1794:                        }
1.78      rillig   1795:                        sp->size += tsize(mem->s_type);
1.63      christos 1796:                }
1.78      rillig   1797:                if (mem->s_name != unnamed)
                   1798:                        n++;
                   1799:        }
1.63      christos 1800:
1.78      rillig   1801:        if (n == 0 && sp->size != 0) {
                   1802:                /* %s has no named members */
                   1803:                warning(65, t == STRUCT ? "structure" : "union");
1.1       cgd      1804:        }
1.76      rillig   1805:        return tp;
1.1       cgd      1806: }
                   1807:
1.78      rillig   1808: type_t *
                   1809: complete_tag_enum(type_t *tp, sym_t *fmem)
                   1810: {
                   1811:
                   1812:        setcomplete(tp, 1);
                   1813:        tp->t_enum->elem = fmem;
                   1814:        return tp;
                   1815: }
                   1816:
1.1       cgd      1817: /*
1.73      rillig   1818:  * Processes the name of an enumerator in an enum declaration.
1.1       cgd      1819:  *
                   1820:  * sym points to the enumerator
                   1821:  * val is the value of the enumerator
1.73      rillig   1822:  * impl is 1 if the value of the enumerator was not explicitly specified.
1.1       cgd      1823:  */
                   1824: sym_t *
1.112     rillig   1825: enumeration_constant(sym_t *sym, int val, int impl)
1.1       cgd      1826: {
1.22      lukem    1827:
1.1       cgd      1828:        if (sym->s_scl) {
                   1829:                if (sym->s_blklev == blklev) {
                   1830:                        /* no hflag, because this is illegal!!! */
                   1831:                        if (sym->s_arg) {
                   1832:                                /* enumeration constant hides parameter: %s */
                   1833:                                warning(57, sym->s_name);
                   1834:                        } else {
                   1835:                                /* redeclaration of %s */
                   1836:                                error(27, sym->s_name);
                   1837:                                /*
1.73      rillig   1838:                                 * inside blocks it should not be too
                   1839:                                 * complicated to find the position of the
                   1840:                                 * previous declaration
1.1       cgd      1841:                                 */
                   1842:                                if (blklev == 0)
1.75      rillig   1843:                                        print_previous_declaration(-1, sym);
1.1       cgd      1844:                        }
                   1845:                } else {
                   1846:                        if (hflag)
                   1847:                                /* redefinition hides earlier one: %s */
                   1848:                                warning(43, sym->s_name);
                   1849:                }
                   1850:                sym = pushdown(sym);
                   1851:        }
                   1852:        sym->s_scl = ENUMCON;
1.3       jpo      1853:        sym->s_type = dcs->d_tagtyp;
1.1       cgd      1854:        sym->s_value.v_tspec = INT;
                   1855:        sym->s_value.v_quad = val;
1.54      christos 1856:        if (impl && val - 1 == TARG_INT_MAX) {
1.1       cgd      1857:                /* overflow in enumeration values: %s */
                   1858:                warning(48, sym->s_name);
                   1859:        }
                   1860:        enumval = val + 1;
1.76      rillig   1861:        return sym;
1.1       cgd      1862: }
                   1863:
                   1864: /*
                   1865:  * Process a single external declarator.
                   1866:  */
                   1867: void
1.22      lukem    1868: decl1ext(sym_t *dsym, int initflg)
1.1       cgd      1869: {
1.44      dholland 1870:        int     dowarn, rval, redec;
1.1       cgd      1871:        sym_t   *rdsym;
                   1872:
1.75      rillig   1873:        check_function_definition(dsym, 1);
1.1       cgd      1874:
1.75      rillig   1875:        check_type(dsym);
1.1       cgd      1876:
1.75      rillig   1877:        if (initflg && !(initerr = check_init(dsym)))
1.1       cgd      1878:                dsym->s_def = DEF;
                   1879:
                   1880:        /*
1.75      rillig   1881:         * Declarations of functions are marked as "tentative" in
                   1882:         * declarator_name(). This is wrong because there are no
                   1883:         * tentative function definitions.
1.1       cgd      1884:         */
                   1885:        if (dsym->s_type->t_tspec == FUNC && dsym->s_def == TDEF)
                   1886:                dsym->s_def = DECL;
                   1887:
1.4       jpo      1888:        if (dcs->d_inline) {
                   1889:                if (dsym->s_type->t_tspec == FUNC) {
                   1890:                        dsym->s_inline = 1;
                   1891:                } else {
                   1892:                        /* variable declared inline: %s */
1.5       jpo      1893:                        warning(268, dsym->s_name);
1.4       jpo      1894:                }
                   1895:        }
                   1896:
1.1       cgd      1897:        /* Write the declaration into the output file */
                   1898:        if (plibflg && llibflg &&
                   1899:            dsym->s_type->t_tspec == FUNC && dsym->s_type->t_proto) {
                   1900:                /*
1.111     rillig   1901:                 * With both LINTLIBRARY and PROTOLIB the prototype is
1.1       cgd      1902:                 * written as a function definition to the output file.
                   1903:                 */
                   1904:                rval = dsym->s_type->t_subt->t_tspec != VOID;
1.84      rillig   1905:                outfdef(dsym, &dsym->s_def_pos, rval, 0, NULL);
1.1       cgd      1906:        } else {
1.4       jpo      1907:                outsym(dsym, dsym->s_scl, dsym->s_def);
1.1       cgd      1908:        }
                   1909:
1.3       jpo      1910:        if ((rdsym = dcs->d_rdcsym) != NULL) {
1.1       cgd      1911:
                   1912:                /*
1.73      rillig   1913:                 * If the old symbol stems from an old style function
                   1914:                 * definition, we have remembered the params in rdsmy->s_args
                   1915:                 * and compare them with the params of the prototype.
1.1       cgd      1916:                 */
1.6       jpo      1917:                if (rdsym->s_osdef && dsym->s_type->t_proto) {
1.75      rillig   1918:                        redec = check_old_style_definition(rdsym, dsym);
1.6       jpo      1919:                } else {
                   1920:                        redec = 0;
                   1921:                }
1.1       cgd      1922:
1.75      rillig   1923:                if (!redec && !check_redeclaration(dsym, (dowarn = 0, &dowarn))) {
1.22      lukem    1924:
1.44      dholland 1925:                        if (dowarn) {
1.105     rillig   1926:                                if (sflag)
                   1927:                                        /* redeclaration of %s */
                   1928:                                        error(27, dsym->s_name);
                   1929:                                else
                   1930:                                        /* redeclaration of %s */
                   1931:                                        warning(27, dsym->s_name);
1.75      rillig   1932:                                print_previous_declaration(-1, rdsym);
1.1       cgd      1933:                        }
                   1934:
                   1935:                        /*
1.73      rillig   1936:                         * Take over the remembered params if the new symbol
1.4       jpo      1937:                         * is not a prototype.
1.1       cgd      1938:                         */
                   1939:                        if (rdsym->s_osdef && !dsym->s_type->t_proto) {
                   1940:                                dsym->s_osdef = rdsym->s_osdef;
                   1941:                                dsym->s_args = rdsym->s_args;
1.85      rillig   1942:                                dsym->s_def_pos = rdsym->s_def_pos;
1.1       cgd      1943:                        }
                   1944:
                   1945:                        /*
                   1946:                         * Remember the position of the declaration if the
1.4       jpo      1947:                         * old symbol was a prototype and the new is not.
                   1948:                         * Also remember the position if the old symbol
1.1       cgd      1949:                         * was defined and the new is not.
                   1950:                         */
                   1951:                        if (rdsym->s_type->t_proto && !dsym->s_type->t_proto) {
1.85      rillig   1952:                                dsym->s_def_pos = rdsym->s_def_pos;
1.1       cgd      1953:                        } else if (rdsym->s_def == DEF && dsym->s_def != DEF) {
1.85      rillig   1954:                                dsym->s_def_pos = rdsym->s_def_pos;
1.1       cgd      1955:                        }
                   1956:
                   1957:                        /*
1.79      rillig   1958:                         * Copy usage information of the name into the new
                   1959:                         * symbol.
1.1       cgd      1960:                         */
1.75      rillig   1961:                        copy_usage_info(dsym, rdsym);
1.1       cgd      1962:
                   1963:                        /* Once a name is defined, it remains defined. */
                   1964:                        if (rdsym->s_def == DEF)
                   1965:                                dsym->s_def = DEF;
                   1966:
1.4       jpo      1967:                        /* once a function is inline, it remains inline */
                   1968:                        if (rdsym->s_inline)
                   1969:                                dsym->s_inline = 1;
                   1970:
1.75      rillig   1971:                        complete_type(dsym, rdsym);
1.1       cgd      1972:
                   1973:                }
1.22      lukem    1974:
1.1       cgd      1975:                rmsym(rdsym);
                   1976:        }
                   1977:
                   1978:        if (dsym->s_scl == TYPEDEF) {
                   1979:                dsym->s_type = duptyp(dsym->s_type);
                   1980:                dsym->s_type->t_typedef = 1;
                   1981:                settdsym(dsym->s_type, dsym);
                   1982:        }
                   1983:
                   1984: }
                   1985:
                   1986: /*
1.73      rillig   1987:  * Copies information about usage into a new symbol table entry of
1.1       cgd      1988:  * the same symbol.
                   1989:  */
                   1990: void
1.75      rillig   1991: copy_usage_info(sym_t *sym, sym_t *rdsym)
1.1       cgd      1992: {
1.22      lukem    1993:
1.84      rillig   1994:        sym->s_set_pos = rdsym->s_set_pos;
                   1995:        sym->s_use_pos = rdsym->s_use_pos;
1.1       cgd      1996:        sym->s_set = rdsym->s_set;
                   1997:        sym->s_used = rdsym->s_used;
                   1998: }
                   1999:
                   2000: /*
                   2001:  * Prints an error and returns 1 if a symbol is redeclared/redefined.
                   2002:  * Otherwise returns 0 and, in some cases of minor problems, prints
                   2003:  * a warning.
                   2004:  */
                   2005: int
1.75      rillig   2006: check_redeclaration(sym_t *dsym, int *dowarn)
1.1       cgd      2007: {
                   2008:        sym_t   *rsym;
                   2009:
1.3       jpo      2010:        if ((rsym = dcs->d_rdcsym)->s_scl == ENUMCON) {
1.1       cgd      2011:                /* redeclaration of %s */
                   2012:                error(27, dsym->s_name);
1.75      rillig   2013:                print_previous_declaration(-1, rsym);
1.76      rillig   2014:                return 1;
1.1       cgd      2015:        }
                   2016:        if (rsym->s_scl == TYPEDEF) {
                   2017:                /* typedef redeclared: %s */
                   2018:                error(89, dsym->s_name);
1.75      rillig   2019:                print_previous_declaration(-1, rsym);
1.76      rillig   2020:                return 1;
1.1       cgd      2021:        }
                   2022:        if (dsym->s_scl == TYPEDEF) {
                   2023:                /* redeclaration of %s */
                   2024:                error(27, dsym->s_name);
1.75      rillig   2025:                print_previous_declaration(-1, rsym);
1.76      rillig   2026:                return 1;
1.1       cgd      2027:        }
                   2028:        if (rsym->s_def == DEF && dsym->s_def == DEF) {
                   2029:                /* redefinition of %s */
                   2030:                error(28, dsym->s_name);
1.75      rillig   2031:                print_previous_declaration(-1, rsym);
1.1       cgd      2032:                return(1);
                   2033:        }
1.44      dholland 2034:        if (!eqtype(rsym->s_type, dsym->s_type, 0, 0, dowarn)) {
1.1       cgd      2035:                /* redeclaration of %s */
                   2036:                error(27, dsym->s_name);
1.75      rillig   2037:                print_previous_declaration(-1, rsym);
1.1       cgd      2038:                return(1);
                   2039:        }
                   2040:        if (rsym->s_scl == EXTERN && dsym->s_scl == EXTERN)
                   2041:                return(0);
                   2042:        if (rsym->s_scl == STATIC && dsym->s_scl == STATIC)
                   2043:                return(0);
                   2044:        if (rsym->s_scl == STATIC && dsym->s_def == DECL)
                   2045:                return(0);
                   2046:        if (rsym->s_scl == EXTERN && rsym->s_def == DEF) {
                   2047:                /*
1.66      kamil    2048:                 * All cases except "int a = 1; static int a;" are caught
1.1       cgd      2049:                 * above with or without a warning
                   2050:                 */
                   2051:                /* redeclaration of %s */
                   2052:                error(27, dsym->s_name);
1.75      rillig   2053:                print_previous_declaration(-1, rsym);
1.1       cgd      2054:                return(1);
                   2055:        }
                   2056:        if (rsym->s_scl == EXTERN) {
                   2057:                /* previously declared extern, becomes static: %s */
                   2058:                warning(29, dsym->s_name);
1.75      rillig   2059:                print_previous_declaration(-1, rsym);
1.1       cgd      2060:                return(0);
                   2061:        }
                   2062:        /*
1.86      rillig   2063:         * Now it's one of:
1.1       cgd      2064:         * "static a; int a;", "static a; int a = 1;", "static a = 1; int a;"
                   2065:         */
                   2066:        /* redeclaration of %s; ANSI C requires "static" */
                   2067:        if (sflag) {
1.94      rillig   2068:                /* redeclaration of %s; ANSI C requires static */
1.1       cgd      2069:                warning(30, dsym->s_name);
1.75      rillig   2070:                print_previous_declaration(-1, rsym);
1.1       cgd      2071:        }
                   2072:        dsym->s_scl = STATIC;
1.76      rillig   2073:        return 0;
1.1       cgd      2074: }
                   2075:
1.45      christos 2076: static int
                   2077: chkqual(type_t *tp1, type_t *tp2, int ignqual)
                   2078: {
                   2079:        if (tp1->t_const != tp2->t_const && !ignqual && !tflag)
                   2080:                return 0;
                   2081:
                   2082:        if (tp1->t_volatile != tp2->t_volatile && !ignqual && !tflag)
                   2083:                return 0;
                   2084:
                   2085:        return 1;
                   2086: }
                   2087:
                   2088: int
                   2089: eqptrtype(type_t *tp1, type_t *tp2, int ignqual)
                   2090: {
                   2091:        if (tp1->t_tspec != VOID && tp2->t_tspec != VOID)
                   2092:                return 0;
                   2093:
                   2094:        if (!chkqual(tp1, tp2, ignqual))
                   2095:                return 0;
                   2096:
                   2097:        return 1;
                   2098: }
                   2099:
                   2100:
1.1       cgd      2101: /*
                   2102:  * Checks if two types are compatible. Returns 0 if not, otherwise 1.
                   2103:  *
                   2104:  * ignqual     ignore qualifiers of type; used for function params
1.15      mycroft  2105:  * promot      promote left type; used for comparison of params of
1.1       cgd      2106:  *             old style function definitions with params of prototypes.
1.44      dholland 2107:  * *dowarn     set to 1 if an old style function declaration is not
1.1       cgd      2108:  *             compatible with a prototype
                   2109:  */
                   2110: int
1.44      dholland 2111: eqtype(type_t *tp1, type_t *tp2, int ignqual, int promot, int *dowarn)
1.1       cgd      2112: {
                   2113:        tspec_t t;
                   2114:
                   2115:        while (tp1 != NULL && tp2 != NULL) {
                   2116:
                   2117:                t = tp1->t_tspec;
                   2118:                if (promot) {
                   2119:                        if (t == FLOAT) {
                   2120:                                t = DOUBLE;
                   2121:                        } else if (t == CHAR || t == SCHAR) {
                   2122:                                t = INT;
                   2123:                        } else if (t == UCHAR) {
                   2124:                                t = tflag ? UINT : INT;
                   2125:                        } else if (t == SHORT) {
                   2126:                                t = INT;
                   2127:                        } else if (t == USHORT) {
                   2128:                                /* CONSTCOND */
1.54      christos 2129:                                t = TARG_INT_MAX < TARG_USHRT_MAX || tflag ? UINT : INT;
1.1       cgd      2130:                        }
                   2131:                }
                   2132:
                   2133:                if (t != tp2->t_tspec)
1.76      rillig   2134:                        return 0;
1.1       cgd      2135:
1.45      christos 2136:                if (!chkqual(tp1, tp2, ignqual))
                   2137:                        return 0;
1.1       cgd      2138:
                   2139:                if (t == STRUCT || t == UNION)
1.76      rillig   2140:                        return tp1->t_str == tp2->t_str;
1.1       cgd      2141:
                   2142:                if (t == ARRAY && tp1->t_dim != tp2->t_dim) {
                   2143:                        if (tp1->t_dim != 0 && tp2->t_dim != 0)
1.76      rillig   2144:                                return 0;
1.1       cgd      2145:                }
                   2146:
                   2147:                /* dont check prototypes for traditional */
                   2148:                if (t == FUNC && !tflag) {
                   2149:                        if (tp1->t_proto && tp2->t_proto) {
1.44      dholland 2150:                                if (!eqargs(tp1, tp2, dowarn))
1.76      rillig   2151:                                        return 0;
1.1       cgd      2152:                        } else if (tp1->t_proto) {
1.44      dholland 2153:                                if (!mnoarg(tp1, dowarn))
1.76      rillig   2154:                                        return 0;
1.1       cgd      2155:                        } else if (tp2->t_proto) {
1.44      dholland 2156:                                if (!mnoarg(tp2, dowarn))
1.76      rillig   2157:                                        return 0;
1.1       cgd      2158:                        }
                   2159:                }
                   2160:
                   2161:                tp1 = tp1->t_subt;
                   2162:                tp2 = tp2->t_subt;
                   2163:                ignqual = promot = 0;
                   2164:
                   2165:        }
                   2166:
1.76      rillig   2167:        return tp1 == tp2;
1.1       cgd      2168: }
                   2169:
                   2170: /*
1.6       jpo      2171:  * Compares the parameter types of two prototypes.
1.1       cgd      2172:  */
                   2173: static int
1.44      dholland 2174: eqargs(type_t *tp1, type_t *tp2, int *dowarn)
1.1       cgd      2175: {
                   2176:        sym_t   *a1, *a2;
                   2177:
                   2178:        if (tp1->t_vararg != tp2->t_vararg)
1.76      rillig   2179:                return 0;
1.1       cgd      2180:
                   2181:        a1 = tp1->t_args;
                   2182:        a2 = tp2->t_args;
                   2183:
                   2184:        while (a1 != NULL && a2 != NULL) {
                   2185:
1.44      dholland 2186:                if (eqtype(a1->s_type, a2->s_type, 1, 0, dowarn) == 0)
1.76      rillig   2187:                        return 0;
1.1       cgd      2188:
1.80      rillig   2189:                a1 = a1->s_next;
                   2190:                a2 = a2->s_next;
1.1       cgd      2191:
                   2192:        }
                   2193:
1.76      rillig   2194:        return a1 == a2;
1.1       cgd      2195: }
                   2196:
                   2197: /*
                   2198:  * mnoarg() (matches functions with no argument type information)
                   2199:  * returns 1 if all parameters of a prototype are compatible with
1.73      rillig   2200:  * an old style function declaration.
                   2201:  * This is the case if the following conditions are met:
1.1       cgd      2202:  *     1. the prototype must have a fixed number of parameters
                   2203:  *     2. no parameter is of type float
                   2204:  *     3. no parameter is converted to another type if integer promotion
                   2205:  *        is applied on it
                   2206:  */
                   2207: static int
1.44      dholland 2208: mnoarg(type_t *tp, int *dowarn)
1.1       cgd      2209: {
                   2210:        sym_t   *arg;
                   2211:        tspec_t t;
                   2212:
                   2213:        if (tp->t_vararg) {
1.44      dholland 2214:                if (dowarn != NULL)
                   2215:                        *dowarn = 1;
1.1       cgd      2216:        }
1.80      rillig   2217:        for (arg = tp->t_args; arg != NULL; arg = arg->s_next) {
1.1       cgd      2218:                if ((t = arg->s_type->t_tspec) == FLOAT ||
                   2219:                    t == CHAR || t == SCHAR || t == UCHAR ||
                   2220:                    t == SHORT || t == USHORT) {
1.44      dholland 2221:                        if (dowarn != NULL)
                   2222:                                *dowarn = 1;
1.1       cgd      2223:                }
                   2224:        }
1.76      rillig   2225:        return 1;
1.1       cgd      2226: }
                   2227:
                   2228: /*
                   2229:  * Compares a prototype declaration with the remembered arguments of
                   2230:  * a previous old style function definition.
                   2231:  */
1.6       jpo      2232: static int
1.75      rillig   2233: check_old_style_definition(sym_t *rdsym, sym_t *dsym)
1.1       cgd      2234: {
                   2235:        sym_t   *args, *pargs, *arg, *parg;
                   2236:        int     narg, nparg, n;
1.44      dholland 2237:        int     dowarn, msg;
1.1       cgd      2238:
                   2239:        args = rdsym->s_args;
                   2240:        pargs = dsym->s_type->t_args;
                   2241:
1.6       jpo      2242:        msg = 0;
1.1       cgd      2243:
                   2244:        narg = nparg = 0;
1.80      rillig   2245:        for (arg = args; arg != NULL; arg = arg->s_next)
1.1       cgd      2246:                narg++;
1.80      rillig   2247:        for (parg = pargs; parg != NULL; parg = parg->s_next)
1.1       cgd      2248:                nparg++;
                   2249:        if (narg != nparg) {
                   2250:                /* prototype does not match old-style definition */
                   2251:                error(63);
1.6       jpo      2252:                msg = 1;
1.1       cgd      2253:                goto end;
                   2254:        }
                   2255:
                   2256:        arg = args;
                   2257:        parg = pargs;
                   2258:        n = 1;
                   2259:        while (narg--) {
1.44      dholland 2260:                dowarn = 0;
1.1       cgd      2261:                /*
                   2262:                 * If it does not match due to promotion and sflag is
                   2263:                 * not set we print only a warning.
                   2264:                 */
1.44      dholland 2265:                if (!eqtype(arg->s_type, parg->s_type, 1, 1, &dowarn) || dowarn) {
1.88      rillig   2266:                        /* prototype does not match old style defn., arg #%d */
1.1       cgd      2267:                        error(299, n);
1.6       jpo      2268:                        msg = 1;
1.1       cgd      2269:                }
1.80      rillig   2270:                arg = arg->s_next;
                   2271:                parg = parg->s_next;
1.1       cgd      2272:                n++;
                   2273:        }
                   2274:
                   2275:  end:
1.6       jpo      2276:        if (msg)
1.7       jpo      2277:                /* old style definition */
1.75      rillig   2278:                print_previous_declaration(300, rdsym);
1.6       jpo      2279:
1.76      rillig   2280:        return msg;
1.1       cgd      2281: }
                   2282:
                   2283: /*
1.73      rillig   2284:  * Completes a type by copying the dimension and prototype information
1.1       cgd      2285:  * from a second compatible type.
                   2286:  *
                   2287:  * Following lines are legal:
                   2288:  *  "typedef a[]; a b; a b[10]; a c; a c[20];"
                   2289:  *  "typedef ft(); ft f; f(int); ft g; g(long);"
                   2290:  * This means that, if a type is completed, the type structure must
                   2291:  * be duplicated.
                   2292:  */
                   2293: void
1.75      rillig   2294: complete_type(sym_t *dsym, sym_t *ssym)
1.1       cgd      2295: {
                   2296:        type_t  **dstp, *src;
                   2297:        type_t  *dst;
                   2298:
                   2299:        dstp = &dsym->s_type;
                   2300:        src = ssym->s_type;
                   2301:
                   2302:        while ((dst = *dstp) != NULL) {
1.92      rillig   2303:                lint_assert(src != NULL);
                   2304:                lint_assert(dst->t_tspec == src->t_tspec);
1.1       cgd      2305:                if (dst->t_tspec == ARRAY) {
                   2306:                        if (dst->t_dim == 0 && src->t_dim != 0) {
                   2307:                                *dstp = dst = duptyp(dst);
                   2308:                                dst->t_dim = src->t_dim;
1.74      rillig   2309:                                setcomplete(dst, 1);
1.1       cgd      2310:                        }
                   2311:                } else if (dst->t_tspec == FUNC) {
                   2312:                        if (!dst->t_proto && src->t_proto) {
                   2313:                                *dstp = dst = duptyp(dst);
                   2314:                                dst->t_proto = 1;
                   2315:                                dst->t_args = src->t_args;
                   2316:                        }
                   2317:                }
                   2318:                dstp = &dst->t_subt;
                   2319:                src = src->t_subt;
                   2320:        }
                   2321: }
                   2322:
                   2323: /*
                   2324:  * Completes the declaration of a single argument.
                   2325:  */
                   2326: sym_t *
1.22      lukem    2327: decl1arg(sym_t *sym, int initflg)
1.1       cgd      2328: {
                   2329:        tspec_t t;
                   2330:
1.75      rillig   2331:        check_function_definition(sym, 1);
1.1       cgd      2332:
1.75      rillig   2333:        check_type(sym);
1.1       cgd      2334:
1.3       jpo      2335:        if (dcs->d_rdcsym != NULL && dcs->d_rdcsym->s_blklev == blklev) {
1.1       cgd      2336:                /* redeclaration of formal parameter %s */
                   2337:                error(237, sym->s_name);
1.3       jpo      2338:                rmsym(dcs->d_rdcsym);
1.1       cgd      2339:                sym->s_arg = 1;
                   2340:        }
                   2341:
                   2342:        if (!sym->s_arg) {
                   2343:                /* declared argument %s is missing */
                   2344:                error(53, sym->s_name);
                   2345:                sym->s_arg = 1;
                   2346:        }
                   2347:
                   2348:        if (initflg) {
                   2349:                /* cannot initialize parameter: %s */
                   2350:                error(52, sym->s_name);
                   2351:                initerr = 1;
                   2352:        }
                   2353:
                   2354:        if ((t = sym->s_type->t_tspec) == ARRAY) {
                   2355:                sym->s_type = incref(sym->s_type->t_subt, PTR);
                   2356:        } else if (t == FUNC) {
                   2357:                if (tflag)
                   2358:                        /* a function is declared as an argument: %s */
                   2359:                        warning(50, sym->s_name);
                   2360:                sym->s_type = incref(sym->s_type, PTR);
                   2361:        } else if (t == FLOAT) {
                   2362:                if (tflag)
                   2363:                        sym->s_type = gettyp(DOUBLE);
                   2364:        }
                   2365:
1.4       jpo      2366:        if (dcs->d_inline)
                   2367:                /* argument declared inline: %s */
1.5       jpo      2368:                warning(269, sym->s_name);
1.4       jpo      2369:
1.1       cgd      2370:        /*
                   2371:         * Arguments must have complete types. lengths() prints the needed
                   2372:         * error messages (null dimension is impossible because arrays are
                   2373:         * converted to pointers).
                   2374:         */
                   2375:        if (sym->s_type->t_tspec != VOID)
                   2376:                (void)length(sym->s_type, sym->s_name);
                   2377:
1.67      christos 2378:        sym->s_used = dcs->d_used;
1.75      rillig   2379:        mark_as_set(sym);
1.1       cgd      2380:
1.76      rillig   2381:        return sym;
1.1       cgd      2382: }
                   2383:
                   2384: void
1.87      rillig   2385: check_func_lint_directives(void)
1.1       cgd      2386: {
1.87      rillig   2387:        sym_t *arg;
                   2388:        int narg, n;
                   2389:        tspec_t t;
1.1       cgd      2390:
                   2391:        /* check for illegal combinations of lint directives */
1.110     rillig   2392:        if (printflike_argnum != -1 && scanflike_argnum != -1) {
1.1       cgd      2393:                /* can't be used together: ** PRINTFLIKE ** ** SCANFLIKE ** */
                   2394:                warning(289);
1.110     rillig   2395:                printflike_argnum = scanflike_argnum = -1;
1.1       cgd      2396:        }
1.110     rillig   2397:        if (nvararg != -1 &&
                   2398:            (printflike_argnum != -1 || scanflike_argnum != -1)) {
1.1       cgd      2399:                /* dubious use of ** VARARGS ** with ** %s ** */
1.110     rillig   2400:                warning(288,
                   2401:                    printflike_argnum != -1 ? "PRINTFLIKE" : "SCANFLIKE");
1.1       cgd      2402:                nvararg = -1;
                   2403:        }
                   2404:
                   2405:        /*
                   2406:         * check if the argument of a lint directive is compatible with the
                   2407:         * number of arguments.
                   2408:         */
                   2409:        narg = 0;
1.80      rillig   2410:        for (arg = dcs->d_fargs; arg != NULL; arg = arg->s_next)
1.1       cgd      2411:                narg++;
                   2412:        if (nargusg > narg) {
                   2413:                /* argument number mismatch with directive: ** %s ** */
                   2414:                warning(283, "ARGSUSED");
                   2415:                nargusg = 0;
                   2416:        }
                   2417:        if (nvararg > narg) {
                   2418:                /* argument number mismatch with directive: ** %s ** */
                   2419:                warning(283, "VARARGS");
                   2420:                nvararg = 0;
                   2421:        }
1.110     rillig   2422:        if (printflike_argnum > narg) {
1.1       cgd      2423:                /* argument number mismatch with directive: ** %s ** */
                   2424:                warning(283, "PRINTFLIKE");
1.110     rillig   2425:                printflike_argnum = -1;
                   2426:        } else if (printflike_argnum == 0) {
                   2427:                printflike_argnum = -1;
1.1       cgd      2428:        }
1.110     rillig   2429:        if (scanflike_argnum > narg) {
1.1       cgd      2430:                /* argument number mismatch with directive: ** %s ** */
                   2431:                warning(283, "SCANFLIKE");
1.110     rillig   2432:                scanflike_argnum = -1;
                   2433:        } else if (scanflike_argnum == 0) {
                   2434:                scanflike_argnum = -1;
                   2435:        }
                   2436:        if (printflike_argnum != -1 || scanflike_argnum != -1) {
                   2437:                narg = printflike_argnum != -1
                   2438:                    ? printflike_argnum : scanflike_argnum;
1.6       jpo      2439:                arg = dcs->d_fargs;
                   2440:                for (n = 1; n < narg; n++)
1.80      rillig   2441:                        arg = arg->s_next;
1.1       cgd      2442:                if (arg->s_type->t_tspec != PTR ||
                   2443:                    ((t = arg->s_type->t_subt->t_tspec) != CHAR &&
                   2444:                     t != UCHAR && t != SCHAR)) {
                   2445:                        /* arg. %d must be 'char *' for PRINTFLIKE/SCANFLIKE */
                   2446:                        warning(293, narg);
1.110     rillig   2447:                        printflike_argnum = scanflike_argnum = -1;
1.1       cgd      2448:                }
                   2449:        }
1.87      rillig   2450: }
                   2451:
                   2452: /*
                   2453:  * Warn about arguments in old style function definitions that default to int.
                   2454:  * Check that an old style function definition is compatible to a previous
                   2455:  * prototype.
                   2456:  */
                   2457: void
                   2458: check_func_old_style_arguments(void)
                   2459: {
                   2460:        sym_t *args, *arg, *pargs, *parg;
                   2461:        int narg, nparg, msg;
                   2462:
                   2463:        args = funcsym->s_args;
                   2464:        pargs = funcsym->s_type->t_args;
1.1       cgd      2465:
                   2466:        /*
1.73      rillig   2467:         * print a warning for each argument of an old style function
1.1       cgd      2468:         * definition which defaults to int
                   2469:         */
1.80      rillig   2470:        for (arg = args; arg != NULL; arg = arg->s_next) {
1.1       cgd      2471:                if (arg->s_defarg) {
1.88      rillig   2472:                        /* argument type defaults to 'int': %s */
1.1       cgd      2473:                        warning(32, arg->s_name);
                   2474:                        arg->s_defarg = 0;
1.75      rillig   2475:                        mark_as_set(arg);
1.1       cgd      2476:                }
                   2477:        }
                   2478:
                   2479:        /*
1.73      rillig   2480:         * If this is an old style function definition and a prototype
1.1       cgd      2481:         * exists, compare the types of arguments.
                   2482:         */
                   2483:        if (funcsym->s_osdef && funcsym->s_type->t_proto) {
                   2484:                /*
1.73      rillig   2485:                 * If the number of arguments does not match, we need not
1.1       cgd      2486:                 * continue.
                   2487:                 */
                   2488:                narg = nparg = 0;
1.6       jpo      2489:                msg = 0;
1.80      rillig   2490:                for (parg = pargs; parg != NULL; parg = parg->s_next)
1.1       cgd      2491:                        nparg++;
1.80      rillig   2492:                for (arg = args; arg != NULL; arg = arg->s_next)
1.1       cgd      2493:                        narg++;
                   2494:                if (narg != nparg) {
                   2495:                        /* parameter mismatch: %d declared, %d defined */
                   2496:                        error(51, nparg, narg);
1.6       jpo      2497:                        msg = 1;
1.1       cgd      2498:                } else {
                   2499:                        parg = pargs;
                   2500:                        arg = args;
                   2501:                        while (narg--) {
1.75      rillig   2502:                                msg |= check_prototype_declaration(arg, parg);
1.80      rillig   2503:                                parg = parg->s_next;
                   2504:                                arg = arg->s_next;
1.1       cgd      2505:                        }
                   2506:                }
1.6       jpo      2507:                if (msg)
1.1       cgd      2508:                        /* prototype declaration */
1.75      rillig   2509:                        print_previous_declaration(285, dcs->d_rdcsym);
1.6       jpo      2510:
1.73      rillig   2511:                /* from now on the prototype is valid */
1.6       jpo      2512:                funcsym->s_osdef = 0;
                   2513:                funcsym->s_args = NULL;
1.1       cgd      2514:        }
                   2515: }
                   2516:
                   2517: /*
                   2518:  * Checks compatibility of an old style function definition with a previous
                   2519:  * prototype declaration.
                   2520:  * Returns 1 if the position of the previous declaration should be reported.
                   2521:  */
                   2522: static int
1.75      rillig   2523: check_prototype_declaration(sym_t *arg, sym_t *parg)
1.1       cgd      2524: {
                   2525:        type_t  *tp, *ptp;
1.44      dholland 2526:        int     dowarn, msg;
1.1       cgd      2527:
                   2528:        tp = arg->s_type;
                   2529:        ptp = parg->s_type;
                   2530:
1.6       jpo      2531:        msg = 0;
1.44      dholland 2532:        dowarn = 0;
1.6       jpo      2533:
1.44      dholland 2534:        if (!eqtype(tp, ptp, 1, 1, &dowarn)) {
                   2535:                if (eqtype(tp, ptp, 1, 0, &dowarn)) {
1.6       jpo      2536:                        /* type does not match prototype: %s */
1.106     rillig   2537:                        gnuism(58, arg->s_name);
                   2538:                        msg = sflag || !gflag;
1.6       jpo      2539:                } else {
                   2540:                        /* type does not match prototype: %s */
                   2541:                        error(58, arg->s_name);
                   2542:                        msg = 1;
                   2543:                }
1.44      dholland 2544:        } else if (dowarn) {
1.105     rillig   2545:                if (sflag)
                   2546:                        /* type does not match prototype: %s */
                   2547:                        error(58, arg->s_name);
                   2548:                else
                   2549:                        /* type does not match prototype: %s */
                   2550:                        warning(58, arg->s_name);
1.6       jpo      2551:                msg = 1;
1.1       cgd      2552:        }
1.6       jpo      2553:
1.76      rillig   2554:        return msg;
1.1       cgd      2555: }
                   2556:
                   2557: /*
                   2558:  * Completes a single local declaration/definition.
                   2559:  */
                   2560: void
1.22      lukem    2561: decl1loc(sym_t *dsym, int initflg)
1.1       cgd      2562: {
1.22      lukem    2563:
1.75      rillig   2564:        /* Correct a mistake done in declarator_name(). */
1.1       cgd      2565:        if (dsym->s_type->t_tspec == FUNC) {
                   2566:                dsym->s_def = DECL;
1.3       jpo      2567:                if (dcs->d_scl == NOSCL)
1.1       cgd      2568:                        dsym->s_scl = EXTERN;
                   2569:        }
                   2570:
                   2571:        if (dsym->s_type->t_tspec == FUNC) {
                   2572:                if (dsym->s_scl == STATIC) {
                   2573:                        /* dubious static function at block level: %s */
                   2574:                        warning(93, dsym->s_name);
                   2575:                        dsym->s_scl = EXTERN;
                   2576:                } else if (dsym->s_scl != EXTERN && dsym->s_scl != TYPEDEF) {
                   2577:                        /* function has illegal storage class: %s */
                   2578:                        error(94, dsym->s_name);
                   2579:                        dsym->s_scl = EXTERN;
                   2580:                }
                   2581:        }
                   2582:
1.4       jpo      2583:        /*
                   2584:         * functions may be declared inline at local scope, although
                   2585:         * this has no effect for a later definition of the same
                   2586:         * function.
                   2587:         * XXX it should have an effect if tflag is set. this would
                   2588:         * also be the way gcc behaves.
                   2589:         */
                   2590:        if (dcs->d_inline) {
                   2591:                if (dsym->s_type->t_tspec == FUNC) {
                   2592:                        dsym->s_inline = 1;
                   2593:                } else {
                   2594:                        /* variable declared inline: %s */
1.5       jpo      2595:                        warning(268, dsym->s_name);
1.4       jpo      2596:                }
                   2597:        }
                   2598:
1.75      rillig   2599:        check_function_definition(dsym, 1);
1.1       cgd      2600:
1.75      rillig   2601:        check_type(dsym);
1.1       cgd      2602:
1.3       jpo      2603:        if (dcs->d_rdcsym != NULL && dsym->s_scl == EXTERN)
1.1       cgd      2604:                ledecl(dsym);
                   2605:
                   2606:        if (dsym->s_scl == EXTERN) {
                   2607:                /*
1.73      rillig   2608:                 * XXX if the static variable at level 0 is only defined
                   2609:                 * later, checking will be possible.
1.1       cgd      2610:                 */
1.83      rillig   2611:                if (dsym->s_ext_sym == NULL) {
1.4       jpo      2612:                        outsym(dsym, EXTERN, dsym->s_def);
1.1       cgd      2613:                } else {
1.83      rillig   2614:                        outsym(dsym, dsym->s_ext_sym->s_scl, dsym->s_def);
1.1       cgd      2615:                }
                   2616:        }
                   2617:
1.3       jpo      2618:        if (dcs->d_rdcsym != NULL) {
1.1       cgd      2619:
1.3       jpo      2620:                if (dcs->d_rdcsym->s_blklev == 0) {
1.1       cgd      2621:
                   2622:                        switch (dsym->s_scl) {
                   2623:                        case AUTO:
                   2624:                                if (hflag)
1.94      rillig   2625:                                        /* automatic hides external decl.: %s */
1.1       cgd      2626:                                        warning(86, dsym->s_name);
                   2627:                                break;
                   2628:                        case STATIC:
                   2629:                                if (hflag)
1.94      rillig   2630:                                        /* static hides external decl.: %s */
1.1       cgd      2631:                                        warning(87, dsym->s_name);
                   2632:                                break;
                   2633:                        case TYPEDEF:
                   2634:                                if (hflag)
1.94      rillig   2635:                                        /* typedef hides external decl.: %s */
1.1       cgd      2636:                                        warning(88, dsym->s_name);
                   2637:                                break;
                   2638:                        case EXTERN:
                   2639:                                /*
                   2640:                                 * Warnings and errors are printed in ledecl()
                   2641:                                 */
                   2642:                                break;
                   2643:                        default:
1.102     rillig   2644:                                lint_assert(/*CONSTCOND*/0);
1.1       cgd      2645:                        }
                   2646:
1.3       jpo      2647:                } else if (dcs->d_rdcsym->s_blklev == blklev) {
1.1       cgd      2648:
1.86      rillig   2649:                        /* no hflag, because it's illegal! */
1.3       jpo      2650:                        if (dcs->d_rdcsym->s_arg) {
1.7       jpo      2651:                                /*
                   2652:                                 * if !tflag, a "redeclaration of %s" error
                   2653:                                 * is produced below
                   2654:                                 */
                   2655:                                if (tflag) {
                   2656:                                        if (hflag)
                   2657:                                                /* decl. hides parameter: %s */
                   2658:                                                warning(91, dsym->s_name);
                   2659:                                        rmsym(dcs->d_rdcsym);
                   2660:                                }
1.1       cgd      2661:                        }
                   2662:
1.3       jpo      2663:                } else if (dcs->d_rdcsym->s_blklev < blklev) {
1.1       cgd      2664:
                   2665:                        if (hflag)
                   2666:                                /* declaration hides earlier one: %s */
                   2667:                                warning(95, dsym->s_name);
1.22      lukem    2668:
1.1       cgd      2669:                }
                   2670:
1.3       jpo      2671:                if (dcs->d_rdcsym->s_blklev == blklev) {
1.1       cgd      2672:
                   2673:                        /* redeclaration of %s */
                   2674:                        error(27, dsym->s_name);
1.3       jpo      2675:                        rmsym(dcs->d_rdcsym);
1.1       cgd      2676:
                   2677:                }
                   2678:
                   2679:        }
                   2680:
1.75      rillig   2681:        if (initflg && !(initerr = check_init(dsym))) {
1.1       cgd      2682:                dsym->s_def = DEF;
1.75      rillig   2683:                mark_as_set(dsym);
1.1       cgd      2684:        }
                   2685:
                   2686:        if (dsym->s_scl == TYPEDEF) {
                   2687:                dsym->s_type = duptyp(dsym->s_type);
                   2688:                dsym->s_type->t_typedef = 1;
                   2689:                settdsym(dsym->s_type, dsym);
                   2690:        }
                   2691:
                   2692:        /*
1.73      rillig   2693:         * Before we can check the size we must wait for a initialization
1.1       cgd      2694:         * which may follow.
                   2695:         */
                   2696: }
                   2697:
                   2698: /*
1.73      rillig   2699:  * Processes (re)declarations of external symbols inside blocks.
1.1       cgd      2700:  */
                   2701: static void
1.22      lukem    2702: ledecl(sym_t *dsym)
1.1       cgd      2703: {
1.44      dholland 2704:        int     eqt, dowarn;
1.1       cgd      2705:        sym_t   *esym;
                   2706:
                   2707:        /* look for a symbol with the same name */
1.3       jpo      2708:        esym = dcs->d_rdcsym;
1.1       cgd      2709:        while (esym != NULL && esym->s_blklev != 0) {
                   2710:                while ((esym = esym->s_link) != NULL) {
                   2711:                        if (esym->s_kind != FVFT)
                   2712:                                continue;
                   2713:                        if (strcmp(dsym->s_name, esym->s_name) == 0)
                   2714:                                break;
                   2715:                }
                   2716:        }
                   2717:        if (esym == NULL)
                   2718:                return;
                   2719:        if (esym->s_scl != EXTERN && esym->s_scl != STATIC) {
                   2720:                /* gcc accepts this without a warning, pcc prints an error. */
                   2721:                /* redeclaration of %s */
                   2722:                warning(27, dsym->s_name);
1.75      rillig   2723:                print_previous_declaration(-1, esym);
1.1       cgd      2724:                return;
                   2725:        }
                   2726:
1.44      dholland 2727:        dowarn = 0;
                   2728:        eqt = eqtype(esym->s_type, dsym->s_type, 0, 0, &dowarn);
1.1       cgd      2729:
1.44      dholland 2730:        if (!eqt || dowarn) {
1.1       cgd      2731:                if (esym->s_scl == EXTERN) {
                   2732:                        /* inconsistent redeclaration of extern: %s */
                   2733:                        warning(90, dsym->s_name);
1.75      rillig   2734:                        print_previous_declaration(-1, esym);
1.1       cgd      2735:                } else {
                   2736:                        /* inconsistent redeclaration of static: %s */
                   2737:                        warning(92, dsym->s_name);
1.75      rillig   2738:                        print_previous_declaration(-1, esym);
1.1       cgd      2739:                }
                   2740:        }
                   2741:
                   2742:        if (eqt) {
                   2743:                /*
                   2744:                 * Remember the external symbol so we can update usage
                   2745:                 * information at the end of the block.
                   2746:                 */
1.83      rillig   2747:                dsym->s_ext_sym = esym;
1.1       cgd      2748:        }
                   2749: }
                   2750:
                   2751: /*
1.73      rillig   2752:  * Print an error or a warning if the symbol cannot be initialized due
                   2753:  * to type/storage class. Return 1 if an error has been detected.
1.1       cgd      2754:  */
                   2755: static int
1.75      rillig   2756: check_init(sym_t *sym)
1.1       cgd      2757: {
1.44      dholland 2758:        int     erred;
1.1       cgd      2759:
1.44      dholland 2760:        erred = 0;
1.1       cgd      2761:
                   2762:        if (sym->s_type->t_tspec == FUNC) {
                   2763:                /* cannot initialize function: %s */
                   2764:                error(24, sym->s_name);
1.44      dholland 2765:                erred = 1;
1.1       cgd      2766:        } else if (sym->s_scl == TYPEDEF) {
                   2767:                /* cannot initialize typedef: %s */
                   2768:                error(25, sym->s_name);
1.44      dholland 2769:                erred = 1;
1.1       cgd      2770:        } else if (sym->s_scl == EXTERN && sym->s_def == DECL) {
                   2771:                /* cannot initialize "extern" declaration: %s */
1.3       jpo      2772:                if (dcs->d_ctx == EXTERN) {
1.94      rillig   2773:                        /* cannot initialize extern declaration: %s */
1.1       cgd      2774:                        warning(26, sym->s_name);
                   2775:                } else {
1.94      rillig   2776:                        /* cannot initialize extern declaration: %s */
1.1       cgd      2777:                        error(26, sym->s_name);
1.44      dholland 2778:                        erred = 1;
1.1       cgd      2779:                }
                   2780:        }
                   2781:
1.76      rillig   2782:        return erred;
1.1       cgd      2783: }
                   2784:
                   2785: /*
1.73      rillig   2786:  * Create a symbol for an abstract declaration.
1.1       cgd      2787:  */
                   2788: sym_t *
1.75      rillig   2789: abstract_name(void)
1.1       cgd      2790: {
                   2791:        sym_t   *sym;
                   2792:
1.92      rillig   2793:        lint_assert(dcs->d_ctx == ABSTRACT || dcs->d_ctx == PARG);
1.1       cgd      2794:
                   2795:        sym = getblk(sizeof (sym_t));
                   2796:
                   2797:        sym->s_name = unnamed;
                   2798:        sym->s_def = DEF;
                   2799:        sym->s_scl = ABSTRACT;
                   2800:        sym->s_blklev = -1;
                   2801:
1.3       jpo      2802:        if (dcs->d_ctx == PARG)
1.1       cgd      2803:                sym->s_arg = 1;
                   2804:
1.3       jpo      2805:        sym->s_type = dcs->d_type;
                   2806:        dcs->d_rdcsym = NULL;
                   2807:        dcs->d_vararg = 0;
1.1       cgd      2808:
1.76      rillig   2809:        return sym;
1.1       cgd      2810: }
                   2811:
                   2812: /*
                   2813:  * Removes anything which has nothing to do on global level.
                   2814:  */
                   2815: void
1.77      rillig   2816: global_clean_up(void)
1.1       cgd      2817: {
1.22      lukem    2818:
1.82      rillig   2819:        while (dcs->d_next != NULL)
1.1       cgd      2820:                popdecl();
                   2821:
                   2822:        cleanup();
                   2823:        blklev = 0;
                   2824:        mblklev = 0;
                   2825:
                   2826:        /*
1.73      rillig   2827:         * remove all information about pending lint directives without
1.1       cgd      2828:         * warnings.
                   2829:         */
1.77      rillig   2830:        global_clean_up_decl(1);
1.1       cgd      2831: }
                   2832:
                   2833: /*
                   2834:  * Process an abstract type declaration
                   2835:  */
                   2836: sym_t *
1.75      rillig   2837: declare_1_abstract(sym_t *sym)
1.1       cgd      2838: {
1.22      lukem    2839:
1.75      rillig   2840:        check_function_definition(sym, 1);
                   2841:        check_type(sym);
1.76      rillig   2842:        return sym;
1.1       cgd      2843: }
                   2844:
                   2845: /*
                   2846:  * Checks size after declarations of variables and their initialisation.
                   2847:  */
                   2848: void
1.75      rillig   2849: check_size(sym_t *dsym)
1.1       cgd      2850: {
1.22      lukem    2851:
1.1       cgd      2852:        if (dsym->s_def != DEF)
                   2853:                return;
                   2854:        if (dsym->s_scl == TYPEDEF)
                   2855:                return;
                   2856:        if (dsym->s_type->t_tspec == FUNC)
                   2857:                return;
                   2858:
                   2859:        if (length(dsym->s_type, dsym->s_name) == 0 &&
                   2860:            dsym->s_type->t_tspec == ARRAY && dsym->s_type->t_dim == 0) {
                   2861:                if (tflag) {
1.94      rillig   2862:                        /* empty array declaration: %s */
1.1       cgd      2863:                        warning(190, dsym->s_name);
                   2864:                } else {
1.94      rillig   2865:                        /* empty array declaration: %s */
1.1       cgd      2866:                        error(190, dsym->s_name);
                   2867:                }
                   2868:        }
                   2869: }
                   2870:
                   2871: /*
                   2872:  * Mark an object as set if it is not already
                   2873:  */
                   2874: void
1.75      rillig   2875: mark_as_set(sym_t *sym)
1.1       cgd      2876: {
1.22      lukem    2877:
1.1       cgd      2878:        if (!sym->s_set) {
                   2879:                sym->s_set = 1;
1.84      rillig   2880:                UNIQUE_CURR_POS(sym->s_set_pos);
1.1       cgd      2881:        }
                   2882: }
                   2883:
                   2884: /*
                   2885:  * Mark an object as used if it is not already
                   2886:  */
                   2887: void
1.75      rillig   2888: mark_as_used(sym_t *sym, int fcall, int szof)
1.1       cgd      2889: {
1.22      lukem    2890:
1.1       cgd      2891:        if (!sym->s_used) {
                   2892:                sym->s_used = 1;
1.84      rillig   2893:                UNIQUE_CURR_POS(sym->s_use_pos);
1.1       cgd      2894:        }
                   2895:        /*
                   2896:         * for function calls another record is written
                   2897:         *
1.73      rillig   2898:         * XXX Should symbols used in sizeof() be treated as used or not?
1.1       cgd      2899:         * Probably not, because there is no sense to declare an
                   2900:         * external variable only to get their size.
                   2901:         */
                   2902:        if (!fcall && !szof && sym->s_kind == FVFT && sym->s_scl == EXTERN)
                   2903:                outusg(sym);
                   2904: }
                   2905:
                   2906: /*
                   2907:  * Prints warnings for a list of variables and labels (concatenated
                   2908:  * with s_dlnxt) if these are not used or only set.
                   2909:  */
                   2910: void
1.75      rillig   2911: check_usage(dinfo_t *di)
1.1       cgd      2912: {
                   2913:        sym_t   *sym;
1.56      christos 2914:        int     mklwarn;
1.1       cgd      2915:
1.57      christos 2916:        /* for this warning LINTED has no effect */
1.56      christos 2917:        mklwarn = lwarn;
                   2918:        lwarn = LWARN_ALL;
1.1       cgd      2919:
1.38      christos 2920: #ifdef DEBUG
1.56      christos 2921:        printf("%s, %d: >temp lwarn = %d\n", curr_pos.p_file, curr_pos.p_line,
                   2922:            lwarn);
1.38      christos 2923: #endif
1.10      jpo      2924:        for (sym = di->d_dlsyms; sym != NULL; sym = sym->s_dlnxt)
1.75      rillig   2925:                check_usage_sym(di->d_asm, sym);
1.56      christos 2926:        lwarn = mklwarn;
1.38      christos 2927: #ifdef DEBUG
1.56      christos 2928:        printf("%s, %d: <temp lwarn = %d\n", curr_pos.p_file, curr_pos.p_line,
                   2929:            lwarn);
1.38      christos 2930: #endif
1.1       cgd      2931: }
                   2932:
                   2933: /*
                   2934:  * Prints a warning for a single variable or label if it is not used or
                   2935:  * only set.
                   2936:  */
                   2937: void
1.75      rillig   2938: check_usage_sym(int novar, sym_t *sym)
1.1       cgd      2939: {
                   2940:        pos_t   cpos;
                   2941:
                   2942:        if (sym->s_blklev == -1)
                   2943:                return;
                   2944:
1.85      rillig   2945:        cpos = curr_pos;
1.1       cgd      2946:
                   2947:        if (sym->s_kind == FVFT) {
                   2948:                if (sym->s_arg) {
1.75      rillig   2949:                        check_argument_usage(novar, sym);
1.1       cgd      2950:                } else {
1.75      rillig   2951:                        check_variable_usage(novar, sym);
1.1       cgd      2952:                }
1.81      rillig   2953:        } else if (sym->s_kind == FLABEL) {
1.75      rillig   2954:                check_label_usage(sym);
1.1       cgd      2955:        } else if (sym->s_kind == FTAG) {
1.75      rillig   2956:                check_tag_usage(sym);
1.1       cgd      2957:        }
                   2958:
1.85      rillig   2959:        curr_pos = cpos;
1.1       cgd      2960: }
                   2961:
                   2962: static void
1.75      rillig   2963: check_argument_usage(int novar, sym_t *arg)
1.1       cgd      2964: {
1.22      lukem    2965:
1.92      rillig   2966:        lint_assert(arg->s_set);
1.1       cgd      2967:
1.10      jpo      2968:        if (novar)
                   2969:                return;
                   2970:
1.1       cgd      2971:        if (!arg->s_used && vflag) {
1.85      rillig   2972:                curr_pos = arg->s_def_pos;
1.1       cgd      2973:                /* argument %s unused in function %s */
                   2974:                warning(231, arg->s_name, funcsym->s_name);
                   2975:        }
                   2976: }
                   2977:
                   2978: static void
1.75      rillig   2979: check_variable_usage(int novar, sym_t *sym)
1.1       cgd      2980: {
                   2981:        scl_t   sc;
                   2982:        sym_t   *xsym;
                   2983:
1.92      rillig   2984:        lint_assert(blklev != 0);
                   2985:        lint_assert(sym->s_blklev != 0);
1.1       cgd      2986:
                   2987:        /* errors in expressions easily cause lots of these warnings */
                   2988:        if (nerr != 0)
                   2989:                return;
                   2990:
                   2991:        /*
1.73      rillig   2992:         * XXX Only variables are checked, although types should
1.1       cgd      2993:         * probably also be checked
                   2994:         */
                   2995:        if ((sc = sym->s_scl) != EXTERN && sc != STATIC &&
                   2996:            sc != AUTO && sc != REG) {
                   2997:                return;
                   2998:        }
1.10      jpo      2999:
                   3000:        if (novar)
                   3001:                return;
1.1       cgd      3002:
                   3003:        if (sc == EXTERN) {
                   3004:                if (!sym->s_used && !sym->s_set) {
1.85      rillig   3005:                        curr_pos = sym->s_def_pos;
1.1       cgd      3006:                        /* %s unused in function %s */
                   3007:                        warning(192, sym->s_name, funcsym->s_name);
                   3008:                }
                   3009:        } else {
                   3010:                if (sym->s_set && !sym->s_used) {
1.85      rillig   3011:                        curr_pos = sym->s_set_pos;
1.1       cgd      3012:                        /* %s set but not used in function %s */
                   3013:                        warning(191, sym->s_name, funcsym->s_name);
                   3014:                } else if (!sym->s_used) {
1.85      rillig   3015:                        curr_pos = sym->s_def_pos;
1.1       cgd      3016:                        /* %s unused in function %s */
                   3017:                        warning(192, sym->s_name, funcsym->s_name);
                   3018:                }
                   3019:        }
                   3020:
                   3021:        if (sc == EXTERN) {
                   3022:                /*
                   3023:                 * information about usage is taken over into the symbol
1.73      rillig   3024:                 * table entry at level 0 if the symbol was locally declared
1.1       cgd      3025:                 * as an external symbol.
                   3026:                 *
                   3027:                 * XXX This is wrong for symbols declared static at level 0
                   3028:                 * if the usage information stems from sizeof(). This is
                   3029:                 * because symbols at level 0 only used in sizeof() are
                   3030:                 * considered to not be used.
                   3031:                 */
1.83      rillig   3032:                if ((xsym = sym->s_ext_sym) != NULL) {
1.1       cgd      3033:                        if (sym->s_used && !xsym->s_used) {
                   3034:                                xsym->s_used = 1;
1.85      rillig   3035:                                xsym->s_use_pos = sym->s_use_pos;
1.1       cgd      3036:                        }
                   3037:                        if (sym->s_set && !xsym->s_set) {
                   3038:                                xsym->s_set = 1;
1.85      rillig   3039:                                xsym->s_set_pos = sym->s_set_pos;
1.1       cgd      3040:                        }
                   3041:                }
                   3042:        }
                   3043: }
                   3044:
                   3045: static void
1.75      rillig   3046: check_label_usage(sym_t *lab)
1.1       cgd      3047: {
1.22      lukem    3048:
1.92      rillig   3049:        lint_assert(blklev == 1);
                   3050:        lint_assert(lab->s_blklev == 1);
1.1       cgd      3051:
                   3052:        if (lab->s_set && !lab->s_used) {
1.85      rillig   3053:                curr_pos = lab->s_set_pos;
1.88      rillig   3054:                /* %s unused in function %s */
1.1       cgd      3055:                warning(192, lab->s_name, funcsym->s_name);
                   3056:        } else if (!lab->s_set) {
1.85      rillig   3057:                curr_pos = lab->s_use_pos;
1.1       cgd      3058:                /* undefined label %s */
                   3059:                warning(23, lab->s_name);
                   3060:        }
                   3061: }
                   3062:
                   3063: static void
1.75      rillig   3064: check_tag_usage(sym_t *sym)
1.1       cgd      3065: {
1.22      lukem    3066:
1.1       cgd      3067:        if (!incompl(sym->s_type))
                   3068:                return;
                   3069:
1.73      rillig   3070:        /* always complain about incomplete tags declared inside blocks */
1.3       jpo      3071:        if (!zflag || dcs->d_ctx != EXTERN)
1.1       cgd      3072:                return;
                   3073:
1.85      rillig   3074:        curr_pos = sym->s_def_pos;
1.1       cgd      3075:        switch (sym->s_type->t_tspec) {
                   3076:        case STRUCT:
                   3077:                /* struct %s never defined */
                   3078:                warning(233, sym->s_name);
                   3079:                break;
                   3080:        case UNION:
                   3081:                /* union %s never defined */
                   3082:                warning(234, sym->s_name);
                   3083:                break;
                   3084:        case ENUM:
                   3085:                /* enum %s never defined */
                   3086:                warning(235, sym->s_name);
                   3087:                break;
                   3088:        default:
1.102     rillig   3089:                lint_assert(/*CONSTCOND*/0);
1.1       cgd      3090:        }
                   3091: }
                   3092:
                   3093: /*
                   3094:  * Called after the entire translation unit has been parsed.
1.73      rillig   3095:  * Changes tentative definitions into definitions.
                   3096:  * Performs some tests on global symbols. Detected problems are:
1.1       cgd      3097:  * - defined variables of incomplete type
                   3098:  * - constant variables which are not initialized
                   3099:  * - static symbols which are never used
                   3100:  */
                   3101: void
1.75      rillig   3102: check_global_symbols(void)
1.1       cgd      3103: {
                   3104:        sym_t   *sym;
                   3105:        pos_t   cpos;
                   3106:
1.82      rillig   3107:        if (blklev != 0 || dcs->d_next != NULL)
1.1       cgd      3108:                norecover();
                   3109:
1.85      rillig   3110:        cpos = curr_pos;
1.1       cgd      3111:
1.3       jpo      3112:        for (sym = dcs->d_dlsyms; sym != NULL; sym = sym->s_dlnxt) {
1.1       cgd      3113:                if (sym->s_blklev == -1)
                   3114:                        continue;
                   3115:                if (sym->s_kind == FVFT) {
1.75      rillig   3116:                        check_global_variable(sym);
1.1       cgd      3117:                } else if (sym->s_kind == FTAG) {
1.75      rillig   3118:                        check_tag_usage(sym);
1.1       cgd      3119:                } else {
1.92      rillig   3120:                        lint_assert(sym->s_kind == FMEMBER);
1.1       cgd      3121:                }
                   3122:        }
                   3123:
1.85      rillig   3124:        curr_pos = cpos;
1.1       cgd      3125: }
                   3126:
                   3127: static void
1.75      rillig   3128: check_global_variable(sym_t *sym)
1.1       cgd      3129: {
1.22      lukem    3130:
1.1       cgd      3131:        if (sym->s_scl == TYPEDEF || sym->s_scl == ENUMCON)
                   3132:                return;
1.22      lukem    3133:
1.92      rillig   3134:        lint_assert(sym->s_scl == EXTERN || sym->s_scl == STATIC);
1.1       cgd      3135:
1.75      rillig   3136:        check_global_variable_size(sym);
1.1       cgd      3137:
                   3138:        if (sym->s_scl == STATIC) {
                   3139:                if (sym->s_type->t_tspec == FUNC) {
                   3140:                        if (sym->s_used && sym->s_def != DEF) {
1.85      rillig   3141:                                curr_pos = sym->s_use_pos;
1.88      rillig   3142:                                /* static func. called but not def... */
1.1       cgd      3143:                                error(225, sym->s_name);
                   3144:                        }
                   3145:                }
                   3146:                if (!sym->s_used) {
1.85      rillig   3147:                        curr_pos = sym->s_def_pos;
1.1       cgd      3148:                        if (sym->s_type->t_tspec == FUNC) {
                   3149:                                if (sym->s_def == DEF) {
1.4       jpo      3150:                                        if (!sym->s_inline)
                   3151:                                                /* static function %s unused */
                   3152:                                                warning(236, sym->s_name);
1.1       cgd      3153:                                } else {
1.88      rillig   3154:                                        /* static function %s declared but... */
1.1       cgd      3155:                                        warning(290, sym->s_name);
                   3156:                                }
                   3157:                        } else if (!sym->s_set) {
                   3158:                                /* static variable %s unused */
                   3159:                                warning(226, sym->s_name);
                   3160:                        } else {
                   3161:                                /* static variable %s set but not used */
                   3162:                                warning(307, sym->s_name);
                   3163:                        }
                   3164:                }
                   3165:                if (!tflag && sym->s_def == TDEF && sym->s_type->t_const) {
1.85      rillig   3166:                        curr_pos = sym->s_def_pos;
1.1       cgd      3167:                        /* const object %s should have initializer */
                   3168:                        warning(227, sym->s_name);
                   3169:                }
                   3170:        }
                   3171: }
                   3172:
                   3173: static void
1.75      rillig   3174: check_global_variable_size(sym_t *sym)
1.1       cgd      3175: {
1.22      lukem    3176:
1.1       cgd      3177:        if (sym->s_def == TDEF) {
                   3178:                if (sym->s_type->t_tspec == FUNC)
                   3179:                        /*
1.24      wiz      3180:                         * this can happen if an syntax error occurred
1.1       cgd      3181:                         * after a function declaration
                   3182:                         */
                   3183:                        return;
1.85      rillig   3184:                curr_pos = sym->s_def_pos;
1.1       cgd      3185:                if (length(sym->s_type, sym->s_name) == 0 &&
                   3186:                    sym->s_type->t_tspec == ARRAY && sym->s_type->t_dim == 0) {
                   3187:                        if (tflag || (sym->s_scl == EXTERN && !sflag)) {
1.94      rillig   3188:                                /* empty array declaration: %s */
1.1       cgd      3189:                                warning(190, sym->s_name);
                   3190:                        } else {
1.94      rillig   3191:                                /* empty array declaration: %s */
1.1       cgd      3192:                                error(190, sym->s_name);
                   3193:                        }
                   3194:                }
                   3195:        }
                   3196: }
                   3197:
                   3198: /*
                   3199:  * Prints information about location of previous definition/declaration.
                   3200:  */
                   3201: void
1.75      rillig   3202: print_previous_declaration(int msg, sym_t *psym)
1.1       cgd      3203: {
                   3204:        pos_t   cpos;
                   3205:
                   3206:        if (!rflag)
                   3207:                return;
                   3208:
1.85      rillig   3209:        cpos = curr_pos;
                   3210:        curr_pos = psym->s_def_pos;
1.6       jpo      3211:        if (msg != -1) {
1.107     rillig   3212:                (message)(msg);
1.6       jpo      3213:        } else if (psym->s_def == DEF || psym->s_def == TDEF) {
1.1       cgd      3214:                /* previous definition of %s */
                   3215:                message(261, psym->s_name);
                   3216:        } else {
                   3217:                /* previous declaration of %s */
                   3218:                message(260, psym->s_name);
                   3219:        }
1.85      rillig   3220:        curr_pos = cpos;
1.1       cgd      3221: }

CVSweb <webmaster@jp.NetBSD.org>