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

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

CVSweb <webmaster@jp.NetBSD.org>