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