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

Annotation of src/usr.bin/xlint/lint1/tree.c, Revision 1.3

1.3     ! cgd         1: /*     $NetBSD: tree.c,v 1.2 1995/07/03 21:24:33 cgd 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:
                     34: #ifndef lint
1.3     ! cgd        35: static char rcsid[] = "$NetBSD: tree.c,v 1.2 1995/07/03 21:24:33 cgd Exp $";
1.1       cgd        36: #endif
                     37:
                     38: #include <stdlib.h>
                     39: #include <string.h>
                     40: #include <float.h>
                     41: #include <limits.h>
                     42: #include <math.h>
                     43:
                     44: #include "lint1.h"
                     45: #include "y.tab.h"
                     46:
                     47: /* Various flags for each operator. */
                     48: static mod_t   modtab[NOPS];
                     49:
                     50: static tnode_t *getinode __P((tspec_t, quad_t));
                     51: static void    ptrcmpok __P((op_t, tnode_t *, tnode_t *));
                     52: static int     asgntypok __P((op_t, int, tnode_t *, tnode_t *));
                     53: static void    chkbeop __P((op_t, tnode_t *, tnode_t *));
                     54: static void    chkeop2 __P((op_t, int, tnode_t *, tnode_t *));
                     55: static void    chkeop1 __P((op_t, int, tnode_t *, tnode_t *));
                     56: static tnode_t *mktnode __P((op_t, type_t *, tnode_t *, tnode_t *));
                     57: static void    balance __P((op_t, tnode_t **, tnode_t **));
                     58: static void    incompat __P((op_t, tspec_t, tspec_t));
                     59: static void    illptrc __P((mod_t *, type_t *, type_t *));
                     60: static void    mrgqual __P((type_t **, type_t *, type_t *));
                     61: static int     conmemb __P((type_t *));
                     62: static void    ptconv __P((int, tspec_t, tspec_t, type_t *, tnode_t *));
                     63: static void    iiconv __P((op_t, int, tspec_t, tspec_t, type_t *, tnode_t *));
                     64: static void    piconv __P((op_t, tspec_t, type_t *, tnode_t *));
                     65: static void    ppconv __P((op_t, tnode_t *, type_t *));
                     66: static tnode_t *bldstr __P((op_t, tnode_t *, tnode_t *));
                     67: static tnode_t *bldincdec __P((op_t, tnode_t *));
                     68: static tnode_t *bldamper __P((tnode_t *, int));
                     69: static tnode_t *bldplmi __P((op_t, tnode_t *, tnode_t *));
                     70: static tnode_t *bldshft __P((op_t, tnode_t *, tnode_t *));
                     71: static tnode_t *bldcol __P((tnode_t *, tnode_t *));
                     72: static tnode_t *bldasgn __P((op_t, tnode_t *, tnode_t *));
                     73: static tnode_t *plength __P((type_t *));
                     74: static tnode_t *fold __P((tnode_t *));
                     75: static tnode_t *foldtst __P((tnode_t *));
                     76: static tnode_t *foldflt __P((tnode_t *));
                     77: static tnode_t *chkfarg __P((type_t *, tnode_t *));
                     78: static tnode_t *parg __P((int, type_t *, tnode_t *));
                     79: static void    nulleff __P((tnode_t *));
                     80: static void    displexpr __P((tnode_t *, int));
                     81: static void    chkaidx __P((tnode_t *, int));
                     82: static void    chkcomp __P((op_t, tnode_t *, tnode_t *));
                     83: static void    precconf __P((tnode_t *));
                     84:
                     85: /*
                     86:  * Initialize mods of operators.
                     87:  */
                     88: void
                     89: initmtab()
                     90: {
                     91:        static  struct {
                     92:                op_t    op;
                     93:                mod_t   m;
                     94:        } imods[] = {
                     95:                { ARROW,  { 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,
                     96:                    "->" } },
                     97:                { POINT,  { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                     98:                    "." } },
                     99:                { NOT,    { 0,1,0,1,0,1,0,1,0,0,0,0,0,0,0,1,0,
                    100:                    "!" } },
                    101:                { COMPL,  { 0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,1,1,
                    102:                    "~" } },
                    103:                { INCBEF, { 0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,
                    104:                    "prefix++" } },
                    105:                { DECBEF, { 0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,
                    106:                    "prefix--" } },
                    107:                { INCAFT, { 0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,
                    108:                    "postfix++" } },
                    109:                { DECAFT, { 0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,
                    110:                    "postfix--" } },
                    111:                { UPLUS,  { 0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,
                    112:                    "unary +" } },
                    113:                { UMINUS, { 0,0,0,0,1,1,1,0,0,0,1,0,0,0,0,1,1,
                    114:                    "unary -" } },
                    115:                { STAR,   { 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,
                    116:                    "unary *" } },
                    117:                { AMPER,  { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                    118:                    "unary &" } },
                    119:                { MULT,   { 1,0,0,0,1,1,1,0,1,0,0,1,0,0,0,1,1,
                    120:                    "*" } },
                    121:                { DIV,    { 1,0,0,0,1,1,1,0,1,0,1,1,0,0,0,1,1,
                    122:                    "/" } },
                    123:                { MOD,    { 1,0,1,0,0,1,1,0,1,0,1,1,0,0,0,1,1,
                    124:                    "%" } },
                    125:                { PLUS,   { 1,0,0,1,0,1,1,0,1,0,0,0,0,0,0,1,0,
                    126:                    "+" } },
                    127:                { MINUS,  { 1,0,0,1,0,1,1,0,1,0,0,0,0,0,0,1,0,
                    128:                    "-" } },
                    129:                { SHL,    { 1,0,1,0,0,1,1,0,0,0,0,0,1,0,0,1,1,
                    130:                    "<<" } },
                    131:                { SHR,    { 1,0,1,0,0,1,1,0,0,0,1,0,1,0,0,1,1,
                    132:                    ">>" } },
                    133:                { LT,     { 1,1,0,1,0,1,1,0,1,0,1,1,0,1,1,0,1,
                    134:                    "<" } },
                    135:                { LE,     { 1,1,0,1,0,1,1,0,1,0,1,1,0,1,1,0,1,
                    136:                    "<=" } },
                    137:                { GT,     { 1,1,0,1,0,1,1,0,1,0,1,1,0,1,1,0,1,
                    138:                    ">" } },
                    139:                { GE,     { 1,1,0,1,0,1,1,0,1,0,1,1,0,1,1,0,1,
                    140:                    ">=" } },
                    141:                { EQ,     { 1,1,0,1,0,1,1,0,1,0,0,0,0,1,1,0,1,
                    142:                    "==" } },
                    143:                { NE,     { 1,1,0,1,0,1,1,0,1,0,0,0,0,1,1,0,1,
                    144:                    "!=" } },
                    145:                { AND,    { 1,0,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,
                    146:                    "&" } },
                    147:                { XOR,    { 1,0,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,
                    148:                    "^" } },
                    149:                { OR,     { 1,0,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,
                    150:                    "|" } },
                    151:                { LOGAND, { 1,1,0,1,0,1,0,1,0,0,0,0,0,0,0,1,0,
                    152:                    "&&" } },
                    153:                { LOGOR,  { 1,1,0,1,0,1,0,1,0,0,0,0,1,0,0,1,0,
                    154:                    "||" } },
                    155:                { QUEST,  { 1,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,
                    156:                    "?" } },
                    157:                { COLON,  { 1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,
                    158:                    ":" } },
                    159:                { ASSIGN, { 1,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,
                    160:                    "=" } },
                    161:                { MULASS, { 1,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,
                    162:                    "*=" } },
                    163:                { DIVASS, { 1,0,0,0,1,0,0,0,0,1,0,1,0,0,0,1,0,
                    164:                    "/=" } },
                    165:                { MODASS, { 1,0,1,0,0,0,0,0,0,1,0,1,0,0,0,1,0,
                    166:                    "%=" } },
                    167:                { ADDASS, { 1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,
                    168:                    "+=" } },
                    169:                { SUBASS, { 1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,
                    170:                    "-=" } },
                    171:                { SHLASS, { 1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,1,0,
                    172:                    "<<=" } },
                    173:                { SHRASS, { 1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,1,0,
                    174:                    ">>=" } },
                    175:                { ANDASS, { 1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,1,0,
                    176:                    "&=" } },
                    177:                { XORASS, { 1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,1,0,
                    178:                    "^=" } },
                    179:                { ORASS,  { 1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,1,0,
                    180:                    "|=" } },
                    181:                { NAME,   { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                    182:                    "NAME" } },
                    183:                { CON,    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                    184:                    "CON" } },
                    185:                { STRING, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                    186:                    "STRING" } },
                    187:                { FSEL,   { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                    188:                    "FSEL" } },
                    189:                { CALL,   { 1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,
                    190:                    "CALL" } },
                    191:                { COMMA,  { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
                    192:                    "," } },
                    193:                { CVT,    { 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,
                    194:                    "CVT" } },
                    195:                { ICALL,  { 1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,
                    196:                    "ICALL" } },
                    197:                { LOAD,   { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                    198:                    "LOAD" } },
                    199:                { PUSH,   { 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,
                    200:                    "PUSH" } },
                    201:                { RETURN, { 1,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,
                    202:                    "RETURN" } },
                    203:                { INIT,   { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,
                    204:                    "INIT" } },
                    205:                { FARG,   { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,
                    206:                    "FARG" } },
                    207:                { NOOP }
                    208:        };
                    209:        int     i;
                    210:
                    211:        for (i = 0; imods[i].op != NOOP; i++)
                    212:                STRUCT_ASSIGN(modtab[imods[i].op], imods[i].m);
                    213: }
                    214:
                    215: /*
                    216:  * Increase degree of reference.
                    217:  * This is most often used to change type "T" in type "pointer to T".
                    218:  */
                    219: type_t *
                    220: incref(tp, t)
                    221:        type_t  *tp;
                    222:        tspec_t t;
                    223: {
                    224:        type_t  *tp2;
                    225:
                    226:        tp2 = getblk(sizeof (type_t));
                    227:        tp2->t_tspec = t;
                    228:        tp2->t_subt = tp;
                    229:        return (tp2);
                    230: }
                    231:
                    232: /*
                    233:  * same for use in expressions
                    234:  */
                    235: type_t *
                    236: tincref(tp, t)
                    237:        type_t  *tp;
                    238:        tspec_t t;
                    239: {
                    240:        type_t  *tp2;
                    241:
                    242:        tp2 = tgetblk(sizeof (type_t));
                    243:        tp2->t_tspec = t;
                    244:        tp2->t_subt = tp;
                    245:        return (tp2);
                    246: }
                    247:
                    248: /*
                    249:  * Create a node for a constant.
                    250:  */
                    251: tnode_t *
                    252: getcnode(tp, v)
                    253:        type_t  *tp;
                    254:        val_t   *v;
                    255: {
                    256:        tnode_t *n;
                    257:
                    258:        n = getnode();
                    259:        n->tn_op = CON;
                    260:        n->tn_type = tp;
                    261:        n->tn_val = tgetblk(sizeof (val_t));
                    262:        n->tn_val->v_tspec = tp->t_tspec;
                    263:        n->tn_val->v_ansiu = v->v_ansiu;
                    264:        n->tn_val->v_u = v->v_u;
                    265:        free(v);
                    266:        return (n);
                    267: }
                    268:
                    269: /*
                    270:  * Create a node for a integer constant.
                    271:  */
                    272: static tnode_t *
                    273: getinode(t, q)
                    274:        tspec_t t;
                    275:        quad_t  q;
                    276: {
                    277:        tnode_t *n;
                    278:
                    279:        n = getnode();
                    280:        n->tn_op = CON;
                    281:        n->tn_type = gettyp(t);
                    282:        n->tn_val = tgetblk(sizeof (val_t));
                    283:        n->tn_val->v_tspec = t;
                    284:        n->tn_val->v_quad = q;
                    285:        return (n);
                    286: }
                    287:
                    288: /*
                    289:  * Create a node for a name (symbol table entry).
                    290:  * ntok is the token which follows the name.
                    291:  */
                    292: tnode_t *
                    293: getnnode(sym, ntok)
                    294:        sym_t   *sym;
                    295:        int     ntok;
                    296: {
                    297:        tnode_t *n;
                    298:
                    299:        if (sym->s_scl == NOSCL) {
                    300:                sym->s_scl = EXTERN;
                    301:                sym->s_def = DECL;
                    302:                if (ntok == T_LPARN) {
                    303:                        if (sflag) {
                    304:                                /* function implicitly declared to ... */
                    305:                                warning(215);
                    306:                        }
                    307:                        /*
                    308:                         * XXX if tflag is set the symbol should be
                    309:                         * exported to level 0
                    310:                         */
                    311:                        sym->s_type = incref(sym->s_type, FUNC);
                    312:                } else {
                    313:                        /* %s undefined */
                    314:                        error(99, sym->s_name);
                    315:                }
                    316:        }
                    317:
                    318:        if (sym->s_kind != FVFT && sym->s_kind != FMOS)
                    319:                lerror("getnnode() 1");
                    320:
                    321:        n = getnode();
                    322:        n->tn_type = sym->s_type;
                    323:        if (sym->s_scl != ENUMCON) {
                    324:                n->tn_op = NAME;
                    325:                n->tn_sym = sym;
                    326:                if (sym->s_kind == FVFT && sym->s_type->t_tspec != FUNC)
                    327:                        n->tn_lvalue = 1;
                    328:        } else {
                    329:                n->tn_op = CON;
                    330:                n->tn_val = tgetblk(sizeof (val_t));
                    331:                *n->tn_val = sym->s_value;
                    332:        }
                    333:
                    334:        return (n);
                    335: }
                    336:
                    337: /*
                    338:  * Create a node for a string.
                    339:  */
                    340: tnode_t *
                    341: getsnode(strg)
                    342:        strg_t  *strg;
                    343: {
                    344:        size_t  len;
                    345:        tnode_t *n;
                    346:
                    347:        len = strg->st_len;
                    348:
                    349:        n = getnode();
                    350:
                    351:        n->tn_op = STRING;
                    352:        n->tn_type = tincref(gettyp(strg->st_tspec), ARRAY);
                    353:        n->tn_type->t_dim = len + 1;
                    354:        n->tn_lvalue = 1;
                    355:
                    356:        n->tn_strg = tgetblk(sizeof (strg_t));
                    357:        n->tn_strg->st_tspec = strg->st_tspec;
                    358:        n->tn_strg->st_len = len;
                    359:
                    360:        if (strg->st_tspec == CHAR) {
                    361:                n->tn_strg->st_cp = tgetblk(len + 1);
                    362:                (void)memcpy(n->tn_strg->st_cp, strg->st_cp, len + 1);
                    363:                free(strg->st_cp);
                    364:        } else {
                    365:                n->tn_strg->st_wcp = tgetblk((len + 1) * sizeof (wchar_t));
                    366:                (void)memcpy(n->tn_strg->st_wcp, strg->st_wcp,
                    367:                             (len + 1) * sizeof (wchar_t));
                    368:                free(strg->st_wcp);
                    369:        }
                    370:        free(strg);
                    371:
                    372:        return (n);
                    373: }
                    374:
                    375: /*
                    376:  * Returns a symbol which has the same name as the msym argument and is a
                    377:  * member of the struct or union specified by the tn argument.
                    378:  */
                    379: sym_t *
                    380: strmemb(tn, op, msym)
                    381:        tnode_t *tn;
                    382:        op_t    op;
                    383:        sym_t   *msym;
                    384: {
                    385:        str_t   *str;
                    386:        type_t  *tp;
                    387:        sym_t   *sym, *csym;
                    388:        int     eq;
                    389:        tspec_t t;
                    390:
                    391:        /*
                    392:         * Remove the member if it was unknown until now (Which means
                    393:         * that no defined struct or union has a member with the same name).
                    394:         */
                    395:        if (msym->s_scl == NOSCL) {
                    396:                /* undefined struct/union member: %s */
                    397:                error(101, msym->s_name);
                    398:                rmsym(msym);
                    399:                msym->s_kind = FMOS;
                    400:                msym->s_scl = MOS;
                    401:                msym->s_styp = tgetblk(sizeof (str_t));
                    402:                msym->s_styp->stag = tgetblk(sizeof (sym_t));
                    403:                msym->s_styp->stag->s_name = unnamed;
                    404:                msym->s_value.v_tspec = INT;
                    405:                return (msym);
                    406:        }
                    407:
                    408:        /* Set str to the tag of which msym is expected to be a member. */
                    409:        str = NULL;
                    410:        t = (tp = tn->tn_type)->t_tspec;
                    411:        if (op == POINT) {
                    412:                if (t == STRUCT || t == UNION)
                    413:                        str = tp->t_str;
                    414:        } else if (op == ARROW && t == PTR) {
                    415:                t = (tp = tp->t_subt)->t_tspec;
                    416:                if (t == STRUCT || t == UNION)
                    417:                        str = tp->t_str;
                    418:        }
                    419:
                    420:        /*
                    421:         * If this struct/union has a member with the name of msym, return
                    422:         * return this it.
                    423:         */
                    424:        if (str != NULL) {
                    425:                for (sym = msym; sym != NULL; sym = sym->s_link) {
                    426:                        if (sym->s_scl != MOS && sym->s_scl != MOU)
                    427:                                continue;
                    428:                        if (sym->s_styp != str)
                    429:                                continue;
                    430:                        if (strcmp(sym->s_name, msym->s_name) != 0)
                    431:                                continue;
                    432:                        return (sym);
                    433:                }
                    434:        }
                    435:
                    436:        /*
                    437:         * Set eq to 0 if there are struct/union members with the same name
                    438:         * and different types and/or offsets.
                    439:         */
                    440:        eq = 1;
                    441:        for (csym = msym; csym != NULL; csym = csym->s_link) {
                    442:                if (csym->s_scl != MOS && csym->s_scl != MOU)
                    443:                        continue;
                    444:                if (strcmp(msym->s_name, csym->s_name) != 0)
                    445:                        continue;
                    446:                for (sym = csym->s_link ; sym != NULL; sym = sym->s_link) {
                    447:                        int w;
                    448:
                    449:                        if (sym->s_scl != MOS && sym->s_scl != MOU)
                    450:                                continue;
                    451:                        if (strcmp(csym->s_name, sym->s_name) != 0)
                    452:                                continue;
                    453:                        if (csym->s_value.v_quad != sym->s_value.v_quad) {
                    454:                                eq = 0;
                    455:                                break;
                    456:                        }
                    457:                        w = 0;
                    458:                        eq = eqtype(csym->s_type, sym->s_type, 0, 0, &w) && !w;
                    459:                        if (!eq)
                    460:                                break;
                    461:                        if (csym->s_field != sym->s_field) {
                    462:                                eq = 0;
                    463:                                break;
                    464:                        }
                    465:                        if (csym->s_field) {
                    466:                                type_t  *tp1, *tp2;
                    467:
                    468:                                tp1 = csym->s_type;
                    469:                                tp2 = sym->s_type;
                    470:                                if (tp1->t_flen != tp2->t_flen) {
                    471:                                        eq = 0;
                    472:                                        break;
                    473:                                }
                    474:                                if (tp1->t_foffs != tp2->t_foffs) {
                    475:                                        eq = 0;
                    476:                                        break;
                    477:                                }
                    478:                        }
                    479:                }
                    480:                if (!eq)
                    481:                        break;
                    482:        }
                    483:
                    484:        /*
                    485:         * Now handle the case in which the left operand refers really
                    486:         * to a struct/union, but the right operand is not member of it.
                    487:         */
                    488:        if (str != NULL) {
                    489:                /* illegal member use: %s */
                    490:                if (eq && tflag) {
                    491:                        warning(102, msym->s_name);
                    492:                } else {
                    493:                        error(102, msym->s_name);
                    494:                }
                    495:                return (msym);
                    496:        }
                    497:
                    498:        /*
                    499:         * Now the left operand of ARROW does not point to a struct/union
                    500:         * or the left operand of POINT is no struct/union.
                    501:         */
                    502:        if (eq) {
                    503:                if (op == POINT) {
                    504:                        /* left operand of "." must be struct/union object */
                    505:                        if (tflag) {
                    506:                                warning(103);
                    507:                        } else {
                    508:                                error(103);
                    509:                        }
                    510:                } else {
                    511:                        /* left operand of "->" must be pointer to ... */
                    512:                        if (tflag && tn->tn_type->t_tspec == PTR) {
                    513:                                warning(104);
                    514:                        } else {
                    515:                                error(104);
                    516:                        }
                    517:                }
                    518:        } else {
                    519:                if (tflag) {
                    520:                        /* non-unique member requires struct/union %s */
                    521:                        error(105, op == POINT ? "object" : "pointer");
                    522:                } else {
                    523:                        /* unacceptable operand of %s */
                    524:                        error(111, modtab[op].m_name);
                    525:                }
                    526:        }
                    527:
                    528:        return (msym);
                    529: }
                    530:
                    531: /*
                    532:  * Create a tree node. Called for most operands except function calls,
                    533:  * sizeof and casts.
                    534:  *
                    535:  * op  operator
                    536:  * ln  left operand
                    537:  * rn  if not NULL, right operand
                    538:  */
                    539: tnode_t *
                    540: build(op, ln, rn)
                    541:        op_t    op;
                    542:        tnode_t *ln, *rn;
                    543: {
                    544:        mod_t   *mp;
                    545:        tnode_t *ntn;
                    546:        type_t  *rtp;
                    547:
                    548:        mp = &modtab[op];
                    549:
                    550:        /* If there was an error in one of the operands, return. */
                    551:        if (ln == NULL || (mp->m_binary && rn == NULL))
                    552:                return (NULL);
                    553:
                    554:        /*
                    555:         * Apply class conversions to the left operand, but only if its
                    556:         * value is needed or it is compaired with null.
                    557:         */
                    558:        if (mp->m_vctx || mp->m_tctx)
                    559:                ln = cconv(ln);
                    560:        /*
                    561:         * The right operand is almost always in a test or value context,
                    562:         * except if it is a struct or union member.
                    563:         */
                    564:        if (mp->m_binary && op != ARROW && op != POINT)
                    565:                rn = cconv(rn);
                    566:
                    567:        /*
                    568:         * Print some warnings for comparisions of unsigned values with
                    569:         * constants lower than or equal to null. This must be done
                    570:         * before promote() because otherwise unsigned char and unsigned
                    571:         * short would be promoted to int. Also types are tested to be
                    572:         * CHAR, which would also become int.
                    573:         */
                    574:        if (mp->m_comp)
                    575:                chkcomp(op, ln, rn);
                    576:
                    577:        /*
                    578:         * Promote the left operand if it is in a test or value context
                    579:         */
                    580:        if (mp->m_vctx || mp->m_tctx)
                    581:                ln = promote(op, 0, ln);
                    582:        /*
                    583:         * Promote the right operand, but only if it is no struct or
                    584:         * union member, or if it is not to be assigned to the left operand
                    585:         */
                    586:        if (mp->m_binary && op != ARROW && op != POINT &&
                    587:            op != ASSIGN && op != RETURN) {
                    588:                rn = promote(op, 0, rn);
                    589:        }
                    590:
                    591:        /*
                    592:         * If the result of the operation is different for signed or
                    593:         * unsigned operands and one of the operands is signed only in
                    594:         * ANSI C, print a warning.
                    595:         */
                    596:        if (mp->m_tlansiu && ln->tn_op == CON && ln->tn_val->v_ansiu) {
                    597:                /* ANSI C treats constant as unsigned, op %s */
                    598:                warning(218, mp->m_name);
                    599:                ln->tn_val->v_ansiu = 0;
                    600:        }
                    601:        if (mp->m_transiu && rn->tn_op == CON && rn->tn_val->v_ansiu) {
                    602:                /* ANSI C treats constant as unsigned, op %s */
                    603:                warning(218, mp->m_name);
                    604:                rn->tn_val->v_ansiu = 0;
                    605:        }
                    606:
                    607:        /* Make sure both operands are of the same type */
                    608:        if (mp->m_balance || (tflag && (op == SHL || op == SHR)))
                    609:                balance(op, &ln, &rn);
                    610:
                    611:        /*
                    612:         * Check types for compatibility with the operation and mutual
                    613:         * compatibility. Return if there are serios problems.
                    614:         */
                    615:        if (!typeok(op, 0, ln, rn))
                    616:                return (NULL);
                    617:
                    618:        /* And now create the node. */
                    619:        switch (op) {
                    620:        case POINT:
                    621:        case ARROW:
                    622:                ntn = bldstr(op, ln, rn);
                    623:                break;
                    624:        case INCAFT:
                    625:        case DECAFT:
                    626:        case INCBEF:
                    627:        case DECBEF:
                    628:                ntn = bldincdec(op, ln);
                    629:                break;
                    630:        case AMPER:
                    631:                ntn = bldamper(ln, 0);
                    632:                break;
                    633:        case STAR:
                    634:                ntn = mktnode(STAR, ln->tn_type->t_subt, ln, NULL);
                    635:                break;
                    636:        case PLUS:
                    637:        case MINUS:
                    638:                ntn = bldplmi(op, ln, rn);
                    639:                break;
                    640:        case SHL:
                    641:        case SHR:
                    642:                ntn = bldshft(op, ln, rn);
                    643:                break;
                    644:        case COLON:
                    645:                ntn = bldcol(ln, rn);
                    646:                break;
                    647:        case ASSIGN:
                    648:        case MULASS:
                    649:        case DIVASS:
                    650:        case MODASS:
                    651:        case ADDASS:
                    652:        case SUBASS:
                    653:        case SHLASS:
                    654:        case SHRASS:
                    655:        case ANDASS:
                    656:        case XORASS:
                    657:        case ORASS:
                    658:        case RETURN:
                    659:                ntn = bldasgn(op, ln, rn);
                    660:                break;
                    661:        case COMMA:
                    662:        case QUEST:
                    663:                ntn = mktnode(op, rn->tn_type, ln, rn);
                    664:                break;
                    665:        default:
                    666:                rtp = mp->m_logop ? gettyp(INT) : ln->tn_type;
                    667:                if (!mp->m_binary && rn != NULL)
                    668:                        lerror("build() 1");
                    669:                ntn = mktnode(op, rtp, ln, rn);
                    670:                break;
                    671:        }
                    672:
                    673:        /* Return if an error occured. */
                    674:        if (ntn == NULL)
                    675:                return (NULL);
                    676:
                    677:        /* Print a warning if precedence confusion is possible */
                    678:        if (mp->m_tpconf)
                    679:                precconf(ntn);
                    680:
                    681:        /*
                    682:         * Print a warning if one of the operands is in a context where
                    683:         * it is compared with null and if this operand is a constant.
                    684:         */
                    685:        if (mp->m_tctx) {
                    686:                if (ln->tn_op == CON ||
                    687:                    ((mp->m_binary && op != QUEST) && rn->tn_op == CON)) {
                    688:                        if (hflag && isrcline > ccline + 1)
                    689:                                /* constant in conditional context */
                    690:                                warning(161);
                    691:                }
                    692:        }
                    693:
                    694:        /* Fold if the operator requires it */
                    695:        if (mp->m_fold) {
                    696:                if (ln->tn_op == CON && (!mp->m_binary || rn->tn_op == CON)) {
                    697:                        if (mp->m_tctx) {
                    698:                                ntn = foldtst(ntn);
                    699:                        } else if (isftyp(ntn->tn_type->t_tspec)) {
                    700:                                ntn = foldflt(ntn);
                    701:                        } else {
                    702:                                ntn = fold(ntn);
                    703:                        }
                    704:                } else if (op == QUEST && ln->tn_op == CON) {
                    705:                        ntn = ln->tn_val->v_quad ? rn->tn_left : rn->tn_right;
                    706:                }
                    707:        }
                    708:
                    709:        return (ntn);
                    710: }
                    711:
                    712: /*
                    713:  * Perform class conversions.
                    714:  *
                    715:  * Arrays of type T are converted into pointers to type T.
                    716:  * Functions are converted to pointers to functions.
                    717:  * Lvalues are converted to rvalues.
                    718:  */
                    719: tnode_t *
                    720: cconv(tn)
                    721:        tnode_t *tn;
                    722: {
                    723:        type_t  *tp;
                    724:
                    725:        /*
                    726:         * Array-lvalue (array of type T) is converted into rvalue
                    727:         * (pointer to type T)
                    728:         */
                    729:        if (tn->tn_type->t_tspec == ARRAY) {
                    730:                if (!tn->tn_lvalue) {
                    731:                        /* %soperand of '%s' must be lvalue */
                    732:                        if (gflag) {
                    733:                                /* XXX print correct operator */
                    734:                                warning(114, "", modtab[AMPER].m_name);
                    735:                        } else {
                    736:                                error(114, "", modtab[AMPER].m_name);
                    737:                        }
                    738:                }
                    739:                tn = mktnode(AMPER, tincref(tn->tn_type->t_subt, PTR),
                    740:                             tn, NULL);
                    741:        }
                    742:
                    743:        /*
                    744:         * Expression of type function (function with return value of type T)
                    745:         * in rvalue-expression (pointer to function with return value
                    746:         * of type T)
                    747:         */
                    748:        if (tn->tn_type->t_tspec == FUNC)
                    749:                tn = bldamper(tn, 1);
                    750:
                    751:        /* lvalue to rvalue */
                    752:        if (tn->tn_lvalue) {
                    753:                tp = tduptyp(tn->tn_type);
                    754:                tp->t_const = tp->t_volatile = 0;
                    755:                tn = mktnode(LOAD, tp, tn, NULL);
                    756:        }
                    757:
                    758:        return (tn);
                    759: }
                    760:
                    761: /*
                    762:  * Perform most type checks. First the types are checked using
                    763:  * informations from modtab[]. After that it is done by hand for
                    764:  * more complicated operators and type combinations.
                    765:  *
                    766:  * If the types are ok, typeok() returns 1, otherwise 0.
                    767:  */
                    768: int
                    769: typeok(op, arg, ln, rn)
                    770:        op_t    op;
                    771:        int     arg;
                    772:        tnode_t *ln, *rn;
                    773: {
                    774:        mod_t   *mp;
                    775:        tspec_t lt, rt, lst, rst, olt, ort;
                    776:        type_t  *ltp, *rtp, *lstp, *rstp;
                    777:        tnode_t *tn;
                    778:
                    779:        mp = &modtab[op];
                    780:
                    781:        if ((lt = (ltp = ln->tn_type)->t_tspec) == PTR)
                    782:                lst = (lstp = ltp->t_subt)->t_tspec;
                    783:        if (mp->m_binary) {
                    784:                if ((rt = (rtp = rn->tn_type)->t_tspec) == PTR)
                    785:                        rst = (rstp = rtp->t_subt)->t_tspec;
                    786:        }
                    787:
                    788:        if (mp->m_rqint) {
                    789:                /* integertypes required */
                    790:                if (!isityp(lt) || (mp->m_binary && !isityp(rt))) {
                    791:                        incompat(op, lt, rt);
                    792:                        return (0);
                    793:                }
                    794:        } else if (mp->m_rqsclt) {
                    795:                /* scalar types required */
                    796:                if (!issclt(lt) || (mp->m_binary && !issclt(rt))) {
                    797:                        incompat(op, lt, rt);
                    798:                        return (0);
                    799:                }
                    800:        } else if (mp->m_rqatyp) {
                    801:                /* arithmetic types required */
                    802:                if (!isatyp(lt) || (mp->m_binary && !isatyp(rt))) {
                    803:                        incompat(op, lt, rt);
                    804:                        return (0);
                    805:                }
                    806:        }
                    807:
                    808:        if (op == SHL || op == SHR || op == SHLASS || op == SHRASS) {
                    809:                /*
                    810:                 * For these operations we need the types before promotion
                    811:                 * and balancing.
                    812:                 */
                    813:                for (tn=ln; tn->tn_op==CVT && !tn->tn_cast; tn=tn->tn_left) ;
                    814:                olt = tn->tn_type->t_tspec;
                    815:                for (tn=rn; tn->tn_op==CVT && !tn->tn_cast; tn=tn->tn_left) ;
                    816:                ort = tn->tn_type->t_tspec;
                    817:        }
                    818:
                    819:        switch (op) {
                    820:        case POINT:
                    821:                /*
                    822:                 * Most errors required by ANSI C are reported in strmemb().
                    823:                 * Here we only must check for totaly wrong things.
                    824:                 */
                    825:                if (lt == FUNC || lt == VOID || ltp->t_isfield ||
                    826:                    ((lt != STRUCT && lt != UNION) && !ln->tn_lvalue) ||
                    827:                    (ln->tn_op == NAME && ln->tn_sym->s_reg)) {
                    828:                        /* Without tflag we got already an error */
                    829:                        if (tflag)
                    830:                                /* unacceptable operand of %s */
                    831:                                error(111, mp->m_name);
                    832:                        return (0);
                    833:                }
                    834:                /* Now we have an object we can create a pointer to */
                    835:                break;
                    836:        case ARROW:
                    837:                if (lt != PTR && !(tflag && isityp(lt))) {
                    838:                        /* Without tflag we got already an error */
                    839:                        if (tflag)
                    840:                                /* unacceptabel operand of %s */
                    841:                                error(111, mp->m_name);
                    842:                        return (0);
                    843:                }
                    844:                break;
                    845:        case INCAFT:
                    846:        case DECAFT:
                    847:        case INCBEF:
                    848:        case DECBEF:
                    849:                /* operands have scalar types (checked above) */
                    850:                if (!ln->tn_lvalue) {
                    851:                        if (ln->tn_op == CVT && ln->tn_cast &&
                    852:                            ln->tn_left->tn_op == LOAD) {
                    853:                                /* a cast does not yield an lvalue */
                    854:                                error(163);
                    855:                        }
                    856:                        /* %soperand of %s must be lvalue */
                    857:                        error(114, "", mp->m_name);
                    858:                        return (0);
                    859:                } else if (ltp->t_const) {
                    860:                        /* %soperand of %s must be modifiable lvalue */
                    861:                        if (!tflag)
                    862:                                warning(115, "", mp->m_name);
                    863:                }
                    864:                break;
                    865:        case AMPER:
                    866:                if (lt == ARRAY || lt == FUNC) {
                    867:                        /* ok, a warning comes later (in bldamper()) */
                    868:                } else if (!ln->tn_lvalue) {
                    869:                        if (ln->tn_op == CVT && ln->tn_cast &&
                    870:                            ln->tn_left->tn_op == LOAD) {
                    871:                                /* a cast does not yield an lvalue */
                    872:                                error(163);
                    873:                        }
                    874:                        /* %soperand of %s must be lvalue */
                    875:                        error(114, "", mp->m_name);
                    876:                        return (0);
                    877:                } else if (issclt(lt)) {
                    878:                        if (ltp->t_isfield) {
                    879:                                /* cannot take address of bit-field */
                    880:                                error(112);
                    881:                                return (0);
                    882:                        }
                    883:                } else if (lt != STRUCT && lt != UNION) {
                    884:                        /* unacceptable operand of %s */
                    885:                        error(111, mp->m_name);
                    886:                        return (0);
                    887:                }
                    888:                if (ln->tn_op == NAME && ln->tn_sym->s_reg) {
                    889:                        /* cannot take address of register %s */
                    890:                        error(113, ln->tn_sym->s_name);
                    891:                        return (0);
                    892:                }
                    893:                break;
                    894:        case STAR:
                    895:                /* until now there were no type checks for this operator */
                    896:                if (lt != PTR) {
                    897:                        /* cannot dereference non-pointer type */
                    898:                        error(96);
                    899:                        return (0);
                    900:                }
                    901:                break;
                    902:        case PLUS:
                    903:                /* operands have scalar types (checked above) */
                    904:                if ((lt == PTR && !isityp(rt)) || (rt == PTR && !isityp(lt))) {
                    905:                        incompat(op, lt, rt);
                    906:                        return (0);
                    907:                }
                    908:                break;
                    909:        case MINUS:
                    910:                /* operands have scalar types (checked above) */
                    911:                if (lt == PTR && (!isityp(rt) && rt != PTR)) {
                    912:                        incompat(op, lt, rt);
                    913:                        return (0);
                    914:                } else if (rt == PTR && lt != PTR) {
                    915:                        incompat(op, lt, rt);
                    916:                        return (0);
                    917:                }
                    918:                if (lt == PTR && rt == PTR) {
                    919:                        if (!eqtype(lstp, rstp, 1, 0, NULL)) {
                    920:                                /* illegal pointer subtraction */
                    921:                                error(116);
                    922:                        }
                    923:                }
                    924:                break;
                    925:        case SHR:
                    926:                /* operands have integer types (checked above) */
                    927:                if (pflag && !isutyp(lt)) {
                    928:                        /*
                    929:                         * The left operand is signed. This means that
                    930:                         * the operation is (possibly) nonportable.
                    931:                         */
                    932:                        /* bitwise operation on signed value nonportable */
                    933:                        if (ln->tn_op != CON) {
                    934:                                /* possibly nonportable */
                    935:                                warning(117);
                    936:                        } else if (ln->tn_val->v_quad < 0) {
                    937:                                warning(120);
                    938:                        }
                    939:                } else if (!tflag && !sflag && !isutyp(olt) && isutyp(ort)) {
                    940:                        /*
                    941:                         * The left operand would become unsigned in
                    942:                         * traditional C.
                    943:                         */
                    944:                        if (hflag &&
                    945:                            (ln->tn_op != CON || ln->tn_val->v_quad < 0)) {
                    946:                                /* semantics of %s change in ANSI C; use ... */
                    947:                                warning(118, mp->m_name);
                    948:                        }
                    949:                } else if (!tflag && !sflag && !isutyp(olt) && !isutyp(ort) &&
                    950:                           psize(lt) < psize(rt)) {
                    951:                        /*
                    952:                         * In traditional C the left operand would be extended,
                    953:                         * possibly with 1, and then shifted.
                    954:                         */
                    955:                        if (hflag &&
                    956:                            (ln->tn_op != CON || ln->tn_val->v_quad < 0)) {
                    957:                                /* semantics of %s change in ANSI C; use ... */
                    958:                                warning(118, mp->m_name);
                    959:                        }
                    960:                }
                    961:                goto shift;
                    962:        case SHL:
                    963:                /*
                    964:                 * ANSI C does not perform balancing for shift operations,
                    965:                 * but traditional C does. If the width of the right operand
                    966:                 * is greather than the width of the left operand, than in
                    967:                 * traditional C the left operand would be extendet to the
                    968:                 * width of the right operand. For SHL this may result in
                    969:                 * different results.
                    970:                 */
                    971:                if (psize(lt) < psize(rt)) {
                    972:                        /*
                    973:                         * XXX If both operands are constant make sure
                    974:                         * that there is really a differencs between
                    975:                         * ANSI C and traditional C.
                    976:                         */
                    977:                        if (hflag)
                    978:                                /* semantics of %s change in ANSI C; use ... */
                    979:                                warning(118, mp->m_name);
                    980:                }
                    981:        shift:
                    982:                if (rn->tn_op == CON) {
                    983:                        if (!isutyp(rt) && rn->tn_val->v_quad < 0) {
                    984:                                /* negative shift */
                    985:                                warning(121);
                    986:                        } else if ((u_quad_t)rn->tn_val->v_quad == size(lt)) {
                    987:                                /* shift equal to size fo object */
                    988:                                warning(267);
                    989:                        } else if ((u_quad_t)rn->tn_val->v_quad > size(lt)) {
                    990:                                /* shift greater than size of object */
                    991:                                warning(122);
                    992:                        }
                    993:                }
                    994:                break;
                    995:        case EQ:
                    996:        case NE:
                    997:                /*
                    998:                 * Accept some things which are allowed with EQ and NE,
                    999:                 * but not with ordered comparisions.
                   1000:                 */
                   1001:                if (lt == PTR && ((rt == PTR && rst == VOID) || isityp(rt))) {
                   1002:                        if (rn->tn_op == CON && rn->tn_val->v_quad == 0)
                   1003:                                break;
                   1004:                }
                   1005:                if (rt == PTR && ((lt == PTR && lst == VOID) || isityp(lt))) {
                   1006:                        if (ln->tn_op == CON && ln->tn_val->v_quad == 0)
                   1007:                                break;
                   1008:                }
                   1009:                /* FALLTHROUGH */
                   1010:        case LT:
                   1011:        case GT:
                   1012:        case LE:
                   1013:        case GE:
                   1014:                if ((lt == PTR || rt == PTR) && lt != rt) {
                   1015:                        if (isityp(lt) || isityp(rt)) {
                   1016:                                /* illegal comb. of pointer and int., op %s */
                   1017:                                warning(123, mp->m_name);
                   1018:                        } else {
                   1019:                                incompat(op, lt, rt);
                   1020:                                return (0);
                   1021:                        }
                   1022:                } else if (lt == PTR && rt == PTR) {
                   1023:                        ptrcmpok(op, ln, rn);
                   1024:                }
                   1025:                break;
                   1026:        case QUEST:
                   1027:                if (!issclt(lt)) {
                   1028:                        /* first operand must have scalar type, op ? : */
                   1029:                        error(170);
                   1030:                        return (0);
                   1031:                }
                   1032:                if (rn->tn_op != COLON)
                   1033:                        lerror("typeok() 2");
                   1034:                break;
                   1035:        case COLON:
                   1036:
                   1037:                if (isatyp(lt) && isatyp(rt))
                   1038:                        break;
                   1039:
                   1040:                if (lt == STRUCT && rt == STRUCT && ltp->t_str == rtp->t_str)
                   1041:                        break;
                   1042:                if (lt == UNION && rt == UNION && ltp->t_str == rtp->t_str)
                   1043:                        break;
                   1044:
                   1045:                /* combination of any pointer and 0, 0L or (void *)0 is ok */
                   1046:                if (lt == PTR && ((rt == PTR && rst == VOID) || isityp(rt))) {
                   1047:                        if (rn->tn_op == CON && rn->tn_val->v_quad == 0)
                   1048:                                break;
                   1049:                }
                   1050:                if (rt == PTR && ((lt == PTR && lst == VOID) || isityp(lt))) {
                   1051:                        if (ln->tn_op == CON && ln->tn_val->v_quad == 0)
                   1052:                                break;
                   1053:                }
                   1054:
                   1055:                if ((lt == PTR && isityp(rt)) || (isityp(lt) && rt == PTR)) {
                   1056:                        /* illegal comb. of ptr. and int., op %s */
                   1057:                        warning(123, mp->m_name);
                   1058:                        break;
                   1059:                }
                   1060:
                   1061:                if (lt == VOID || rt == VOID) {
                   1062:                        if (lt != VOID || rt != VOID)
                   1063:                                /* incompatible types in conditional */
                   1064:                                warning(126);
                   1065:                        break;
                   1066:                }
                   1067:
                   1068:                if (lt == PTR && rt == PTR && ((lst == VOID && rst == FUNC) ||
                   1069:                                               (lst == FUNC && rst == VOID))) {
                   1070:                        /* (void *)0 handled above */
                   1071:                        if (sflag)
                   1072:                                /* ANSI C forbids conv. of %s to %s, op %s */
                   1073:                                warning(305, "function pointer", "'void *'",
                   1074:                                        mp->m_name);
                   1075:                        break;
                   1076:                }
                   1077:
                   1078:                if (rt == PTR && lt == PTR) {
                   1079:                        if (!eqtype(lstp, rstp, 1, 0, NULL))
                   1080:                                illptrc(mp, ltp, rtp);
                   1081:                        break;
                   1082:                }
                   1083:
                   1084:                /* incompatible types in conditional */
                   1085:                error(126);
                   1086:                return (0);
                   1087:
                   1088:        case ASSIGN:
                   1089:        case INIT:
                   1090:        case FARG:
                   1091:        case RETURN:
                   1092:                if (!asgntypok(op, arg, ln, rn))
                   1093:                        return (0);
                   1094:                goto assign;
                   1095:        case MULASS:
                   1096:        case DIVASS:
                   1097:        case MODASS:
                   1098:                goto assign;
                   1099:        case ADDASS:
                   1100:        case SUBASS:
                   1101:                /* operands have scalar types (checked above) */
                   1102:                if ((lt == PTR && !isityp(rt)) || rt == PTR) {
                   1103:                        incompat(op, lt, rt);
                   1104:                        return (0);
                   1105:                }
                   1106:                goto assign;
                   1107:        case SHLASS:
                   1108:                goto assign;
                   1109:        case SHRASS:
                   1110:                if (pflag && !isutyp(lt) && !(tflag && isutyp(rt))) {
                   1111:                        /* bitwise operation on s.v. possibly nonportabel */
                   1112:                        warning(117);
                   1113:                }
                   1114:                goto assign;
                   1115:        case ANDASS:
                   1116:        case XORASS:
                   1117:        case ORASS:
                   1118:                goto assign;
                   1119:        assign:
                   1120:                if (!ln->tn_lvalue) {
                   1121:                        if (ln->tn_op == CVT && ln->tn_cast &&
                   1122:                            ln->tn_left->tn_op == LOAD) {
                   1123:                                /* a cast does not yield an lvalue */
                   1124:                                error(163);
                   1125:                        }
                   1126:                        /* %soperand of %s must be lvalue */
                   1127:                        error(114, "left ", mp->m_name);
                   1128:                        return (0);
                   1129:                } else if (ltp->t_const || ((lt == STRUCT || lt == UNION) &&
                   1130:                                            conmemb(ltp))) {
                   1131:                        /* %soperand of %s must be modifiable lvalue */
                   1132:                        if (!tflag)
                   1133:                                warning(115, "left ", mp->m_name);
                   1134:                }
                   1135:                break;
                   1136:        case COMMA:
                   1137:                if (!modtab[ln->tn_op].m_sideeff)
                   1138:                        nulleff(ln);
                   1139:                break;
                   1140:                /* LINTED (enumeration values not handled in switch) */
                   1141:        }
                   1142:
                   1143:        if (mp->m_badeop &&
                   1144:            (ltp->t_isenum || (mp->m_binary && rtp->t_isenum))) {
                   1145:                chkbeop(op, ln, rn);
                   1146:        } else if (mp->m_enumop && (ltp->t_isenum && rtp->t_isenum)) {
                   1147:                chkeop2(op, arg, ln, rn);
                   1148:        } else if (mp->m_enumop && (ltp->t_isenum || rtp->t_isenum)) {
                   1149:                chkeop1(op, arg, ln, rn);
                   1150:        }
                   1151:
                   1152:        return (1);
                   1153: }
                   1154:
                   1155: static void
                   1156: ptrcmpok(op, ln, rn)
                   1157:        op_t    op;
                   1158:        tnode_t *ln, *rn;
                   1159: {
                   1160:        type_t  *ltp, *rtp;
                   1161:        tspec_t lt, rt;
                   1162:        const   char *lts, *rts;
                   1163:
                   1164:        lt = (ltp = ln->tn_type)->t_subt->t_tspec;
                   1165:        rt = (rtp = rn->tn_type)->t_subt->t_tspec;
                   1166:
                   1167:        if (lt == VOID || rt == VOID) {
                   1168:                if (sflag && (lt == FUNC || rt == FUNC)) {
                   1169:                        /* (void *)0 already handled in typeok() */
                   1170:                        *(lt == FUNC ? &lts : &rts) = "function pointer";
                   1171:                        *(lt == VOID ? &lts : &rts) = "'void *'";
                   1172:                        /* ANSI C forbids comparision of %s with %s */
                   1173:                        warning(274, lts, rts);
                   1174:                }
                   1175:                return;
                   1176:        }
                   1177:
                   1178:        if (!eqtype(ltp->t_subt, rtp->t_subt, 1, 0, NULL)) {
                   1179:                illptrc(&modtab[op], ltp, rtp);
                   1180:                return;
                   1181:        }
                   1182:
                   1183:        if (lt == FUNC && rt == FUNC) {
                   1184:                if (sflag && op != EQ && op != NE)
                   1185:                        /* ANSI C forbids ordered comp. of func ptr */
                   1186:                        warning(125);
                   1187:        }
                   1188: }
                   1189:
                   1190: /*
                   1191:  * Checks type compatibility for ASSIGN, INIT, FARG and RETURN
                   1192:  * and prints warnings/errors if necessary.
                   1193:  * If the types are (almost) compatible, 1 is returned, otherwise 0.
                   1194:  */
                   1195: static int
                   1196: asgntypok(op, arg, ln, rn)
                   1197:        op_t    op;
                   1198:        int     arg;
                   1199:        tnode_t *ln, *rn;
                   1200: {
                   1201:        tspec_t lt, rt, lst, rst;
                   1202:        type_t  *ltp, *rtp, *lstp, *rstp;
                   1203:        mod_t   *mp;
                   1204:        const   char *lts, *rts;
                   1205:
                   1206:        if ((lt = (ltp = ln->tn_type)->t_tspec) == PTR)
                   1207:                lst = (lstp = ltp->t_subt)->t_tspec;
                   1208:        if ((rt = (rtp = rn->tn_type)->t_tspec) == PTR)
                   1209:                rst = (rstp = rtp->t_subt)->t_tspec;
                   1210:        mp = &modtab[op];
                   1211:
                   1212:        if (isatyp(lt) && isatyp(rt))
                   1213:                return (1);
                   1214:
                   1215:        if ((lt == STRUCT || lt == UNION) && (rt == STRUCT || rt == UNION))
                   1216:                /* both are struct or union */
                   1217:                return (ltp->t_str == rtp->t_str);
                   1218:
                   1219:        /* 0, 0L and (void *)0 may be assigned to any pointer */
                   1220:        if (lt == PTR && ((rt == PTR && rst == VOID) || isityp(rt))) {
                   1221:                if (rn->tn_op == CON && rn->tn_val->v_quad == 0)
                   1222:                        return (1);
                   1223:        }
                   1224:
                   1225:        if (lt == PTR && rt == PTR && (lst == VOID || rst == VOID)) {
                   1226:                /* two pointers, at least one pointer to void */
                   1227:                if (sflag && (lst == FUNC || rst == FUNC)) {
                   1228:                        /* comb. of ptr to func and ptr to void */
                   1229:                        *(lst == FUNC ? &lts : &rts) = "function pointer";
                   1230:                        *(lst == VOID ? &lts : &rts) = "'void *'";
                   1231:                        switch (op) {
                   1232:                        case INIT:
                   1233:                        case RETURN:
                   1234:                                /* ANSI C forbids conversion of %s to %s */
                   1235:                                warning(303, rts, lts);
                   1236:                                break;
                   1237:                        case FARG:
                   1238:                                /* ANSI C forbids conv. of %s to %s, arg #%d */
                   1239:                                warning(304, rts, lts, arg);
                   1240:                                break;
                   1241:                        default:
                   1242:                                /* ANSI C forbids conv. of %s to %s, op %s */
                   1243:                                warning(305, rts, lts, mp->m_name);
                   1244:                                break;
                   1245:                        }
                   1246:                }
                   1247:        }
                   1248:
                   1249:        if (lt == PTR && rt == PTR && (lst == VOID || rst == VOID ||
                   1250:                                       eqtype(lstp, rstp, 1, 0, NULL))) {
                   1251:                /* compatible pointer types (qualifiers ignored) */
                   1252:                if (!tflag &&
                   1253:                    ((!lstp->t_const && rstp->t_const) ||
                   1254:                     (!lstp->t_volatile && rstp->t_volatile))) {
                   1255:                        /* left side has not all qualifiers of right */
                   1256:                        switch (op) {
                   1257:                        case INIT:
                   1258:                        case RETURN:
                   1259:                                /* incompatible pointer types */
                   1260:                                warning(182);
                   1261:                                break;
                   1262:                        case FARG:
                   1263:                                /* argument has incompat. ptr. type, arg #%d */
                   1264:                                warning(153, arg);
                   1265:                                break;
                   1266:                        default:
                   1267:                                /* operands have incompat. ptr. types, op %s */
                   1268:                                warning(128, mp->m_name);
                   1269:                                break;
                   1270:                        }
                   1271:                }
                   1272:                return (1);
                   1273:        }
                   1274:
                   1275:        if ((lt == PTR && isityp(rt)) || (isityp(lt) && rt == PTR)) {
                   1276:                switch (op) {
                   1277:                case INIT:
                   1278:                case RETURN:
                   1279:                        /* illegal combination of pointer and integer */
                   1280:                        warning(183);
                   1281:                        break;
                   1282:                case FARG:
                   1283:                        /* illegal comb. of ptr. and int., arg #%d */
                   1284:                        warning(154, arg);
                   1285:                        break;
                   1286:                default:
                   1287:                        /* illegal comb. of ptr. and int., op %s */
                   1288:                        warning(123, mp->m_name);
                   1289:                        break;
                   1290:                }
                   1291:                return (1);
                   1292:        }
                   1293:
                   1294:        if (lt == PTR && rt == PTR) {
                   1295:                switch (op) {
                   1296:                case INIT:
                   1297:                case RETURN:
                   1298:                        illptrc(NULL, ltp, rtp);
                   1299:                        break;
                   1300:                case FARG:
                   1301:                        /* argument has incompatible pointer type, arg #%d */
                   1302:                        warning(153, arg);
                   1303:                        break;
                   1304:                default:
                   1305:                        illptrc(mp, ltp, rtp);
                   1306:                        break;
                   1307:                }
                   1308:                return (1);
                   1309:        }
                   1310:
                   1311:        switch (op) {
                   1312:        case INIT:
                   1313:                /* initialisation type mismatch */
                   1314:                error(185);
                   1315:                break;
                   1316:        case RETURN:
                   1317:                /* return value type mismatch */
                   1318:                error(211);
                   1319:                break;
                   1320:        case FARG:
                   1321:                /* argument is incompatible with prototype, arg #%d */
                   1322:                warning(155, arg);
                   1323:                break;
                   1324:        default:
                   1325:                incompat(op, lt, rt);
                   1326:                break;
                   1327:        }
                   1328:
                   1329:        return (0);
                   1330: }
                   1331:
                   1332: /*
                   1333:  * Prints a warning if an operator, which should be senseless for an
                   1334:  * enum type, is applied to an enum type.
                   1335:  */
                   1336: static void
                   1337: chkbeop(op, ln, rn)
                   1338:        op_t    op;
                   1339:        tnode_t *ln, *rn;
                   1340: {
                   1341:        mod_t   *mp;
                   1342:
                   1343:        if (!eflag)
                   1344:                return;
                   1345:
                   1346:        mp = &modtab[op];
                   1347:
                   1348:        if (!(ln->tn_type->t_isenum ||
                   1349:              (mp->m_binary && rn->tn_type->t_isenum))) {
                   1350:                return;
                   1351:        }
                   1352:
                   1353:        /*
                   1354:         * Enum as offset to a pointer is an exception (otherwise enums
                   1355:         * could not be used as array indizes).
                   1356:         */
                   1357:        if (op == PLUS &&
                   1358:            ((ln->tn_type->t_isenum && rn->tn_type->t_tspec == PTR) ||
                   1359:             (rn->tn_type->t_isenum && ln->tn_type->t_tspec == PTR))) {
                   1360:                return;
                   1361:        }
                   1362:
                   1363:        /* dubious operation on enum, op %s */
                   1364:        warning(241, mp->m_name);
                   1365:
                   1366: }
                   1367:
                   1368: /*
                   1369:  * Prints a warning if an operator is applied to two different enum types.
                   1370:  */
                   1371: static void
                   1372: chkeop2(op, arg, ln, rn)
                   1373:        op_t    op;
                   1374:        int     arg;
                   1375:        tnode_t *ln, *rn;
                   1376: {
                   1377:        mod_t   *mp;
                   1378:
                   1379:        mp = &modtab[op];
                   1380:
                   1381:        if (ln->tn_type->t_enum != rn->tn_type->t_enum) {
                   1382:                switch (op) {
                   1383:                case INIT:
                   1384:                        /* enum type mismatch in initialisation */
                   1385:                        warning(210);
                   1386:                        break;
                   1387:                case FARG:
                   1388:                        /* enum type mismatch, arg #%d */
                   1389:                        warning(156, arg);
                   1390:                        break;
                   1391:                case RETURN:
                   1392:                        /* return value type mismatch */
                   1393:                        warning(211);
                   1394:                        break;
                   1395:                default:
                   1396:                        /* enum type mismatch, op %s */
                   1397:                        warning(130, mp->m_name);
                   1398:                        break;
                   1399:                }
                   1400: #if 0
                   1401:        } else if (mp->m_comp && op != EQ && op != NE) {
                   1402:                if (eflag)
                   1403:                        /* dubious comparisions of enums */
                   1404:                        warning(243, mp->m_name);
                   1405: #endif
                   1406:        }
                   1407: }
                   1408:
                   1409: /*
                   1410:  * Prints a warning if an operator has both enum end other integer
                   1411:  * types.
                   1412:  */
                   1413: static void
                   1414: chkeop1(op, arg, ln, rn)
                   1415:        op_t    op;
                   1416:        int     arg;
                   1417:        tnode_t *ln, *rn;
                   1418: {
                   1419:        if (!eflag)
                   1420:                return;
                   1421:
                   1422:        switch (op) {
                   1423:        case INIT:
                   1424:                /*
                   1425:                 * Initializations with 0 should be allowed. Otherwise,
                   1426:                 * we should complain about all uninitialized enums,
                   1427:                 * consequently.
                   1428:                 */
                   1429:                if (!rn->tn_type->t_isenum && rn->tn_op == CON &&
                   1430:                    isityp(rn->tn_type->t_tspec) && rn->tn_val->v_quad == 0) {
                   1431:                        return;
                   1432:                }
                   1433:                /* initialisation of '%s' with '%s' */
                   1434:                warning(277, tyname(ln->tn_type), tyname(rn->tn_type));
                   1435:                break;
                   1436:        case FARG:
                   1437:                /* combination of '%s' and '%s', arg #%d */
                   1438:                warning(278, tyname(ln->tn_type), tyname(rn->tn_type), arg);
                   1439:                break;
                   1440:        case RETURN:
                   1441:                /* combination of '%s' and '%s' in return */
                   1442:                warning(279, tyname(ln->tn_type), tyname(rn->tn_type));
                   1443:                break;
                   1444:        default:
                   1445:                /* combination of '%s' and %s, op %s */
                   1446:                warning(242, tyname(ln->tn_type), tyname(rn->tn_type),
                   1447:                        modtab[op].m_name);
                   1448:                break;
                   1449:        }
                   1450: }
                   1451:
                   1452: /*
                   1453:  * Build and initialize a new node.
                   1454:  */
                   1455: static tnode_t *
                   1456: mktnode(op, type, ln, rn)
                   1457:        op_t    op;
                   1458:        type_t  *type;
                   1459:        tnode_t *ln, *rn;
                   1460: {
                   1461:        tnode_t *ntn;
                   1462:        tspec_t t;
                   1463:
                   1464:        ntn = getnode();
                   1465:
                   1466:        ntn->tn_op = op;
                   1467:        ntn->tn_type = type;
                   1468:        ntn->tn_left = ln;
                   1469:        ntn->tn_right = rn;
                   1470:
                   1471:        if (op == STAR || op == FSEL) {
                   1472:                if (ln->tn_type->t_tspec == PTR) {
                   1473:                        t = ln->tn_type->t_subt->t_tspec;
                   1474:                        if (t != FUNC && t != VOID)
                   1475:                                ntn->tn_lvalue = 1;
                   1476:                } else {
                   1477:                        lerror("mktnode() 2");
                   1478:                }
                   1479:        }
                   1480:
                   1481:        return (ntn);
                   1482: }
                   1483:
                   1484: /*
                   1485:  * Performs usual conversion of operands to (unsigned) int.
                   1486:  *
                   1487:  * If tflag is set or the operand is a function argument with no
                   1488:  * type information (no prototype or variable # of args), convert
                   1489:  * float to double.
                   1490:  */
                   1491: tnode_t *
                   1492: promote(op, farg, tn)
                   1493:        op_t    op;
                   1494:        int     farg;
                   1495:        tnode_t *tn;
                   1496: {
                   1497:        tspec_t t;
                   1498:        type_t  *ntp;
                   1499:        int     len;
                   1500:
                   1501:        t = tn->tn_type->t_tspec;
                   1502:
                   1503:        if (!isatyp(t))
                   1504:                return (tn);
                   1505:
                   1506:        if (!tflag) {
                   1507:                /*
                   1508:                 * ANSI C requires that the result is always of type INT
                   1509:                 * if INT can represent all possible values of the previous
                   1510:                 * type.
                   1511:                 */
                   1512:                if (tn->tn_type->t_isfield) {
                   1513:                        len = tn->tn_type->t_flen;
                   1514:                        if (size(INT) > len) {
                   1515:                                t = INT;
                   1516:                        } else {
                   1517:                                if (size(INT) != len)
                   1518:                                        lerror("promote() 1");
                   1519:                                if (isutyp(t)) {
                   1520:                                        t = UINT;
                   1521:                                } else {
                   1522:                                        t = INT;
                   1523:                                }
                   1524:                        }
                   1525:                } else if (t == CHAR || t == UCHAR || t == SCHAR) {
                   1526:                        t = (size(CHAR) < size(INT) || t != UCHAR) ?
                   1527:                                INT : UINT;
                   1528:                } else if (t == SHORT || t == USHORT) {
                   1529:                        t = (size(SHORT) < size(INT) || t == SHORT) ?
                   1530:                                INT : UINT;
                   1531:                } else if (t == ENUM) {
                   1532:                        t = INT;
                   1533:                } else if (farg && t == FLOAT) {
                   1534:                        t = DOUBLE;
                   1535:                }
                   1536:        } else {
                   1537:                /*
                   1538:                 * In traditional C, keep unsigned and promote FLOAT
                   1539:                 * to DOUBLE.
                   1540:                 */
                   1541:                if (t == UCHAR || t == USHORT) {
                   1542:                        t = UINT;
                   1543:                } else if (t == CHAR || t == SCHAR || t == SHORT) {
                   1544:                        t = INT;
                   1545:                } else if (t == FLOAT) {
                   1546:                        t = DOUBLE;
                   1547:                } else if (t == ENUM) {
                   1548:                        t = INT;
                   1549:                }
                   1550:        }
                   1551:
                   1552:        if (t != tn->tn_type->t_tspec) {
                   1553:                ntp = tduptyp(tn->tn_type);
                   1554:                ntp->t_tspec = t;
                   1555:                /*
                   1556:                 * Keep t_isenum so we are later able to check compatibility
                   1557:                 * of enum types.
                   1558:                 */
                   1559:                tn = convert(op, 0, ntp, tn);
                   1560:        }
                   1561:
                   1562:        return (tn);
                   1563: }
                   1564:
                   1565: /*
                   1566:  * Insert conversions which are necessary to give both operands the same
                   1567:  * type. This is done in different ways for traditional C and ANIS C.
                   1568:  */
                   1569: static void
                   1570: balance(op, lnp, rnp)
                   1571:        op_t    op;
                   1572:        tnode_t **lnp, **rnp;
                   1573: {
                   1574:        tspec_t lt, rt, t;
                   1575:        int     i, u;
                   1576:        type_t  *ntp;
                   1577:        static  tspec_t tl[] = {
                   1578:                LDOUBLE, DOUBLE, FLOAT, UQUAD, QUAD, ULONG, LONG, UINT, INT,
                   1579:        };
                   1580:
                   1581:        lt = (*lnp)->tn_type->t_tspec;
                   1582:        rt = (*rnp)->tn_type->t_tspec;
                   1583:
                   1584:        if (!isatyp(lt) || !isatyp(rt))
                   1585:                return;
                   1586:
                   1587:        if (!tflag) {
                   1588:                if (lt == rt) {
                   1589:                        t = lt;
                   1590:                } else if (lt == LDOUBLE || rt == LDOUBLE) {
                   1591:                        t = LDOUBLE;
                   1592:                } else if (lt == DOUBLE || rt == DOUBLE) {
                   1593:                        t = DOUBLE;
                   1594:                } else if (lt == FLOAT || rt == FLOAT) {
                   1595:                        t = FLOAT;
                   1596:                } else {
                   1597:                        /*
                   1598:                         * If type A has more bits than type B it should
                   1599:                         * be able to hold all possible values of type B.
                   1600:                         */
                   1601:                        if (size(lt) > size(rt)) {
                   1602:                                t = lt;
                   1603:                        } else if (size(lt) < size(rt)) {
                   1604:                                t = rt;
                   1605:                        } else {
                   1606:                                for (i = 3; tl[i] != INT; i++) {
                   1607:                                        if (tl[i] == lt || tl[i] == rt)
                   1608:                                                break;
                   1609:                                }
                   1610:                                if ((isutyp(lt) || isutyp(rt)) &&
                   1611:                                    !isutyp(tl[i])) {
                   1612:                                        i--;
                   1613:                                }
                   1614:                                t = tl[i];
                   1615:                        }
                   1616:                }
                   1617:        } else {
                   1618:                /* Keep unsigned in traditional C */
                   1619:                u = isutyp(lt) || isutyp(rt);
                   1620:                for (i = 0; tl[i] != INT; i++) {
                   1621:                        if (lt == tl[i] || rt == tl[i])
                   1622:                                break;
                   1623:                }
                   1624:                t = tl[i];
                   1625:                if (u && isityp(t) && !isutyp(t))
                   1626:                        t = utyp(t);
                   1627:        }
                   1628:
                   1629:        if (t != lt) {
                   1630:                ntp = tduptyp((*lnp)->tn_type);
                   1631:                ntp->t_tspec = t;
                   1632:                *lnp = convert(op, 0, ntp, *lnp);
                   1633:        }
                   1634:        if (t != rt) {
                   1635:                ntp = tduptyp((*rnp)->tn_type);
                   1636:                ntp->t_tspec = t;
                   1637:                *rnp = convert(op, 0, ntp, *rnp);
                   1638:        }
                   1639: }
                   1640:
                   1641: /*
                   1642:  * Insert a conversion operator, which converts the type of the node
                   1643:  * to another given type.
                   1644:  * If op is FARG, arg is the number of the argument (used for warnings).
                   1645:  */
                   1646: tnode_t *
                   1647: convert(op, arg, tp, tn)
                   1648:        op_t    op;
                   1649:        int     arg;
                   1650:        type_t  *tp;
                   1651:        tnode_t *tn;
                   1652: {
                   1653:        tnode_t *ntn;
                   1654:        tspec_t nt, ot, ost;
                   1655:
                   1656:        if (tn->tn_lvalue)
                   1657:                lerror("convert() 1");
                   1658:
                   1659:        nt = tp->t_tspec;
                   1660:        if ((ot = tn->tn_type->t_tspec) == PTR)
                   1661:                ost = tn->tn_type->t_subt->t_tspec;
                   1662:
                   1663:        if (!tflag && !sflag && op == FARG)
                   1664:                ptconv(arg, nt, ot, tp, tn);
                   1665:        if (isityp(nt) && isityp(ot)) {
                   1666:                iiconv(op, arg, nt, ot, tp, tn);
                   1667:        } else if (nt == PTR && ((ot == PTR && ost == VOID) || isityp(ot)) &&
                   1668:                   tn->tn_op == CON && tn->tn_val->v_quad == 0) {
                   1669:                /* 0, 0L and (void *)0 may be assigned to any pointer. */
                   1670:        } else if (isityp(nt) && ot == PTR) {
                   1671:                piconv(op, nt, tp, tn);
                   1672:        } else if (nt == PTR && ot == PTR) {
                   1673:                ppconv(op, tn, tp);
                   1674:        }
                   1675:
                   1676:        ntn = getnode();
                   1677:        ntn->tn_op = CVT;
                   1678:        ntn->tn_type = tp;
                   1679:        ntn->tn_cast = op == CVT;
                   1680:        if (tn->tn_op != CON || nt == VOID) {
                   1681:                ntn->tn_left = tn;
                   1682:        } else {
                   1683:                ntn->tn_op = CON;
                   1684:                ntn->tn_val = tgetblk(sizeof (val_t));
                   1685:                cvtcon(op, arg, ntn->tn_type, ntn->tn_val, tn->tn_val);
                   1686:        }
                   1687:
                   1688:        return (ntn);
                   1689: }
                   1690:
                   1691: /*
                   1692:  * Print a warning if a prototype causes a type conversion that is
                   1693:  * different from what would happen to the same argument in the
                   1694:  * absence of a prototype.
                   1695:  *
                   1696:  * Errors/Warnings about illegal type combinations are already printed
                   1697:  * in asgntypok().
                   1698:  */
                   1699: static void
                   1700: ptconv(arg, nt, ot, tp, tn)
                   1701:        int     arg;
                   1702:        tspec_t nt, ot;
                   1703:        type_t  *tp;
                   1704:        tnode_t *tn;
                   1705: {
                   1706:        tnode_t *ptn;
                   1707:
                   1708:        if (!isatyp(nt) || !isatyp(ot))
                   1709:                return;
                   1710:
                   1711:        /*
                   1712:         * If the type of the formal parameter is char/short, a warning
                   1713:         * would be useless, because functions declared the old style
                   1714:         * can't expect char/short arguments.
                   1715:         */
                   1716:        if (nt == CHAR || nt == UCHAR || nt == SHORT || nt == USHORT)
                   1717:                return;
                   1718:
                   1719:        /* get default promotion */
                   1720:        ptn = promote(NOOP, 1, tn);
                   1721:        ot = ptn->tn_type->t_tspec;
                   1722:
                   1723:        /* return if types are the same with and without prototype */
                   1724:        if (nt == ot || (nt == ENUM && ot == INT))
                   1725:                return;
                   1726:
                   1727:        if (isftyp(nt) != isftyp(ot) || psize(nt) != psize(ot)) {
                   1728:                /* representation and/or width change */
                   1729:                if (styp(nt) != SHORT || !isityp(ot) || psize(ot) > psize(INT))
                   1730:                        /* conversion to '%s' due to prototype, arg #%d */
                   1731:                        warning(259, tyname(tp), arg);
                   1732:        } else if (hflag) {
                   1733:                /*
                   1734:                 * they differ in sign or base type (char, short, int,
                   1735:                 * long, long long, float, double, long double)
                   1736:                 *
                   1737:                 * if they differ only in sign and the argument is a constant
                   1738:                 * and the msb of the argument is not set, print no warning
                   1739:                 */
                   1740:                if (isityp(nt) && styp(nt) == styp(ot) &&
                   1741:                    msb(ptn->tn_val->v_quad, ot, -1) == 0) {
                   1742:                        /* ok */
                   1743:                } else {
                   1744:                        /* conversion to '%s' due to prototype, arg #%d */
                   1745:                        warning(259, tyname(tp), arg);
                   1746:                }
                   1747:        }
                   1748: }
                   1749:
                   1750: /*
                   1751:  * Print warnings for conversions of integer types which my cause
                   1752:  * problems.
                   1753:  */
                   1754: /* ARGSUSED */
                   1755: static void
                   1756: iiconv(op, arg, nt, ot, tp, tn)
                   1757:        op_t    op;
                   1758:        int     arg;
                   1759:        tspec_t nt, ot;
                   1760:        type_t  *tp;
                   1761:        tnode_t *tn;
                   1762: {
                   1763:        if (tn->tn_op == CON)
                   1764:                return;
                   1765:
                   1766:        if (op == CVT)
                   1767:                return;
                   1768:
                   1769: #if 0
                   1770:        if (psize(nt) > psize(ot) && isutyp(nt) != isutyp(ot)) {
                   1771:                /* conversion to %s may sign-extend incorrectly (, arg #%d) */
                   1772:                if (aflag && pflag) {
                   1773:                        if (op == FARG) {
                   1774:                                warning(297, tyname(tp), arg);
                   1775:                        } else {
                   1776:                                warning(131, tyname(tp));
                   1777:                        }
                   1778:                }
                   1779:        }
                   1780: #endif
                   1781:
                   1782:        if (psize(nt) < psize(ot) &&
                   1783:            (ot == LONG || ot == ULONG || ot == QUAD || ot == UQUAD ||
                   1784:             aflag > 1)) {
                   1785:                /* conversion from '%s' may lose accuracy */
                   1786:                if (aflag) {
                   1787:                        if (op == FARG) {
                   1788:                                warning(298, tyname(tn->tn_type), arg);
                   1789:                        } else {
                   1790:                                warning(132, tyname(tn->tn_type));
                   1791:                        }
                   1792:                }
                   1793:        }
                   1794: }
                   1795:
                   1796: /*
                   1797:  * Print warnings for dubious conversions of pointer to integer.
                   1798:  */
                   1799: static void
                   1800: piconv(op, nt, tp, tn)
                   1801:        op_t    op;
                   1802:        tspec_t nt;
                   1803:        type_t  *tp;
                   1804:        tnode_t *tn;
                   1805: {
                   1806:        if (tn->tn_op == CON)
                   1807:                return;
                   1808:
                   1809:        if (op != CVT) {
                   1810:                /* We got already an error. */
                   1811:                return;
                   1812:        }
                   1813:
                   1814:        if (psize(nt) < psize(PTR)) {
                   1815:                if (pflag && size(nt) >= size(PTR)) {
                   1816:                        /* conv. of pointer to %s may lose bits */
                   1817:                        warning(134, tyname(tp));
                   1818:                } else {
                   1819:                        /* conv. of pointer to %s loses bits */
                   1820:                        warning(133, tyname(tp));
                   1821:                }
                   1822:        }
                   1823: }
                   1824:
                   1825: /*
                   1826:  * Print warnings for questionable pointer conversions.
                   1827:  */
                   1828: static void
                   1829: ppconv(op, tn, tp)
                   1830:        op_t    op;
                   1831:        tnode_t *tn;
                   1832:        type_t  *tp;
                   1833: {
                   1834:        tspec_t nt, ot;
                   1835:        const   char *nts, *ots;
                   1836:
                   1837:        /*
                   1838:         * We got already an error (pointers of different types
                   1839:         * without a cast) or we will not get a warning.
                   1840:         */
                   1841:        if (op != CVT)
                   1842:                return;
                   1843:
                   1844:        nt = tp->t_subt->t_tspec;
                   1845:        ot = tn->tn_type->t_subt->t_tspec;
                   1846:
                   1847:        if (nt == VOID || ot == VOID) {
                   1848:                if (sflag && (nt == FUNC || ot == FUNC)) {
                   1849:                        /* (void *)0 already handled in convert() */
                   1850:                        *(nt == FUNC ? &nts : &ots) = "function pointer";
                   1851:                        *(nt == VOID ? &nts : &ots) = "'void *'";
                   1852:                        /* ANSI C forbids conversion of %s to %s */
                   1853:                        warning(303, ots, nts);
                   1854:                }
                   1855:                return;
                   1856:        } else if (nt == FUNC && ot == FUNC) {
                   1857:                return;
                   1858:        } else if (nt == FUNC || ot == FUNC) {
                   1859:                /* questionable conversion of function pointer */
                   1860:                warning(229);
                   1861:                return;
                   1862:        }
                   1863:
                   1864:        if (getbound(tp->t_subt) > getbound(tn->tn_type->t_subt)) {
                   1865:                if (hflag)
                   1866:                        /* possible pointer alignment problem */
                   1867:                        warning(135);
                   1868:        }
                   1869:        if (((nt == STRUCT || nt == UNION) &&
                   1870:             tp->t_subt->t_str != tn->tn_type->t_subt->t_str) ||
                   1871:            psize(nt) != psize(ot)) {
                   1872:                if (cflag) {
                   1873:                        /* pointer casts may be troublesome */
                   1874:                        warning(247);
                   1875:                }
                   1876:        }
                   1877: }
                   1878:
                   1879: /*
                   1880:  * Converts a typed constant in a constant of another type.
                   1881:  *
                   1882:  * op          operator which requires conversion
                   1883:  * arg         if op is FARG, # of argument
                   1884:  * tp          type in which to convert the constant
                   1885:  * nv          new constant
                   1886:  * v           old constant
                   1887:  */
                   1888: void
                   1889: cvtcon(op, arg, tp, nv, v)
                   1890:        op_t    op;
                   1891:        int     arg;
                   1892:        type_t  *tp;
                   1893:        val_t   *nv, *v;
                   1894: {
                   1895:        tspec_t ot, nt;
                   1896:        ldbl_t  max, min;
                   1897:        int     sz, rchk;
                   1898:        quad_t  xmask, xmsk1;
                   1899:        int     osz, nsz;
                   1900:
                   1901:        ot = v->v_tspec;
                   1902:        nt = nv->v_tspec = tp->t_tspec;
                   1903:        rchk = 0;
                   1904:
                   1905:        if (ot == FLOAT || ot == DOUBLE || ot == LDOUBLE) {
                   1906:                switch (nt) {
                   1907:                case CHAR:
                   1908:                        max = CHAR_MAX;         min = CHAR_MIN;         break;
                   1909:                case UCHAR:
                   1910:                        max = UCHAR_MAX;        min = 0;                break;
                   1911:                case SCHAR:
                   1912:                        max = SCHAR_MAX;        min = SCHAR_MIN;        break;
                   1913:                case SHORT:
                   1914:                        max = SHRT_MAX;         min = SHRT_MIN;         break;
                   1915:                case USHORT:
                   1916:                        max = USHRT_MAX;        min = 0;                break;
                   1917:                case ENUM:
                   1918:                case INT:
                   1919:                        max = INT_MAX;          min = INT_MIN;          break;
                   1920:                case UINT:
                   1921:                        max = (u_int)UINT_MAX;  min = 0;                break;
                   1922:                case LONG:
                   1923:                        max = LONG_MAX;         min = LONG_MIN;         break;
                   1924:                case ULONG:
                   1925:                        max = (u_long)ULONG_MAX; min = 0;               break;
                   1926:                case QUAD:
                   1927:                        max = QUAD_MAX;         min = QUAD_MIN;         break;
                   1928:                case UQUAD:
                   1929:                        max = (u_quad_t)UQUAD_MAX; min = 0;             break;
                   1930:                case FLOAT:
                   1931:                        max = FLT_MAX;          min = -FLT_MAX;         break;
                   1932:                case DOUBLE:
                   1933:                        max = DBL_MAX;          min = -DBL_MAX;         break;
                   1934:                case PTR:
                   1935:                        /* Got already an error because of float --> ptr */
                   1936:                case LDOUBLE:
                   1937:                        max = LDBL_MAX;         min = -LDBL_MAX;        break;
                   1938:                default:
                   1939:                        lerror("cvtcon() 1");
                   1940:                }
                   1941:                if (v->v_ldbl > max || v->v_ldbl < min) {
                   1942:                        if (nt == LDOUBLE)
                   1943:                                lerror("cvtcon() 2");
                   1944:                        if (op == FARG) {
                   1945:                                /* conv. of %s to %s is out of rng., arg #%d */
                   1946:                                warning(295, tyname(gettyp(ot)), tyname(tp),
                   1947:                                        arg);
                   1948:                        } else {
                   1949:                                /* conversion of %s to %s is out of range */
                   1950:                                warning(119, tyname(gettyp(ot)), tyname(tp));
                   1951:                        }
                   1952:                        v->v_ldbl = v->v_ldbl > 0 ? max : min;
                   1953:                }
                   1954:                if (nt == FLOAT) {
                   1955:                        nv->v_ldbl = (float)v->v_ldbl;
                   1956:                } else if (nt == DOUBLE) {
                   1957:                        nv->v_ldbl = (double)v->v_ldbl;
                   1958:                } else if (nt == LDOUBLE) {
                   1959:                        nv->v_ldbl = v->v_ldbl;
                   1960:                } else {
                   1961:                        nv->v_quad = (nt == PTR || isutyp(nt)) ?
                   1962:                                (u_quad_t)v->v_ldbl : (quad_t)v->v_ldbl;
                   1963:                }
                   1964:        } else {
                   1965:                if (nt == FLOAT) {
                   1966:                        nv->v_ldbl = (ot == PTR || isutyp(ot)) ?
                   1967:                               (float)(u_quad_t)v->v_quad : (float)v->v_quad;
                   1968:                } else if (nt == DOUBLE) {
                   1969:                        nv->v_ldbl = (ot == PTR || isutyp(ot)) ?
                   1970:                               (double)(u_quad_t)v->v_quad : (double)v->v_quad;
                   1971:                } else if (nt == LDOUBLE) {
                   1972:                        nv->v_ldbl = (ot == PTR || isutyp(ot)) ?
                   1973:                               (ldbl_t)(u_quad_t)v->v_quad : (ldbl_t)v->v_quad;
                   1974:                } else {
                   1975:                        rchk = 1;               /* Check for lost precision. */
                   1976:                        nv->v_quad = v->v_quad;
                   1977:                }
                   1978:        }
                   1979:
                   1980:        if (v->v_ansiu && isftyp(nt)) {
                   1981:                /* ANSI C treats constant as unsigned */
                   1982:                warning(157);
                   1983:                v->v_ansiu = 0;
                   1984:        } else if (v->v_ansiu && (isityp(nt) && !isutyp(nt) &&
                   1985:                                  psize(nt) > psize(ot))) {
                   1986:                /* ANSI C treats constant as unsigned */
                   1987:                warning(157);
                   1988:                v->v_ansiu = 0;
                   1989:        }
                   1990:
                   1991:        if (nt != FLOAT && nt != DOUBLE && nt != LDOUBLE) {
                   1992:                sz = tp->t_isfield ? tp->t_flen : size(nt);
                   1993:                nv->v_quad = xsign(nv->v_quad, nt, sz);
                   1994:        }
                   1995:
                   1996:        if (rchk && op != CVT) {
                   1997:                osz = size(ot);
                   1998:                nsz = tp->t_isfield ? tp->t_flen : size(nt);
                   1999:                xmask = qlmasks[nsz] ^ qlmasks[osz];
                   2000:                xmsk1 = qlmasks[nsz] ^ qlmasks[osz - 1];
                   2001:                /*
                   2002:                 * for bitwise operations we are not interested in the
                   2003:                 * value, but in the bits itself
                   2004:                 */
                   2005:                if (op == ORASS || op == OR || op == XOR) {
                   2006:                        /*
                   2007:                         * print a warning if we get additional bits set
                   2008:                         * or loose bits which are set
                   2009:                         */
                   2010:                        if (nsz > osz && (nv->v_quad & xmask) != 0) {
                   2011:                                /*
                   2012:                                 * extra bits set to 1 in conversion
                   2013:                                 * of '%s' to '%s', op %s
                   2014:                                 */
                   2015:                                warning(308, tyname(gettyp(ot)),
                   2016:                                        tyname(tp), modtab[op].m_name);
                   2017:                        } else if (nsz < osz && (v->v_quad & xmask) != 0) {
                   2018:                                /* constant truncated by conv., op %s */
                   2019:                                warning(306, modtab[op].m_name);
                   2020:                        }
                   2021:                } else if (op == ANDASS || op == AND) {
                   2022:                        /*
                   2023:                         * print a warning if additional bits are not all 1
                   2024:                         * or at least one (but not all) removed bit was 0
                   2025:                         */
                   2026:                        if (nsz > osz && (nv->v_quad & xmask) != xmask) {
                   2027:                                /*
                   2028:                                 * extra bits set to 0 in conversion
                   2029:                                 * of '%s' to '%s', op %s
                   2030:                                 */
                   2031:                                warning(309, tyname(gettyp(ot)),
                   2032:                                        tyname(tp), modtab[op].m_name);
                   2033:                        } else if (nsz < osz && (v->v_quad & xmask) != xmask &&
                   2034:                                   (v->v_quad & xmask) != 0) {
                   2035:                                /* const. truncated by conv., op %s */
                   2036:                                warning(306, modtab[op].m_name);
                   2037:                        }
                   2038:                } else if ((nt != PTR && isutyp(nt)) &&
                   2039:                           (ot != PTR && !isutyp(ot)) && v->v_quad < 0) {
                   2040:                        if (op == ASSIGN) {
                   2041:                                /* assignment of negative constant to ... */
                   2042:                                warning(164);
                   2043:                        } else if (op == INIT) {
                   2044:                                /* initialisation of unsigned with neg. ... */
                   2045:                                warning(221);
                   2046:                        } else if (op == FARG) {
                   2047:                                /* conversion of neg. const. to ..., arg #%d */
                   2048:                                warning(296, arg);
                   2049:                        } else if (modtab[op].m_comp) {
                   2050:                                /* we get this warning already in chkcomp() */
                   2051:                        } else {
                   2052:                                /* conversion of negative constant to ... */
                   2053:                                warning(222);
                   2054:                        }
                   2055:                } else if (nv->v_quad != v->v_quad && nsz <= osz &&
                   2056:                           (v->v_quad & xmask) != 0 &&
                   2057:                           (isutyp(ot) || (v->v_quad & xmsk1) != xmsk1)) {
                   2058:                        /*
                   2059:                         * Loss of significant bit(s). All truncated bits
                   2060:                         * of unsigned types or all truncated bits plus the
                   2061:                         * msb of the target for signed types are considered
                   2062:                         * to be significant bits. Loss of significant bits
                   2063:                         * means that at least on of the bits was set in an
                   2064:                         * unsigned type or that at least one, but not all of
                   2065:                         * the bits was set in an signed type.
                   2066:                         * Loss of significant bits means that it is not
                   2067:                         * possible, also not with necessary casts, to convert
                   2068:                         * back to the original type. A example for a
                   2069:                         * necessary cast is:
                   2070:                         *      char c; int     i; c = 128;
                   2071:                         *      i = c;                  ** yields -128 **
                   2072:                         *      i = (unsigned char)c;   ** yields 128 **
                   2073:                         */
                   2074:                        if (op == ASSIGN && tp->t_isfield) {
                   2075:                                /* precision lost in bit-field assignment */
                   2076:                                warning(166);
                   2077:                        } else if (op == ASSIGN) {
                   2078:                                /* constant truncated by assignment */
                   2079:                                warning(165);
                   2080:                        } else if (op == INIT && tp->t_isfield) {
                   2081:                                /* bit-field initializer does not fit */
                   2082:                                warning(180);
                   2083:                        } else if (op == INIT) {
                   2084:                                /* initializer does not fit */
                   2085:                                warning(178);
                   2086:                        } else if (op == CASE) {
                   2087:                                /* case label affected by conversion */
                   2088:                                warning(196);
                   2089:                        } else if (op == FARG) {
                   2090:                                /* conv. of %s to %s is out of rng., arg #%d */
                   2091:                                warning(295, tyname(gettyp(ot)), tyname(tp),
                   2092:                                        arg);
                   2093:                        } else {
                   2094:                                /* conversion of %s to %s is out of range */
                   2095:                                warning(119, tyname(gettyp(ot)), tyname(tp));
                   2096:                        }
                   2097:                } else if (nv->v_quad != v->v_quad) {
                   2098:                        if (op == ASSIGN && tp->t_isfield) {
                   2099:                                /* precision lost in bit-field assignment */
                   2100:                                warning(166);
                   2101:                        } else if (op == INIT && tp->t_isfield) {
                   2102:                                /* bit-field initializer out of range */
                   2103:                                warning(11);
                   2104:                        } else if (op == CASE) {
                   2105:                                /* case label affected by conversion */
                   2106:                                warning(196);
                   2107:                        } else if (op == FARG) {
                   2108:                                /* conv. of %s to %s is out of rng., arg #%d */
                   2109:                                warning(295, tyname(gettyp(ot)), tyname(tp),
                   2110:                                        arg);
                   2111:                        } else {
                   2112:                                /* conversion of %s to %s is out of range */
                   2113:                                warning(119, tyname(gettyp(ot)), tyname(tp));
                   2114:                        }
                   2115:                }
                   2116:        }
                   2117: }
                   2118:
                   2119: /*
                   2120:  * Called if incompatible types were detected.
                   2121:  * Prints a appropriate warning.
                   2122:  */
                   2123: static void
                   2124: incompat(op, lt, rt)
                   2125:        op_t    op;
                   2126:        tspec_t lt, rt;
                   2127: {
                   2128:        mod_t   *mp;
                   2129:
                   2130:        mp = &modtab[op];
                   2131:
                   2132:        if (lt == VOID || (mp->m_binary && rt == VOID)) {
                   2133:                /* void type illegal in expression */
                   2134:                error(109);
                   2135:        } else if (op == ASSIGN) {
                   2136:                if ((lt == STRUCT || lt == UNION) &&
                   2137:                    (rt == STRUCT || rt == UNION)) {
                   2138:                        /* assignment of different structures */
                   2139:                        error(240);
                   2140:                } else {
                   2141:                        /* assignment type mismatch */
                   2142:                        error(171);
                   2143:                }
                   2144:        } else if (mp->m_binary) {
                   2145:                /* operands of %s have incompatible types */
                   2146:                error(107, mp->m_name);
                   2147:        } else {
                   2148:                /* operand of %s has incompatible type */
                   2149:                error(108, mp->m_name);
                   2150:        }
                   2151: }
                   2152:
                   2153: /*
                   2154:  * Called if incompatible pointer types are detected.
                   2155:  * Print an appropriate warning.
                   2156:  */
                   2157: static void
                   2158: illptrc(mp, ltp, rtp)
                   2159:        mod_t   *mp;
                   2160:        type_t  *ltp, *rtp;
                   2161: {
                   2162:        tspec_t lt, rt;
                   2163:
                   2164:        if (ltp->t_tspec != PTR || rtp->t_tspec != PTR)
                   2165:                lerror("illptrc() 1");
                   2166:
                   2167:        lt = ltp->t_subt->t_tspec;
                   2168:        rt = rtp->t_subt->t_tspec;
                   2169:
                   2170:        if ((lt == STRUCT || lt == UNION) && (rt == STRUCT || rt == UNION)) {
                   2171:                if (mp == NULL) {
                   2172:                        /* illegal structure pointer combination */
                   2173:                        warning(244);
                   2174:                } else {
                   2175:                        /* illegal structure pointer combination, op %s */
                   2176:                        warning(245, mp->m_name);
                   2177:                }
                   2178:        } else {
                   2179:                if (mp == NULL) {
                   2180:                        /* illegal pointer combination */
                   2181:                        warning(184);
                   2182:                } else {
                   2183:                        /* illegal pointer combination, op %s */
                   2184:                        warning(124, mp->m_name);
                   2185:                }
                   2186:        }
                   2187: }
                   2188:
                   2189: /*
                   2190:  * Make sure type (*tpp)->t_subt has at least the qualifiers
                   2191:  * of tp1->t_subt and tp2->t_subt.
                   2192:  */
                   2193: static void
                   2194: mrgqual(tpp, tp1, tp2)
                   2195:        type_t  **tpp, *tp1, *tp2;
                   2196: {
                   2197:        if ((*tpp)->t_tspec != PTR ||
                   2198:            tp1->t_tspec != PTR || tp2->t_tspec != PTR) {
                   2199:                lerror("mrgqual()");
                   2200:        }
                   2201:
                   2202:        if ((*tpp)->t_subt->t_const ==
                   2203:            (tp1->t_subt->t_const | tp2->t_subt->t_const) &&
                   2204:            (*tpp)->t_subt->t_volatile ==
                   2205:            (tp1->t_subt->t_volatile | tp2->t_subt->t_volatile)) {
                   2206:                return;
                   2207:        }
                   2208:
                   2209:        *tpp = tduptyp(*tpp);
                   2210:        (*tpp)->t_subt = tduptyp((*tpp)->t_subt);
                   2211:        (*tpp)->t_subt->t_const =
                   2212:                tp1->t_subt->t_const | tp2->t_subt->t_const;
                   2213:        (*tpp)->t_subt->t_volatile =
                   2214:                tp1->t_subt->t_volatile | tp2->t_subt->t_volatile;
                   2215: }
                   2216:
                   2217: /*
                   2218:  * Returns 1 if the given structure or union has a constant member
                   2219:  * (maybe recursively).
                   2220:  */
                   2221: static int
                   2222: conmemb(tp)
                   2223:        type_t  *tp;
                   2224: {
                   2225:        sym_t   *m;
                   2226:        tspec_t t;
                   2227:
                   2228:        if ((t = tp->t_tspec) != STRUCT && t != UNION)
                   2229:                lerror("conmemb()");
                   2230:        for (m = tp->t_str->memb; m != NULL; m = m->s_nxt) {
                   2231:                tp = m->s_type;
                   2232:                if (tp->t_const)
                   2233:                        return (1);
                   2234:                if ((t = tp->t_tspec) == STRUCT || t == UNION) {
                   2235:                        if (conmemb(m->s_type))
                   2236:                                return (1);
                   2237:                }
                   2238:        }
                   2239:        return (0);
                   2240: }
                   2241:
                   2242: const char *
                   2243: tyname(tp)
                   2244:        type_t  *tp;
                   2245: {
                   2246:        tspec_t t;
                   2247:        const   char *s;
                   2248:
                   2249:        if ((t = tp->t_tspec) == INT && tp->t_isenum)
                   2250:                t = ENUM;
                   2251:
                   2252:        switch (t) {
                   2253:        case CHAR:      s = "char";                     break;
                   2254:        case UCHAR:     s = "unsigned char";            break;
                   2255:        case SCHAR:     s = "signed char";              break;
                   2256:        case SHORT:     s = "short";                    break;
                   2257:        case USHORT:    s = "unsigned short";           break;
                   2258:        case INT:       s = "int";                      break;
                   2259:        case UINT:      s = "unsigned int";             break;
                   2260:        case LONG:      s = "long";                     break;
                   2261:        case ULONG:     s = "unsigned long";            break;
                   2262:        case QUAD:      s = "long long";                break;
                   2263:        case UQUAD:     s = "unsigned long long";       break;
                   2264:        case FLOAT:     s = "float";                    break;
                   2265:        case DOUBLE:    s = "double";                   break;
                   2266:        case LDOUBLE:   s = "long double";              break;
                   2267:        case PTR:       s = "pointer";                  break;
                   2268:        case ENUM:      s = "enum";                     break;
                   2269:        case STRUCT:    s = "struct";                   break;
                   2270:        case UNION:     s = "union";                    break;
                   2271:        case FUNC:      s = "function";                 break;
                   2272:        case ARRAY:     s = "array";                    break;
                   2273:        default:
                   2274:                lerror("tyname()");
                   2275:        }
                   2276:        return (s);
                   2277: }
                   2278:
                   2279: /*
                   2280:  * Create a new node for one of the operators POINT and ARROW.
                   2281:  */
                   2282: static tnode_t *
                   2283: bldstr(op, ln, rn)
                   2284:        op_t    op;
                   2285:        tnode_t *ln, *rn;
                   2286: {
                   2287:        tnode_t *ntn, *ctn;
                   2288:        int     nolval;
                   2289:
                   2290:        if (rn->tn_op != NAME)
                   2291:                lerror("bldstr() 1");
                   2292:        if (rn->tn_sym->s_value.v_tspec != INT)
                   2293:                lerror("bldstr() 2");
                   2294:        if (rn->tn_sym->s_scl != MOS && rn->tn_sym->s_scl != MOU)
                   2295:                lerror("bldstr() 3");
                   2296:
                   2297:        /*
                   2298:         * Remember if the left operand is an lvalue (structure members
                   2299:         * are lvalues if and only if the structure itself is an lvalue).
                   2300:         */
                   2301:        nolval = op == POINT && !ln->tn_lvalue;
                   2302:
                   2303:        if (op == POINT) {
                   2304:                ln = bldamper(ln, 1);
                   2305:        } else if (ln->tn_type->t_tspec != PTR) {
                   2306:                if (!tflag || !isityp(ln->tn_type->t_tspec))
                   2307:                        lerror("bldstr() 4");
                   2308:                ln = convert(NOOP, 0, tincref(gettyp(VOID), PTR), ln);
                   2309:        }
                   2310:
                   2311: #if PTRDIFF_IS_LONG
                   2312:        ctn = getinode(LONG, rn->tn_sym->s_value.v_quad / CHAR_BIT);
                   2313: #else
                   2314:        ctn = getinode(INT, rn->tn_sym->s_value.v_quad / CHAR_BIT);
                   2315: #endif
                   2316:
                   2317:        ntn = mktnode(PLUS, tincref(rn->tn_type, PTR), ln, ctn);
                   2318:        if (ln->tn_op == CON)
                   2319:                ntn = fold(ntn);
                   2320:
                   2321:        if (rn->tn_type->t_isfield) {
                   2322:                ntn = mktnode(FSEL, ntn->tn_type->t_subt, ntn, NULL);
                   2323:        } else {
                   2324:                ntn = mktnode(STAR, ntn->tn_type->t_subt, ntn, NULL);
                   2325:        }
                   2326:
                   2327:        if (nolval)
                   2328:                ntn->tn_lvalue = 0;
                   2329:
                   2330:        return (ntn);
                   2331: }
                   2332:
                   2333: /*
                   2334:  * Create a node for INCAFT, INCBEF, DECAFT and DECBEF.
                   2335:  */
                   2336: static tnode_t *
                   2337: bldincdec(op, ln)
                   2338:        op_t    op;
                   2339:        tnode_t *ln;
                   2340: {
                   2341:        tnode_t *cn, *ntn;
                   2342:
                   2343:        if (ln == NULL)
                   2344:                lerror("bldincdec() 1");
                   2345:
                   2346:        if (ln->tn_type->t_tspec == PTR) {
                   2347:                cn = plength(ln->tn_type);
                   2348:        } else {
                   2349:                cn = getinode(INT, (quad_t)1);
                   2350:        }
                   2351:        ntn = mktnode(op, ln->tn_type, ln, cn);
                   2352:
                   2353:        return (ntn);
                   2354: }
                   2355:
                   2356: /*
                   2357:  * Create a tree node for the & operator
                   2358:  */
                   2359: static tnode_t *
                   2360: bldamper(tn, noign)
                   2361:        tnode_t *tn;
                   2362:        int     noign;
                   2363: {
                   2364:        tnode_t *ntn;
                   2365:        tspec_t t;
                   2366:
                   2367:        if (!noign && ((t = tn->tn_type->t_tspec) == ARRAY || t == FUNC)) {
                   2368:                /* & before array or function: ignored */
                   2369:                if (tflag)
                   2370:                        warning(127);
                   2371:                return (tn);
                   2372:        }
                   2373:
                   2374:        /* eliminate &* */
                   2375:        if (tn->tn_op == STAR &&
                   2376:            tn->tn_left->tn_type->t_tspec == PTR &&
                   2377:            tn->tn_left->tn_type->t_subt == tn->tn_type) {
                   2378:                return (tn->tn_left);
                   2379:        }
                   2380:
                   2381:        ntn = mktnode(AMPER, tincref(tn->tn_type, PTR), tn, NULL);
                   2382:
                   2383:        return (ntn);
                   2384: }
                   2385:
                   2386: /*
                   2387:  * Create a node for operators PLUS and MINUS.
                   2388:  */
                   2389: static tnode_t *
                   2390: bldplmi(op, ln, rn)
                   2391:        op_t    op;
                   2392:        tnode_t *ln, *rn;
                   2393: {
                   2394:        tnode_t *ntn, *ctn;
                   2395:        type_t  *tp;
                   2396:
                   2397:        /* If pointer and integer, then pointer to the lhs. */
                   2398:        if (rn->tn_type->t_tspec == PTR && isityp(ln->tn_type->t_tspec)) {
                   2399:                ntn = ln;
                   2400:                ln = rn;
                   2401:                rn = ntn;
                   2402:        }
                   2403:
                   2404:        if (ln->tn_type->t_tspec == PTR && rn->tn_type->t_tspec != PTR) {
                   2405:
                   2406:                if (!isityp(rn->tn_type->t_tspec))
                   2407:                        lerror("bldplmi() 1");
                   2408:
                   2409:                ctn = plength(ln->tn_type);
                   2410:                if (rn->tn_type->t_tspec != ctn->tn_type->t_tspec)
                   2411:                        rn = convert(NOOP, 0, ctn->tn_type, rn);
                   2412:                rn = mktnode(MULT, rn->tn_type, rn, ctn);
                   2413:                if (rn->tn_left->tn_op == CON)
                   2414:                        rn = fold(rn);
                   2415:                ntn = mktnode(op, ln->tn_type, ln, rn);
                   2416:
                   2417:        } else if (rn->tn_type->t_tspec == PTR) {
                   2418:
                   2419:                if (ln->tn_type->t_tspec != PTR || op != MINUS)
                   2420:                        lerror("bldplmi() 2");
                   2421: #if PTRDIFF_IS_LONG
                   2422:                tp = gettyp(LONG);
                   2423: #else
                   2424:                tp = gettyp(INT);
                   2425: #endif
                   2426:                ntn = mktnode(op, tp, ln, rn);
                   2427:                if (ln->tn_op == CON && rn->tn_op == CON)
                   2428:                        ntn = fold(ntn);
                   2429:                ctn = plength(ln->tn_type);
                   2430:                balance(NOOP, &ntn, &ctn);
                   2431:                ntn = mktnode(DIV, tp, ntn, ctn);
                   2432:
                   2433:        } else {
                   2434:
                   2435:                ntn = mktnode(op, ln->tn_type, ln, rn);
                   2436:
                   2437:        }
                   2438:        return (ntn);
                   2439: }
                   2440:
                   2441: /*
                   2442:  * Create a node for operators SHL and SHR.
                   2443:  */
                   2444: static tnode_t *
                   2445: bldshft(op, ln, rn)
                   2446:        op_t    op;
                   2447:        tnode_t *ln, *rn;
                   2448: {
                   2449:        tspec_t t;
                   2450:        tnode_t *ntn;
                   2451:
                   2452:        if ((t = rn->tn_type->t_tspec) != INT && t != UINT)
                   2453:                rn = convert(CVT, 0, gettyp(INT), rn);
                   2454:        ntn = mktnode(op, ln->tn_type, ln, rn);
                   2455:        return (ntn);
                   2456: }
                   2457:
                   2458: /*
                   2459:  * Create a node for COLON.
                   2460:  */
                   2461: static tnode_t *
                   2462: bldcol(ln, rn)
                   2463:        tnode_t *ln, *rn;
                   2464: {
                   2465:        tspec_t lt, rt, pdt;
                   2466:        type_t  *rtp;
                   2467:        tnode_t *ntn;
                   2468:
                   2469:        lt = ln->tn_type->t_tspec;
                   2470:        rt = rn->tn_type->t_tspec;
                   2471: #if PTRDIFF_IS_LONG
                   2472:        pdt = LONG;
                   2473: #else
                   2474:        pdt = INT;
                   2475: #endif
                   2476:
                   2477:        /*
                   2478:         * Arithmetic types are balanced, all other type combinations
                   2479:         * still need to be handled.
                   2480:         */
                   2481:        if (isatyp(lt) && isatyp(rt)) {
                   2482:                rtp = ln->tn_type;
                   2483:        } else if (lt == VOID || rt == VOID) {
                   2484:                rtp = gettyp(VOID);
                   2485:        } else if (lt == STRUCT || lt == UNION) {
                   2486:                /* Both types must be identical. */
                   2487:                if (rt != STRUCT && rt != UNION)
                   2488:                        lerror("bldcol() 1");
                   2489:                if (ln->tn_type->t_str != rn->tn_type->t_str)
                   2490:                        lerror("bldcol() 2");
                   2491:                if (incompl(ln->tn_type)) {
                   2492:                        /* unknown operand size, op %s */
                   2493:                        error(138, modtab[COLON].m_name);
                   2494:                        return (NULL);
                   2495:                }
                   2496:                rtp = ln->tn_type;
                   2497:        } else if (lt == PTR && isityp(rt)) {
                   2498:                if (rt != pdt) {
                   2499:                        rn = convert(NOOP, 0, gettyp(pdt), rn);
                   2500:                        rt = pdt;
                   2501:                }
                   2502:                rtp = ln->tn_type;
                   2503:        } else if (rt == PTR && isityp(lt)) {
                   2504:                if (lt != pdt) {
                   2505:                        ln = convert(NOOP, 0, gettyp(pdt), ln);
                   2506:                        lt = pdt;
                   2507:                }
                   2508:                rtp = rn->tn_type;
                   2509:        } else if (lt == PTR && ln->tn_type->t_subt->t_tspec == VOID) {
                   2510:                if (rt != PTR)
                   2511:                        lerror("bldcol() 4");
                   2512:                rtp = ln->tn_type;
                   2513:                mrgqual(&rtp, ln->tn_type, rn->tn_type);
                   2514:        } else if (rt == PTR && rn->tn_type->t_subt->t_tspec == VOID) {
                   2515:                if (lt != PTR)
                   2516:                        lerror("bldcol() 5");
                   2517:                rtp = rn->tn_type;
                   2518:                mrgqual(&rtp, ln->tn_type, rn->tn_type);
                   2519:        } else {
                   2520:                if (lt != PTR || rt != PTR)
                   2521:                        lerror("bldcol() 6");
                   2522:                /*
                   2523:                 * XXX For now we simply take the left type. This is
                   2524:                 * probably wrong, if one type contains a functionprototype
                   2525:                 * and the other one, at the same place, only an old style
                   2526:                 * declaration.
                   2527:                 */
                   2528:                rtp = ln->tn_type;
                   2529:                mrgqual(&rtp, ln->tn_type, rn->tn_type);
                   2530:        }
                   2531:
                   2532:        ntn = mktnode(COLON, rtp, ln, rn);
                   2533:
                   2534:        return (ntn);
                   2535: }
                   2536:
                   2537: /*
                   2538:  * Create a node for an assignment operator (both = and op= ).
                   2539:  */
                   2540: static tnode_t *
                   2541: bldasgn(op, ln, rn)
                   2542:        op_t    op;
                   2543:        tnode_t *ln, *rn;
                   2544: {
                   2545:        tspec_t lt, rt;
                   2546:        tnode_t *ntn, *ctn;
                   2547:
                   2548:        if (ln == NULL || rn == NULL)
                   2549:                lerror("bldasgn() 1");
                   2550:
                   2551:        lt = ln->tn_type->t_tspec;
                   2552:        rt = rn->tn_type->t_tspec;
                   2553:
                   2554:        if ((op == ADDASS || op == SUBASS) && lt == PTR) {
                   2555:                if (!isityp(rt))
                   2556:                        lerror("bldasgn() 2");
                   2557:                ctn = plength(ln->tn_type);
                   2558:                if (rn->tn_type->t_tspec != ctn->tn_type->t_tspec)
                   2559:                        rn = convert(NOOP, 0, ctn->tn_type, rn);
                   2560:                rn = mktnode(MULT, rn->tn_type, rn, ctn);
                   2561:                if (rn->tn_left->tn_op == CON)
                   2562:                        rn = fold(rn);
                   2563:        }
                   2564:
                   2565:        if ((op == ASSIGN || op == RETURN) && (lt == STRUCT || rt == STRUCT)) {
                   2566:                if (rt != lt || ln->tn_type->t_str != rn->tn_type->t_str)
                   2567:                        lerror("bldasgn() 3");
                   2568:                if (incompl(ln->tn_type)) {
                   2569:                        if (op == RETURN) {
                   2570:                                /* cannot return incomplete type */
                   2571:                                error(212);
                   2572:                        } else {
                   2573:                                /* unknown operand size, op %s */
                   2574:                                error(138, modtab[op].m_name);
                   2575:                        }
                   2576:                        return (NULL);
                   2577:                }
                   2578:        }
                   2579:
                   2580:        if (op == SHLASS || op == SHRASS) {
                   2581:                if (rt != INT) {
                   2582:                        rn = convert(NOOP, 0, gettyp(INT), rn);
                   2583:                        rt = INT;
                   2584:                }
                   2585:        } else {
                   2586:                if (op == ASSIGN || lt != PTR) {
                   2587:                        if (lt != rt ||
                   2588:                            (ln->tn_type->t_isfield && rn->tn_op == CON)) {
                   2589:                                rn = convert(op, 0, ln->tn_type, rn);
                   2590:                                rt = lt;
                   2591:                        }
                   2592:                }
                   2593:        }
                   2594:
                   2595:        ntn = mktnode(op, ln->tn_type, ln, rn);
                   2596:
                   2597:        return (ntn);
                   2598: }
                   2599:
                   2600: /*
                   2601:  * Get length of type tp->t_subt.
                   2602:  */
                   2603: static tnode_t *
                   2604: plength(tp)
                   2605:        type_t  *tp;
                   2606: {
                   2607:        int     elem, elsz;
                   2608:        tspec_t st;
                   2609:
                   2610:        if (tp->t_tspec != PTR)
                   2611:                lerror("plength() 1");
                   2612:        tp = tp->t_subt;
                   2613:
                   2614:        elem = 1;
                   2615:        elsz = 0;
                   2616:
                   2617:        while (tp->t_tspec == ARRAY) {
                   2618:                elem *= tp->t_dim;
                   2619:                tp = tp->t_subt;
                   2620:        }
                   2621:
                   2622:        switch (tp->t_tspec) {
                   2623:        case FUNC:
                   2624:                /* pointer to function is not allowed here */
                   2625:                error(110);
                   2626:                break;
                   2627:        case VOID:
                   2628:                /* cannot do pointer arithmetic on operand of ... */
                   2629:                if (gflag) {
                   2630:                        warning(136);
                   2631:                } else {
                   2632:                        error(136);
                   2633:                }
                   2634:                break;
                   2635:        case STRUCT:
                   2636:        case UNION:
                   2637:                if ((elsz = tp->t_str->size) == 0)
                   2638:                        /* cannot do pointer arithmetic on operand of ... */
                   2639:                        error(136);
                   2640:                break;
                   2641:        case ENUM:
                   2642:                if (incompl(tp)) {
                   2643:                        /* cannot do pointer arithmetic on operand of ... */
                   2644:                        warning(136);
                   2645:                }
                   2646:                /* FALLTHROUGH */
                   2647:        default:
                   2648:                if ((elsz = size(tp->t_tspec)) == 0) {
                   2649:                        /* cannot do pointer arithmetic on operand of ... */
                   2650:                        error(136);
                   2651:                } else if (elsz == -1) {
                   2652:                        lerror("plength() 2");
                   2653:                }
                   2654:                break;
                   2655:        }
                   2656:
                   2657:        if (elem == 0 && elsz != 0) {
                   2658:                /* cannot do pointer arithmetic on operand of ... */
                   2659:                error(136);
                   2660:        }
                   2661:
                   2662:        if (elsz == 0)
                   2663:                elsz = CHAR_BIT;
                   2664:
                   2665: #if PTRDIFF_IS_LONG
                   2666:        st = LONG;
                   2667: #else
                   2668:        st = INT;
                   2669: #endif
                   2670:
                   2671:        return (getinode(st, (quad_t)(elem * elsz / CHAR_BIT)));
                   2672: }
                   2673:
1.3     ! cgd      2674: #ifdef XXX_BROKEN_GCC
        !          2675: static int
        !          2676: quad_t_eq(x, y)
        !          2677:        quad_t x, y;
        !          2678: {
        !          2679:        return (x == y);
        !          2680: }
        !          2681:
        !          2682: static int
        !          2683: u_quad_t_eq(x, y)
        !          2684:        u_quad_t x, y;
        !          2685: {
        !          2686:        return (x == y);
        !          2687: }
        !          2688: #endif
        !          2689:
1.1       cgd      2690: /*
                   2691:  * Do only as much as necessary to compute constant expressions.
                   2692:  * Called only if the operator allows folding and (both) operands
                   2693:  * are constants.
                   2694:  */
                   2695: static tnode_t *
                   2696: fold(tn)
                   2697:        tnode_t *tn;
                   2698: {
                   2699:        val_t   *v;
                   2700:        tspec_t t;
                   2701:        int     utyp, ovfl;
                   2702:        quad_t  sl, sr, q, mask;
                   2703:        u_quad_t ul, ur;
                   2704:        tnode_t *cn;
                   2705:
                   2706:        v = xcalloc(1, sizeof (val_t));
                   2707:        v->v_tspec = t = tn->tn_type->t_tspec;
                   2708:
                   2709:        utyp = t == PTR || isutyp(t);
                   2710:        ul = sl = tn->tn_left->tn_val->v_quad;
                   2711:        if (modtab[tn->tn_op].m_binary)
                   2712:                ur = sr = tn->tn_right->tn_val->v_quad;
                   2713:
                   2714:        ovfl = 0;
                   2715:
                   2716:        switch (tn->tn_op) {
                   2717:        case UPLUS:
                   2718:                q = sl;
                   2719:                break;
                   2720:        case UMINUS:
                   2721:                q = -sl;
                   2722:                if (msb(q, t, -1) == msb(sl, t, -1))
                   2723:                        ovfl = 1;
                   2724:                break;
                   2725:        case COMPL:
                   2726:                q = ~sl;
                   2727:                break;
                   2728:        case MULT:
                   2729:                q = utyp ? ul * ur : sl * sr;
                   2730:                if (msb(q, t, -1) != (msb(sl, t, -1) ^ msb(sr, t, -1)))
                   2731:                        ovfl = 1;
                   2732:                break;
                   2733:        case DIV:
                   2734:                if (sr == 0) {
                   2735:                        /* division by 0 */
                   2736:                        error(139);
                   2737:                        q = utyp ? UQUAD_MAX : QUAD_MAX;
                   2738:                } else {
                   2739:                        q = utyp ? ul / ur : sl / sr;
                   2740:                }
                   2741:                break;
                   2742:        case MOD:
                   2743:                if (sr == 0) {
                   2744:                        /* modulus by 0 */
                   2745:                        error(140);
                   2746:                        q = 0;
                   2747:                } else {
                   2748:                        q = utyp ? ul % ur : sl % sr;
                   2749:                }
                   2750:                break;
                   2751:        case PLUS:
                   2752:                q = utyp ? ul + ur : sl + sr;
                   2753:                if (msb(sl, t, -1)  != 0 && msb(sr, t, -1) != 0) {
                   2754:                        if (msb(q, t, -1) == 0)
                   2755:                                ovfl = 1;
                   2756:                } else if (msb(sl, t, -1) == 0 && msb(sr, t, -1) == 0) {
                   2757:                        if (msb(q, t, -1) != 0)
                   2758:                                ovfl = 1;
                   2759:                }
                   2760:                break;
                   2761:        case MINUS:
                   2762:                q = utyp ? ul - ur : sl - sr;
                   2763:                if (msb(sl, t, -1) != 0 && msb(sr, t, -1) == 0) {
                   2764:                        if (msb(q, t, -1) == 0)
                   2765:                                ovfl = 1;
                   2766:                } else if (msb(sl, t, -1) == 0 && msb(sr, t, -1) != 0) {
                   2767:                        if (msb(q, t, -1) != 0)
                   2768:                                ovfl = 1;
                   2769:                }
                   2770:                break;
                   2771:        case SHL:
                   2772:                q = utyp ? ul << sr : sl << sr;
                   2773:                break;
                   2774:        case SHR:
                   2775:                /*
                   2776:                 * The sign must be explizitly extended because
                   2777:                 * shifts of signed values are implementation dependent.
                   2778:                 */
                   2779:                q = ul >> sr;
                   2780:                q = xsign(q, t, size(t) - (int)sr);
                   2781:                break;
                   2782:        case LT:
                   2783:                q = utyp ? ul < ur : sl < sr;
                   2784:                break;
                   2785:        case LE:
                   2786:                q = utyp ? ul <= ur : sl <= sr;
                   2787:                break;
                   2788:        case GE:
                   2789:                q = utyp ? ul >= ur : sl >= sr;
                   2790:                break;
                   2791:        case GT:
                   2792:                q = utyp ? ul > ur : sl > sr;
                   2793:                break;
                   2794:        case EQ:
1.3     ! cgd      2795: #ifdef XXX_BROKEN_GCC
        !          2796:                q = utyp ? u_quad_t_eq(ul, ur) : quad_t_eq(sl, sr);
        !          2797: #else
1.1       cgd      2798:                q = utyp ? ul == ur : sl == sr;
1.3     ! cgd      2799: #endif
1.1       cgd      2800:                break;
                   2801:        case NE:
                   2802:                q = utyp ? ul != ur : sl != sr;
                   2803:                break;
                   2804:        case AND:
                   2805:                q = utyp ? ul & ur : sl & sr;
                   2806:                break;
                   2807:        case XOR:
                   2808:                q = utyp ? ul ^ ur : sl ^ sr;
                   2809:                break;
                   2810:        case OR:
                   2811:                q = utyp ? ul | ur : sl | sr;
                   2812:                break;
                   2813:        default:
                   2814:                lerror("fold() 5");
                   2815:        }
                   2816:
                   2817:        mask = qlmasks[size(t)];
                   2818:
                   2819:        /* XXX does not work for quads. */
                   2820:        if (ovfl || ((q | mask) != ~(u_quad_t)0 && (q & ~mask) != 0)) {
                   2821:                if (hflag)
                   2822:                        /* integer overflow detected, op %s */
                   2823:                        warning(141, modtab[tn->tn_op].m_name);
                   2824:        }
                   2825:
                   2826:        v->v_quad = xsign(q, t, -1);
                   2827:
                   2828:        cn = getcnode(tn->tn_type, v);
                   2829:
                   2830:        return (cn);
                   2831: }
                   2832:
1.3     ! cgd      2833: #ifdef XXX_BROKEN_GCC
        !          2834: int
        !          2835: ldbl_t_neq(x, y)
        !          2836:        ldbl_t x, y;
        !          2837: {
        !          2838:        return (x != y);
        !          2839: }
        !          2840: #endif
        !          2841:
1.1       cgd      2842: /*
                   2843:  * Same for operators whose operands are compared with 0 (test context).
                   2844:  */
                   2845: static tnode_t *
                   2846: foldtst(tn)
                   2847:        tnode_t *tn;
                   2848: {
                   2849:        int     l, r;
                   2850:        val_t   *v;
                   2851:
                   2852:        v = xcalloc(1, sizeof (val_t));
                   2853:        v->v_tspec = tn->tn_type->t_tspec;
                   2854:        if (tn->tn_type->t_tspec != INT)
                   2855:                lerror("foldtst() 1");
                   2856:
                   2857:        if (isftyp(tn->tn_left->tn_type->t_tspec)) {
1.3     ! cgd      2858: #ifdef XXX_BROKEN_GCC
        !          2859:                l = ldbl_t_neq(tn->tn_left->tn_val->v_ldbl, 0.0);
        !          2860: #else
1.1       cgd      2861:                l = tn->tn_left->tn_val->v_ldbl != 0.0;
1.3     ! cgd      2862: #endif
1.1       cgd      2863:        } else {
                   2864:                l = tn->tn_left->tn_val->v_quad != 0;
                   2865:        }
                   2866:
                   2867:        if (modtab[tn->tn_op].m_binary) {
                   2868:                if (isftyp(tn->tn_right->tn_type->t_tspec)) {
1.3     ! cgd      2869: #ifdef XXX_BROKEN_GCC
        !          2870:                        r = ldbl_t_neq(tn->tn_right->tn_val->v_ldbl, 0.0);
        !          2871: #else
1.1       cgd      2872:                        r = tn->tn_right->tn_val->v_ldbl != 0.0;
1.3     ! cgd      2873: #endif
1.1       cgd      2874:                } else {
                   2875:                        r = tn->tn_right->tn_val->v_quad != 0;
                   2876:                }
                   2877:        }
                   2878:
                   2879:        switch (tn->tn_op) {
                   2880:        case NOT:
                   2881:                if (hflag)
                   2882:                        /* constant argument to NOT */
                   2883:                        warning(239);
                   2884:                v->v_quad = !l;
                   2885:                break;
                   2886:        case LOGAND:
                   2887:                v->v_quad = l && r;
                   2888:                break;
                   2889:        case LOGOR:
                   2890:                v->v_quad = l || r;
                   2891:                break;
                   2892:        default:
                   2893:                lerror("foldtst() 1");
                   2894:        }
                   2895:
                   2896:        return (getcnode(tn->tn_type, v));
                   2897: }
                   2898:
                   2899: /*
                   2900:  * Same for operands with floating point type.
                   2901:  */
                   2902: static tnode_t *
                   2903: foldflt(tn)
                   2904:        tnode_t *tn;
                   2905: {
                   2906:        val_t   *v;
                   2907:        tspec_t t;
                   2908:        ldbl_t  l, r;
                   2909:
                   2910:        v = xcalloc(1, sizeof (val_t));
                   2911:        v->v_tspec = t = tn->tn_type->t_tspec;
                   2912:
                   2913:        if (!isftyp(t))
                   2914:                lerror("foldflt() 1");
                   2915:
                   2916:        if (t != tn->tn_left->tn_type->t_tspec)
                   2917:                lerror("foldflt() 2");
                   2918:        if (modtab[tn->tn_op].m_binary && t != tn->tn_right->tn_type->t_tspec)
                   2919:                lerror("foldflt() 3");
                   2920:
                   2921:        l = tn->tn_left->tn_val->v_ldbl;
                   2922:        if (modtab[tn->tn_op].m_binary)
                   2923:                r = tn->tn_right->tn_val->v_ldbl;
                   2924:
                   2925:        switch (tn->tn_op) {
                   2926:        case UPLUS:
                   2927:                v->v_ldbl = l;
                   2928:                break;
                   2929:        case UMINUS:
                   2930:                v->v_ldbl = -l;
                   2931:                break;
                   2932:        case MULT:
                   2933:                v->v_ldbl = l * r;
                   2934:                break;
                   2935:        case DIV:
                   2936:                if (r == 0.0) {
                   2937:                        /* division by 0 */
                   2938:                        error(139);
                   2939:                        if (t == FLOAT) {
                   2940:                                v->v_ldbl = l < 0 ? -FLT_MAX : FLT_MAX;
                   2941:                        } else if (t == DOUBLE) {
                   2942:                                v->v_ldbl = l < 0 ? -DBL_MAX : DBL_MAX;
                   2943:                        } else {
                   2944:                                v->v_ldbl = l < 0 ? -LDBL_MAX : LDBL_MAX;
                   2945:                        }
                   2946:                } else {
                   2947:                        v->v_ldbl = l / r;
                   2948:                }
                   2949:                break;
                   2950:        case PLUS:
                   2951:                v->v_ldbl = l + r;
                   2952:                break;
                   2953:        case MINUS:
                   2954:                v->v_ldbl = l - r;
                   2955:                break;
                   2956:        case LT:
                   2957:                v->v_quad = l < r;
                   2958:                break;
                   2959:        case LE:
                   2960:                v->v_quad = l <= r;
                   2961:                break;
                   2962:        case GE:
                   2963:                v->v_quad = l >= r;
                   2964:                break;
                   2965:        case GT:
                   2966:                v->v_quad = l > r;
                   2967:                break;
                   2968:        case EQ:
                   2969:                v->v_quad = l == r;
                   2970:                break;
                   2971:        case NE:
                   2972:                v->v_quad = l != r;
                   2973:                break;
                   2974:        default:
                   2975:                lerror("foldflt() 4");
                   2976:        }
                   2977:
                   2978:        if (isnan((double)v->v_ldbl))
                   2979:                lerror("foldflt() 5");
                   2980:        if (isinf((double)v->v_ldbl) ||
                   2981:            (t == FLOAT &&
                   2982:             (v->v_ldbl > FLT_MAX || v->v_ldbl < -FLT_MAX)) ||
                   2983:            (t == DOUBLE &&
                   2984:             (v->v_ldbl > DBL_MAX || v->v_ldbl < -DBL_MAX))) {
                   2985:                /* floating point overflow detected, op %s */
                   2986:                warning(142, modtab[tn->tn_op].m_name);
                   2987:                if (t == FLOAT) {
                   2988:                        v->v_ldbl = v->v_ldbl < 0 ? -FLT_MAX : FLT_MAX;
                   2989:                } else if (t == DOUBLE) {
                   2990:                        v->v_ldbl = v->v_ldbl < 0 ? -DBL_MAX : DBL_MAX;
                   2991:                } else {
                   2992:                        v->v_ldbl = v->v_ldbl < 0 ? -LDBL_MAX: LDBL_MAX;
                   2993:                }
                   2994:        }
                   2995:
                   2996:        return (getcnode(tn->tn_type, v));
                   2997: }
                   2998:
                   2999: /*
                   3000:  * Create a constant node for sizeof.
                   3001:  */
                   3002: tnode_t *
                   3003: bldszof(tp)
                   3004:        type_t  *tp;
                   3005: {
                   3006:        int     elem, elsz;
                   3007:        tspec_t st;
                   3008:
                   3009:        elem = 1;
                   3010:        while (tp->t_tspec == ARRAY) {
                   3011:                elem *= tp->t_dim;
                   3012:                tp = tp->t_subt;
                   3013:        }
                   3014:        if (elem == 0) {
                   3015:                /* cannot take size of incomplete type */
                   3016:                error(143);
                   3017:                elem = 1;
                   3018:        }
                   3019:        switch (tp->t_tspec) {
                   3020:        case FUNC:
                   3021:                /* cannot take size of function */
                   3022:                error(144);
                   3023:                elsz = 1;
                   3024:                break;
                   3025:        case STRUCT:
                   3026:        case UNION:
                   3027:                if (incompl(tp)) {
                   3028:                        /* cannot take size of incomplete type */
                   3029:                        error(143);
                   3030:                        elsz = 1;
                   3031:                } else {
                   3032:                        elsz = tp->t_str->size;
                   3033:                }
                   3034:                break;
                   3035:        case ENUM:
                   3036:                if (incompl(tp)) {
                   3037:                        /* cannot take size of incomplete type */
                   3038:                        warning(143);
                   3039:                }
                   3040:                /* FALLTHROUGH */
                   3041:        default:
                   3042:                if (tp->t_isfield) {
                   3043:                        /* cannot take size of bit-field */
                   3044:                        error(145);
                   3045:                }
                   3046:                if (tp->t_tspec == VOID) {
                   3047:                        /* cannot take size of void */
                   3048:                        error(146);
                   3049:                        elsz = 1;
                   3050:                } else {
                   3051:                        elsz = size(tp->t_tspec);
                   3052:                        if (elsz <= 0)
                   3053:                                lerror("bldszof() 1");
                   3054:                }
                   3055:                break;
                   3056:        }
                   3057:
                   3058: #if SIZEOF_IS_ULONG
                   3059:        st = ULONG;
                   3060: #else
                   3061:        st = UINT;
                   3062: #endif
                   3063:
                   3064:        return (getinode(st, (quad_t)(elem * elsz / CHAR_BIT)));
                   3065: }
                   3066:
                   3067: /*
                   3068:  * Type casts.
                   3069:  */
                   3070: tnode_t *
                   3071: cast(tn, tp)
                   3072:        tnode_t *tn;
                   3073:        type_t  *tp;
                   3074: {
                   3075:        tspec_t nt, ot;
                   3076:
                   3077:        if (tn == NULL)
                   3078:                return (NULL);
                   3079:
                   3080:        tn = cconv(tn);
                   3081:
                   3082:        nt = tp->t_tspec;
                   3083:        ot = tn->tn_type->t_tspec;
                   3084:
                   3085:        if (nt == VOID) {
                   3086:                /*
                   3087:                 * XXX ANSI C requires scalar types or void (Plauger&Brodie).
                   3088:                 * But this seams really questionable.
                   3089:                 */
                   3090:        } else if (nt == STRUCT || nt == UNION || nt == ARRAY || nt == FUNC) {
                   3091:                /* invalid cast expression */
                   3092:                error(147);
                   3093:                return (NULL);
                   3094:        } else if (ot == STRUCT || ot == UNION) {
                   3095:                /* invalid cast expression */
                   3096:                error(147);
                   3097:                return (NULL);
                   3098:        } else if (ot == VOID) {
                   3099:                /* improper cast of void expression */
                   3100:                error(148);
                   3101:                return (NULL);
                   3102:        } else if (isityp(nt) && issclt(ot)) {
                   3103:                /* ok */
                   3104:        } else if (isftyp(nt) && isatyp(ot)) {
                   3105:                /* ok */
                   3106:        } else if (nt == PTR && isityp(ot)) {
                   3107:                /* ok */
                   3108:        } else if (nt == PTR && ot == PTR) {
                   3109:                /* ok */
                   3110:        } else {
                   3111:                /* invalid cast expression */
                   3112:                error(147);
                   3113:                return (NULL);
                   3114:        }
                   3115:
                   3116:        tn = convert(CVT, 0, tp, tn);
                   3117:        tn->tn_cast = 1;
                   3118:
                   3119:        return (tn);
                   3120: }
                   3121:
                   3122: /*
                   3123:  * Create the node for a function argument.
                   3124:  * All necessary conversions and type checks are done in funccall(), because
                   3125:  * in funcarg() we have no information about expected argument types.
                   3126:  */
                   3127: tnode_t *
                   3128: funcarg(args, arg)
                   3129:        tnode_t *args, *arg;
                   3130: {
                   3131:        tnode_t *ntn;
                   3132:
                   3133:        /*
                   3134:         * If there was a serious error in the expression for the argument,
                   3135:         * create a dummy argument so the positions of the remaining arguments
                   3136:         * will not change.
                   3137:         */
                   3138:        if (arg == NULL)
                   3139:                arg = getinode(INT, (quad_t)0);
                   3140:
                   3141:        ntn = mktnode(PUSH, arg->tn_type, arg, args);
                   3142:
                   3143:        return (ntn);
                   3144: }
                   3145:
                   3146: /*
                   3147:  * Create the node for a function call. Also check types of
                   3148:  * function arguments and insert conversions, if necessary.
                   3149:  */
                   3150: tnode_t *
                   3151: funccall(func, args)
                   3152:        tnode_t *func, *args;
                   3153: {
                   3154:        tnode_t *ntn;
                   3155:        op_t    fcop;
                   3156:
                   3157:        if (func == NULL)
                   3158:                return (NULL);
                   3159:
                   3160:        if (func->tn_op == NAME && func->tn_type->t_tspec == FUNC) {
                   3161:                fcop = CALL;
                   3162:        } else {
                   3163:                fcop = ICALL;
                   3164:        }
                   3165:
                   3166:        /*
                   3167:         * after cconv() func will always be a pointer to a function
                   3168:         * if it is a valid function designator.
                   3169:         */
                   3170:        func = cconv(func);
                   3171:
                   3172:        if (func->tn_type->t_tspec != PTR ||
                   3173:            func->tn_type->t_subt->t_tspec != FUNC) {
                   3174:                /* illegal function */
                   3175:                error(149);
                   3176:                return (NULL);
                   3177:        }
                   3178:
                   3179:        args = chkfarg(func->tn_type->t_subt, args);
                   3180:
                   3181:        ntn = mktnode(fcop, func->tn_type->t_subt->t_subt, func, args);
                   3182:
                   3183:        return (ntn);
                   3184: }
                   3185:
                   3186: /*
                   3187:  * Check types of all function arguments and insert conversions,
                   3188:  * if necessary.
                   3189:  */
                   3190: static tnode_t *
                   3191: chkfarg(ftp, args)
                   3192:        type_t  *ftp;           /* type of called function */
                   3193:        tnode_t *args;          /* arguments */
                   3194: {
                   3195:        tnode_t *arg;
                   3196:        sym_t   *asym;
                   3197:        tspec_t at;
                   3198:        int     narg, npar, n, i;
                   3199:
                   3200:        /* get # of args in the prototype */
                   3201:        npar = 0;
                   3202:        for (asym = ftp->t_args; asym != NULL; asym = asym->s_nxt)
                   3203:                npar++;
                   3204:
                   3205:        /* get # of args in function call */
                   3206:        narg = 0;
                   3207:        for (arg = args; arg != NULL; arg = arg->tn_right)
                   3208:                narg++;
                   3209:
                   3210:        asym = ftp->t_args;
                   3211:        if (ftp->t_proto && npar != narg && !(ftp->t_vararg && npar < narg)) {
                   3212:                /* argument mismatch: %d arg%s passed, %d expected */
                   3213:                error(150, narg, narg > 1 ? "s" : "", npar);
                   3214:                asym = NULL;
                   3215:        }
                   3216:
                   3217:        for (n = 1; n <= narg; n++) {
                   3218:
                   3219:                /*
                   3220:                 * The rightmost argument is at the top of the argument
                   3221:                 * subtree.
                   3222:                 */
                   3223:                for (i = narg, arg = args; i > n; i--, arg = arg->tn_right) ;
                   3224:
                   3225:                /* some things which are always not allowd */
                   3226:                if ((at = arg->tn_left->tn_type->t_tspec) == VOID) {
                   3227:                        /* void expressions may not be arguments, arg #%d */
                   3228:                        error(151, n);
                   3229:                        return (NULL);
                   3230:                } else if ((at == STRUCT || at == UNION) &&
                   3231:                           incompl(arg->tn_left->tn_type)) {
                   3232:                        /* argument cannot have unknown size, arg #%d */
                   3233:                        error(152, n);
                   3234:                        return (NULL);
                   3235:                } else if (isityp(at) && arg->tn_left->tn_type->t_isenum &&
                   3236:                           incompl(arg->tn_left->tn_type)) {
                   3237:                        /* argument cannot have unknown size, arg #%d */
                   3238:                        warning(152, n);
                   3239:                }
                   3240:
                   3241:                /* class conversions (arg in value context) */
                   3242:                arg->tn_left = cconv(arg->tn_left);
                   3243:
                   3244:                if (asym != NULL) {
                   3245:                        arg->tn_left = parg(n, asym->s_type, arg->tn_left);
                   3246:                } else {
                   3247:                        arg->tn_left = promote(NOOP, 1, arg->tn_left);
                   3248:                }
                   3249:                arg->tn_type = arg->tn_left->tn_type;
                   3250:
                   3251:                if (asym != NULL)
                   3252:                        asym = asym->s_nxt;
                   3253:        }
                   3254:
                   3255:        return (args);
                   3256: }
                   3257:
                   3258: /*
                   3259:  * Compare the type of an argument with the corresponding type of a
                   3260:  * prototype parameter. If it is a valid combination, but both types
                   3261:  * are not the same, insert a conversion to convert the argument into
                   3262:  * the type of the parameter.
                   3263:  */
                   3264: static tnode_t *
                   3265: parg(n, tp, tn)
                   3266:        int     n;              /* pos of arg */
                   3267:        type_t  *tp;            /* expected type (from prototype) */
                   3268:        tnode_t *tn;            /* argument */
                   3269: {
                   3270:        tnode_t *ln;
                   3271:
                   3272:        ln = xcalloc(1, sizeof (tnode_t));
                   3273:        ln->tn_type = tduptyp(tp);
                   3274:        ln->tn_type->t_const = 0;
                   3275:        ln->tn_lvalue = 1;
                   3276:        if (typeok(FARG, n, ln, tn)) {
                   3277:                if (tp->t_tspec != tn->tn_type->t_tspec)
                   3278:                        tn = convert(FARG, n, tp, tn);
                   3279:        }
                   3280:        free(ln);
                   3281:        return (tn);
                   3282: }
                   3283:
                   3284: /*
                   3285:  * Return the value of an integral constant expression.
                   3286:  * If the expression is not constant or its type is not an integer
                   3287:  * type, an error message is printed.
                   3288:  */
                   3289: val_t *
                   3290: constant(tn)
                   3291:        tnode_t *tn;
                   3292: {
                   3293:        val_t   *v;
                   3294:
                   3295:        if (tn != NULL)
                   3296:                tn = cconv(tn);
                   3297:        if (tn != NULL)
                   3298:                tn = promote(NOOP, 0, tn);
                   3299:
                   3300:        v = xcalloc(1, sizeof (val_t));
                   3301:
                   3302:        if (tn == NULL) {
                   3303:                if (nerr == 0)
                   3304:                        lerror("constant() 1");
                   3305:                v->v_tspec = INT;
                   3306:                v->v_quad = 1;
                   3307:                return (v);
                   3308:        }
                   3309:
                   3310:        v->v_tspec = tn->tn_type->t_tspec;
                   3311:
                   3312:        if (tn->tn_op == CON) {
                   3313:                if (tn->tn_type->t_tspec != tn->tn_val->v_tspec)
                   3314:                        lerror("constant() 2");
                   3315:                if (isityp(tn->tn_val->v_tspec)) {
                   3316:                        v->v_ansiu = tn->tn_val->v_ansiu;
                   3317:                        v->v_quad = tn->tn_val->v_quad;
                   3318:                        return (v);
                   3319:                }
                   3320:                v->v_quad = tn->tn_val->v_ldbl;
                   3321:        } else {
                   3322:                v->v_quad = 1;
                   3323:        }
                   3324:
                   3325:        /* integral constant expression expected */
                   3326:        error(55);
                   3327:
                   3328:        if (!isityp(v->v_tspec))
                   3329:                v->v_tspec = INT;
                   3330:
                   3331:        return (v);
                   3332: }
                   3333:
                   3334: /*
                   3335:  * Perform some tests on expressions which can't be done in build() and
                   3336:  * functions called by build(). These tests must be done here because
                   3337:  * we need some information about the context in which the operations
                   3338:  * are performed.
                   3339:  * After all tests are performed, expr() frees the memory which is used
                   3340:  * for the expression.
                   3341:  */
                   3342: void
                   3343: expr(tn, vctx, tctx)
                   3344:        tnode_t *tn;
                   3345:        int     vctx, tctx;
                   3346: {
                   3347:        if (tn == NULL && nerr == 0)
                   3348:                lerror("expr() 1");
                   3349:
                   3350:        if (tn == NULL) {
                   3351:                tfreeblk();
                   3352:                return;
                   3353:        }
                   3354:
                   3355:        /* expr() is also called in global initialisations */
                   3356:        if (dcs->ctx != EXTERN)
                   3357:                chkreach();
                   3358:
                   3359:        chkmisc(tn, vctx, tctx, !tctx, 0, 0, 0);
                   3360:        if (tn->tn_op == ASSIGN) {
                   3361:                if (hflag && tctx)
                   3362:                        /* assignment in conditional context */
                   3363:                        warning(159);
                   3364:        } else if (tn->tn_op == CON) {
                   3365:                if (hflag && tctx && isrcline > ccline + 1)
                   3366:                        /* constant in conditional context */
                   3367:                        warning(161);
                   3368:        }
                   3369:        if (!modtab[tn->tn_op].m_sideeff) {
                   3370:                /*
                   3371:                 * for left operands of COMMA this warning is already
                   3372:                 * printed
                   3373:                 */
                   3374:                if (tn->tn_op != COMMA && !vctx && !tctx)
                   3375:                        nulleff(tn);
                   3376:        }
                   3377:        if (dflag)
                   3378:                displexpr(tn, 0);
                   3379:
                   3380:        /* free the tree memory */
                   3381:        tfreeblk();
                   3382: }
                   3383:
                   3384: static void
                   3385: nulleff(tn)
                   3386:        tnode_t *tn;
                   3387: {
                   3388:        if (tn->tn_op == CVT && tn->tn_type->t_tspec == VOID)
                   3389:                tn = tn->tn_left;
                   3390:        if (!modtab[tn->tn_op].m_sideeff) {
                   3391:                if (hflag)
                   3392:                        /* expression has null effect */
                   3393:                        warning(129);
                   3394:        }
                   3395: }
                   3396:
                   3397: /*
                   3398:  * Dump an expression to stdout
                   3399:  * only used for debugging
                   3400:  */
                   3401: static void
                   3402: displexpr(tn, offs)
                   3403:        tnode_t *tn;
                   3404:        int     offs;
                   3405: {
                   3406:        u_quad_t uq;
                   3407:
                   3408:        if (tn == NULL) {
                   3409:                (void)printf("%*s%s\n", offs, "", "NULL");
                   3410:                return;
                   3411:        }
                   3412:        (void)printf("%*sop %s  ", offs, "", modtab[tn->tn_op].m_name);
                   3413:
                   3414:        if (tn->tn_op == NAME) {
                   3415:                (void)printf("%s: %s ",
                   3416:                             tn->tn_sym->s_name, scltoa(tn->tn_sym->s_scl));
                   3417:        } else if (tn->tn_op == CON && isftyp(tn->tn_type->t_tspec)) {
                   3418:                (void)printf("%#g ", (double)tn->tn_val->v_ldbl);
                   3419:        } else if (tn->tn_op == CON && isityp(tn->tn_type->t_tspec)) {
                   3420:                uq = tn->tn_val->v_quad;
                   3421:                (void)printf("0x %08lx %08lx ", (long)(uq >> 32) & 0xffffffffl,
                   3422:                             (long)uq & 0xffffffffl);
                   3423:        } else if (tn->tn_op == CON) {
                   3424:                if (tn->tn_type->t_tspec != PTR)
                   3425:                        lerror("displexpr() 1");
                   3426:                (void)printf("0x%0*lx ", (int)(sizeof (void *) * CHAR_BIT / 4),
                   3427:                             (u_long)tn->tn_val->v_quad);
                   3428:        } else if (tn->tn_op == STRING) {
                   3429:                if (tn->tn_strg->st_tspec == CHAR) {
                   3430:                        (void)printf("\"%s\"", tn->tn_strg->st_cp);
                   3431:                } else {
                   3432:                        char    *s;
                   3433:                        size_t  n;
                   3434:                        n = MB_CUR_MAX * (tn->tn_strg->st_len + 1);
                   3435:                        s = xmalloc(n);
                   3436:                        (void)wcstombs(s, tn->tn_strg->st_wcp, n);
                   3437:                        (void)printf("L\"%s\"", s);
                   3438:                        free(s);
                   3439:                }
                   3440:                (void)printf(" ");
                   3441:        } else if (tn->tn_op == FSEL) {
                   3442:                (void)printf("o=%d, l=%d ", tn->tn_type->t_foffs,
                   3443:                             tn->tn_type->t_flen);
                   3444:        }
                   3445:        (void)printf("%s\n", ttos(tn->tn_type));
                   3446:        if (tn->tn_op == NAME || tn->tn_op == CON || tn->tn_op == STRING)
                   3447:                return;
                   3448:        displexpr(tn->tn_left, offs + 2);
                   3449:        if (modtab[tn->tn_op].m_binary ||
                   3450:            (tn->tn_op == PUSH && tn->tn_right != NULL)) {
                   3451:                displexpr(tn->tn_right, offs + 2);
                   3452:        }
                   3453: }
                   3454:
                   3455: /*
                   3456:  * Called by expr() to recursively perform some tests.
                   3457:  */
                   3458: /* ARGSUSED */
                   3459: void
                   3460: chkmisc(tn, vctx, tctx, eqwarn, fcall, rvdisc, szof)
                   3461:        tnode_t *tn;
                   3462:        int     vctx, tctx, eqwarn, fcall, rvdisc, szof;
                   3463: {
                   3464:        tnode_t *ln, *rn;
                   3465:        mod_t   *mp;
                   3466:        int     nrvdisc, cvctx, ctctx;
                   3467:        op_t    op;
                   3468:        scl_t   sc;
                   3469:
                   3470:        if (tn == NULL)
                   3471:                return;
                   3472:
                   3473:        ln = tn->tn_left;
                   3474:        rn = tn->tn_right;
                   3475:        mp = &modtab[op = tn->tn_op];
                   3476:
                   3477:        switch (op) {
                   3478:        case AMPER:
                   3479:                if (ln->tn_op == NAME && (reached || rchflg)) {
                   3480:                        if (!szof)
                   3481:                                setsflg(ln->tn_sym);
                   3482:                        setuflg(ln->tn_sym, fcall, szof);
                   3483:                }
                   3484:                if (ln->tn_op == STAR && ln->tn_left->tn_op == PLUS)
                   3485:                        /* check the range of array indices */
                   3486:                        chkaidx(ln->tn_left, 1);
                   3487:                break;
                   3488:        case LOAD:
                   3489:                if (ln->tn_op == STAR && ln->tn_left->tn_op == PLUS)
                   3490:                        /* check the range of array indices */
                   3491:                        chkaidx(ln->tn_left, 0);
                   3492:                /* FALLTHROUGH */
                   3493:        case PUSH:
                   3494:        case INCBEF:
                   3495:        case DECBEF:
                   3496:        case INCAFT:
                   3497:        case DECAFT:
                   3498:        case ADDASS:
                   3499:        case SUBASS:
                   3500:        case MULASS:
                   3501:        case DIVASS:
                   3502:        case MODASS:
                   3503:        case ANDASS:
                   3504:        case ORASS:
                   3505:        case XORASS:
                   3506:        case SHLASS:
                   3507:        case SHRASS:
                   3508:                if (ln->tn_op == NAME && (reached || rchflg)) {
                   3509:                        sc = ln->tn_sym->s_scl;
                   3510:                        if (sc != EXTERN && sc != STATIC &&
                   3511:                            !ln->tn_sym->s_set && !szof) {
                   3512:                                /* %s may be used before set */
                   3513:                                warning(158, ln->tn_sym->s_name);
                   3514:                                setsflg(ln->tn_sym);
                   3515:                        }
                   3516:                        setuflg(ln->tn_sym, 0, 0);
                   3517:                }
                   3518:                break;
                   3519:        case ASSIGN:
                   3520:                if (ln->tn_op == NAME && !szof && (reached || rchflg)) {
                   3521:                        setsflg(ln->tn_sym);
                   3522:                        if (ln->tn_sym->s_scl == EXTERN)
                   3523:                                outusg(ln->tn_sym);
                   3524:                }
                   3525:                if (ln->tn_op == STAR && ln->tn_left->tn_op == PLUS)
                   3526:                        /* check the range of array indices */
                   3527:                        chkaidx(ln->tn_left, 0);
                   3528:                break;
                   3529:        case CALL:
                   3530:                if (ln->tn_op != AMPER || ln->tn_left->tn_op != NAME)
                   3531:                        lerror("chkmisc() 1");
                   3532:                if (!szof)
                   3533:                        outcall(tn, vctx || tctx, rvdisc);
                   3534:                break;
                   3535:        case EQ:
                   3536:                /* equality operator "==" found where "=" was exp. */
                   3537:                if (hflag && eqwarn)
                   3538:                        warning(160);
                   3539:                break;
                   3540:        case CON:
                   3541:        case NAME:
                   3542:        case STRING:
                   3543:                return;
                   3544:                /* LINTED (enumeration values not handled in switch) */
                   3545:        }
                   3546:
                   3547:        cvctx = mp->m_vctx;
                   3548:        ctctx = mp->m_tctx;
                   3549:        /*
                   3550:         * values of operands of ':' are not used if the type of at least
                   3551:         * one of the operands (for gcc compatibility) is void
                   3552:         * XXX test/value context of QUEST should probably be used as
                   3553:         * context for both operands of COLON
                   3554:         */
                   3555:        if (op == COLON && tn->tn_type->t_tspec == VOID)
                   3556:                cvctx = ctctx = 0;
                   3557:        nrvdisc = op == CVT && tn->tn_type->t_tspec == VOID;
                   3558:        chkmisc(ln, cvctx, ctctx, mp->m_eqwarn, op == CALL, nrvdisc, szof);
                   3559:
                   3560:        switch (op) {
                   3561:        case PUSH:
                   3562:                if (rn != NULL)
                   3563:                        chkmisc(rn, 0, 0, mp->m_eqwarn, 0, 0, szof);
                   3564:                break;
                   3565:        case LOGAND:
                   3566:        case LOGOR:
                   3567:                chkmisc(rn, 0, 1, mp->m_eqwarn, 0, 0, szof);
                   3568:                break;
                   3569:        case COLON:
                   3570:                chkmisc(rn, cvctx, ctctx, mp->m_eqwarn, 0, 0, szof);
                   3571:                break;
                   3572:        default:
                   3573:                if (mp->m_binary)
                   3574:                        chkmisc(rn, 1, 0, mp->m_eqwarn, 0, 0, szof);
                   3575:                break;
                   3576:        }
                   3577:
                   3578: }
                   3579:
                   3580: /*
                   3581:  * Checks the range of array indices, if possible.
                   3582:  * amper is set if only the address of the element is used. This
                   3583:  * means that the index is allowd to refere to the first element
                   3584:  * after the array.
                   3585:  */
                   3586: static void
                   3587: chkaidx(tn, amper)
                   3588:        tnode_t *tn;
                   3589:        int     amper;
                   3590: {
                   3591:        int     dim;
                   3592:        tnode_t *ln, *rn;
                   3593:        int     elsz;
                   3594:        quad_t  con;
                   3595:
                   3596:        ln = tn->tn_left;
                   3597:        rn = tn->tn_right;
                   3598:
                   3599:        /* We can only check constant indices. */
                   3600:        if (rn->tn_op != CON)
                   3601:                return;
                   3602:
                   3603:        /* Return if the left node does not stem from an array. */
                   3604:        if (ln->tn_op != AMPER)
                   3605:                return;
                   3606:        if (ln->tn_left->tn_op != STRING && ln->tn_left->tn_op != NAME)
                   3607:                return;
                   3608:        if (ln->tn_left->tn_type->t_tspec != ARRAY)
                   3609:                return;
                   3610:
                   3611:        /*
                   3612:         * For incomplete array types, we can print a warning only if
                   3613:         * the index is negative.
                   3614:         */
                   3615:        if (incompl(ln->tn_left->tn_type) && rn->tn_val->v_quad >= 0)
                   3616:                return;
                   3617:
                   3618:        /* Get the size of one array element */
                   3619:        if ((elsz = length(ln->tn_type->t_subt, NULL)) == 0)
                   3620:                return;
                   3621:        elsz /= CHAR_BIT;
                   3622:
                   3623:        /* Change the unit of the index from bytes to element size. */
                   3624:        if (isutyp(rn->tn_type->t_tspec)) {
                   3625:                con = (u_quad_t)rn->tn_val->v_quad / elsz;
                   3626:        } else {
                   3627:                con = rn->tn_val->v_quad / elsz;
                   3628:        }
                   3629:
                   3630:        dim = ln->tn_left->tn_type->t_dim + (amper ? 1 : 0);
                   3631:
                   3632:        if (!isutyp(rn->tn_type->t_tspec) && con < 0) {
                   3633:                /* array subscript cannot be negative: %ld */
                   3634:                warning(167, (long)con);
                   3635:        } else if (dim > 0 && (u_quad_t)con >= dim) {
                   3636:                /* array subscript cannot be > %d: %ld */
                   3637:                warning(168, dim - 1, (long)con);
                   3638:        }
                   3639: }
                   3640:
                   3641: /*
                   3642:  * Check for ordered comparisions of unsigned values with 0.
                   3643:  */
                   3644: static void
                   3645: chkcomp(op, ln, rn)
                   3646:        op_t    op;
                   3647:        tnode_t *ln, *rn;
                   3648: {
                   3649:        tspec_t lt, rt;
                   3650:        mod_t   *mp;
                   3651:
                   3652:        lt = ln->tn_type->t_tspec;
                   3653:        rt = rn->tn_type->t_tspec;
                   3654:        mp = &modtab[op];
                   3655:
                   3656:        if (ln->tn_op != CON && rn->tn_op != CON)
                   3657:                return;
                   3658:
                   3659:        if (!isityp(lt) || !isityp(rt))
                   3660:                return;
                   3661:
                   3662:        if ((hflag || pflag) && lt == CHAR && rn->tn_op == CON &&
                   3663:            (rn->tn_val->v_quad < 0 ||
                   3664:             rn->tn_val->v_quad > ~(~0 << (CHAR_BIT - 1)))) {
                   3665:                /* nonportable character comparision, op %s */
                   3666:                warning(230, mp->m_name);
                   3667:                return;
                   3668:        }
                   3669:        if ((hflag || pflag) && rt == CHAR && ln->tn_op == CON &&
                   3670:            (ln->tn_val->v_quad < 0 ||
                   3671:             ln->tn_val->v_quad > ~(~0 << (CHAR_BIT - 1)))) {
                   3672:                /* nonportable character comparision, op %s */
                   3673:                warning(230, mp->m_name);
                   3674:                return;
                   3675:        }
                   3676:        if (isutyp(lt) && !isutyp(rt) &&
                   3677:            rn->tn_op == CON && rn->tn_val->v_quad <= 0) {
                   3678:                if (rn->tn_val->v_quad < 0) {
                   3679:                        /* comparision of %s with %s, op %s */
                   3680:                        warning(162, tyname(ln->tn_type), "negative constant",
                   3681:                                mp->m_name);
                   3682:                } else if (op == LT || op == GE || (hflag && op == LE)) {
                   3683:                        /* comparision of %s with %s, op %s */
                   3684:                        warning(162, tyname(ln->tn_type), "0", mp->m_name);
                   3685:                }
                   3686:                return;
                   3687:        }
                   3688:        if (isutyp(rt) && !isutyp(lt) &&
                   3689:            ln->tn_op == CON && ln->tn_val->v_quad <= 0) {
                   3690:                if (ln->tn_val->v_quad < 0) {
                   3691:                        /* comparision of %s with %s, op %s */
                   3692:                        warning(162, "negative constant", tyname(rn->tn_type),
                   3693:                                mp->m_name);
                   3694:                } else if (op == GT || op == LE || (hflag && op == GE)) {
                   3695:                        /* comparision of %s with %s, op %s */
                   3696:                        warning(162, "0", tyname(rn->tn_type), mp->m_name);
                   3697:                }
                   3698:                return;
                   3699:        }
                   3700: }
                   3701:
                   3702: /*
                   3703:  * Takes an expression an returns 0 if this expression can be used
                   3704:  * for static initialisation, otherwise -1.
                   3705:  *
                   3706:  * Constant initialisation expressions must be costant or an address
                   3707:  * of a static object with an optional offset. In the first case,
                   3708:  * the result is returned in *offsp. In the second case, the static
                   3709:  * object is returned in *symp and the offset in *offsp.
                   3710:  *
                   3711:  * The expression can consist of PLUS, MINUS, AMPER, NAME, STRING and
                   3712:  * CON. Type conversions are allowed if they do not change binary
                   3713:  * representation (including width).
                   3714:  */
                   3715: int
                   3716: conaddr(tn, symp, offsp)
                   3717:        tnode_t *tn;
                   3718:        sym_t   **symp;
                   3719:        ptrdiff_t *offsp;
                   3720: {
                   3721:        sym_t   *sym;
                   3722:        ptrdiff_t offs1, offs2;
                   3723:        tspec_t t, ot;
                   3724:
                   3725:        switch (tn->tn_op) {
                   3726:        case MINUS:
                   3727:                if (tn->tn_right->tn_op != CON)
                   3728:                        return (-1);
                   3729:                /* FALLTHROUGH */
                   3730:        case PLUS:
                   3731:                offs1 = offs2 = 0;
                   3732:                if (tn->tn_left->tn_op == CON) {
                   3733:                        offs1 = (ptrdiff_t)tn->tn_left->tn_val->v_quad;
                   3734:                        if (conaddr(tn->tn_right, &sym, &offs2) == -1)
                   3735:                                return (-1);
                   3736:                } else if (tn->tn_right->tn_op == CON) {
                   3737:                        offs2 = (ptrdiff_t)tn->tn_right->tn_val->v_quad;
                   3738:                        if (tn->tn_op == MINUS)
                   3739:                                offs2 = -offs2;
                   3740:                        if (conaddr(tn->tn_left, &sym, &offs1) == -1)
                   3741:                                return (-1);
                   3742:                } else {
                   3743:                        return (-1);
                   3744:                }
                   3745:                *symp = sym;
                   3746:                *offsp = offs1 + offs2;
                   3747:                break;
                   3748:        case AMPER:
                   3749:                if (tn->tn_left->tn_op == NAME) {
                   3750:                        *symp = tn->tn_left->tn_sym;
                   3751:                        *offsp = 0;
                   3752:                } else if (tn->tn_left->tn_op == STRING) {
                   3753:                        /*
                   3754:                         * If this would be the front end of a compiler we
                   3755:                         * would return a label instead of 0.
                   3756:                         */
                   3757:                        *offsp = 0;
                   3758:                }
                   3759:                break;
                   3760:        case CVT:
                   3761:                t = tn->tn_type->t_tspec;
                   3762:                ot = tn->tn_left->tn_type->t_tspec;
                   3763:                if ((!isityp(t) && t != PTR) || (!isityp(ot) && ot != PTR)) {
                   3764:                        return (-1);
                   3765:                } else if (psize(t) != psize(ot)) {
                   3766:                        return (-1);
                   3767:                }
                   3768:                if (conaddr(tn->tn_left, symp, offsp) == -1)
                   3769:                        return (-1);
                   3770:                break;
                   3771:        default:
                   3772:                return (-1);
                   3773:        }
                   3774:        return (0);
                   3775: }
                   3776:
                   3777: /*
                   3778:  * Concatenate two string constants.
                   3779:  */
                   3780: strg_t *
                   3781: catstrg(strg1, strg2)
                   3782:        strg_t  *strg1, *strg2;
                   3783: {
                   3784:        size_t  len1, len2, len;
                   3785:
                   3786:        if (strg1->st_tspec != strg2->st_tspec) {
                   3787:                /* cannot concatenate wide and regular string literals */
                   3788:                error(292);
                   3789:                return (strg1);
                   3790:        }
                   3791:
                   3792:        len = (len1 = strg1->st_len) + (len2 = strg2->st_len);
                   3793:
                   3794:        if (strg1->st_tspec == CHAR) {
                   3795:                strg1->st_cp = xrealloc(strg1->st_cp, len + 1);
                   3796:                (void)memcpy(strg1->st_cp + len1, strg2->st_cp, len2 + 1);
                   3797:                free(strg2->st_cp);
                   3798:        } else {
                   3799:                strg1->st_wcp = xrealloc(strg1->st_wcp,
                   3800:                                         (len + 1) * sizeof (wchar_t));
                   3801:                (void)memcpy(strg1->st_wcp + len1, strg2->st_wcp,
                   3802:                             (len2 + 1) * sizeof (wchar_t));
                   3803:                free(strg2->st_wcp);
                   3804:        }
                   3805:        free(strg2);
                   3806:
                   3807:        return (strg1);
                   3808: }
                   3809:
                   3810: /*
                   3811:  * Print a warning if the given node has operands which should be
                   3812:  * parenthesized.
                   3813:  *
                   3814:  * XXX Does not work if an operand is a constant expression. Constant
                   3815:  * expressions are already folded.
                   3816:  */
                   3817: static void
                   3818: precconf(tn)
                   3819:        tnode_t *tn;
                   3820: {
                   3821:        tnode_t *ln, *rn;
                   3822:        op_t    lop, rop;
                   3823:        int     lparn, rparn;
                   3824:        mod_t   *mp;
                   3825:        int     warn;
                   3826:
                   3827:        if (!hflag)
                   3828:                return;
                   3829:
                   3830:        mp = &modtab[tn->tn_op];
                   3831:
                   3832:        lparn = 0;
                   3833:        for (ln = tn->tn_left; ln->tn_op == CVT; ln = ln->tn_left)
                   3834:                lparn |= ln->tn_parn;
                   3835:        lparn |= ln->tn_parn;
                   3836:        lop = ln->tn_op;
                   3837:
                   3838:        if (mp->m_binary) {
                   3839:                rparn = 0;
                   3840:                for (rn = tn->tn_right; tn->tn_op == CVT; rn = rn->tn_left)
                   3841:                        rparn |= rn->tn_parn;
                   3842:                rparn |= rn->tn_parn;
                   3843:                rop = rn->tn_op;
                   3844:        }
                   3845:
                   3846:        warn = 0;
                   3847:
                   3848:        switch (tn->tn_op) {
                   3849:        case SHL:
                   3850:        case SHR:
                   3851:                if (!lparn && (lop == PLUS || lop == MINUS)) {
                   3852:                        warn = 1;
                   3853:                } else if (!rparn && (rop == PLUS || rop == MINUS)) {
                   3854:                        warn = 1;
                   3855:                }
                   3856:                break;
                   3857:        case LOGOR:
                   3858:                if (!lparn && lop == LOGAND) {
                   3859:                        warn = 1;
                   3860:                } else if (!rparn && rop == LOGAND) {
                   3861:                        warn = 1;
                   3862:                }
                   3863:                break;
                   3864:        case AND:
                   3865:        case XOR:
                   3866:        case OR:
                   3867:                if (!lparn && lop != tn->tn_op) {
                   3868:                        if (lop == PLUS || lop == MINUS) {
                   3869:                                warn = 1;
                   3870:                        } else if (lop == AND || lop == XOR) {
                   3871:                                warn = 1;
                   3872:                        }
                   3873:                }
                   3874:                if (!warn && !rparn && rop != tn->tn_op) {
                   3875:                        if (rop == PLUS || rop == MINUS) {
                   3876:                                warn = 1;
                   3877:                        } else if (rop == AND || rop == XOR) {
                   3878:                                warn = 1;
                   3879:                        }
                   3880:                }
                   3881:                break;
                   3882:                /* LINTED (enumeration values not handled in switch) */
                   3883:        }
                   3884:
                   3885:        if (warn) {
                   3886:                /* precedence confusion possible: parenthesize! */
                   3887:                warning(169);
                   3888:        }
                   3889:
                   3890: }

CVSweb <webmaster@jp.NetBSD.org>