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

Annotation of src/usr.bin/xlint/lint1/init.c, Revision 1.10

1.10    ! tv          1: /*     $NetBSD: init.c,v 1.9 2001/09/18 18:15:54 wiz Exp $     */
1.2       cgd         2:
1.1       cgd         3: /*
                      4:  * Copyright (c) 1994, 1995 Jochen Pohl
                      5:  * All Rights Reserved.
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
                     15:  * 3. All advertising materials mentioning features or use of this software
                     16:  *    must display the following acknowledgement:
                     17:  *      This product includes software developed by Jochen Pohl for
                     18:  *     The NetBSD Project.
                     19:  * 4. The name of the author may not be used to endorse or promote products
                     20:  *    derived from this software without specific prior written permission.
                     21:  *
                     22:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     23:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     24:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     25:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     26:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     27:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     28:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     29:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     30:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     31:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     32:  */
                     33:
1.5       christos   34: #include <sys/cdefs.h>
1.10    ! tv         35: #if defined(__RCSID) && !defined(lint)
        !            36: __RCSID("$NetBSD: init.c,v 1.9 2001/09/18 18:15:54 wiz Exp $");
1.1       cgd        37: #endif
                     38:
                     39: #include <stdlib.h>
                     40:
                     41: #include "lint1.h"
                     42:
                     43: /*
1.8       wiz        44:  * initerr is set as soon as a fatal error occurred in an initialisation.
1.1       cgd        45:  * The effect is that the rest of the initialisation is ignored (parsed
                     46:  * by yacc, expression trees built, but no initialisation takes place).
                     47:  */
                     48: int    initerr;
                     49:
                     50: /* Pointer to the symbol which is to be initialized. */
                     51: sym_t  *initsym;
                     52:
                     53: /* Points to the top element of the initialisation stack. */
                     54: istk_t *initstk;
                     55:
                     56:
1.7       lukem      57: static void    popi2(void);
                     58: static void    popinit(int);
                     59: static void    pushinit(void);
                     60: static void    testinit(void);
                     61: static void    nextinit(int);
                     62: static int     strginit(tnode_t *);
1.1       cgd        63:
                     64:
                     65: /*
                     66:  * Initialize the initialisation stack by putting an entry for the variable
                     67:  * which is to be initialized on it.
                     68:  */
                     69: void
1.7       lukem      70: prepinit(void)
1.1       cgd        71: {
                     72:        istk_t  *istk;
                     73:
                     74:        if (initerr)
                     75:                return;
                     76:
                     77:        /* free memory used in last initialisation */
                     78:        while ((istk = initstk) != NULL) {
                     79:                initstk = istk->i_nxt;
                     80:                free(istk);
                     81:        }
                     82:
                     83:        /*
                     84:         * If the type which is to be initialized is an incomplete type,
                     85:         * it must be duplicated.
                     86:         */
                     87:        if (initsym->s_type->t_tspec == ARRAY && incompl(initsym->s_type))
                     88:                initsym->s_type = duptyp(initsym->s_type);
                     89:
                     90:        istk = initstk = xcalloc(1, sizeof (istk_t));
                     91:        istk->i_subt = initsym->s_type;
                     92:        istk->i_cnt = 1;
                     93:
                     94: }
                     95:
                     96: static void
1.7       lukem      97: popi2(void)
1.1       cgd        98: {
                     99:        istk_t  *istk;
                    100:        sym_t   *m;
                    101:
                    102:        initstk = (istk = initstk)->i_nxt;
                    103:        if (initstk == NULL)
                    104:                lerror("popi2() 1");
                    105:        free(istk);
                    106:
                    107:        istk = initstk;
                    108:
                    109:        istk->i_cnt--;
                    110:        if (istk->i_cnt < 0)
                    111:                lerror("popi2() 3");
                    112:
                    113:        /*
                    114:         * If the removed element was a structure member, we must go
                    115:         * to the next structure member.
                    116:         */
                    117:        if (istk->i_cnt > 0 && istk->i_type->t_tspec == STRUCT) {
                    118:                do {
                    119:                        m = istk->i_mem = istk->i_mem->s_nxt;
                    120:                        if (m == NULL)
                    121:                                lerror("popi2() 2");
                    122:                } while (m->s_field && m->s_name == unnamed);
                    123:                istk->i_subt = m->s_type;
                    124:        }
                    125: }
                    126:
                    127: static void
1.7       lukem     128: popinit(int brace)
1.1       cgd       129: {
1.7       lukem     130:
1.1       cgd       131:        if (brace) {
                    132:                /*
                    133:                 * Take all entries, including the first which requires
                    134:                 * a closing brace, from the stack.
                    135:                 */
                    136:                do {
                    137:                        brace = initstk->i_brace;
                    138:                        popi2();
                    139:                } while (!brace);
                    140:        } else {
                    141:                /*
                    142:                 * Take all entries which cannot be used for further
                    143:                 * initializers from the stack, but do this only if
                    144:                 * they do not require a closing brace.
                    145:                 */
                    146:                while (!initstk->i_brace &&
                    147:                       initstk->i_cnt == 0 && !initstk->i_nolimit) {
                    148:                        popi2();
                    149:                }
                    150:        }
                    151: }
                    152:
                    153: static void
1.7       lukem     154: pushinit(void)
1.1       cgd       155: {
                    156:        istk_t  *istk;
                    157:        int     cnt;
                    158:        sym_t   *m;
                    159:
                    160:        istk = initstk;
                    161:
                    162:        /* Extend an incomplete array type by one element */
                    163:        if (istk->i_cnt == 0) {
                    164:                /*
                    165:                 * Inside of other aggregate types must not be an incomplete
                    166:                 * type.
                    167:                 */
                    168:                if (istk->i_nxt->i_nxt != NULL)
                    169:                        lerror("pushinit() 1");
                    170:                istk->i_cnt = 1;
                    171:                if (istk->i_type->t_tspec != ARRAY)
                    172:                        lerror("pushinit() 2");
                    173:                istk->i_type->t_dim++;
                    174:                /* from now its an complete type */
                    175:                setcompl(istk->i_type, 0);
                    176:        }
                    177:
                    178:        if (istk->i_cnt <= 0)
                    179:                lerror("pushinit() 3");
                    180:        if (istk->i_type != NULL && issclt(istk->i_type->t_tspec))
                    181:                lerror("pushinit() 4");
                    182:
                    183:        initstk = xcalloc(1, sizeof (istk_t));
                    184:        initstk->i_nxt = istk;
                    185:        initstk->i_type = istk->i_subt;
                    186:        if (initstk->i_type->t_tspec == FUNC)
                    187:                lerror("pushinit() 5");
                    188:
                    189:        istk = initstk;
                    190:
                    191:        switch (istk->i_type->t_tspec) {
                    192:        case ARRAY:
                    193:                if (incompl(istk->i_type) && istk->i_nxt->i_nxt != NULL) {
                    194:                        /* initialisation of an incomplete type */
                    195:                        error(175);
                    196:                        initerr = 1;
                    197:                        return;
                    198:                }
                    199:                istk->i_subt = istk->i_type->t_subt;
                    200:                istk->i_nolimit = incompl(istk->i_type);
                    201:                istk->i_cnt = istk->i_type->t_dim;
                    202:                break;
                    203:        case UNION:
                    204:                if (tflag)
                    205:                        /* initialisation of union is illegal in trad. C */
                    206:                        warning(238);
                    207:                /* FALLTHROUGH */
                    208:        case STRUCT:
                    209:                if (incompl(istk->i_type)) {
                    210:                        /* initialisation of an incomplete type */
                    211:                        error(175);
                    212:                        initerr = 1;
                    213:                        return;
                    214:                }
                    215:                cnt = 0;
                    216:                for (m = istk->i_type->t_str->memb; m != NULL; m = m->s_nxt) {
                    217:                        if (m->s_field && m->s_name == unnamed)
                    218:                                continue;
                    219:                        if (++cnt == 1) {
                    220:                                istk->i_mem = m;
                    221:                                istk->i_subt = m->s_type;
                    222:                        }
                    223:                }
                    224:                if (cnt == 0) {
                    225:                        /* cannot init. struct/union with no named member */
                    226:                        error(179);
                    227:                        initerr = 1;
                    228:                        return;
                    229:                }
                    230:                istk->i_cnt = istk->i_type->t_tspec == STRUCT ? cnt : 1;
                    231:                break;
                    232:        default:
                    233:                istk->i_cnt = 1;
                    234:                break;
                    235:        }
                    236: }
                    237:
                    238: static void
1.7       lukem     239: testinit(void)
1.1       cgd       240: {
                    241:        istk_t  *istk;
                    242:
                    243:        istk = initstk;
                    244:
                    245:        /*
                    246:         * If a closing brace is expected we have at least one initializer
                    247:         * too much.
                    248:         */
                    249:        if (istk->i_cnt == 0 && !istk->i_nolimit) {
                    250:                switch (istk->i_type->t_tspec) {
                    251:                case ARRAY:
                    252:                        /* too many array initializers */
                    253:                        error(173);
                    254:                        break;
                    255:                case STRUCT:
                    256:                case UNION:
                    257:                        /* too many struct/union initializers */
                    258:                        error(172);
                    259:                        break;
                    260:                default:
                    261:                        /* too many initializers */
                    262:                        error(174);
                    263:                        break;
                    264:                }
                    265:                initerr = 1;
                    266:        }
                    267: }
                    268:
                    269: static void
1.7       lukem     270: nextinit(int brace)
1.1       cgd       271: {
1.7       lukem     272:
1.1       cgd       273:        if (!brace) {
                    274:                if (initstk->i_type == NULL &&
                    275:                    !issclt(initstk->i_subt->t_tspec)) {
                    276:                        /* {}-enclosed initializer required */
                    277:                        error(181);
                    278:                }
                    279:                /*
                    280:                 * Make sure an entry with a scalar type is at the top
                    281:                 * of the stack.
                    282:                 */
                    283:                if (!initerr)
                    284:                        testinit();
                    285:                while (!initerr && (initstk->i_type == NULL ||
                    286:                                    !issclt(initstk->i_type->t_tspec))) {
                    287:                        if (!initerr)
                    288:                                pushinit();
                    289:                }
                    290:        } else {
                    291:                if (initstk->i_type != NULL &&
                    292:                    issclt(initstk->i_type->t_tspec)) {
                    293:                        /* invalid initializer */
                    294:                        error(176);
                    295:                        initerr = 1;
                    296:                }
                    297:                if (!initerr)
                    298:                        testinit();
                    299:                if (!initerr)
                    300:                        pushinit();
                    301:                if (!initerr)
                    302:                        initstk->i_brace = 1;
                    303:        }
                    304: }
                    305:
                    306: void
1.7       lukem     307: initlbr(void)
1.1       cgd       308: {
1.7       lukem     309:
1.1       cgd       310:        if (initerr)
                    311:                return;
                    312:
                    313:        if ((initsym->s_scl == AUTO || initsym->s_scl == REG) &&
                    314:            initstk->i_nxt == NULL) {
                    315:                if (tflag && !issclt(initstk->i_subt->t_tspec))
                    316:                        /* no automatic aggregate initialization in trad. C*/
                    317:                        warning(188);
                    318:        }
                    319:
                    320:        /*
                    321:         * Remove all entries which cannot be used for further initializers
                    322:         * and do not expect a closing brace.
                    323:         */
                    324:        popinit(0);
                    325:
                    326:        nextinit(1);
                    327: }
                    328:
                    329: void
1.7       lukem     330: initrbr(void)
1.1       cgd       331: {
1.7       lukem     332:
1.1       cgd       333:        if (initerr)
                    334:                return;
                    335:
                    336:        popinit(1);
                    337: }
                    338:
                    339: void
1.7       lukem     340: mkinit(tnode_t *tn)
1.1       cgd       341: {
                    342:        ptrdiff_t offs;
                    343:        sym_t   *sym;
                    344:        tspec_t lt, rt;
                    345:        tnode_t *ln;
                    346:        struct  mbl *tmem;
                    347:        scl_t   sc;
                    348:
                    349:        if (initerr || tn == NULL)
                    350:                goto end;
                    351:
                    352:        sc = initsym->s_scl;
                    353:
                    354:        /*
                    355:         * Do not test for automatic aggregat initialisation. If the
1.9       wiz       356:         * initializer starts with a brace we have the warning already.
1.1       cgd       357:         * If not, an error will be printed that the initializer must
                    358:         * be enclosed by braces.
                    359:         */
                    360:
                    361:        /*
                    362:         * Local initialisation of non-array-types with only one expression
                    363:         * without braces is done by ASSIGN
                    364:         */
                    365:        if ((sc == AUTO || sc == REG) &&
                    366:            initsym->s_type->t_tspec != ARRAY && initstk->i_nxt == NULL) {
                    367:                ln = getnnode(initsym, 0);
                    368:                ln->tn_type = tduptyp(ln->tn_type);
                    369:                ln->tn_type->t_const = 0;
                    370:                tn = build(ASSIGN, ln, tn);
                    371:                expr(tn, 0, 0);
                    372:                goto end;
                    373:        }
                    374:
                    375:        /*
                    376:         * Remove all entries which cannot be used for further initializers
                    377:         * and do not require a closing brace.
                    378:         */
                    379:        popinit(0);
                    380:
                    381:        /* Initialisations by strings are done in strginit(). */
                    382:        if (strginit(tn))
                    383:                goto end;
                    384:
                    385:        nextinit(0);
                    386:        if (initerr || tn == NULL)
                    387:                goto end;
                    388:
                    389:        initstk->i_cnt--;
                    390:
                    391:        /* Create a temporary node for the left side. */
                    392:        ln = tgetblk(sizeof (tnode_t));
                    393:        ln->tn_op = NAME;
                    394:        ln->tn_type = tduptyp(initstk->i_type);
                    395:        ln->tn_type->t_const = 0;
                    396:        ln->tn_lvalue = 1;
                    397:        ln->tn_sym = initsym;           /* better than nothing */
                    398:
                    399:        tn = cconv(tn);
                    400:
                    401:        lt = ln->tn_type->t_tspec;
                    402:        rt = tn->tn_type->t_tspec;
                    403:
                    404:        if (!issclt(lt))
                    405:                lerror("mkinit() 1");
                    406:
                    407:        if (!typeok(INIT, 0, ln, tn))
                    408:                goto end;
                    409:
                    410:        /*
                    411:         * Store the tree memory. This is nessesary because otherwise
                    412:         * expr() would free it.
                    413:         */
                    414:        tmem = tsave();
                    415:        expr(tn, 1, 0);
                    416:        trestor(tmem);
1.7       lukem     417:
1.1       cgd       418:        if (isityp(lt) && ln->tn_type->t_isfield && !isityp(rt)) {
                    419:                /*
                    420:                 * Bit-fields can be initialized in trad. C only by integer
                    421:                 * constants.
                    422:                 */
                    423:                if (tflag)
                    424:                        /* bit-field initialisation is illegal in trad. C */
                    425:                        warning(186);
                    426:        }
                    427:
                    428:        if (lt != rt || (initstk->i_type->t_isfield && tn->tn_op == CON))
                    429:                tn = convert(INIT, 0, initstk->i_type, tn);
                    430:
                    431:        if (tn != NULL && tn->tn_op != CON) {
                    432:                sym = NULL;
                    433:                offs = 0;
                    434:                if (conaddr(tn, &sym, &offs) == -1) {
1.3       jpo       435:                        if (sc == AUTO || sc == REG) {
1.1       cgd       436:                                /* non-constant initializer */
1.4       jpo       437:                                (void)gnuism(177);
1.1       cgd       438:                        } else {
                    439:                                /* non-constant initializer */
                    440:                                error(177);
                    441:                        }
                    442:                }
                    443:        }
                    444:
                    445:  end:
                    446:        tfreeblk();
                    447: }
                    448:
                    449:
                    450: static int
1.7       lukem     451: strginit(tnode_t *tn)
1.1       cgd       452: {
                    453:        tspec_t t;
                    454:        istk_t  *istk;
                    455:        int     len;
                    456:        strg_t  *strg;
                    457:
                    458:        if (tn->tn_op != STRING)
                    459:                return (0);
                    460:
                    461:        istk = initstk;
                    462:        strg = tn->tn_strg;
                    463:
                    464:        /*
                    465:         * Check if we have an array type which can be initialized by
                    466:         * the string.
                    467:         */
                    468:        if (istk->i_subt->t_tspec == ARRAY) {
                    469:                t = istk->i_subt->t_subt->t_tspec;
                    470:                if (!((strg->st_tspec == CHAR &&
                    471:                       (t == CHAR || t == UCHAR || t == SCHAR)) ||
                    472:                      (strg->st_tspec == WCHAR && t == WCHAR))) {
                    473:                        return (0);
                    474:                }
                    475:                /* Put the array at top of stack */
                    476:                pushinit();
                    477:                istk = initstk;
                    478:        } else if (istk->i_type != NULL && istk->i_type->t_tspec == ARRAY) {
                    479:                t = istk->i_type->t_subt->t_tspec;
                    480:                if (!((strg->st_tspec == CHAR &&
                    481:                       (t == CHAR || t == UCHAR || t == SCHAR)) ||
                    482:                      (strg->st_tspec == WCHAR && t == WCHAR))) {
                    483:                        return (0);
                    484:                }
                    485:                /*
                    486:                 * If the array is already partly initialized, we are
                    487:                 * wrong here.
                    488:                 */
                    489:                if (istk->i_cnt != istk->i_type->t_dim)
                    490:                        return (0);
                    491:        } else {
                    492:                return (0);
                    493:        }
                    494:
                    495:        /* Get length without trailing NUL character. */
                    496:        len = strg->st_len;
                    497:
                    498:        if (istk->i_nolimit) {
                    499:                istk->i_nolimit = 0;
                    500:                istk->i_type->t_dim = len + 1;
                    501:                /* from now complete type */
                    502:                setcompl(istk->i_type, 0);
                    503:        } else {
                    504:                if (istk->i_type->t_dim < len) {
                    505:                        /* non-null byte ignored in string initializer */
                    506:                        warning(187);
                    507:                }
                    508:        }
                    509:
                    510:        /* In every case the array is initialized completely. */
                    511:        istk->i_cnt = 0;
                    512:
                    513:        return (1);
                    514: }

CVSweb <webmaster@jp.NetBSD.org>