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

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

CVSweb <webmaster@jp.NetBSD.org>