[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.84.10.2

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

CVSweb <webmaster@jp.NetBSD.org>