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