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