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

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

CVSweb <webmaster@jp.NetBSD.org>