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

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

CVSweb <webmaster@jp.NetBSD.org>