tree.c revision 1.4 1 /* $NetBSD: tree.c,v 1.4 1995/10/02 17:08:47 jpo Exp $ */
2
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
35 static char rcsid[] = "$NetBSD: tree.c,v 1.4 1995/10/02 17:08:47 jpo Exp $";
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
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
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:
2795 #ifdef XXX_BROKEN_GCC
2796 q = utyp ? u_quad_t_eq(ul, ur) : quad_t_eq(sl, sr);
2797 #else
2798 q = utyp ? ul == ur : sl == sr;
2799 #endif
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
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
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)) {
2858 #ifdef XXX_BROKEN_GCC
2859 l = ldbl_t_neq(tn->tn_left->tn_val->v_ldbl, 0.0);
2860 #else
2861 l = tn->tn_left->tn_val->v_ldbl != 0.0;
2862 #endif
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)) {
2869 #ifdef XXX_BROKEN_GCC
2870 r = ldbl_t_neq(tn->tn_right->tn_val->v_ldbl, 0.0);
2871 #else
2872 r = tn->tn_right->tn_val->v_ldbl != 0.0;
2873 #endif
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->d_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 }
3891