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