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