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

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

CVSweb <webmaster@jp.NetBSD.org>