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