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

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

CVSweb <webmaster@jp.NetBSD.org>