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