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