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