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