tree.c revision 1.2 1 /* $NetBSD: tree.c,v 1.2 1995/07/03 21:24:33 cgd 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.2 1995/07/03 21:24:33 cgd 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 /*
2675 * Do only as much as necessary to compute constant expressions.
2676 * Called only if the operator allows folding and (both) operands
2677 * are constants.
2678 */
2679 static tnode_t *
2680 fold(tn)
2681 tnode_t *tn;
2682 {
2683 val_t *v;
2684 tspec_t t;
2685 int utyp, ovfl;
2686 quad_t sl, sr, q, mask;
2687 u_quad_t ul, ur;
2688 tnode_t *cn;
2689
2690 v = xcalloc(1, sizeof (val_t));
2691 v->v_tspec = t = tn->tn_type->t_tspec;
2692
2693 utyp = t == PTR || isutyp(t);
2694 ul = sl = tn->tn_left->tn_val->v_quad;
2695 if (modtab[tn->tn_op].m_binary)
2696 ur = sr = tn->tn_right->tn_val->v_quad;
2697
2698 ovfl = 0;
2699
2700 switch (tn->tn_op) {
2701 case UPLUS:
2702 q = sl;
2703 break;
2704 case UMINUS:
2705 q = -sl;
2706 if (msb(q, t, -1) == msb(sl, t, -1))
2707 ovfl = 1;
2708 break;
2709 case COMPL:
2710 q = ~sl;
2711 break;
2712 case MULT:
2713 q = utyp ? ul * ur : sl * sr;
2714 if (msb(q, t, -1) != (msb(sl, t, -1) ^ msb(sr, t, -1)))
2715 ovfl = 1;
2716 break;
2717 case DIV:
2718 if (sr == 0) {
2719 /* division by 0 */
2720 error(139);
2721 q = utyp ? UQUAD_MAX : QUAD_MAX;
2722 } else {
2723 q = utyp ? ul / ur : sl / sr;
2724 }
2725 break;
2726 case MOD:
2727 if (sr == 0) {
2728 /* modulus by 0 */
2729 error(140);
2730 q = 0;
2731 } else {
2732 q = utyp ? ul % ur : sl % sr;
2733 }
2734 break;
2735 case PLUS:
2736 q = utyp ? ul + ur : sl + sr;
2737 if (msb(sl, t, -1) != 0 && msb(sr, t, -1) != 0) {
2738 if (msb(q, t, -1) == 0)
2739 ovfl = 1;
2740 } else if (msb(sl, t, -1) == 0 && msb(sr, t, -1) == 0) {
2741 if (msb(q, t, -1) != 0)
2742 ovfl = 1;
2743 }
2744 break;
2745 case MINUS:
2746 q = utyp ? ul - ur : sl - sr;
2747 if (msb(sl, t, -1) != 0 && msb(sr, t, -1) == 0) {
2748 if (msb(q, t, -1) == 0)
2749 ovfl = 1;
2750 } else if (msb(sl, t, -1) == 0 && msb(sr, t, -1) != 0) {
2751 if (msb(q, t, -1) != 0)
2752 ovfl = 1;
2753 }
2754 break;
2755 case SHL:
2756 q = utyp ? ul << sr : sl << sr;
2757 break;
2758 case SHR:
2759 /*
2760 * The sign must be explizitly extended because
2761 * shifts of signed values are implementation dependent.
2762 */
2763 q = ul >> sr;
2764 q = xsign(q, t, size(t) - (int)sr);
2765 break;
2766 case LT:
2767 q = utyp ? ul < ur : sl < sr;
2768 break;
2769 case LE:
2770 q = utyp ? ul <= ur : sl <= sr;
2771 break;
2772 case GE:
2773 q = utyp ? ul >= ur : sl >= sr;
2774 break;
2775 case GT:
2776 q = utyp ? ul > ur : sl > sr;
2777 break;
2778 case EQ:
2779 q = utyp ? ul == ur : sl == sr;
2780 break;
2781 case NE:
2782 q = utyp ? ul != ur : sl != sr;
2783 break;
2784 case AND:
2785 q = utyp ? ul & ur : sl & sr;
2786 break;
2787 case XOR:
2788 q = utyp ? ul ^ ur : sl ^ sr;
2789 break;
2790 case OR:
2791 q = utyp ? ul | ur : sl | sr;
2792 break;
2793 default:
2794 lerror("fold() 5");
2795 }
2796
2797 mask = qlmasks[size(t)];
2798
2799 /* XXX does not work for quads. */
2800 if (ovfl || ((q | mask) != ~(u_quad_t)0 && (q & ~mask) != 0)) {
2801 if (hflag)
2802 /* integer overflow detected, op %s */
2803 warning(141, modtab[tn->tn_op].m_name);
2804 }
2805
2806 v->v_quad = xsign(q, t, -1);
2807
2808 cn = getcnode(tn->tn_type, v);
2809
2810 return (cn);
2811 }
2812
2813 /*
2814 * Same for operators whose operands are compared with 0 (test context).
2815 */
2816 static tnode_t *
2817 foldtst(tn)
2818 tnode_t *tn;
2819 {
2820 int l, r;
2821 val_t *v;
2822
2823 v = xcalloc(1, sizeof (val_t));
2824 v->v_tspec = tn->tn_type->t_tspec;
2825 if (tn->tn_type->t_tspec != INT)
2826 lerror("foldtst() 1");
2827
2828 if (isftyp(tn->tn_left->tn_type->t_tspec)) {
2829 l = tn->tn_left->tn_val->v_ldbl != 0.0;
2830 } else {
2831 l = tn->tn_left->tn_val->v_quad != 0;
2832 }
2833
2834 if (modtab[tn->tn_op].m_binary) {
2835 if (isftyp(tn->tn_right->tn_type->t_tspec)) {
2836 r = tn->tn_right->tn_val->v_ldbl != 0.0;
2837 } else {
2838 r = tn->tn_right->tn_val->v_quad != 0;
2839 }
2840 }
2841
2842 switch (tn->tn_op) {
2843 case NOT:
2844 if (hflag)
2845 /* constant argument to NOT */
2846 warning(239);
2847 v->v_quad = !l;
2848 break;
2849 case LOGAND:
2850 v->v_quad = l && r;
2851 break;
2852 case LOGOR:
2853 v->v_quad = l || r;
2854 break;
2855 default:
2856 lerror("foldtst() 1");
2857 }
2858
2859 return (getcnode(tn->tn_type, v));
2860 }
2861
2862 /*
2863 * Same for operands with floating point type.
2864 */
2865 static tnode_t *
2866 foldflt(tn)
2867 tnode_t *tn;
2868 {
2869 val_t *v;
2870 tspec_t t;
2871 ldbl_t l, r;
2872
2873 v = xcalloc(1, sizeof (val_t));
2874 v->v_tspec = t = tn->tn_type->t_tspec;
2875
2876 if (!isftyp(t))
2877 lerror("foldflt() 1");
2878
2879 if (t != tn->tn_left->tn_type->t_tspec)
2880 lerror("foldflt() 2");
2881 if (modtab[tn->tn_op].m_binary && t != tn->tn_right->tn_type->t_tspec)
2882 lerror("foldflt() 3");
2883
2884 l = tn->tn_left->tn_val->v_ldbl;
2885 if (modtab[tn->tn_op].m_binary)
2886 r = tn->tn_right->tn_val->v_ldbl;
2887
2888 switch (tn->tn_op) {
2889 case UPLUS:
2890 v->v_ldbl = l;
2891 break;
2892 case UMINUS:
2893 v->v_ldbl = -l;
2894 break;
2895 case MULT:
2896 v->v_ldbl = l * r;
2897 break;
2898 case DIV:
2899 if (r == 0.0) {
2900 /* division by 0 */
2901 error(139);
2902 if (t == FLOAT) {
2903 v->v_ldbl = l < 0 ? -FLT_MAX : FLT_MAX;
2904 } else if (t == DOUBLE) {
2905 v->v_ldbl = l < 0 ? -DBL_MAX : DBL_MAX;
2906 } else {
2907 v->v_ldbl = l < 0 ? -LDBL_MAX : LDBL_MAX;
2908 }
2909 } else {
2910 v->v_ldbl = l / r;
2911 }
2912 break;
2913 case PLUS:
2914 v->v_ldbl = l + r;
2915 break;
2916 case MINUS:
2917 v->v_ldbl = l - r;
2918 break;
2919 case LT:
2920 v->v_quad = l < r;
2921 break;
2922 case LE:
2923 v->v_quad = l <= r;
2924 break;
2925 case GE:
2926 v->v_quad = l >= r;
2927 break;
2928 case GT:
2929 v->v_quad = l > r;
2930 break;
2931 case EQ:
2932 v->v_quad = l == r;
2933 break;
2934 case NE:
2935 v->v_quad = l != r;
2936 break;
2937 default:
2938 lerror("foldflt() 4");
2939 }
2940
2941 if (isnan((double)v->v_ldbl))
2942 lerror("foldflt() 5");
2943 if (isinf((double)v->v_ldbl) ||
2944 (t == FLOAT &&
2945 (v->v_ldbl > FLT_MAX || v->v_ldbl < -FLT_MAX)) ||
2946 (t == DOUBLE &&
2947 (v->v_ldbl > DBL_MAX || v->v_ldbl < -DBL_MAX))) {
2948 /* floating point overflow detected, op %s */
2949 warning(142, modtab[tn->tn_op].m_name);
2950 if (t == FLOAT) {
2951 v->v_ldbl = v->v_ldbl < 0 ? -FLT_MAX : FLT_MAX;
2952 } else if (t == DOUBLE) {
2953 v->v_ldbl = v->v_ldbl < 0 ? -DBL_MAX : DBL_MAX;
2954 } else {
2955 v->v_ldbl = v->v_ldbl < 0 ? -LDBL_MAX: LDBL_MAX;
2956 }
2957 }
2958
2959 return (getcnode(tn->tn_type, v));
2960 }
2961
2962 /*
2963 * Create a constant node for sizeof.
2964 */
2965 tnode_t *
2966 bldszof(tp)
2967 type_t *tp;
2968 {
2969 int elem, elsz;
2970 tspec_t st;
2971
2972 elem = 1;
2973 while (tp->t_tspec == ARRAY) {
2974 elem *= tp->t_dim;
2975 tp = tp->t_subt;
2976 }
2977 if (elem == 0) {
2978 /* cannot take size of incomplete type */
2979 error(143);
2980 elem = 1;
2981 }
2982 switch (tp->t_tspec) {
2983 case FUNC:
2984 /* cannot take size of function */
2985 error(144);
2986 elsz = 1;
2987 break;
2988 case STRUCT:
2989 case UNION:
2990 if (incompl(tp)) {
2991 /* cannot take size of incomplete type */
2992 error(143);
2993 elsz = 1;
2994 } else {
2995 elsz = tp->t_str->size;
2996 }
2997 break;
2998 case ENUM:
2999 if (incompl(tp)) {
3000 /* cannot take size of incomplete type */
3001 warning(143);
3002 }
3003 /* FALLTHROUGH */
3004 default:
3005 if (tp->t_isfield) {
3006 /* cannot take size of bit-field */
3007 error(145);
3008 }
3009 if (tp->t_tspec == VOID) {
3010 /* cannot take size of void */
3011 error(146);
3012 elsz = 1;
3013 } else {
3014 elsz = size(tp->t_tspec);
3015 if (elsz <= 0)
3016 lerror("bldszof() 1");
3017 }
3018 break;
3019 }
3020
3021 #if SIZEOF_IS_ULONG
3022 st = ULONG;
3023 #else
3024 st = UINT;
3025 #endif
3026
3027 return (getinode(st, (quad_t)(elem * elsz / CHAR_BIT)));
3028 }
3029
3030 /*
3031 * Type casts.
3032 */
3033 tnode_t *
3034 cast(tn, tp)
3035 tnode_t *tn;
3036 type_t *tp;
3037 {
3038 tspec_t nt, ot;
3039
3040 if (tn == NULL)
3041 return (NULL);
3042
3043 tn = cconv(tn);
3044
3045 nt = tp->t_tspec;
3046 ot = tn->tn_type->t_tspec;
3047
3048 if (nt == VOID) {
3049 /*
3050 * XXX ANSI C requires scalar types or void (Plauger&Brodie).
3051 * But this seams really questionable.
3052 */
3053 } else if (nt == STRUCT || nt == UNION || nt == ARRAY || nt == FUNC) {
3054 /* invalid cast expression */
3055 error(147);
3056 return (NULL);
3057 } else if (ot == STRUCT || ot == UNION) {
3058 /* invalid cast expression */
3059 error(147);
3060 return (NULL);
3061 } else if (ot == VOID) {
3062 /* improper cast of void expression */
3063 error(148);
3064 return (NULL);
3065 } else if (isityp(nt) && issclt(ot)) {
3066 /* ok */
3067 } else if (isftyp(nt) && isatyp(ot)) {
3068 /* ok */
3069 } else if (nt == PTR && isityp(ot)) {
3070 /* ok */
3071 } else if (nt == PTR && ot == PTR) {
3072 /* ok */
3073 } else {
3074 /* invalid cast expression */
3075 error(147);
3076 return (NULL);
3077 }
3078
3079 tn = convert(CVT, 0, tp, tn);
3080 tn->tn_cast = 1;
3081
3082 return (tn);
3083 }
3084
3085 /*
3086 * Create the node for a function argument.
3087 * All necessary conversions and type checks are done in funccall(), because
3088 * in funcarg() we have no information about expected argument types.
3089 */
3090 tnode_t *
3091 funcarg(args, arg)
3092 tnode_t *args, *arg;
3093 {
3094 tnode_t *ntn;
3095
3096 /*
3097 * If there was a serious error in the expression for the argument,
3098 * create a dummy argument so the positions of the remaining arguments
3099 * will not change.
3100 */
3101 if (arg == NULL)
3102 arg = getinode(INT, (quad_t)0);
3103
3104 ntn = mktnode(PUSH, arg->tn_type, arg, args);
3105
3106 return (ntn);
3107 }
3108
3109 /*
3110 * Create the node for a function call. Also check types of
3111 * function arguments and insert conversions, if necessary.
3112 */
3113 tnode_t *
3114 funccall(func, args)
3115 tnode_t *func, *args;
3116 {
3117 tnode_t *ntn;
3118 op_t fcop;
3119
3120 if (func == NULL)
3121 return (NULL);
3122
3123 if (func->tn_op == NAME && func->tn_type->t_tspec == FUNC) {
3124 fcop = CALL;
3125 } else {
3126 fcop = ICALL;
3127 }
3128
3129 /*
3130 * after cconv() func will always be a pointer to a function
3131 * if it is a valid function designator.
3132 */
3133 func = cconv(func);
3134
3135 if (func->tn_type->t_tspec != PTR ||
3136 func->tn_type->t_subt->t_tspec != FUNC) {
3137 /* illegal function */
3138 error(149);
3139 return (NULL);
3140 }
3141
3142 args = chkfarg(func->tn_type->t_subt, args);
3143
3144 ntn = mktnode(fcop, func->tn_type->t_subt->t_subt, func, args);
3145
3146 return (ntn);
3147 }
3148
3149 /*
3150 * Check types of all function arguments and insert conversions,
3151 * if necessary.
3152 */
3153 static tnode_t *
3154 chkfarg(ftp, args)
3155 type_t *ftp; /* type of called function */
3156 tnode_t *args; /* arguments */
3157 {
3158 tnode_t *arg;
3159 sym_t *asym;
3160 tspec_t at;
3161 int narg, npar, n, i;
3162
3163 /* get # of args in the prototype */
3164 npar = 0;
3165 for (asym = ftp->t_args; asym != NULL; asym = asym->s_nxt)
3166 npar++;
3167
3168 /* get # of args in function call */
3169 narg = 0;
3170 for (arg = args; arg != NULL; arg = arg->tn_right)
3171 narg++;
3172
3173 asym = ftp->t_args;
3174 if (ftp->t_proto && npar != narg && !(ftp->t_vararg && npar < narg)) {
3175 /* argument mismatch: %d arg%s passed, %d expected */
3176 error(150, narg, narg > 1 ? "s" : "", npar);
3177 asym = NULL;
3178 }
3179
3180 for (n = 1; n <= narg; n++) {
3181
3182 /*
3183 * The rightmost argument is at the top of the argument
3184 * subtree.
3185 */
3186 for (i = narg, arg = args; i > n; i--, arg = arg->tn_right) ;
3187
3188 /* some things which are always not allowd */
3189 if ((at = arg->tn_left->tn_type->t_tspec) == VOID) {
3190 /* void expressions may not be arguments, arg #%d */
3191 error(151, n);
3192 return (NULL);
3193 } else if ((at == STRUCT || at == UNION) &&
3194 incompl(arg->tn_left->tn_type)) {
3195 /* argument cannot have unknown size, arg #%d */
3196 error(152, n);
3197 return (NULL);
3198 } else if (isityp(at) && arg->tn_left->tn_type->t_isenum &&
3199 incompl(arg->tn_left->tn_type)) {
3200 /* argument cannot have unknown size, arg #%d */
3201 warning(152, n);
3202 }
3203
3204 /* class conversions (arg in value context) */
3205 arg->tn_left = cconv(arg->tn_left);
3206
3207 if (asym != NULL) {
3208 arg->tn_left = parg(n, asym->s_type, arg->tn_left);
3209 } else {
3210 arg->tn_left = promote(NOOP, 1, arg->tn_left);
3211 }
3212 arg->tn_type = arg->tn_left->tn_type;
3213
3214 if (asym != NULL)
3215 asym = asym->s_nxt;
3216 }
3217
3218 return (args);
3219 }
3220
3221 /*
3222 * Compare the type of an argument with the corresponding type of a
3223 * prototype parameter. If it is a valid combination, but both types
3224 * are not the same, insert a conversion to convert the argument into
3225 * the type of the parameter.
3226 */
3227 static tnode_t *
3228 parg(n, tp, tn)
3229 int n; /* pos of arg */
3230 type_t *tp; /* expected type (from prototype) */
3231 tnode_t *tn; /* argument */
3232 {
3233 tnode_t *ln;
3234
3235 ln = xcalloc(1, sizeof (tnode_t));
3236 ln->tn_type = tduptyp(tp);
3237 ln->tn_type->t_const = 0;
3238 ln->tn_lvalue = 1;
3239 if (typeok(FARG, n, ln, tn)) {
3240 if (tp->t_tspec != tn->tn_type->t_tspec)
3241 tn = convert(FARG, n, tp, tn);
3242 }
3243 free(ln);
3244 return (tn);
3245 }
3246
3247 /*
3248 * Return the value of an integral constant expression.
3249 * If the expression is not constant or its type is not an integer
3250 * type, an error message is printed.
3251 */
3252 val_t *
3253 constant(tn)
3254 tnode_t *tn;
3255 {
3256 val_t *v;
3257
3258 if (tn != NULL)
3259 tn = cconv(tn);
3260 if (tn != NULL)
3261 tn = promote(NOOP, 0, tn);
3262
3263 v = xcalloc(1, sizeof (val_t));
3264
3265 if (tn == NULL) {
3266 if (nerr == 0)
3267 lerror("constant() 1");
3268 v->v_tspec = INT;
3269 v->v_quad = 1;
3270 return (v);
3271 }
3272
3273 v->v_tspec = tn->tn_type->t_tspec;
3274
3275 if (tn->tn_op == CON) {
3276 if (tn->tn_type->t_tspec != tn->tn_val->v_tspec)
3277 lerror("constant() 2");
3278 if (isityp(tn->tn_val->v_tspec)) {
3279 v->v_ansiu = tn->tn_val->v_ansiu;
3280 v->v_quad = tn->tn_val->v_quad;
3281 return (v);
3282 }
3283 v->v_quad = tn->tn_val->v_ldbl;
3284 } else {
3285 v->v_quad = 1;
3286 }
3287
3288 /* integral constant expression expected */
3289 error(55);
3290
3291 if (!isityp(v->v_tspec))
3292 v->v_tspec = INT;
3293
3294 return (v);
3295 }
3296
3297 /*
3298 * Perform some tests on expressions which can't be done in build() and
3299 * functions called by build(). These tests must be done here because
3300 * we need some information about the context in which the operations
3301 * are performed.
3302 * After all tests are performed, expr() frees the memory which is used
3303 * for the expression.
3304 */
3305 void
3306 expr(tn, vctx, tctx)
3307 tnode_t *tn;
3308 int vctx, tctx;
3309 {
3310 if (tn == NULL && nerr == 0)
3311 lerror("expr() 1");
3312
3313 if (tn == NULL) {
3314 tfreeblk();
3315 return;
3316 }
3317
3318 /* expr() is also called in global initialisations */
3319 if (dcs->ctx != EXTERN)
3320 chkreach();
3321
3322 chkmisc(tn, vctx, tctx, !tctx, 0, 0, 0);
3323 if (tn->tn_op == ASSIGN) {
3324 if (hflag && tctx)
3325 /* assignment in conditional context */
3326 warning(159);
3327 } else if (tn->tn_op == CON) {
3328 if (hflag && tctx && isrcline > ccline + 1)
3329 /* constant in conditional context */
3330 warning(161);
3331 }
3332 if (!modtab[tn->tn_op].m_sideeff) {
3333 /*
3334 * for left operands of COMMA this warning is already
3335 * printed
3336 */
3337 if (tn->tn_op != COMMA && !vctx && !tctx)
3338 nulleff(tn);
3339 }
3340 if (dflag)
3341 displexpr(tn, 0);
3342
3343 /* free the tree memory */
3344 tfreeblk();
3345 }
3346
3347 static void
3348 nulleff(tn)
3349 tnode_t *tn;
3350 {
3351 if (tn->tn_op == CVT && tn->tn_type->t_tspec == VOID)
3352 tn = tn->tn_left;
3353 if (!modtab[tn->tn_op].m_sideeff) {
3354 if (hflag)
3355 /* expression has null effect */
3356 warning(129);
3357 }
3358 }
3359
3360 /*
3361 * Dump an expression to stdout
3362 * only used for debugging
3363 */
3364 static void
3365 displexpr(tn, offs)
3366 tnode_t *tn;
3367 int offs;
3368 {
3369 u_quad_t uq;
3370
3371 if (tn == NULL) {
3372 (void)printf("%*s%s\n", offs, "", "NULL");
3373 return;
3374 }
3375 (void)printf("%*sop %s ", offs, "", modtab[tn->tn_op].m_name);
3376
3377 if (tn->tn_op == NAME) {
3378 (void)printf("%s: %s ",
3379 tn->tn_sym->s_name, scltoa(tn->tn_sym->s_scl));
3380 } else if (tn->tn_op == CON && isftyp(tn->tn_type->t_tspec)) {
3381 (void)printf("%#g ", (double)tn->tn_val->v_ldbl);
3382 } else if (tn->tn_op == CON && isityp(tn->tn_type->t_tspec)) {
3383 uq = tn->tn_val->v_quad;
3384 (void)printf("0x %08lx %08lx ", (long)(uq >> 32) & 0xffffffffl,
3385 (long)uq & 0xffffffffl);
3386 } else if (tn->tn_op == CON) {
3387 if (tn->tn_type->t_tspec != PTR)
3388 lerror("displexpr() 1");
3389 (void)printf("0x%0*lx ", (int)(sizeof (void *) * CHAR_BIT / 4),
3390 (u_long)tn->tn_val->v_quad);
3391 } else if (tn->tn_op == STRING) {
3392 if (tn->tn_strg->st_tspec == CHAR) {
3393 (void)printf("\"%s\"", tn->tn_strg->st_cp);
3394 } else {
3395 char *s;
3396 size_t n;
3397 n = MB_CUR_MAX * (tn->tn_strg->st_len + 1);
3398 s = xmalloc(n);
3399 (void)wcstombs(s, tn->tn_strg->st_wcp, n);
3400 (void)printf("L\"%s\"", s);
3401 free(s);
3402 }
3403 (void)printf(" ");
3404 } else if (tn->tn_op == FSEL) {
3405 (void)printf("o=%d, l=%d ", tn->tn_type->t_foffs,
3406 tn->tn_type->t_flen);
3407 }
3408 (void)printf("%s\n", ttos(tn->tn_type));
3409 if (tn->tn_op == NAME || tn->tn_op == CON || tn->tn_op == STRING)
3410 return;
3411 displexpr(tn->tn_left, offs + 2);
3412 if (modtab[tn->tn_op].m_binary ||
3413 (tn->tn_op == PUSH && tn->tn_right != NULL)) {
3414 displexpr(tn->tn_right, offs + 2);
3415 }
3416 }
3417
3418 /*
3419 * Called by expr() to recursively perform some tests.
3420 */
3421 /* ARGSUSED */
3422 void
3423 chkmisc(tn, vctx, tctx, eqwarn, fcall, rvdisc, szof)
3424 tnode_t *tn;
3425 int vctx, tctx, eqwarn, fcall, rvdisc, szof;
3426 {
3427 tnode_t *ln, *rn;
3428 mod_t *mp;
3429 int nrvdisc, cvctx, ctctx;
3430 op_t op;
3431 scl_t sc;
3432
3433 if (tn == NULL)
3434 return;
3435
3436 ln = tn->tn_left;
3437 rn = tn->tn_right;
3438 mp = &modtab[op = tn->tn_op];
3439
3440 switch (op) {
3441 case AMPER:
3442 if (ln->tn_op == NAME && (reached || rchflg)) {
3443 if (!szof)
3444 setsflg(ln->tn_sym);
3445 setuflg(ln->tn_sym, fcall, szof);
3446 }
3447 if (ln->tn_op == STAR && ln->tn_left->tn_op == PLUS)
3448 /* check the range of array indices */
3449 chkaidx(ln->tn_left, 1);
3450 break;
3451 case LOAD:
3452 if (ln->tn_op == STAR && ln->tn_left->tn_op == PLUS)
3453 /* check the range of array indices */
3454 chkaidx(ln->tn_left, 0);
3455 /* FALLTHROUGH */
3456 case PUSH:
3457 case INCBEF:
3458 case DECBEF:
3459 case INCAFT:
3460 case DECAFT:
3461 case ADDASS:
3462 case SUBASS:
3463 case MULASS:
3464 case DIVASS:
3465 case MODASS:
3466 case ANDASS:
3467 case ORASS:
3468 case XORASS:
3469 case SHLASS:
3470 case SHRASS:
3471 if (ln->tn_op == NAME && (reached || rchflg)) {
3472 sc = ln->tn_sym->s_scl;
3473 if (sc != EXTERN && sc != STATIC &&
3474 !ln->tn_sym->s_set && !szof) {
3475 /* %s may be used before set */
3476 warning(158, ln->tn_sym->s_name);
3477 setsflg(ln->tn_sym);
3478 }
3479 setuflg(ln->tn_sym, 0, 0);
3480 }
3481 break;
3482 case ASSIGN:
3483 if (ln->tn_op == NAME && !szof && (reached || rchflg)) {
3484 setsflg(ln->tn_sym);
3485 if (ln->tn_sym->s_scl == EXTERN)
3486 outusg(ln->tn_sym);
3487 }
3488 if (ln->tn_op == STAR && ln->tn_left->tn_op == PLUS)
3489 /* check the range of array indices */
3490 chkaidx(ln->tn_left, 0);
3491 break;
3492 case CALL:
3493 if (ln->tn_op != AMPER || ln->tn_left->tn_op != NAME)
3494 lerror("chkmisc() 1");
3495 if (!szof)
3496 outcall(tn, vctx || tctx, rvdisc);
3497 break;
3498 case EQ:
3499 /* equality operator "==" found where "=" was exp. */
3500 if (hflag && eqwarn)
3501 warning(160);
3502 break;
3503 case CON:
3504 case NAME:
3505 case STRING:
3506 return;
3507 /* LINTED (enumeration values not handled in switch) */
3508 }
3509
3510 cvctx = mp->m_vctx;
3511 ctctx = mp->m_tctx;
3512 /*
3513 * values of operands of ':' are not used if the type of at least
3514 * one of the operands (for gcc compatibility) is void
3515 * XXX test/value context of QUEST should probably be used as
3516 * context for both operands of COLON
3517 */
3518 if (op == COLON && tn->tn_type->t_tspec == VOID)
3519 cvctx = ctctx = 0;
3520 nrvdisc = op == CVT && tn->tn_type->t_tspec == VOID;
3521 chkmisc(ln, cvctx, ctctx, mp->m_eqwarn, op == CALL, nrvdisc, szof);
3522
3523 switch (op) {
3524 case PUSH:
3525 if (rn != NULL)
3526 chkmisc(rn, 0, 0, mp->m_eqwarn, 0, 0, szof);
3527 break;
3528 case LOGAND:
3529 case LOGOR:
3530 chkmisc(rn, 0, 1, mp->m_eqwarn, 0, 0, szof);
3531 break;
3532 case COLON:
3533 chkmisc(rn, cvctx, ctctx, mp->m_eqwarn, 0, 0, szof);
3534 break;
3535 default:
3536 if (mp->m_binary)
3537 chkmisc(rn, 1, 0, mp->m_eqwarn, 0, 0, szof);
3538 break;
3539 }
3540
3541 }
3542
3543 /*
3544 * Checks the range of array indices, if possible.
3545 * amper is set if only the address of the element is used. This
3546 * means that the index is allowd to refere to the first element
3547 * after the array.
3548 */
3549 static void
3550 chkaidx(tn, amper)
3551 tnode_t *tn;
3552 int amper;
3553 {
3554 int dim;
3555 tnode_t *ln, *rn;
3556 int elsz;
3557 quad_t con;
3558
3559 ln = tn->tn_left;
3560 rn = tn->tn_right;
3561
3562 /* We can only check constant indices. */
3563 if (rn->tn_op != CON)
3564 return;
3565
3566 /* Return if the left node does not stem from an array. */
3567 if (ln->tn_op != AMPER)
3568 return;
3569 if (ln->tn_left->tn_op != STRING && ln->tn_left->tn_op != NAME)
3570 return;
3571 if (ln->tn_left->tn_type->t_tspec != ARRAY)
3572 return;
3573
3574 /*
3575 * For incomplete array types, we can print a warning only if
3576 * the index is negative.
3577 */
3578 if (incompl(ln->tn_left->tn_type) && rn->tn_val->v_quad >= 0)
3579 return;
3580
3581 /* Get the size of one array element */
3582 if ((elsz = length(ln->tn_type->t_subt, NULL)) == 0)
3583 return;
3584 elsz /= CHAR_BIT;
3585
3586 /* Change the unit of the index from bytes to element size. */
3587 if (isutyp(rn->tn_type->t_tspec)) {
3588 con = (u_quad_t)rn->tn_val->v_quad / elsz;
3589 } else {
3590 con = rn->tn_val->v_quad / elsz;
3591 }
3592
3593 dim = ln->tn_left->tn_type->t_dim + (amper ? 1 : 0);
3594
3595 if (!isutyp(rn->tn_type->t_tspec) && con < 0) {
3596 /* array subscript cannot be negative: %ld */
3597 warning(167, (long)con);
3598 } else if (dim > 0 && (u_quad_t)con >= dim) {
3599 /* array subscript cannot be > %d: %ld */
3600 warning(168, dim - 1, (long)con);
3601 }
3602 }
3603
3604 /*
3605 * Check for ordered comparisions of unsigned values with 0.
3606 */
3607 static void
3608 chkcomp(op, ln, rn)
3609 op_t op;
3610 tnode_t *ln, *rn;
3611 {
3612 tspec_t lt, rt;
3613 mod_t *mp;
3614
3615 lt = ln->tn_type->t_tspec;
3616 rt = rn->tn_type->t_tspec;
3617 mp = &modtab[op];
3618
3619 if (ln->tn_op != CON && rn->tn_op != CON)
3620 return;
3621
3622 if (!isityp(lt) || !isityp(rt))
3623 return;
3624
3625 if ((hflag || pflag) && lt == CHAR && rn->tn_op == CON &&
3626 (rn->tn_val->v_quad < 0 ||
3627 rn->tn_val->v_quad > ~(~0 << (CHAR_BIT - 1)))) {
3628 /* nonportable character comparision, op %s */
3629 warning(230, mp->m_name);
3630 return;
3631 }
3632 if ((hflag || pflag) && rt == CHAR && ln->tn_op == CON &&
3633 (ln->tn_val->v_quad < 0 ||
3634 ln->tn_val->v_quad > ~(~0 << (CHAR_BIT - 1)))) {
3635 /* nonportable character comparision, op %s */
3636 warning(230, mp->m_name);
3637 return;
3638 }
3639 if (isutyp(lt) && !isutyp(rt) &&
3640 rn->tn_op == CON && rn->tn_val->v_quad <= 0) {
3641 if (rn->tn_val->v_quad < 0) {
3642 /* comparision of %s with %s, op %s */
3643 warning(162, tyname(ln->tn_type), "negative constant",
3644 mp->m_name);
3645 } else if (op == LT || op == GE || (hflag && op == LE)) {
3646 /* comparision of %s with %s, op %s */
3647 warning(162, tyname(ln->tn_type), "0", mp->m_name);
3648 }
3649 return;
3650 }
3651 if (isutyp(rt) && !isutyp(lt) &&
3652 ln->tn_op == CON && ln->tn_val->v_quad <= 0) {
3653 if (ln->tn_val->v_quad < 0) {
3654 /* comparision of %s with %s, op %s */
3655 warning(162, "negative constant", tyname(rn->tn_type),
3656 mp->m_name);
3657 } else if (op == GT || op == LE || (hflag && op == GE)) {
3658 /* comparision of %s with %s, op %s */
3659 warning(162, "0", tyname(rn->tn_type), mp->m_name);
3660 }
3661 return;
3662 }
3663 }
3664
3665 /*
3666 * Takes an expression an returns 0 if this expression can be used
3667 * for static initialisation, otherwise -1.
3668 *
3669 * Constant initialisation expressions must be costant or an address
3670 * of a static object with an optional offset. In the first case,
3671 * the result is returned in *offsp. In the second case, the static
3672 * object is returned in *symp and the offset in *offsp.
3673 *
3674 * The expression can consist of PLUS, MINUS, AMPER, NAME, STRING and
3675 * CON. Type conversions are allowed if they do not change binary
3676 * representation (including width).
3677 */
3678 int
3679 conaddr(tn, symp, offsp)
3680 tnode_t *tn;
3681 sym_t **symp;
3682 ptrdiff_t *offsp;
3683 {
3684 sym_t *sym;
3685 ptrdiff_t offs1, offs2;
3686 tspec_t t, ot;
3687
3688 switch (tn->tn_op) {
3689 case MINUS:
3690 if (tn->tn_right->tn_op != CON)
3691 return (-1);
3692 /* FALLTHROUGH */
3693 case PLUS:
3694 offs1 = offs2 = 0;
3695 if (tn->tn_left->tn_op == CON) {
3696 offs1 = (ptrdiff_t)tn->tn_left->tn_val->v_quad;
3697 if (conaddr(tn->tn_right, &sym, &offs2) == -1)
3698 return (-1);
3699 } else if (tn->tn_right->tn_op == CON) {
3700 offs2 = (ptrdiff_t)tn->tn_right->tn_val->v_quad;
3701 if (tn->tn_op == MINUS)
3702 offs2 = -offs2;
3703 if (conaddr(tn->tn_left, &sym, &offs1) == -1)
3704 return (-1);
3705 } else {
3706 return (-1);
3707 }
3708 *symp = sym;
3709 *offsp = offs1 + offs2;
3710 break;
3711 case AMPER:
3712 if (tn->tn_left->tn_op == NAME) {
3713 *symp = tn->tn_left->tn_sym;
3714 *offsp = 0;
3715 } else if (tn->tn_left->tn_op == STRING) {
3716 /*
3717 * If this would be the front end of a compiler we
3718 * would return a label instead of 0.
3719 */
3720 *offsp = 0;
3721 }
3722 break;
3723 case CVT:
3724 t = tn->tn_type->t_tspec;
3725 ot = tn->tn_left->tn_type->t_tspec;
3726 if ((!isityp(t) && t != PTR) || (!isityp(ot) && ot != PTR)) {
3727 return (-1);
3728 } else if (psize(t) != psize(ot)) {
3729 return (-1);
3730 }
3731 if (conaddr(tn->tn_left, symp, offsp) == -1)
3732 return (-1);
3733 break;
3734 default:
3735 return (-1);
3736 }
3737 return (0);
3738 }
3739
3740 /*
3741 * Concatenate two string constants.
3742 */
3743 strg_t *
3744 catstrg(strg1, strg2)
3745 strg_t *strg1, *strg2;
3746 {
3747 size_t len1, len2, len;
3748
3749 if (strg1->st_tspec != strg2->st_tspec) {
3750 /* cannot concatenate wide and regular string literals */
3751 error(292);
3752 return (strg1);
3753 }
3754
3755 len = (len1 = strg1->st_len) + (len2 = strg2->st_len);
3756
3757 if (strg1->st_tspec == CHAR) {
3758 strg1->st_cp = xrealloc(strg1->st_cp, len + 1);
3759 (void)memcpy(strg1->st_cp + len1, strg2->st_cp, len2 + 1);
3760 free(strg2->st_cp);
3761 } else {
3762 strg1->st_wcp = xrealloc(strg1->st_wcp,
3763 (len + 1) * sizeof (wchar_t));
3764 (void)memcpy(strg1->st_wcp + len1, strg2->st_wcp,
3765 (len2 + 1) * sizeof (wchar_t));
3766 free(strg2->st_wcp);
3767 }
3768 free(strg2);
3769
3770 return (strg1);
3771 }
3772
3773 /*
3774 * Print a warning if the given node has operands which should be
3775 * parenthesized.
3776 *
3777 * XXX Does not work if an operand is a constant expression. Constant
3778 * expressions are already folded.
3779 */
3780 static void
3781 precconf(tn)
3782 tnode_t *tn;
3783 {
3784 tnode_t *ln, *rn;
3785 op_t lop, rop;
3786 int lparn, rparn;
3787 mod_t *mp;
3788 int warn;
3789
3790 if (!hflag)
3791 return;
3792
3793 mp = &modtab[tn->tn_op];
3794
3795 lparn = 0;
3796 for (ln = tn->tn_left; ln->tn_op == CVT; ln = ln->tn_left)
3797 lparn |= ln->tn_parn;
3798 lparn |= ln->tn_parn;
3799 lop = ln->tn_op;
3800
3801 if (mp->m_binary) {
3802 rparn = 0;
3803 for (rn = tn->tn_right; tn->tn_op == CVT; rn = rn->tn_left)
3804 rparn |= rn->tn_parn;
3805 rparn |= rn->tn_parn;
3806 rop = rn->tn_op;
3807 }
3808
3809 warn = 0;
3810
3811 switch (tn->tn_op) {
3812 case SHL:
3813 case SHR:
3814 if (!lparn && (lop == PLUS || lop == MINUS)) {
3815 warn = 1;
3816 } else if (!rparn && (rop == PLUS || rop == MINUS)) {
3817 warn = 1;
3818 }
3819 break;
3820 case LOGOR:
3821 if (!lparn && lop == LOGAND) {
3822 warn = 1;
3823 } else if (!rparn && rop == LOGAND) {
3824 warn = 1;
3825 }
3826 break;
3827 case AND:
3828 case XOR:
3829 case OR:
3830 if (!lparn && lop != tn->tn_op) {
3831 if (lop == PLUS || lop == MINUS) {
3832 warn = 1;
3833 } else if (lop == AND || lop == XOR) {
3834 warn = 1;
3835 }
3836 }
3837 if (!warn && !rparn && rop != tn->tn_op) {
3838 if (rop == PLUS || rop == MINUS) {
3839 warn = 1;
3840 } else if (rop == AND || rop == XOR) {
3841 warn = 1;
3842 }
3843 }
3844 break;
3845 /* LINTED (enumeration values not handled in switch) */
3846 }
3847
3848 if (warn) {
3849 /* precedence confusion possible: parenthesize! */
3850 warning(169);
3851 }
3852
3853 }
3854