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