1/*	$NetBSD: tree.c,v 1.643 2024/05/12 09:07:41 rillig Exp $	*/
2
3/*
4 * Copyright (c) 1994, 1995 Jochen Pohl
5 * All Rights Reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 *    must display the following acknowledgement:
17 *	This product includes software developed by Jochen Pohl for
18 *	The NetBSD Project.
19 * 4. The name of the author may not be used to endorse or promote products
20 *    derived from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#if HAVE_NBTOOL_CONFIG_H
35#include "nbtool_config.h"
36#endif
37
38#include <sys/cdefs.h>
39#if defined(__RCSID)
40__RCSID("$NetBSD: tree.c,v 1.643 2024/05/12 09:07:41 rillig Exp $");
41#endif
42
43#include <float.h>
44#include <limits.h>
45#include <math.h>
46#include <signal.h>
47#include <stdlib.h>
48#include <string.h>
49
50#include "lint1.h"
51
52
53typedef struct integer_constraints {
54	int64_t		smin;	/* signed minimum */
55	int64_t		smax;	/* signed maximum */
56	uint64_t	umin;	/* unsigned minimum */
57	uint64_t	umax;	/* unsigned maximum */
58	uint64_t	bset;	/* bits that are definitely set */
59	uint64_t	bclr;	/* bits that are definitely clear */
60} integer_constraints;
61
62
63static uint64_t
64u64_fill_right(uint64_t x)
65{
66	x |= x >> 1;
67	x |= x >> 2;
68	x |= x >> 4;
69	x |= x >> 8;
70	x |= x >> 16;
71	x |= x >> 32;
72	return x;
73}
74
75static bool
76str_ends_with(const char *haystack, const char *needle)
77{
78	size_t hlen = strlen(haystack);
79	size_t nlen = strlen(needle);
80
81	return nlen <= hlen &&
82	    memcmp(haystack + hlen - nlen, needle, nlen) == 0;
83}
84
85static unsigned
86width_in_bits(const type_t *tp)
87{
88
89	lint_assert(is_integer(tp->t_tspec));
90	return tp->t_bitfield
91	    ? tp->t_bit_field_width
92	    : size_in_bits(tp->t_tspec);
93}
94
95static int
96portable_rank_cmp(tspec_t t1, tspec_t t2)
97{
98	const ttab_t *p1 = type_properties(t1), *p2 = type_properties(t2);
99	lint_assert(p1->tt_rank_kind == p2->tt_rank_kind);
100	lint_assert(p1->tt_rank_value > 0);
101	lint_assert(p2->tt_rank_value > 0);
102	return (int)p1->tt_rank_value - (int)p2->tt_rank_value;
103}
104
105static bool
106ic_maybe_signed(const type_t *tp, const integer_constraints *ic)
107{
108	return !is_uinteger(tp->t_tspec) && ic->bclr >> 63 == 0;
109}
110
111static integer_constraints
112ic_any(const type_t *tp)
113{
114	integer_constraints c;
115
116	uint64_t vbits = value_bits(width_in_bits(tp));
117	if (is_uinteger(tp->t_tspec)) {
118		c.smin = INT64_MIN;
119		c.smax = INT64_MAX;
120		c.umin = 0;
121		c.umax = vbits;
122		c.bset = 0;
123		c.bclr = ~c.umax;
124	} else {
125		c.smin = (int64_t)-1 - (int64_t)(vbits >> 1);
126		c.smax = (int64_t)(vbits >> 1);
127		c.umin = 0;
128		c.umax = UINT64_MAX;
129		c.bset = 0;
130		c.bclr = 0;
131	}
132	return c;
133}
134
135static integer_constraints
136ic_con(const type_t *tp, const val_t *v)
137{
138	integer_constraints c;
139
140	lint_assert(is_integer(tp->t_tspec));
141	int64_t si = v->u.integer;
142	uint64_t ui = (uint64_t)si;
143	c.smin = si;
144	c.smax = si;
145	c.umin = ui;
146	c.umax = ui;
147	c.bset = ui;
148	c.bclr = ~ui;
149	return c;
150}
151
152static integer_constraints
153ic_cvt(const type_t *ntp, const type_t *otp, integer_constraints a)
154{
155	unsigned nw = width_in_bits(ntp);
156	unsigned ow = width_in_bits(otp);
157	bool nu = is_uinteger(ntp->t_tspec);
158	bool ou = is_uinteger(otp->t_tspec);
159
160	if (nw >= ow && nu == ou)
161		return a;
162	if (nw > ow && ou)
163		return a;
164	return ic_any(ntp);
165}
166
167static integer_constraints
168ic_bitand(integer_constraints a, integer_constraints b)
169{
170	integer_constraints c;
171
172	c.smin = INT64_MIN;
173	c.smax = INT64_MAX;
174	c.umin = 0;
175	c.umax = UINT64_MAX;
176	c.bset = a.bset & b.bset;
177	c.bclr = a.bclr | b.bclr;
178	return c;
179}
180
181static integer_constraints
182ic_bitor(integer_constraints a, integer_constraints b)
183{
184	integer_constraints c;
185
186	c.smin = INT64_MIN;
187	c.smax = INT64_MAX;
188	c.umin = 0;
189	c.umax = UINT64_MAX;
190	c.bset = a.bset | b.bset;
191	c.bclr = a.bclr & b.bclr;
192	return c;
193}
194
195static integer_constraints
196ic_mod(const type_t *tp, integer_constraints a, integer_constraints b)
197{
198	integer_constraints c;
199
200	if (ic_maybe_signed(tp, &a) || ic_maybe_signed(tp, &b))
201		return ic_any(tp);
202
203	c.smin = INT64_MIN;
204	c.smax = INT64_MAX;
205	c.umin = 0;
206	c.umax = b.umax - 1;
207	c.bset = 0;
208	c.bclr = ~u64_fill_right(c.umax);
209	return c;
210}
211
212static integer_constraints
213ic_shl(const type_t *tp, integer_constraints a, integer_constraints b)
214{
215	integer_constraints c;
216	unsigned int amount;
217
218	if (ic_maybe_signed(tp, &a))
219		return ic_any(tp);
220
221	if (b.smin == b.smax && b.smin >= 0 && b.smin < 64)
222		amount = (unsigned int)b.smin;
223	else if (b.umin == b.umax && b.umin < 64)
224		amount = (unsigned int)b.umin;
225	else
226		return ic_any(tp);
227
228	c.smin = INT64_MIN;
229	c.smax = INT64_MAX;
230	c.umin = 0;
231	c.umax = UINT64_MAX;
232	c.bset = a.bset << amount;
233	c.bclr = a.bclr << amount | (((uint64_t)1 << amount) - 1);
234	return c;
235}
236
237static integer_constraints
238ic_shr(const type_t *tp, integer_constraints a, integer_constraints b)
239{
240	integer_constraints c;
241	unsigned int amount;
242
243	if (ic_maybe_signed(tp, &a))
244		return ic_any(tp);
245
246	if (b.smin == b.smax && b.smin >= 0 && b.smin < 64)
247		amount = (unsigned int)b.smin;
248	else if (b.umin == b.umax && b.umin < 64)
249		amount = (unsigned int)b.umin;
250	else
251		return ic_any(tp);
252
253	c.smin = INT64_MIN;
254	c.smax = INT64_MAX;
255	c.umin = 0;
256	c.umax = UINT64_MAX;
257	c.bset = a.bset >> amount;
258	c.bclr = a.bclr >> amount | ~(~(uint64_t)0 >> amount);
259	return c;
260}
261
262static integer_constraints
263ic_cond(integer_constraints a, integer_constraints b)
264{
265	integer_constraints c;
266
267	c.smin = a.smin < b.smin ? a.smin : b.smin;
268	c.smax = a.smax > b.smax ? a.smax : b.smax;
269	c.umin = a.umin < b.umin ? a.umin : b.umin;
270	c.umax = a.umax > b.umax ? a.umax : b.umax;
271	c.bset = a.bset | b.bset;
272	c.bclr = a.bclr & b.bclr;
273	return c;
274}
275
276static integer_constraints
277ic_expr(const tnode_t *tn)
278{
279	integer_constraints lc, rc;
280
281	lint_assert(is_integer(tn->tn_type->t_tspec));
282
283	switch (tn->tn_op) {
284	case CON:
285		return ic_con(tn->tn_type, &tn->u.value);
286	case CVT:
287		if (!is_integer(tn->u.ops.left->tn_type->t_tspec))
288			return ic_any(tn->tn_type);
289		lc = ic_expr(tn->u.ops.left);
290		return ic_cvt(tn->tn_type, tn->u.ops.left->tn_type, lc);
291	case MOD:
292		lc = ic_expr(before_conversion(tn->u.ops.left));
293		rc = ic_expr(before_conversion(tn->u.ops.right));
294		return ic_mod(tn->tn_type, lc, rc);
295	case SHL:
296		lc = ic_expr(tn->u.ops.left);
297		rc = ic_expr(tn->u.ops.right);
298		return ic_shl(tn->tn_type, lc, rc);
299	case SHR:
300		lc = ic_expr(tn->u.ops.left);
301		rc = ic_expr(tn->u.ops.right);
302		return ic_shr(tn->tn_type, lc, rc);
303	case BITAND:
304		lc = ic_expr(tn->u.ops.left);
305		rc = ic_expr(tn->u.ops.right);
306		return ic_bitand(lc, rc);
307	case BITOR:
308		lc = ic_expr(tn->u.ops.left);
309		rc = ic_expr(tn->u.ops.right);
310		return ic_bitor(lc, rc);
311	case QUEST:
312		lc = ic_expr(tn->u.ops.right->u.ops.left);
313		rc = ic_expr(tn->u.ops.right->u.ops.right);
314		return ic_cond(lc, rc);
315	default:
316		return ic_any(tn->tn_type);
317	}
318}
319
320uint64_t
321possible_bits(const tnode_t *tn)
322{
323	return ~ic_expr(tn).bclr;
324}
325
326/* Build 'pointer to tp', 'array of tp' or 'function returning tp'. */
327type_t *
328block_derive_type(type_t *tp, tspec_t t)
329{
330
331	type_t *tp2 = block_zero_alloc(sizeof(*tp2), "type");
332	tp2->t_tspec = t;
333	tp2->t_subt = tp;
334	return tp2;
335}
336
337/*
338 * Derive 'pointer to tp' or 'function returning tp'.
339 * The memory is freed at the end of the current expression.
340 */
341type_t *
342expr_derive_type(type_t *tp, tspec_t t)
343{
344
345	type_t *tp2 = expr_zero_alloc(sizeof(*tp2), "type");
346	tp2->t_tspec = t;
347	tp2->t_subt = tp;
348	return tp2;
349}
350
351/* Create an expression from a unary or binary operator and its operands. */
352static tnode_t *
353build_op(op_t op, bool sys, type_t *type, tnode_t *ln, tnode_t *rn)
354{
355
356	tnode_t *ntn = expr_alloc_tnode();
357	ntn->tn_op = op;
358	ntn->tn_type = type;
359	ntn->tn_sys = sys;
360	ntn->u.ops.left = ln;
361	ntn->u.ops.right = rn;
362
363	if (op == INDIR || op == FSEL) {
364		lint_assert(ln->tn_type->t_tspec == PTR);
365		tspec_t t = ln->tn_type->t_subt->t_tspec;
366		ntn->tn_lvalue = t != FUNC && t != VOID;
367	}
368
369	return ntn;
370}
371
372tnode_t *
373build_constant(type_t *tp, val_t *v)
374{
375
376	tnode_t *n = expr_alloc_tnode();
377	n->tn_op = CON;
378	n->tn_type = tp;
379	n->u.value = *v;
380	n->u.value.v_tspec = tp->t_tspec;
381	free(v);
382	return n;
383}
384
385static tnode_t *
386build_integer_constant(tspec_t t, int64_t si)
387{
388
389	tnode_t *n = expr_alloc_tnode();
390	n->tn_op = CON;
391	n->tn_type = gettyp(t);
392	n->u.value.v_tspec = t;
393	n->u.value.v_unsigned_since_c90 = false;
394	n->u.value.v_char_constant = false;
395	n->u.value.u.integer = si;
396	return n;
397}
398
399static void
400fallback_symbol(sym_t *sym)
401{
402
403	if (Tflag && fallback_symbol_strict_bool(sym))
404		return;
405
406	if (block_level > 0 && (strcmp(sym->s_name, "__FUNCTION__") == 0 ||
407			   strcmp(sym->s_name, "__PRETTY_FUNCTION__") == 0)) {
408		/* __FUNCTION__/__PRETTY_FUNCTION__ is a GCC extension */
409		gnuism(316);
410		// XXX: Should probably be ARRAY instead of PTR.
411		sym->s_type = block_derive_type(gettyp(CHAR), PTR);
412		sym->s_type->t_const = true;
413		return;
414	}
415
416	if (funcsym != NULL && strcmp(sym->s_name, "__func__") == 0) {
417		if (!allow_c99)
418			/* __func__ is a C99 feature */
419			warning(317);
420		/* C11 6.4.2.2 */
421		sym->s_type = block_derive_type(gettyp(CHAR), ARRAY);
422		sym->s_type->t_const = true;
423		sym->s_type->u.dimension = (int)strlen(funcsym->s_name) + 1;
424		return;
425	}
426
427	/* '%s' undefined */
428	error(99, sym->s_name);
429}
430
431/*
432 * Functions that are predeclared by GCC or other compilers can be called
433 * with arbitrary arguments.  Since lint usually runs after a successful
434 * compilation, it's the compiler's job to catch any errors.
435 */
436bool
437is_compiler_builtin(const char *name)
438{
439	/* https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html */
440	if (allow_gcc) {
441		if (strncmp(name, "__atomic_", 9) == 0 ||
442		    strncmp(name, "__builtin_", 10) == 0 ||
443		    strcmp(name, "alloca") == 0 ||
444		    /* obsolete but still in use, as of 2021 */
445		    strncmp(name, "__sync_", 7) == 0)
446			return true;
447	}
448
449	/* https://software.intel.com/sites/landingpage/IntrinsicsGuide/ */
450	if (strncmp(name, "_mm_", 4) == 0)
451		return true;
452
453	return false;
454}
455
456/* https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html */
457static bool
458is_gcc_bool_builtin(const char *name)
459{
460	return strncmp(name, "__builtin_", 10) == 0 &&
461	    (str_ends_with(name, "_overflow") ||
462		str_ends_with(name, "_overflow_p"));
463}
464
465static void
466build_name_call(sym_t *sym)
467{
468
469	if (is_compiler_builtin(sym->s_name)) {
470		/*
471		 * Do not warn about these, just assume that they are regular
472		 * functions compatible with non-prototype calling conventions.
473		 */
474		if (allow_gcc && is_gcc_bool_builtin(sym->s_name))
475			sym->s_type = gettyp(BOOL);
476	} else if (allow_c99)
477		/* function '%s' implicitly declared to return int */
478		error(215, sym->s_name);
479	else if (!allow_trad)
480		/* function '%s' implicitly declared to return int */
481		warning(215, sym->s_name);
482
483	/* XXX if !allow_c90, the symbol should be exported to level 0 */
484	sym->s_type = block_derive_type(sym->s_type, FUNC);
485}
486
487/* Create a node for a name (symbol table entry). */
488tnode_t *
489build_name(sym_t *sym, bool is_funcname)
490{
491
492	if (sym->s_scl == NO_SCL && !in_gcc_attribute) {
493		sym->s_scl = EXTERN;
494		sym->s_def = DECL;
495		if (is_funcname)
496			build_name_call(sym);
497		else
498			fallback_symbol(sym);
499	}
500
501	lint_assert(sym->s_kind == SK_VCFT || sym->s_kind == SK_MEMBER);
502
503	tnode_t *n = expr_alloc_tnode();
504	n->tn_type = sym->s_type;
505	if (sym->s_scl == BOOL_CONST) {
506		n->tn_op = CON;
507		n->u.value.v_tspec = BOOL;
508		n->u.value.v_unsigned_since_c90 = false;
509		n->u.value.v_char_constant = false;
510		n->u.value.u.integer = sym->u.s_bool_constant ? 1 : 0;
511	} else if (sym->s_scl == ENUM_CONST) {
512		n->tn_op = CON;
513		n->u.value.v_tspec = INT;	/* ENUM is in n->tn_type */
514		n->u.value.v_unsigned_since_c90 = false;
515		n->u.value.v_char_constant = false;
516		n->u.value.u.integer = sym->u.s_enum_constant;
517	} else {
518		n->tn_op = NAME;
519		n->u.sym = sym;
520		if (sym->s_kind == SK_VCFT && sym->s_type->t_tspec != FUNC)
521			n->tn_lvalue = true;
522	}
523
524	return n;
525}
526
527tnode_t *
528build_string(buffer *lit)
529{
530	size_t value_len = lit->len;
531	if (lit->data != NULL) {
532		quoted_iterator it = { .end = 0 };
533		for (value_len = 0; quoted_next(lit, &it); value_len++)
534			continue;
535	}
536
537	type_t *tp = expr_zero_alloc(sizeof(*tp), "type");
538	tp->t_tspec = ARRAY;
539	tp->t_subt = gettyp(lit->data != NULL ? CHAR : WCHAR_TSPEC);
540	tp->u.dimension = (int)(value_len + 1);
541
542	tnode_t *n = expr_alloc_tnode();
543	n->tn_op = STRING;
544	n->tn_type = tp;
545	n->tn_lvalue = true;
546
547	n->u.str_literals = expr_zero_alloc(sizeof(*n->u.str_literals), "tnode.string");
548	n->u.str_literals->len = lit->len;
549
550	if (lit->data != NULL) {
551		n->u.str_literals->data = expr_zero_alloc(lit->len + 1,
552		    "tnode.string.data");
553		(void)memcpy(n->u.str_literals->data, lit->data, lit->len + 1);
554		free(lit->data);
555	}
556	free(lit);
557
558	return n;
559}
560
561tnode_t *
562build_generic_selection(const tnode_t *expr,
563			struct generic_association *sel)
564{
565	tnode_t *default_result = NULL;
566
567	for (; sel != NULL; sel = sel->ga_prev) {
568		if (expr != NULL &&
569		    types_compatible(sel->ga_arg, expr->tn_type,
570			false, false, NULL))
571			return sel->ga_result;
572		else if (sel->ga_arg == NULL)
573			default_result = sel->ga_result;
574	}
575	return default_result;
576}
577
578static bool
579is_out_of_char_range(const tnode_t *tn)
580{
581	return tn->tn_op == CON &&
582	    !tn->u.value.v_char_constant &&
583	    !(0 <= tn->u.value.u.integer &&
584		tn->u.value.u.integer < 1 << (CHAR_SIZE - 1));
585}
586
587static bool
588check_nonportable_char_comparison(op_t op,
589				  const tnode_t *ln, tspec_t lt,
590				  const tnode_t *rn, tspec_t rt)
591{
592	if (!(hflag || pflag))
593		return true;
594
595	if (lt == CHAR && is_out_of_char_range(rn)) {
596		char buf[128];
597		(void)snprintf(buf, sizeof(buf), "%s %d",
598		    op_name(op), (int)rn->u.value.u.integer);
599		/* nonportable character comparison '%s' */
600		warning(230, buf);
601		return false;
602	}
603	if (rt == CHAR && is_out_of_char_range(ln)) {
604		char buf[128];
605		(void)snprintf(buf, sizeof(buf), "%d %s ?",
606		    (int)ln->u.value.u.integer, op_name(op));
607		/* nonportable character comparison '%s' */
608		warning(230, buf);
609		return false;
610	}
611	return true;
612}
613
614static void
615check_integer_comparison(op_t op, tnode_t *ln, tnode_t *rn)
616{
617
618	tspec_t lt = ln->tn_type->t_tspec;
619	tspec_t rt = rn->tn_type->t_tspec;
620
621	if (ln->tn_op != CON && rn->tn_op != CON)
622		return;
623
624	if (!is_integer(lt) || !is_integer(rt))
625		return;
626
627	if (any_query_enabled && !in_system_header) {
628		if (lt == CHAR && rn->tn_op == CON &&
629		    !rn->u.value.v_char_constant) {
630			/* comparison '%s' of 'char' with plain integer %d */
631			query_message(14,
632			    op_name(op), (int)rn->u.value.u.integer);
633		}
634		if (rt == CHAR && ln->tn_op == CON &&
635		    !ln->u.value.v_char_constant) {
636			/* comparison '%s' of 'char' with plain integer %d */
637			query_message(14,
638			    op_name(op), (int)ln->u.value.u.integer);
639		}
640	}
641
642	if (!check_nonportable_char_comparison(op, ln, lt, rn, rt))
643		return;
644
645	if (is_uinteger(lt) && !is_uinteger(rt) &&
646	    rn->tn_op == CON && rn->u.value.u.integer <= 0) {
647		if (rn->u.value.u.integer < 0) {
648			/* operator '%s' compares '%s' with '%s' */
649			warning(162, op_name(op),
650			    type_name(ln->tn_type), "negative constant");
651		} else if (op == LT || op == GE)
652			/* operator '%s' compares '%s' with '%s' */
653			warning(162, op_name(op), type_name(ln->tn_type), "0");
654		return;
655	}
656	if (is_uinteger(rt) && !is_uinteger(lt) &&
657	    ln->tn_op == CON && ln->u.value.u.integer <= 0) {
658		if (ln->u.value.u.integer < 0) {
659			/* operator '%s' compares '%s' with '%s' */
660			warning(162, op_name(op),
661			    "negative constant", type_name(rn->tn_type));
662		} else if (op == GT || op == LE)
663			/* operator '%s' compares '%s' with '%s' */
664			warning(162, op_name(op), "0", type_name(rn->tn_type));
665		return;
666	}
667}
668
669static const tspec_t arith_rank[] = {
670	LDOUBLE, DOUBLE, FLOAT,
671#ifdef INT128_SIZE
672	UINT128, INT128,
673#endif
674	ULLONG, LLONG,
675	ULONG, LONG,
676	UINT, INT,
677};
678
679/* Keep unsigned in traditional C */
680static tspec_t
681usual_arithmetic_conversion_trad(tspec_t lt, tspec_t rt)
682{
683
684	size_t i;
685	for (i = 0; arith_rank[i] != INT; i++)
686		if (lt == arith_rank[i] || rt == arith_rank[i])
687			break;
688
689	tspec_t t = arith_rank[i];
690	if (is_uinteger(lt) || is_uinteger(rt))
691		if (is_integer(t) && !is_uinteger(t))
692			return unsigned_type(t);
693	return t;
694}
695
696static tspec_t
697usual_arithmetic_conversion_c90(tspec_t lt, tspec_t rt)
698{
699
700	if (lt == rt)
701		return lt;
702
703	if (lt == LCOMPLEX || rt == LCOMPLEX)
704		return LCOMPLEX;
705	if (lt == DCOMPLEX || rt == DCOMPLEX)
706		return DCOMPLEX;
707	if (lt == FCOMPLEX || rt == FCOMPLEX)
708		return FCOMPLEX;
709	if (lt == LDOUBLE || rt == LDOUBLE)
710		return LDOUBLE;
711	if (lt == DOUBLE || rt == DOUBLE)
712		return DOUBLE;
713	if (lt == FLOAT || rt == FLOAT)
714		return FLOAT;
715
716	if (size_in_bits(lt) > size_in_bits(rt))
717		return lt;
718	if (size_in_bits(lt) < size_in_bits(rt))
719		return rt;
720
721	size_t i;
722	for (i = 3; arith_rank[i] != INT; i++)
723		if (arith_rank[i] == lt || arith_rank[i] == rt)
724			break;
725	if ((is_uinteger(lt) || is_uinteger(rt)) &&
726	    !is_uinteger(arith_rank[i]))
727		i--;
728	return arith_rank[i];
729}
730
731static tnode_t *
732apply_usual_arithmetic_conversions(op_t op, tnode_t *tn, tspec_t t)
733{
734	type_t *ntp = expr_dup_type(tn->tn_type);
735	ntp->t_tspec = t;
736	if (tn->tn_op != CON) {
737		/* usual arithmetic conversion for '%s' from '%s' to '%s' */
738		query_message(4, op_name(op),
739		    type_name(tn->tn_type), type_name(ntp));
740	}
741	return convert(op, 0, ntp, tn);
742}
743
744/*
745 * Apply the "usual arithmetic conversions" (C99 6.3.1.8), which gives both
746 * operands the same type.
747 */
748static void
749balance(op_t op, tnode_t **lnp, tnode_t **rnp)
750{
751
752	tspec_t lt = (*lnp)->tn_type->t_tspec;
753	tspec_t rt = (*rnp)->tn_type->t_tspec;
754	if (!is_arithmetic(lt) || !is_arithmetic(rt))
755		return;
756
757	tspec_t t = allow_c90
758	    ? usual_arithmetic_conversion_c90(lt, rt)
759	    : usual_arithmetic_conversion_trad(lt, rt);
760
761	if (modtab[op].m_comparison
762	    && is_integer(lt) && (*lnp)->tn_op != CON
763	    && is_floating(t) && (*rnp)->tn_op == CON)
764		/* comparing integer '%s' to floating point constant %Lg */
765		warning(379, type_name((*lnp)->tn_type),
766		    (*rnp)->u.value.u.floating);
767
768	if (t != lt)
769		*lnp = apply_usual_arithmetic_conversions(op, *lnp, t);
770	if (t != rt)
771		*rnp = apply_usual_arithmetic_conversions(op, *rnp, t);
772
773	if (is_integer(t)) {
774		unsigned lw = width_in_bits((*lnp)->tn_type);
775		unsigned rw = width_in_bits((*rnp)->tn_type);
776		if (lw < rw)
777			*lnp = convert(NOOP, 0, (*rnp)->tn_type, *lnp);
778		if (rw < lw)
779			*rnp = convert(NOOP, 0, (*lnp)->tn_type, *rnp);
780	}
781}
782
783static tnode_t *
784build_address(bool sys, tnode_t *tn, bool force)
785{
786	tspec_t t;
787
788	if (!force && ((t = tn->tn_type->t_tspec) == ARRAY || t == FUNC)) {
789		if (!allow_c90)
790			/* '&' before array or function: ignored */
791			warning(127);
792		return tn;
793	}
794
795	/* eliminate '&*' */
796	if (tn->tn_op == INDIR &&
797	    tn->u.ops.left->tn_type->t_tspec == PTR &&
798	    tn->u.ops.left->tn_type->t_subt == tn->tn_type) {
799		return tn->u.ops.left;
800	}
801
802	return build_op(ADDR, sys, expr_derive_type(tn->tn_type, PTR),
803	    tn, NULL);
804}
805
806static uint64_t
807fold_unsigned_integer(op_t op, uint64_t l, uint64_t r,
808		      uint64_t max_value, bool *overflow)
809{
810	switch (op) {
811	case COMPL:
812		return ~l & max_value;
813	case UPLUS:
814		return +l;
815	case UMINUS:
816		return -l & max_value;
817	case MULT:
818		*overflow = r > 0 && l > max_value / r;
819		return l * r;
820	case DIV:
821		if (r == 0) {
822			/* division by 0 */
823			error(139);
824			return max_value;
825		}
826		return l / r;
827	case MOD:
828		if (r == 0) {
829			/* modulus by 0 */
830			error(140);
831			return 0;
832		}
833		return l % r;
834	case PLUS:
835		*overflow = l > max_value - r;
836		return l + r;
837	case MINUS:
838		*overflow = l < r;
839		return l - r;
840	case SHL:
841		/* TODO: warn about out-of-bounds 'r'. */
842		/* TODO: warn about overflow. */
843		return l << (r & 63);
844	case SHR:
845		/* TODO: warn about out-of-bounds 'r'. */
846		return l >> (r & 63);
847	case LT:
848		return l < r ? 1 : 0;
849	case LE:
850		return l <= r ? 1 : 0;
851	case GT:
852		return l > r ? 1 : 0;
853	case GE:
854		return l >= r ? 1 : 0;
855	case EQ:
856		return l == r ? 1 : 0;
857	case NE:
858		return l != r ? 1 : 0;
859	case BITAND:
860		return l & r;
861	case BITXOR:
862		return l ^ r;
863	case BITOR:
864		return l | r;
865	default:
866		lint_assert(/*CONSTCOND*/false);
867		/* NOTREACHED */
868	}
869}
870
871static int64_t
872fold_signed_integer(op_t op, int64_t l, int64_t r,
873		    int64_t min_value, int64_t max_value, bool *overflow)
874{
875	switch (op) {
876	case COMPL:
877		return ~l;
878	case UPLUS:
879		return +l;
880	case UMINUS:
881		*overflow = l == min_value;
882		return *overflow ? l : -l;
883	case MULT:;
884		uint64_t al = l >= 0 ? (uint64_t)l : -(uint64_t)l;
885		uint64_t ar = r >= 0 ? (uint64_t)r : -(uint64_t)r;
886		bool neg = (l >= 0) != (r >= 0);
887		uint64_t max_prod = (uint64_t)max_value + (neg ? 1 : 0);
888		if (al > 0 && ar > max_prod / al) {
889			*overflow = true;
890			return neg ? min_value : max_value;
891		}
892		return l * r;
893	case DIV:
894		if (r == 0) {
895			/* division by 0 */
896			error(139);
897			return max_value;
898		}
899		if (l == min_value && r == -1) {
900			*overflow = true;
901			return l;
902		}
903		return l / r;
904	case MOD:
905		if (r == 0) {
906			/* modulus by 0 */
907			error(140);
908			return 0;
909		}
910		if (l == min_value && r == -1) {
911			*overflow = true;
912			return 0;
913		}
914		return l % r;
915	case PLUS:
916		if (r > 0 && l > max_value - r) {
917			*overflow = true;
918			return max_value;
919		}
920		if (r < 0 && l < min_value - r) {
921			*overflow = true;
922			return min_value;
923		}
924		return l + r;
925	case MINUS:
926		if (r > 0 && l < min_value + r) {
927			*overflow = true;
928			return min_value;
929		}
930		if (r < 0 && l > max_value + r) {
931			*overflow = true;
932			return max_value;
933		}
934		return l - r;
935	case SHL:
936		/* TODO: warn about out-of-bounds 'r'. */
937		/* TODO: warn about overflow. */
938		return l << (r & 63);
939	case SHR:
940		/* TODO: warn about out-of-bounds 'r'. */
941		if (l < 0)
942			return (int64_t)~(~(uint64_t)l >> (r & 63));
943		return (int64_t)((uint64_t)l >> (r & 63));
944	case LT:
945		return l < r ? 1 : 0;
946	case LE:
947		return l <= r ? 1 : 0;
948	case GT:
949		return l > r ? 1 : 0;
950	case GE:
951		return l >= r ? 1 : 0;
952	case EQ:
953		return l == r ? 1 : 0;
954	case NE:
955		return l != r ? 1 : 0;
956	case BITAND:
957		return l & r;
958	case BITXOR:
959		return l ^ r;
960	case BITOR:
961		return l | r;
962	default:
963		lint_assert(/*CONSTCOND*/false);
964		/* NOTREACHED */
965	}
966}
967
968static tnode_t *
969fold_constant_integer(tnode_t *tn)
970{
971
972	lint_assert(has_operands(tn));
973	tspec_t t = tn->u.ops.left->tn_type->t_tspec;
974	int64_t l = tn->u.ops.left->u.value.u.integer;
975	int64_t r = is_binary(tn) ? tn->u.ops.right->u.value.u.integer : 0;
976	uint64_t mask = value_bits(size_in_bits(t));
977
978	int64_t res;
979	bool overflow = false;
980	if (!is_integer(t) || is_uinteger(t)) {
981		uint64_t u_res = fold_unsigned_integer(tn->tn_op,
982		    (uint64_t)l, (uint64_t)r, mask, &overflow);
983		if (u_res > mask)
984			overflow = true;
985		res = (int64_t)u_res;
986		if (overflow && hflag) {
987			char buf[128];
988			if (is_binary(tn)) {
989				snprintf(buf, sizeof(buf), "%ju %s %ju",
990				    (uintmax_t)l, op_name(tn->tn_op),
991				    (uintmax_t)r);
992			} else {
993				snprintf(buf, sizeof(buf), "%s%ju",
994				    op_name(tn->tn_op), (uintmax_t)l);
995			}
996			/* '%s' overflows '%s' */
997			warning(141, buf, type_name(tn->tn_type));
998		}
999	} else {
1000		int64_t max_value = (int64_t)(mask >> 1);
1001		int64_t min_value = -max_value - 1;
1002		res = fold_signed_integer(tn->tn_op,
1003		    l, r, min_value, max_value, &overflow);
1004		if (res < min_value || res > max_value)
1005			overflow = true;
1006		if (overflow && hflag) {
1007			char buf[128];
1008			if (is_binary(tn)) {
1009				snprintf(buf, sizeof(buf), "%jd %s %jd",
1010				    (intmax_t)l, op_name(tn->tn_op),
1011				    (intmax_t)r);
1012			} else if (tn->tn_op == UMINUS && l < 0) {
1013				snprintf(buf, sizeof(buf), "-(%jd)",
1014				    (intmax_t)l);
1015			} else {
1016				snprintf(buf, sizeof(buf), "%s%jd",
1017				    op_name(tn->tn_op), (intmax_t)l);
1018			}
1019			/* '%s' overflows '%s' */
1020			warning(141, buf, type_name(tn->tn_type));
1021		}
1022	}
1023
1024	val_t *v = xcalloc(1, sizeof(*v));
1025	v->v_tspec = tn->tn_type->t_tspec;
1026	v->u.integer = convert_integer(res, t, size_in_bits(t));
1027
1028	tnode_t *cn = build_constant(tn->tn_type, v);
1029	if (tn->u.ops.left->tn_system_dependent)
1030		cn->tn_system_dependent = true;
1031	if (is_binary(tn) && tn->u.ops.right->tn_system_dependent)
1032		cn->tn_system_dependent = true;
1033
1034	return cn;
1035}
1036
1037static tnode_t *
1038build_struct_access(op_t op, bool sys, tnode_t *ln, tnode_t *rn)
1039{
1040
1041	lint_assert(rn->tn_op == NAME);
1042	lint_assert(is_member(rn->u.sym));
1043
1044	bool lvalue = op == ARROW || ln->tn_lvalue;
1045
1046	if (op == POINT)
1047		ln = build_address(sys, ln, true);
1048	else if (ln->tn_type->t_tspec != PTR) {
1049		lint_assert(!allow_c90);
1050		lint_assert(is_integer(ln->tn_type->t_tspec));
1051		ln = convert(NOOP, 0, expr_derive_type(gettyp(VOID), PTR), ln);
1052	}
1053
1054	tnode_t *ctn = build_integer_constant(PTRDIFF_TSPEC,
1055	    rn->u.sym->u.s_member.sm_offset_in_bits / CHAR_SIZE);
1056
1057	type_t *ptr_tp = expr_derive_type(rn->tn_type, PTR);
1058	tnode_t *ntn = build_op(PLUS, sys, ptr_tp, ln, ctn);
1059	if (ln->tn_op == CON)
1060		ntn = fold_constant_integer(ntn);
1061
1062	op_t nop = rn->tn_type->t_bitfield ? FSEL : INDIR;
1063	ntn = build_op(nop, sys, ntn->tn_type->t_subt, ntn, NULL);
1064	if (!lvalue)
1065		ntn->tn_lvalue = false;
1066
1067	return ntn;
1068}
1069
1070/*
1071 * Get the size in bytes of type tp->t_subt, as a constant expression of type
1072 * ptrdiff_t as seen from the target platform.
1073 */
1074static tnode_t *
1075subt_size_in_bytes(type_t *tp)
1076{
1077
1078	lint_assert(tp->t_tspec == PTR);
1079	tp = tp->t_subt;
1080
1081	int elem = 1;
1082	while (tp->t_tspec == ARRAY) {
1083		elem *= tp->u.dimension;
1084		tp = tp->t_subt;
1085	}
1086
1087	int elsz_in_bits = 0;
1088	switch (tp->t_tspec) {
1089	case FUNC:
1090		/* pointer to function is not allowed here */
1091		error(110);
1092		break;
1093	case VOID:
1094		/* cannot do pointer arithmetic on operand of unknown size */
1095		gnuism(136);
1096		break;
1097	case STRUCT:
1098	case UNION:
1099		if ((elsz_in_bits = (int)tp->u.sou->sou_size_in_bits) == 0)
1100			/* cannot do pointer arithmetic on operand of ... */
1101			error(136);
1102		break;
1103	case ENUM:
1104		if (is_incomplete(tp))
1105			/* cannot do pointer arithmetic on operand of ... */
1106			warning(136);
1107		/* FALLTHROUGH */
1108	default:
1109		if ((elsz_in_bits = size_in_bits(tp->t_tspec)) == 0)
1110			/* cannot do pointer arithmetic on operand of ... */
1111			error(136);
1112		else
1113			lint_assert(elsz_in_bits != -1);
1114		break;
1115	}
1116
1117	if (elem == 0 && elsz_in_bits != 0)
1118		/* cannot do pointer arithmetic on operand of unknown size */
1119		error(136);
1120
1121	if (elsz_in_bits == 0)
1122		elsz_in_bits = CHAR_SIZE;
1123
1124	return build_integer_constant(PTRDIFF_TSPEC,
1125	    (int64_t)(elem * elsz_in_bits / CHAR_SIZE));
1126}
1127
1128static tnode_t *
1129build_prepost_incdec(op_t op, bool sys, tnode_t *ln)
1130{
1131
1132	lint_assert(ln != NULL);
1133	tnode_t *cn = ln->tn_type->t_tspec == PTR
1134	    ? subt_size_in_bytes(ln->tn_type)
1135	    : build_integer_constant(INT, 1);
1136	return build_op(op, sys, ln->tn_type, ln, cn);
1137}
1138
1139static void
1140check_enum_array_index(const tnode_t *ln, const tnode_t *rn)
1141{
1142
1143	if (ln->tn_op != ADDR || ln->u.ops.left->tn_op != NAME)
1144		return;
1145
1146	const type_t *ltp = ln->u.ops.left->tn_type;
1147	if (ltp->t_tspec != ARRAY || ltp->t_incomplete_array)
1148		return;
1149
1150	if (rn->tn_op != CVT || !rn->tn_type->t_is_enum)
1151		return;
1152	if (rn->u.ops.left->tn_op != LOAD)
1153		return;
1154
1155	const type_t *rtp = rn->u.ops.left->tn_type;
1156	const sym_t *ec = rtp->u.enumer->en_first_enumerator;
1157	const sym_t *max_ec = ec;
1158	lint_assert(ec != NULL);
1159	for (ec = ec->s_next; ec != NULL; ec = ec->s_next)
1160		if (ec->u.s_enum_constant > max_ec->u.s_enum_constant)
1161			max_ec = ec;
1162
1163	int64_t max_enum_value = max_ec->u.s_enum_constant;
1164	lint_assert(INT_MIN <= max_enum_value && max_enum_value <= INT_MAX);
1165
1166	int max_array_index = ltp->u.dimension - 1;
1167	if (max_enum_value == max_array_index)
1168		return;
1169
1170	if (max_enum_value == max_array_index + 1 &&
1171	    (strstr(max_ec->s_name, "MAX") != NULL ||
1172	     strstr(max_ec->s_name, "max") != NULL ||
1173	     strstr(max_ec->s_name, "NUM") != NULL ||
1174	     strstr(max_ec->s_name, "num") != NULL))
1175		return;
1176
1177	/* maximum value %d of '%s' does not match maximum array index %d */
1178	warning(348, (int)max_enum_value, type_name(rtp), max_array_index);
1179	print_previous_declaration(max_ec);
1180}
1181
1182static tnode_t *
1183build_plus_minus(op_t op, bool sys, tnode_t *ln, tnode_t *rn)
1184{
1185
1186	if (rn->tn_type->t_tspec == PTR && is_integer(ln->tn_type->t_tspec)) {
1187		tnode_t *tmp = ln;
1188		ln = rn;
1189		rn = tmp;
1190		/* pointer addition has integer on the left-hand side */
1191		query_message(5);
1192	}
1193
1194	/* pointer +- integer */
1195	tspec_t lt = ln->tn_type->t_tspec;
1196	tspec_t rt = rn->tn_type->t_tspec;
1197	if (lt == PTR && rt != PTR) {
1198		lint_assert(is_integer(rt));
1199
1200		check_ctype_macro_invocation(ln, rn);
1201		check_enum_array_index(ln, rn);
1202
1203		tnode_t *elsz = subt_size_in_bytes(ln->tn_type);
1204		tspec_t szt = elsz->tn_type->t_tspec;
1205		if (rt != szt && rt != unsigned_type(szt))
1206			rn = convert(NOOP, 0, elsz->tn_type, rn);
1207
1208		tnode_t *prod = build_op(MULT, sys, rn->tn_type, rn, elsz);
1209		if (rn->tn_op == CON)
1210			prod = fold_constant_integer(prod);
1211
1212		return build_op(op, sys, ln->tn_type, ln, prod);
1213	}
1214
1215	/* pointer - pointer */
1216	if (rt == PTR) {
1217		lint_assert(lt == PTR);
1218		lint_assert(op == MINUS);
1219
1220		type_t *ptrdiff = gettyp(PTRDIFF_TSPEC);
1221		tnode_t *raw_diff = build_op(op, sys, ptrdiff, ln, rn);
1222		if (ln->tn_op == CON && rn->tn_op == CON)
1223			raw_diff = fold_constant_integer(raw_diff);
1224
1225		tnode_t *elsz = subt_size_in_bytes(ln->tn_type);
1226		balance(NOOP, &raw_diff, &elsz);
1227
1228		return build_op(DIV, sys, ptrdiff, raw_diff, elsz);
1229	}
1230
1231	return build_op(op, sys, ln->tn_type, ln, rn);
1232}
1233
1234static tnode_t *
1235build_bit_shift(op_t op, bool sys, tnode_t *ln, tnode_t *rn)
1236{
1237
1238	if (!allow_c90 && rn->tn_type->t_tspec != INT)
1239		// XXX: C1978 7.5 says: "Both [operators] perform the usual
1240		// arithmetic conversions on their operands."
1241		// TODO: Add a test to exercise this part of the code.
1242		rn = convert(NOOP, 0, gettyp(INT), rn);
1243	return build_op(op, sys, ln->tn_type, ln, rn);
1244}
1245
1246static bool
1247is_null_pointer(const tnode_t *tn)
1248{
1249	tspec_t t = tn->tn_type->t_tspec;
1250
1251	// TODO: Investigate how other pointers are stored, in particular,
1252	// whether a pointer constant can have a non-zero value.
1253	// If not, simplify the code below.
1254	return ((t == PTR && tn->tn_type->t_subt->t_tspec == VOID)
1255		|| is_integer(t))
1256	    && (tn->tn_op == CON && tn->u.value.u.integer == 0);
1257}
1258
1259/* Return a type based on tp1, with added qualifiers from tp2. */
1260static type_t *
1261merge_qualifiers(type_t *tp1, const type_t *tp2)
1262{
1263
1264	lint_assert(tp1->t_tspec == PTR);
1265	lint_assert(tp2->t_tspec == PTR);
1266
1267	bool c1 = tp1->t_subt->t_const;
1268	bool c2 = tp2->t_subt->t_const;
1269	bool v1 = tp1->t_subt->t_volatile;
1270	bool v2 = tp2->t_subt->t_volatile;
1271
1272	if (c1 == (c1 | c2) && v1 == (v1 | v2))
1273		return tp1;
1274
1275	type_t *nstp = expr_dup_type(tp1->t_subt);
1276	nstp->t_const |= c2;
1277	nstp->t_volatile |= v2;
1278
1279	type_t *ntp = expr_dup_type(tp1);
1280	ntp->t_subt = nstp;
1281	return ntp;
1282}
1283
1284/* See C99 6.5.15 "Conditional operator". */
1285static tnode_t *
1286build_colon(bool sys, tnode_t *ln, tnode_t *rn)
1287{
1288	tspec_t lt = ln->tn_type->t_tspec;
1289	tspec_t rt = rn->tn_type->t_tspec;
1290
1291	type_t *tp;
1292	if (is_arithmetic(lt) && is_arithmetic(rt))
1293		/* The operands were already balanced in build_binary. */
1294		tp = ln->tn_type;
1295	else if (lt == BOOL && rt == BOOL)
1296		tp = ln->tn_type;
1297	else if (lt == VOID || rt == VOID)
1298		tp = gettyp(VOID);
1299	else if (is_struct_or_union(lt)) {
1300		lint_assert(is_struct_or_union(rt));
1301		lint_assert(ln->tn_type->u.sou == rn->tn_type->u.sou);
1302		if (is_incomplete(ln->tn_type)) {
1303			/* unknown operand size, op '%s' */
1304			error(138, op_name(COLON));
1305			return NULL;
1306		}
1307		tp = ln->tn_type;
1308	} else if (lt == PTR && is_integer(rt)) {
1309		if (rt != PTRDIFF_TSPEC)
1310			rn = convert(NOOP, 0, gettyp(PTRDIFF_TSPEC), rn);
1311		tp = ln->tn_type;
1312	} else if (rt == PTR && is_integer(lt)) {
1313		if (lt != PTRDIFF_TSPEC)
1314			ln = convert(NOOP, 0, gettyp(PTRDIFF_TSPEC), ln);
1315		tp = rn->tn_type;
1316	} else if (lt == PTR && is_null_pointer(rn))
1317		tp = merge_qualifiers(ln->tn_type, rn->tn_type);
1318	else if (rt == PTR && is_null_pointer(ln))
1319		tp = merge_qualifiers(rn->tn_type, ln->tn_type);
1320	else if (lt == PTR && ln->tn_type->t_subt->t_tspec == VOID)
1321		tp = merge_qualifiers(ln->tn_type, rn->tn_type);
1322	else if (rt == PTR && rn->tn_type->t_subt->t_tspec == VOID)
1323		tp = merge_qualifiers(rn->tn_type, ln->tn_type);
1324	else {
1325		/*
1326		 * XXX For now we simply take the left type. This is probably
1327		 * wrong, if one type contains a function prototype and the
1328		 * other one, at the same place, only an old-style declaration.
1329		 */
1330		tp = merge_qualifiers(ln->tn_type, rn->tn_type);
1331	}
1332
1333	return build_op(COLON, sys, tp, ln, rn);
1334}
1335
1336/* TODO: check for varargs */
1337static bool
1338is_cast_redundant(const tnode_t *tn)
1339{
1340	const type_t *ntp = tn->tn_type, *otp = tn->u.ops.left->tn_type;
1341	tspec_t nt = ntp->t_tspec, ot = otp->t_tspec;
1342
1343	if (nt == BOOL || ot == BOOL)
1344		return nt == BOOL && ot == BOOL;
1345
1346	if (is_integer(nt) && is_integer(ot)) {
1347		unsigned int nw = width_in_bits(ntp), ow = width_in_bits(otp);
1348		if (is_uinteger(nt) == is_uinteger(ot))
1349			return nw >= ow;
1350		return is_uinteger(ot) && nw > ow;
1351	}
1352
1353	if (is_complex(nt) || is_complex(ot))
1354		return is_complex(nt) && is_complex(ot) &&
1355		    size_in_bits(nt) >= size_in_bits(ot);
1356
1357	if (is_floating(nt) && is_floating(ot))
1358		return size_in_bits(nt) >= size_in_bits(ot);
1359
1360	if (nt == PTR && ot == PTR) {
1361		if (!ntp->t_subt->t_const && otp->t_subt->t_const)
1362			return false;
1363		if (!ntp->t_subt->t_volatile && otp->t_subt->t_volatile)
1364			return false;
1365
1366		if (ntp->t_subt->t_tspec == VOID ||
1367		    otp->t_subt->t_tspec == VOID ||
1368		    types_compatible(ntp->t_subt, otp->t_subt,
1369			false, false, NULL))
1370			return true;
1371	}
1372
1373	return false;
1374}
1375
1376static bool
1377is_assignment(op_t op)
1378{
1379
1380	return op == ASSIGN ||
1381	    op == MULASS ||
1382	    op == DIVASS ||
1383	    op == MODASS ||
1384	    op == ADDASS ||
1385	    op == SUBASS ||
1386	    op == SHLASS ||
1387	    op == SHRASS ||
1388	    op == ANDASS ||
1389	    op == XORASS ||
1390	    op == ORASS ||
1391	    op == RETURN ||
1392	    op == INIT;
1393}
1394
1395static tnode_t *
1396build_assignment(op_t op, bool sys, tnode_t *ln, tnode_t *rn)
1397{
1398
1399	tspec_t lt = ln->tn_type->t_tspec;
1400	tspec_t rt = rn->tn_type->t_tspec;
1401
1402	if (any_query_enabled && is_assignment(rn->tn_op)) {
1403		/* chained assignment with '%s' and '%s' */
1404		query_message(10, op_name(op), op_name(rn->tn_op));
1405	}
1406
1407	if ((op == ADDASS || op == SUBASS) && lt == PTR) {
1408		lint_assert(is_integer(rt));
1409		tnode_t *ctn = subt_size_in_bytes(ln->tn_type);
1410		if (rn->tn_type->t_tspec != ctn->tn_type->t_tspec)
1411			rn = convert(NOOP, 0, ctn->tn_type, rn);
1412		rn = build_op(MULT, sys, rn->tn_type, rn, ctn);
1413		if (rn->u.ops.left->tn_op == CON)
1414			rn = fold_constant_integer(rn);
1415	}
1416
1417	if ((op == ASSIGN || op == RETURN || op == INIT) &&
1418	    (lt == STRUCT || rt == STRUCT)) {
1419		lint_assert(lt == rt);
1420		lint_assert(ln->tn_type->u.sou == rn->tn_type->u.sou);
1421		if (is_incomplete(ln->tn_type)) {
1422			if (op == RETURN)
1423				/* cannot return incomplete type */
1424				error(212);
1425			else
1426				/* unknown operand size, op '%s' */
1427				error(138, op_name(op));
1428			return NULL;
1429		}
1430	}
1431
1432	if (op == SHLASS && hflag && allow_trad && allow_c90
1433	    && portable_rank_cmp(lt, rt) < 0)
1434		/* semantics of '%s' change in C90; ... */
1435		warning(118, "<<=");
1436
1437	if (op != SHLASS && op != SHRASS
1438	    && (op == ASSIGN || lt != PTR)
1439	    && (lt != rt || (ln->tn_type->t_bitfield && rn->tn_op == CON))) {
1440		rn = convert(op, 0, ln->tn_type, rn);
1441		rt = lt;
1442	}
1443
1444	if (is_query_enabled[20]
1445	    && lt == PTR && ln->tn_type->t_subt->t_tspec != VOID
1446	    && rt == PTR && rn->tn_type->t_subt->t_tspec == VOID
1447	    && !is_null_pointer(rn))
1448		/* implicit narrowing conversion from void ... */
1449		query_message(20, type_name(ln->tn_type));
1450
1451	if (any_query_enabled && rn->tn_op == CVT && rn->tn_cast &&
1452	    types_compatible(ln->tn_type, rn->tn_type, false, false, NULL) &&
1453	    is_cast_redundant(rn)) {
1454		/* redundant cast from '%s' to '%s' before assignment */
1455		query_message(7, type_name(rn->u.ops.left->tn_type),
1456		    type_name(rn->tn_type));
1457	}
1458
1459	return build_op(op, sys, ln->tn_type, ln, rn);
1460}
1461
1462static tnode_t *
1463build_real_imag(op_t op, bool sys, tnode_t *ln)
1464{
1465
1466	lint_assert(ln != NULL);
1467	if (ln->tn_op == NAME) {
1468		/*
1469		 * This may be too much, but it avoids wrong warnings. See
1470		 * d_c99_complex_split.c.
1471		 */
1472		mark_as_used(ln->u.sym, false, false);
1473		mark_as_set(ln->u.sym);
1474	}
1475
1476	tspec_t t;
1477	switch (ln->tn_type->t_tspec) {
1478	case LCOMPLEX:
1479		t = LDOUBLE;
1480		break;
1481	case DCOMPLEX:
1482		t = DOUBLE;
1483		break;
1484	case FCOMPLEX:
1485		t = FLOAT;
1486		break;
1487	default:
1488		/* '__%s__' is illegal for type '%s' */
1489		error(276, op == REAL ? "real" : "imag",
1490		    type_name(ln->tn_type));
1491		return NULL;
1492	}
1493
1494	tnode_t *ntn = build_op(op, sys, gettyp(t), ln, NULL);
1495	ntn->tn_lvalue = true;
1496	return ntn;
1497}
1498
1499static bool
1500is_confusing_precedence(op_t op, op_t lop, bool lparen, op_t rop, bool rparen)
1501{
1502
1503	if (op == SHL || op == SHR) {
1504		if (!lparen && (lop == PLUS || lop == MINUS))
1505			return true;
1506		if (!rparen && (rop == PLUS || rop == MINUS))
1507			return true;
1508		return false;
1509	}
1510
1511	if (op == LOGOR) {
1512		if (!lparen && lop == LOGAND)
1513			return true;
1514		if (!rparen && rop == LOGAND)
1515			return true;
1516		return false;
1517	}
1518
1519	lint_assert(op == BITAND || op == BITXOR || op == BITOR);
1520	if (!lparen && lop != op) {
1521		if (lop == PLUS || lop == MINUS)
1522			return true;
1523		if (lop == BITAND || lop == BITXOR)
1524			return true;
1525	}
1526	if (!rparen && rop != op) {
1527		if (rop == PLUS || rop == MINUS)
1528			return true;
1529		if (rop == BITAND || rop == BITXOR)
1530			return true;
1531	}
1532	return false;
1533}
1534
1535/*
1536 * Print a warning if the given node has operands which should be
1537 * parenthesized.
1538 *
1539 * XXX Does not work if an operand is a constant expression. Constant
1540 * expressions are already folded.
1541 */
1542static void
1543check_precedence_confusion(tnode_t *tn)
1544{
1545	tnode_t *ln, *rn;
1546
1547	if (!hflag)
1548		return;
1549
1550	debug_node(tn);
1551
1552	lint_assert(is_binary(tn));
1553	for (ln = tn->u.ops.left; ln->tn_op == CVT; ln = ln->u.ops.left)
1554		continue;
1555	for (rn = tn->u.ops.right; rn->tn_op == CVT; rn = rn->u.ops.left)
1556		continue;
1557
1558	if (is_confusing_precedence(tn->tn_op,
1559	    ln->tn_op, ln->tn_parenthesized,
1560	    rn->tn_op, rn->tn_parenthesized)) {
1561		/* precedence confusion possible: parenthesize! */
1562		warning(169);
1563	}
1564}
1565
1566static tnode_t *
1567fold_constant_compare_zero(tnode_t *tn)
1568{
1569
1570	val_t *v = xcalloc(1, sizeof(*v));
1571	v->v_tspec = tn->tn_type->t_tspec;
1572	lint_assert(v->v_tspec == INT || (Tflag && v->v_tspec == BOOL));
1573
1574	lint_assert(has_operands(tn));
1575	bool l = constant_is_nonzero(tn->u.ops.left);
1576	bool r = is_binary(tn) && constant_is_nonzero(tn->u.ops.right);
1577
1578	switch (tn->tn_op) {
1579	case NOT:
1580		if (hflag && !suppress_constcond)
1581			/* constant operand to '!' */
1582			warning(239);
1583		v->u.integer = !l ? 1 : 0;
1584		break;
1585	case LOGAND:
1586		v->u.integer = l && r ? 1 : 0;
1587		break;
1588	case LOGOR:
1589		v->u.integer = l || r ? 1 : 0;
1590		break;
1591	default:
1592		lint_assert(/*CONSTCOND*/false);
1593	}
1594
1595	return build_constant(tn->tn_type, v);
1596}
1597
1598static long double
1599floating_error_value(tspec_t t, long double lv)
1600{
1601	if (t == FLOAT)
1602		return lv < 0 ? -FLT_MAX : FLT_MAX;
1603	if (t == DOUBLE)
1604		return lv < 0 ? -DBL_MAX : DBL_MAX;
1605	/*
1606	 * When NetBSD is cross-built in MKLINT=yes mode on x86_64 for sparc64,
1607	 * tools/lint checks this code while building usr.bin/xlint. In that
1608	 * situation, lint uses the preprocessor for sparc64, in which the type
1609	 * 'long double' is IEEE-754-binary128, affecting the macro LDBL_MAX
1610	 * below. The type 'long double', as well as the strtold
1611	 * implementation, comes from the host platform x86_64 though, where
1612	 * 'long double' consumes 128 bits as well but only uses 80 of them.
1613	 * The exponent range of the two 'long double' types is the same, but
1614	 * the maximum finite value differs due to the extended precision on
1615	 * sparc64.
1616	 *
1617	 * To properly handle the data types of the target platform, lint would
1618	 * have to implement the floating-point types in a platform-independent
1619	 * way, which is not worth the effort, given how few programs
1620	 * practically use 'long double'.
1621	 */
1622	/* LINTED 248: floating-point constant out of range */
1623	long double max = LDBL_MAX;
1624	return lv < 0 ? -max : max;
1625}
1626
1627static bool
1628is_floating_overflow(tspec_t t, long double val)
1629{
1630	if (fpe != 0 || isfinite(val) == 0)
1631		return true;
1632	if (t == FLOAT && (val > FLT_MAX || val < -FLT_MAX))
1633		return true;
1634	if (t == DOUBLE && (val > DBL_MAX || val < -DBL_MAX))
1635		return true;
1636	return false;
1637}
1638
1639static tnode_t *
1640fold_constant_floating(tnode_t *tn)
1641{
1642
1643	fpe = 0;
1644
1645	tspec_t t = tn->tn_type->t_tspec;
1646
1647	val_t *v = xcalloc(1, sizeof(*v));
1648	v->v_tspec = t;
1649
1650	lint_assert(is_floating(t));
1651	lint_assert(has_operands(tn));
1652	lint_assert(t == tn->u.ops.left->tn_type->t_tspec);
1653	lint_assert(!is_binary(tn) || t == tn->u.ops.right->tn_type->t_tspec);
1654
1655	long double lv = tn->u.ops.left->u.value.u.floating;
1656	long double rv = is_binary(tn) ? tn->u.ops.right->u.value.u.floating
1657	    : 0.0;
1658
1659	switch (tn->tn_op) {
1660	case UPLUS:
1661		v->u.floating = lv;
1662		break;
1663	case UMINUS:
1664		v->u.floating = -lv;
1665		break;
1666	case MULT:
1667		v->u.floating = lv * rv;
1668		break;
1669	case DIV:
1670		if (rv == 0.0) {
1671			/* division by 0 */
1672			error(139);
1673			v->u.floating = floating_error_value(t, lv);
1674		} else {
1675			v->u.floating = lv / rv;
1676		}
1677		break;
1678	case PLUS:
1679		v->u.floating = lv + rv;
1680		break;
1681	case MINUS:
1682		v->u.floating = lv - rv;
1683		break;
1684	case LT:
1685		v->u.integer = lv < rv ? 1 : 0;
1686		break;
1687	case LE:
1688		v->u.integer = lv <= rv ? 1 : 0;
1689		break;
1690	case GE:
1691		v->u.integer = lv >= rv ? 1 : 0;
1692		break;
1693	case GT:
1694		v->u.integer = lv > rv ? 1 : 0;
1695		break;
1696	case EQ:
1697		v->u.integer = lv == rv ? 1 : 0;
1698		break;
1699	case NE:
1700		v->u.integer = lv != rv ? 1 : 0;
1701		break;
1702	default:
1703		lint_assert(/*CONSTCOND*/false);
1704	}
1705
1706	// XXX: Must not access u.floating after setting u.integer.
1707	lint_assert(fpe != 0 || isnan(v->u.floating) == 0);
1708	if (is_complex(v->v_tspec)) {
1709		/*
1710		 * Don't warn, as lint doesn't model the imaginary part of
1711		 * complex numbers.
1712		 */
1713		fpe = 0;
1714	} else if (is_floating_overflow(t, v->u.floating)) {
1715		/* operator '%s' produces floating point overflow */
1716		warning(142, op_name(tn->tn_op));
1717		v->u.floating = floating_error_value(t, v->u.floating);
1718		fpe = 0;
1719	}
1720
1721	return build_constant(tn->tn_type, v);
1722}
1723
1724static void
1725use(const tnode_t *tn)
1726{
1727	if (tn == NULL)
1728		return;
1729	switch (tn->tn_op) {
1730	case NAME:
1731		mark_as_used(tn->u.sym, false /* XXX */, false /* XXX */);
1732		break;
1733	case CON:
1734	case STRING:
1735		break;
1736	case CALL:;
1737		const function_call *call = tn->u.call;
1738		for (size_t i = 0, n = call->args_len; i < n; i++)
1739			use(call->args[i]);
1740		break;
1741	default:
1742		lint_assert(has_operands(tn));
1743		use(tn->u.ops.left);
1744		if (is_binary(tn))
1745			use(tn->u.ops.right);
1746	}
1747}
1748
1749/*
1750 * Create a tree node for a binary operator and its two operands. Also called
1751 * for unary operators; in that case rn is NULL.
1752 *
1753 * Function calls, sizeof and casts are handled elsewhere.
1754 */
1755tnode_t *
1756build_binary(tnode_t *ln, op_t op, bool sys, tnode_t *rn)
1757{
1758	const mod_t *mp = &modtab[op];
1759
1760	/* If there was an error in one of the operands, return. */
1761	if (ln == NULL || (mp->m_binary && rn == NULL))
1762		return NULL;
1763
1764	if (mp->m_value_context || mp->m_compares_with_zero)
1765		ln = cconv(ln);
1766	if (mp->m_binary && op != ARROW && op != POINT)
1767		rn = cconv(rn);
1768
1769	if (mp->m_comparison)
1770		check_integer_comparison(op, ln, rn);
1771
1772	if (mp->m_value_context || mp->m_compares_with_zero)
1773		ln = promote(op, false, ln);
1774	if (mp->m_binary && op != ARROW && op != POINT &&
1775	    op != ASSIGN && op != RETURN && op != INIT)
1776		rn = promote(op, false, rn);
1777
1778	if (mp->m_warn_if_left_unsigned_in_c90 &&
1779	    ln->tn_op == CON && ln->u.value.v_unsigned_since_c90) {
1780		/* C90 treats constant as unsigned, op '%s' */
1781		warning(218, op_name(op));
1782		ln->u.value.v_unsigned_since_c90 = false;
1783	}
1784	if (mp->m_warn_if_right_unsigned_in_c90 &&
1785	    rn->tn_op == CON && rn->u.value.v_unsigned_since_c90) {
1786		/* C90 treats constant as unsigned, op '%s' */
1787		warning(218, op_name(op));
1788		rn->u.value.v_unsigned_since_c90 = false;
1789	}
1790
1791	if (mp->m_balance_operands || (!allow_c90 && (op == SHL || op == SHR)))
1792		balance(op, &ln, &rn);
1793
1794	if (!typeok(op, 0, ln, rn))
1795		return NULL;
1796
1797	tnode_t *ntn;
1798	switch (op) {
1799	case POINT:
1800	case ARROW:
1801		ntn = build_struct_access(op, sys, ln, rn);
1802		break;
1803	case INCAFT:
1804	case DECAFT:
1805	case INCBEF:
1806	case DECBEF:
1807		ntn = build_prepost_incdec(op, sys, ln);
1808		break;
1809	case ADDR:
1810		ntn = build_address(sys, ln, false);
1811		break;
1812	case INDIR:
1813		ntn = build_op(INDIR, sys, ln->tn_type->t_subt, ln, NULL);
1814		break;
1815	case PLUS:
1816	case MINUS:
1817		ntn = build_plus_minus(op, sys, ln, rn);
1818		break;
1819	case SHL:
1820	case SHR:
1821		ntn = build_bit_shift(op, sys, ln, rn);
1822		break;
1823	case COLON:
1824		ntn = build_colon(sys, ln, rn);
1825		break;
1826	case ASSIGN:
1827	case MULASS:
1828	case DIVASS:
1829	case MODASS:
1830	case ADDASS:
1831	case SUBASS:
1832	case SHLASS:
1833	case SHRASS:
1834	case ANDASS:
1835	case XORASS:
1836	case ORASS:
1837	case RETURN:
1838	case INIT:
1839		ntn = build_assignment(op, sys, ln, rn);
1840		break;
1841	case COMMA:
1842		if (any_query_enabled) {
1843			/* comma operator with types '%s' and '%s' */
1844			query_message(12,
1845			    type_name(ln->tn_type), type_name(rn->tn_type));
1846		}
1847		/* FALLTHROUGH */
1848	case QUEST:
1849		ntn = build_op(op, sys, rn->tn_type, ln, rn);
1850		break;
1851	case REAL:
1852	case IMAG:
1853		ntn = build_real_imag(op, sys, ln);
1854		break;
1855	default:
1856		lint_assert(mp->m_binary == (rn != NULL));
1857		type_t *rettp = mp->m_returns_bool
1858		    ? gettyp(Tflag ? BOOL : INT) : ln->tn_type;
1859		ntn = build_op(op, sys, rettp, ln, rn);
1860		break;
1861	}
1862
1863	if (ntn == NULL)
1864		return NULL;
1865
1866	if (mp->m_possible_precedence_confusion)
1867		check_precedence_confusion(ntn);
1868
1869	if (hflag && !suppress_constcond &&
1870	    mp->m_compares_with_zero &&
1871	    (ln->tn_op == CON ||
1872	     (mp->m_binary && op != QUEST && rn->tn_op == CON)) &&
1873	    /* XXX: rn->tn_system_dependent should be checked as well */
1874	    !ln->tn_system_dependent)
1875		/* constant in conditional context */
1876		warning(161);
1877
1878	if (mp->m_fold_constant_operands && ln->tn_op == CON) {
1879		if (!mp->m_binary || rn->tn_op == CON) {
1880			if (mp->m_compares_with_zero)
1881				ntn = fold_constant_compare_zero(ntn);
1882			else if (is_floating(ntn->tn_type->t_tspec))
1883				ntn = fold_constant_floating(ntn);
1884			else
1885				ntn = fold_constant_integer(ntn);
1886		} else if (op == QUEST) {
1887			lint_assert(has_operands(rn));
1888			use(ln->u.value.u.integer != 0
1889			    ? rn->u.ops.right : rn->u.ops.left);
1890			ntn = ln->u.value.u.integer != 0
1891			    ? rn->u.ops.left : rn->u.ops.right;
1892		}
1893	}
1894
1895	return ntn;
1896}
1897
1898tnode_t *
1899build_unary(op_t op, bool sys, tnode_t *tn)
1900{
1901	return build_binary(tn, op, sys, NULL);
1902}
1903
1904static bool
1905are_members_compatible(const sym_t *a, const sym_t *b)
1906{
1907	if (a->u.s_member.sm_offset_in_bits != b->u.s_member.sm_offset_in_bits)
1908		return false;
1909
1910	const type_t *atp = a->s_type;
1911	const type_t *btp = b->s_type;
1912	bool w = false;
1913	if (!types_compatible(atp, btp, false, false, &w) && !w)
1914		return false;
1915	if (a->s_bitfield != b->s_bitfield)
1916		return false;
1917	if (a->s_bitfield) {
1918		if (atp->t_bit_field_width != btp->t_bit_field_width)
1919			return false;
1920		if (atp->t_bit_field_offset != btp->t_bit_field_offset)
1921			return false;
1922	}
1923	return true;
1924}
1925
1926/*
1927 * Return whether all struct/union members with the same name have the same
1928 * type and offset.
1929 */
1930static bool
1931all_members_compatible(const sym_t *msym)
1932{
1933	for (const sym_t *csym = msym;
1934	    csym != NULL; csym = csym->s_symtab_next) {
1935		if (!is_member(csym))
1936			continue;
1937		if (strcmp(msym->s_name, csym->s_name) != 0)
1938			continue;
1939
1940		for (const sym_t *sym = csym->s_symtab_next;
1941		    sym != NULL; sym = sym->s_symtab_next) {
1942			if (is_member(sym)
1943			    && strcmp(csym->s_name, sym->s_name) == 0
1944			    && !are_members_compatible(csym, sym))
1945				return false;
1946		}
1947	}
1948	return true;
1949}
1950
1951sym_t *
1952find_member(const struct_or_union *sou, const char *name)
1953{
1954	for (sym_t *mem = sou->sou_first_member;
1955	    mem != NULL; mem = mem->s_next) {
1956		lint_assert(is_member(mem));
1957		lint_assert(mem->u.s_member.sm_containing_type == sou);
1958		if (strcmp(mem->s_name, name) == 0)
1959			return mem;
1960	}
1961
1962	for (sym_t *mem = sou->sou_first_member;
1963	    mem != NULL; mem = mem->s_next) {
1964		if (is_struct_or_union(mem->s_type->t_tspec)
1965		    && mem->s_name == unnamed) {
1966			sym_t *nested_mem =
1967			    find_member(mem->s_type->u.sou, name);
1968			if (nested_mem != NULL)
1969				return nested_mem;
1970		}
1971	}
1972	return NULL;
1973}
1974
1975/*
1976 * Remove the member if it was unknown until now, which means
1977 * that no defined struct or union has a member with the same name.
1978 */
1979static void
1980remove_unknown_member(tnode_t *tn, sym_t *msym)
1981{
1982	/* type '%s' does not have member '%s' */
1983	error(101, type_name(tn->tn_type), msym->s_name);
1984	symtab_remove_forever(msym);
1985	msym->s_kind = SK_MEMBER;
1986	msym->s_scl = STRUCT_MEMBER;
1987
1988	struct_or_union *sou = expr_zero_alloc(sizeof(*sou),
1989	    "struct_or_union");
1990	sou->sou_tag = expr_zero_alloc(sizeof(*sou->sou_tag), "sym");
1991	sou->sou_tag->s_name = unnamed;
1992
1993	msym->u.s_member.sm_containing_type = sou;
1994	/*
1995	 * The member sm_offset_in_bits is not needed here since this symbol
1996	 * can only be used for error reporting.
1997	 */
1998}
1999
2000/*
2001 * Returns a symbol which has the same name as 'msym' and is a member of the
2002 * struct or union specified by 'tn'.
2003 */
2004static sym_t *
2005struct_or_union_member(tnode_t *tn, op_t op, sym_t *msym)
2006{
2007
2008	/* Determine the tag type of which msym is expected to be a member. */
2009	const type_t *tp = NULL;
2010	if (op == POINT && is_struct_or_union(tn->tn_type->t_tspec))
2011		tp = tn->tn_type;
2012	if (op == ARROW && tn->tn_type->t_tspec == PTR
2013	    && is_struct_or_union(tn->tn_type->t_subt->t_tspec))
2014		tp = tn->tn_type->t_subt;
2015	struct_or_union *sou = tp != NULL ? tp->u.sou : NULL;
2016
2017	if (sou != NULL) {
2018		sym_t *nested_mem = find_member(sou, msym->s_name);
2019		if (nested_mem != NULL)
2020			return nested_mem;
2021	}
2022
2023	if (msym->s_scl == NO_SCL) {
2024		remove_unknown_member(tn, msym);
2025		return msym;
2026	}
2027
2028	bool eq = all_members_compatible(msym);
2029
2030	/*
2031	 * Now handle the case in which the left operand refers really to a
2032	 * struct/union, but the right operand is not member of it.
2033	 */
2034	if (sou != NULL) {
2035		if (eq && !allow_c90)
2036			/* illegal use of member '%s' */
2037			warning(102, msym->s_name);
2038		else
2039			/* illegal use of member '%s' */
2040			error(102, msym->s_name);
2041		return msym;
2042	}
2043
2044	if (eq) {
2045		if (op == POINT) {
2046			if (!allow_c90)
2047				/* left operand of '.' must be struct ... */
2048				warning(103, type_name(tn->tn_type));
2049			else
2050				/* left operand of '.' must be struct ... */
2051				error(103, type_name(tn->tn_type));
2052		} else {
2053			if (!allow_c90 && tn->tn_type->t_tspec == PTR)
2054				/* left operand of '->' must be pointer ... */
2055				warning(104, type_name(tn->tn_type));
2056			else
2057				/* left operand of '->' must be pointer ... */
2058				error(104, type_name(tn->tn_type));
2059		}
2060	} else {
2061		if (!allow_c90)
2062			/* non-unique member requires struct/union %s */
2063			error(105, op == POINT ? "object" : "pointer");
2064		else
2065			/* unacceptable operand of '%s' */
2066			error(111, op_name(op));
2067	}
2068
2069	return msym;
2070}
2071
2072tnode_t *
2073build_member_access(tnode_t *ln, op_t op, bool sys, sbuf_t *member)
2074{
2075	sym_t *msym;
2076
2077	if (ln == NULL)
2078		return NULL;
2079
2080	if (op == ARROW)
2081		/* must do this before struct_or_union_member is called */
2082		ln = cconv(ln);
2083	msym = struct_or_union_member(ln, op, getsym(member));
2084	return build_binary(ln, op, sys, build_name(msym, false));
2085}
2086
2087/*
2088 * Perform class conversions.
2089 *
2090 * Arrays of type T are converted into pointers to type T.
2091 * Functions are converted to pointers to functions.
2092 * Lvalues are converted to rvalues.
2093 *
2094 * C99 6.3 "Conversions"
2095 * C99 6.3.2 "Other operands"
2096 * C99 6.3.2.1 "Lvalues, arrays, and function designators"
2097 */
2098tnode_t *
2099cconv(tnode_t *tn)
2100{
2101	if (tn->tn_type->t_tspec == ARRAY) {
2102		if (!tn->tn_lvalue) {
2103			/* XXX print correct operator */
2104			/* %soperand of '%s' must be lvalue */
2105			gnuism(114, "", op_name(ADDR));
2106		}
2107		tn = build_op(ADDR, tn->tn_sys,
2108		    expr_derive_type(tn->tn_type->t_subt, PTR), tn, NULL);
2109	}
2110
2111	if (tn->tn_type->t_tspec == FUNC)
2112		tn = build_address(tn->tn_sys, tn, true);
2113
2114	if (tn->tn_lvalue) {
2115		type_t *tp = expr_dup_type(tn->tn_type);
2116		/* C99 6.3.2.1p2 sentence 2 says to remove the qualifiers. */
2117		tp->t_const = tp->t_volatile = false;
2118		tn = build_op(LOAD, tn->tn_sys, tp, tn, NULL);
2119	}
2120
2121	return tn;
2122}
2123
2124const tnode_t *
2125before_conversion(const tnode_t *tn)
2126{
2127	while (tn->tn_op == CVT && !tn->tn_cast)
2128		tn = tn->u.ops.left;
2129	return tn;
2130}
2131
2132/*
2133 * Most errors required by C90 are reported in struct_or_union_member().
2134 * Here we only check for totally wrong things.
2135 */
2136static bool
2137typeok_point(const tnode_t *ln, const type_t *ltp, tspec_t lt)
2138{
2139	if (is_struct_or_union(lt))
2140		return true;
2141
2142	if (lt == FUNC || lt == VOID || ltp->t_bitfield)
2143		goto wrong;
2144
2145	/*
2146	 * Some C dialects from before C90 tolerated any lvalue on the
2147	 * left-hand side of the '.' operator, allowing things like 'char
2148	 * st[100]; st.st_mtime', assuming that the member 'st_mtime' only
2149	 * occurred in a single struct; see typeok_arrow.
2150	 */
2151	if (ln->tn_lvalue)
2152		return true;
2153
2154wrong:
2155	/* With allow_c90 we already got an error */
2156	if (!allow_c90)
2157		/* unacceptable operand of '%s' */
2158		error(111, op_name(POINT));
2159
2160	return false;
2161}
2162
2163static bool
2164typeok_arrow(tspec_t lt)
2165{
2166	/*
2167	 * C1978 Appendix A 14.1 says: <quote>In fact, any lvalue is allowed
2168	 * before '.', and that lvalue is then assumed to have the form of the
2169	 * structure of which the name of the right is a member. [...] Such
2170	 * constructions are non-portable.</quote>
2171	 */
2172	if (lt == PTR || (!allow_c90 && is_integer(lt)))
2173		return true;
2174
2175	/* With allow_c90 we already got an error */
2176	if (!allow_c90)
2177		/* unacceptable operand of '%s' */
2178		error(111, op_name(ARROW));
2179	return false;
2180}
2181
2182static bool
2183typeok_incdec(op_t op, const tnode_t *tn, const type_t *tp)
2184{
2185	/* operand has scalar type (checked in typeok) */
2186	if (!tn->tn_lvalue) {
2187		if (tn->tn_op == CVT && tn->tn_cast &&
2188		    tn->u.ops.left->tn_op == LOAD)
2189			/* a cast does not yield an lvalue */
2190			error(163);
2191		/* %soperand of '%s' must be lvalue */
2192		error(114, "", op_name(op));
2193		return false;
2194	}
2195	if (tp->t_const && allow_c90)
2196		/* %soperand of '%s' must be modifiable lvalue */
2197		warning(115, "", op_name(op));
2198	return true;
2199}
2200
2201static bool
2202typeok_address(op_t op, const tnode_t *tn, const type_t *tp, tspec_t t)
2203{
2204	if (t == ARRAY || t == FUNC) {
2205		/* ok, a warning comes later (in build_address()) */
2206	} else if (!tn->tn_lvalue) {
2207		if (tn->tn_op == CVT && tn->tn_cast &&
2208		    tn->u.ops.left->tn_op == LOAD)
2209			/* a cast does not yield an lvalue */
2210			error(163);
2211		/* %soperand of '%s' must be lvalue */
2212		error(114, "", op_name(op));
2213		return false;
2214	} else if (is_scalar(t)) {
2215		if (tp->t_bitfield) {
2216			/* cannot take address of bit-field */
2217			error(112);
2218			return false;
2219		}
2220	} else if (t != STRUCT && t != UNION) {
2221		/* unacceptable operand of '%s' */
2222		error(111, op_name(op));
2223		return false;
2224	}
2225	if (tn->tn_op == NAME && tn->u.sym->s_register) {
2226		/* cannot take address of register '%s' */
2227		error(113, tn->u.sym->s_name);
2228		return false;
2229	}
2230	return true;
2231}
2232
2233static bool
2234typeok_indir(const type_t *tp, tspec_t t)
2235{
2236
2237	if (t != PTR) {
2238		/* cannot dereference non-pointer type '%s' */
2239		error(96, type_name(tp));
2240		return false;
2241	}
2242	return true;
2243}
2244
2245static void
2246warn_incompatible_types(op_t op,
2247			const type_t *ltp, tspec_t lt,
2248			const type_t *rtp, tspec_t rt)
2249{
2250	bool binary = modtab[op].m_binary;
2251
2252	if (lt == VOID || (binary && rt == VOID)) {
2253		/* void type illegal in expression */
2254		error(109);
2255	} else if (op == ASSIGN)
2256		/* cannot assign to '%s' from '%s' */
2257		error(171, type_name(ltp), type_name(rtp));
2258	else if (binary)
2259		/* operands of '%s' have incompatible types '%s' and '%s' */
2260		error(107, op_name(op), type_name(ltp), type_name(rtp));
2261	else {
2262		lint_assert(rt == NO_TSPEC);
2263		/* operand of '%s' has invalid type '%s' */
2264		error(108, op_name(op), type_name(ltp));
2265	}
2266}
2267
2268static bool
2269typeok_plus(op_t op,
2270	    const type_t *ltp, tspec_t lt,
2271	    const type_t *rtp, tspec_t rt)
2272{
2273	/* operands have scalar types (checked in typeok) */
2274	if ((lt == PTR && !is_integer(rt)) || (rt == PTR && !is_integer(lt))) {
2275		warn_incompatible_types(op, ltp, lt, rtp, rt);
2276		return false;
2277	}
2278	return true;
2279}
2280
2281static bool
2282typeok_minus(op_t op,
2283	     const type_t *ltp, tspec_t lt,
2284	     const type_t *rtp, tspec_t rt)
2285{
2286	/* operands have scalar types (checked in typeok) */
2287	if ((lt == PTR && rt != PTR && !is_integer(rt)) ||
2288	    (lt != PTR && rt == PTR)) {
2289		warn_incompatible_types(op, ltp, lt, rtp, rt);
2290		return false;
2291	}
2292	if (lt == PTR && rt == PTR &&
2293	    !types_compatible(ltp->t_subt, rtp->t_subt, true, false, NULL)) {
2294		/* illegal pointer subtraction */
2295		error(116);
2296	}
2297	return true;
2298}
2299
2300static void
2301typeok_shr(op_t op,
2302	   const tnode_t *ln, tspec_t lt,
2303	   const tnode_t *rn, tspec_t rt)
2304{
2305	tspec_t olt = before_conversion(ln)->tn_type->t_tspec;
2306	tspec_t ort = before_conversion(rn)->tn_type->t_tspec;
2307
2308	/* operands have integer types (checked in typeok) */
2309	if (pflag && !is_uinteger(olt)) {
2310		integer_constraints lc = ic_expr(ln);
2311		if (!ic_maybe_signed(ln->tn_type, &lc))
2312			return;
2313
2314		if (ln->tn_op != CON)
2315			/* bitwise '%s' on signed value possibly nonportable */
2316			warning(117, op_name(op));
2317		else if (ln->u.value.u.integer < 0)
2318			/* bitwise '%s' on signed value nonportable */
2319			warning(120, op_name(op));
2320	} else if (allow_trad && allow_c90 &&
2321	    !is_uinteger(olt) && is_uinteger(ort)) {
2322		/* The left operand would become unsigned in traditional C. */
2323		if (hflag && (ln->tn_op != CON || ln->u.value.u.integer < 0)) {
2324			/* semantics of '%s' change in C90; use ... */
2325			warning(118, op_name(op));
2326		}
2327	} else if (allow_trad && allow_c90 &&
2328	    !is_uinteger(olt) && !is_uinteger(ort) &&
2329	    portable_rank_cmp(lt, rt) < 0) {
2330		/*
2331		 * In traditional C, the left operand would be extended
2332		 * (possibly sign-extended) and then shifted.
2333		 */
2334		if (hflag && (ln->tn_op != CON || ln->u.value.u.integer < 0)) {
2335			/* semantics of '%s' change in C90; use ... */
2336			warning(118, op_name(op));
2337		}
2338	}
2339}
2340
2341static void
2342typeok_shl(op_t op, tspec_t lt, tspec_t rt)
2343{
2344	/*
2345	 * C90 does not perform balancing for shift operations, but traditional
2346	 * C does. If the width of the right operand is greater than the width
2347	 * of the left operand, then in traditional C the left operand would be
2348	 * extended to the width of the right operand. For SHL this may result
2349	 * in different results.
2350	 */
2351	if (portable_rank_cmp(lt, rt) < 0) {
2352		/*
2353		 * XXX If both operands are constant, make sure that there is
2354		 * really a difference between C90 and traditional C.
2355		 */
2356		if (hflag && allow_trad && allow_c90)
2357			/* semantics of '%s' change in C90; use ... */
2358			warning(118, op_name(op));
2359	}
2360}
2361
2362static void
2363typeok_shift(const type_t *ltp, tspec_t lt, const tnode_t *rn, tspec_t rt)
2364{
2365	if (rn->tn_op != CON)
2366		return;
2367
2368	if (!is_uinteger(rt) && rn->u.value.u.integer < 0)
2369		/* negative shift */
2370		warning(121);
2371	else if ((uint64_t)rn->u.value.u.integer == size_in_bits(lt))
2372		/* shift amount %u equals bit-size of '%s' */
2373		warning(267, (unsigned)rn->u.value.u.integer, type_name(ltp));
2374	else if ((uint64_t)rn->u.value.u.integer > size_in_bits(lt)) {
2375		/* shift amount %llu is greater than bit-size %llu of '%s' */
2376		warning(122, (unsigned long long)rn->u.value.u.integer,
2377		    (unsigned long long)size_in_bits(lt),
2378		    tspec_name(lt));
2379	}
2380}
2381
2382static bool
2383is_typeok_eq(const tnode_t *ln, tspec_t lt, const tnode_t *rn, tspec_t rt)
2384{
2385	if (lt == PTR && is_null_pointer(rn))
2386		return true;
2387	if (rt == PTR && is_null_pointer(ln))
2388		return true;
2389	return false;
2390}
2391
2392static void
2393warn_incompatible_pointers(op_t op, const type_t *ltp, const type_t *rtp)
2394{
2395	lint_assert(ltp->t_tspec == PTR);
2396	lint_assert(rtp->t_tspec == PTR);
2397
2398	tspec_t lt = ltp->t_subt->t_tspec;
2399	tspec_t rt = rtp->t_subt->t_tspec;
2400
2401	if (is_struct_or_union(lt) && is_struct_or_union(rt)) {
2402		if (op == RETURN)
2403			/* illegal structure pointer combination */
2404			warning(244);
2405		else {
2406			/* incompatible structure pointers: '%s' '%s' '%s' */
2407			warning(245, type_name(ltp),
2408			    op_name(op), type_name(rtp));
2409		}
2410	} else {
2411		if (op == RETURN)
2412			/* illegal combination of '%s' and '%s' */
2413			warning(184, type_name(ltp), type_name(rtp));
2414		else {
2415			/* illegal combination of '%s' and '%s', op '%s' */
2416			warning(124,
2417			    type_name(ltp), type_name(rtp), op_name(op));
2418		}
2419	}
2420}
2421
2422static void
2423check_pointer_comparison(op_t op, const tnode_t *ln, const tnode_t *rn)
2424{
2425	type_t *ltp = ln->tn_type, *rtp = rn->tn_type;
2426	tspec_t lst = ltp->t_subt->t_tspec, rst = rtp->t_subt->t_tspec;
2427
2428	if (lst == VOID || rst == VOID) {
2429		/* TODO: C99 behaves like C90 here. */
2430		if (!allow_trad && !allow_c99 &&
2431		    (lst == FUNC || rst == FUNC)) {
2432			/* (void *)0 is already handled in typeok() */
2433			const char *lsts, *rsts;
2434			*(lst == FUNC ? &lsts : &rsts) = "function pointer";
2435			*(lst == VOID ? &lsts : &rsts) = "'void *'";
2436			/* C90 or later forbid comparison of %s with %s */
2437			warning(274, lsts, rsts);
2438		}
2439		return;
2440	}
2441
2442	if (!types_compatible(ltp->t_subt, rtp->t_subt, true, false, NULL)) {
2443		warn_incompatible_pointers(op, ltp, rtp);
2444		return;
2445	}
2446
2447	if (lst == FUNC && rst == FUNC) {
2448		/* TODO: C99 behaves like C90 here, see C99 6.5.8p2. */
2449		if (!allow_trad && !allow_c99 && op != EQ && op != NE)
2450			/* pointers to functions can only be compared ... */
2451			warning(125);
2452	}
2453}
2454
2455static bool
2456typeok_compare(op_t op,
2457	       const tnode_t *ln, const type_t *ltp, tspec_t lt,
2458	       const tnode_t *rn, const type_t *rtp, tspec_t rt)
2459{
2460	if (lt == PTR && rt == PTR) {
2461		check_pointer_comparison(op, ln, rn);
2462		return true;
2463	}
2464
2465	if (lt != PTR && rt != PTR)
2466		return true;
2467
2468	if (!is_integer(lt) && !is_integer(rt)) {
2469		warn_incompatible_types(op, ltp, lt, rtp, rt);
2470		return false;
2471	}
2472
2473	const char *lx = lt == PTR ? "pointer" : "integer";
2474	const char *rx = rt == PTR ? "pointer" : "integer";
2475	/* illegal combination of %s '%s' and %s '%s', op '%s' */
2476	warning(123, lx, type_name(ltp), rx, type_name(rtp), op_name(op));
2477	return true;
2478}
2479
2480static bool
2481typeok_quest(tspec_t lt, const tnode_t *rn)
2482{
2483	if (!is_scalar(lt)) {
2484		/* first operand of '?' must have scalar type */
2485		error(170);
2486		return false;
2487	}
2488	lint_assert(before_conversion(rn)->tn_op == COLON);
2489	return true;
2490}
2491
2492static void
2493typeok_colon_pointer(const type_t *ltp, const type_t *rtp)
2494{
2495	type_t *lstp = ltp->t_subt;
2496	type_t *rstp = rtp->t_subt;
2497	tspec_t lst = lstp->t_tspec;
2498	tspec_t rst = rstp->t_tspec;
2499
2500	if ((lst == VOID && rst == FUNC) || (lst == FUNC && rst == VOID)) {
2501		/* (void *)0 is handled in typeok_colon */
2502		/* TODO: C99 behaves like C90 here. */
2503		if (!allow_trad && !allow_c99)
2504			/* conversion of %s to %s requires a cast, op %s */
2505			warning(305, "function pointer", "'void *'",
2506			    op_name(COLON));
2507		return;
2508	}
2509
2510	if (pointer_types_are_compatible(lstp, rstp, true))
2511		return;
2512	if (!types_compatible(lstp, rstp, true, false, NULL))
2513		warn_incompatible_pointers(COLON, ltp, rtp);
2514}
2515
2516static bool
2517typeok_colon(const tnode_t *ln, const type_t *ltp, tspec_t lt,
2518	     const tnode_t *rn, const type_t *rtp, tspec_t rt)
2519{
2520
2521	if (is_arithmetic(lt) && is_arithmetic(rt))
2522		return true;
2523	if (lt == BOOL && rt == BOOL)
2524		return true;
2525
2526	if (lt == STRUCT && rt == STRUCT && ltp->u.sou == rtp->u.sou)
2527		return true;
2528	if (lt == UNION && rt == UNION && ltp->u.sou == rtp->u.sou)
2529		return true;
2530
2531	if (lt == PTR && is_null_pointer(rn))
2532		return true;
2533	if (rt == PTR && is_null_pointer(ln))
2534		return true;
2535
2536	if ((lt == PTR && is_integer(rt)) || (is_integer(lt) && rt == PTR)) {
2537		const char *lx = lt == PTR ? "pointer" : "integer";
2538		const char *rx = rt == PTR ? "pointer" : "integer";
2539		/* illegal combination of %s '%s' and %s '%s', op '%s' */
2540		warning(123, lx, type_name(ltp),
2541		    rx, type_name(rtp), op_name(COLON));
2542		return true;
2543	}
2544
2545	if (lt == VOID || rt == VOID) {
2546		if (lt != VOID || rt != VOID)
2547			/* incompatible types '%s' and '%s' in conditional */
2548			warning(126, type_name(ltp), type_name(rtp));
2549		return true;
2550	}
2551
2552	if (lt == PTR && rt == PTR) {
2553		typeok_colon_pointer(ltp, rtp);
2554		return true;
2555	}
2556
2557	/* incompatible types '%s' and '%s' in conditional */
2558	error(126, type_name(ltp), type_name(rtp));
2559	return false;
2560}
2561
2562static bool
2563has_constant_member(const type_t *tp)
2564{
2565	lint_assert(is_struct_or_union(tp->t_tspec));
2566
2567	for (sym_t *m = tp->u.sou->sou_first_member;
2568	    m != NULL; m = m->s_next) {
2569		const type_t *mtp = m->s_type;
2570		if (mtp->t_const)
2571			return true;
2572		if (is_struct_or_union(mtp->t_tspec) &&
2573		    has_constant_member(mtp))
2574			return true;
2575	}
2576	return false;
2577}
2578
2579static bool
2580typeok_assign(op_t op, const tnode_t *ln, const type_t *ltp, tspec_t lt)
2581{
2582	if (op == RETURN || op == INIT || op == FARG)
2583		return true;
2584
2585	if (!ln->tn_lvalue) {
2586		if (ln->tn_op == CVT && ln->tn_cast &&
2587		    ln->u.ops.left->tn_op == LOAD)
2588			/* a cast does not yield an lvalue */
2589			error(163);
2590		/* %soperand of '%s' must be lvalue */
2591		error(114, "left ", op_name(op));
2592		return false;
2593	} else if (ltp->t_const
2594	    || (is_struct_or_union(lt) && has_constant_member(ltp))) {
2595		if (allow_c90)
2596			/* %soperand of '%s' must be modifiable lvalue */
2597			warning(115, "left ", op_name(op));
2598	}
2599	return true;
2600}
2601
2602static bool
2603typeok_scalar(op_t op, const mod_t *mp,
2604	      const type_t *ltp, tspec_t lt,
2605	      const type_t *rtp, tspec_t rt)
2606{
2607	if (mp->m_takes_bool && lt == BOOL && rt == BOOL)
2608		return true;
2609	if (mp->m_requires_integer) {
2610		if (!is_integer(lt) || (mp->m_binary && !is_integer(rt))) {
2611			warn_incompatible_types(op, ltp, lt, rtp, rt);
2612			return false;
2613		}
2614	} else if (mp->m_requires_integer_or_complex) {
2615		if ((!is_integer(lt) && !is_complex(lt)) ||
2616		    (mp->m_binary && (!is_integer(rt) && !is_complex(rt)))) {
2617			warn_incompatible_types(op, ltp, lt, rtp, rt);
2618			return false;
2619		}
2620	} else if (mp->m_requires_scalar) {
2621		if (!is_scalar(lt) || (mp->m_binary && !is_scalar(rt))) {
2622			warn_incompatible_types(op, ltp, lt, rtp, rt);
2623			return false;
2624		}
2625	} else if (mp->m_requires_arith) {
2626		if (!is_arithmetic(lt) ||
2627		    (mp->m_binary && !is_arithmetic(rt))) {
2628			warn_incompatible_types(op, ltp, lt, rtp, rt);
2629			return false;
2630		}
2631	}
2632	return true;
2633}
2634
2635static void
2636check_assign_void_pointer(op_t op, int arg,
2637			  tspec_t lt, tspec_t lst,
2638			  tspec_t rt, tspec_t rst)
2639{
2640
2641	if (!(lt == PTR && rt == PTR && (lst == VOID || rst == VOID)))
2642		return;
2643	/* two pointers, at least one pointer to void */
2644
2645	/* TODO: C99 behaves like C90 here. */
2646	if (!(!allow_trad && !allow_c99 && (lst == FUNC || rst == FUNC)))
2647		return;
2648	/* comb. of ptr to func and ptr to void */
2649
2650	const char *lts, *rts;
2651	*(lst == FUNC ? &lts : &rts) = "function pointer";
2652	*(lst == VOID ? &lts : &rts) = "'void *'";
2653
2654	switch (op) {
2655	case INIT:
2656	case RETURN:
2657		/* conversion of %s to %s requires a cast */
2658		warning(303, rts, lts);
2659		break;
2660	case FARG:
2661		/* conversion of %s to %s requires a cast, arg #%d */
2662		warning(304, rts, lts, arg);
2663		break;
2664	default:
2665		/* conversion of %s to %s requires a cast, op %s */
2666		warning(305, rts, lts, op_name(op));
2667		break;
2668	}
2669}
2670
2671static bool
2672is_direct_function_call(const tnode_t *tn, const char **out_name)
2673{
2674
2675	if (tn->tn_op == CALL
2676	    && tn->u.call->func->tn_op == ADDR
2677	    && tn->u.call->func->u.ops.left->tn_op == NAME) {
2678		*out_name = tn->u.call->func->u.ops.left->u.sym->s_name;
2679		return true;
2680	}
2681	return false;
2682}
2683
2684static bool
2685is_unconst_function(const char *name)
2686{
2687
2688	return strcmp(name, "memchr") == 0 ||
2689	    strcmp(name, "strchr") == 0 ||
2690	    strcmp(name, "strpbrk") == 0 ||
2691	    strcmp(name, "strrchr") == 0 ||
2692	    strcmp(name, "strstr") == 0;
2693}
2694
2695static bool
2696is_const_char_pointer(const tnode_t *tn)
2697{
2698	/*
2699	 * For traditional reasons, C99 6.4.5p5 defines that string literals
2700	 * have type 'char[]'.  They are often implicitly converted to 'char
2701	 * *', for example when they are passed as function arguments.
2702	 *
2703	 * C99 6.4.5p6 further defines that modifying a string that is
2704	 * constructed from a string literal invokes undefined behavior.
2705	 *
2706	 * Out of these reasons, string literals are treated as 'effectively
2707	 * const' here.
2708	 */
2709	if (tn->tn_op == CVT &&
2710	    tn->u.ops.left->tn_op == ADDR &&
2711	    tn->u.ops.left->u.ops.left->tn_op == STRING)
2712		return true;
2713
2714	const type_t *tp = before_conversion(tn)->tn_type;
2715	return tp->t_tspec == PTR &&
2716	    tp->t_subt->t_tspec == CHAR &&
2717	    tp->t_subt->t_const;
2718}
2719
2720static bool
2721is_const_pointer(const tnode_t *tn)
2722{
2723	const type_t *tp = before_conversion(tn)->tn_type;
2724	return tp->t_tspec == PTR && tp->t_subt->t_const;
2725}
2726
2727static void
2728check_unconst_function(const type_t *lstp, const tnode_t *rn)
2729{
2730	const char *function_name;
2731
2732	if (lstp->t_tspec == CHAR && !lstp->t_const &&
2733	    is_direct_function_call(rn, &function_name) &&
2734	    is_unconst_function(function_name) &&
2735	    rn->u.call->args_len >= 1 &&
2736	    is_const_char_pointer(rn->u.call->args[0])) {
2737		/* call to '%s' effectively discards 'const' from argument */
2738		warning(346, function_name);
2739	}
2740
2741	if (!lstp->t_const &&
2742	    is_direct_function_call(rn, &function_name) &&
2743	    strcmp(function_name, "bsearch") == 0 &&
2744	    rn->u.call->args_len >= 2 &&
2745	    is_const_pointer(rn->u.call->args[1])) {
2746		/* call to '%s' effectively discards 'const' from argument */
2747		warning(346, function_name);
2748	}
2749}
2750
2751static bool
2752check_assign_void_pointer_compat(op_t op, int arg,
2753				 const type_t *ltp, tspec_t lt,
2754				 const type_t *lstp, tspec_t lst,
2755				 const tnode_t *rn,
2756				 const type_t *rtp, tspec_t rt,
2757				 const type_t *rstp, tspec_t rst)
2758{
2759	if (!(lt == PTR && rt == PTR && (lst == VOID || rst == VOID ||
2760					 types_compatible(lstp, rstp,
2761					     true, false, NULL))))
2762		return false;
2763
2764	/* compatible pointer types (qualifiers ignored) */
2765	if (allow_c90 &&
2766	    ((!lstp->t_const && rstp->t_const) ||
2767	     (!lstp->t_volatile && rstp->t_volatile))) {
2768		/* left side has not all qualifiers of right */
2769		switch (op) {
2770		case INIT:
2771		case RETURN:
2772			/* incompatible pointer types to '%s' and '%s' */
2773			warning(182, type_name(lstp), type_name(rstp));
2774			break;
2775		case FARG:
2776			/* converting '%s' to incompatible '%s' ... */
2777			warning(153,
2778			    type_name(rtp), type_name(ltp), arg);
2779			break;
2780		default:
2781			/* operands of '%s' have incompatible pointer ... */
2782			warning(128, op_name(op),
2783			    type_name(lstp), type_name(rstp));
2784			break;
2785		}
2786	}
2787
2788	if (allow_c90)
2789		check_unconst_function(lstp, rn);
2790
2791	return true;
2792}
2793
2794static bool
2795check_assign_pointer_integer(op_t op, int arg,
2796			     const type_t *ltp, tspec_t lt,
2797			     const type_t *rtp, tspec_t rt)
2798{
2799
2800	if (!((lt == PTR && is_integer(rt)) || (is_integer(lt) && rt == PTR)))
2801		return false;
2802
2803	const char *lx = lt == PTR ? "pointer" : "integer";
2804	const char *rx = rt == PTR ? "pointer" : "integer";
2805
2806	switch (op) {
2807	case INIT:
2808	case RETURN:
2809		/* illegal combination of %s '%s' and %s '%s' */
2810		warning(183, lx, type_name(ltp), rx, type_name(rtp));
2811		break;
2812	case FARG:
2813		/* illegal combination of %s '%s' and %s '%s', arg #%d */
2814		warning(154,
2815		    lx, type_name(ltp), rx, type_name(rtp), arg);
2816		break;
2817	default:
2818		/* illegal combination of %s '%s' and %s '%s', op '%s' */
2819		warning(123,
2820		    lx, type_name(ltp), rx, type_name(rtp), op_name(op));
2821		break;
2822	}
2823	return true;
2824}
2825
2826static bool
2827check_assign_pointer(op_t op, int arg,
2828		     const type_t *ltp, tspec_t lt,
2829		     const type_t *rtp, tspec_t rt)
2830{
2831	if (!(lt == PTR && rt == PTR))
2832		return false;
2833
2834	if (op == FARG)
2835		/* converting '%s' to incompatible '%s' for ... */
2836		warning(153, type_name(rtp), type_name(ltp), arg);
2837	else
2838		warn_incompatible_pointers(op, ltp, rtp);
2839	return true;
2840}
2841
2842static void
2843warn_assign(op_t op, int arg,
2844	    const type_t *ltp, tspec_t lt,
2845	    const type_t *rtp, tspec_t rt)
2846{
2847	switch (op) {
2848	case INIT:
2849		/* cannot initialize '%s' from '%s' */
2850		error(185, type_name(ltp), type_name(rtp));
2851		break;
2852	case RETURN:
2853		/* function has return type '%s' but returns '%s' */
2854		error(211, type_name(ltp), type_name(rtp));
2855		break;
2856	case FARG:
2857		/* passing '%s' to incompatible '%s', arg #%d */
2858		warning(155, type_name(rtp), type_name(ltp), arg);
2859		break;
2860	default:
2861		warn_incompatible_types(op, ltp, lt, rtp, rt);
2862		break;
2863	}
2864}
2865
2866/*
2867 * Checks type compatibility for ASSIGN, INIT, FARG and RETURN
2868 * and prints warnings/errors if necessary.
2869 * Returns whether the types are (almost) compatible.
2870 */
2871static bool
2872check_assign_types_compatible(op_t op, int arg,
2873			      const tnode_t *ln, const tnode_t *rn)
2874{
2875	tspec_t lt, rt, lst = NO_TSPEC, rst = NO_TSPEC;
2876	type_t *ltp, *rtp, *lstp = NULL, *rstp = NULL;
2877
2878	if ((lt = (ltp = ln->tn_type)->t_tspec) == PTR)
2879		lst = (lstp = ltp->t_subt)->t_tspec;
2880	if ((rt = (rtp = rn->tn_type)->t_tspec) == PTR)
2881		rst = (rstp = rtp->t_subt)->t_tspec;
2882
2883	if (lt == BOOL && is_scalar(rt))	/* C99 6.3.1.2 */
2884		return true;
2885
2886	if (is_arithmetic(lt) && (is_arithmetic(rt) || rt == BOOL))
2887		return true;
2888
2889	if (is_struct_or_union(lt) && is_struct_or_union(rt))
2890		return ltp->u.sou == rtp->u.sou;
2891
2892	if (lt == PTR && is_null_pointer(rn)) {
2893		if (is_integer(rn->tn_type->t_tspec))
2894			/* implicit conversion from integer 0 to pointer ... */
2895			query_message(15, type_name(ltp));
2896		return true;
2897	}
2898
2899	check_assign_void_pointer(op, arg, lt, lst, rt, rst);
2900
2901	if (check_assign_void_pointer_compat(op, arg,
2902	    ltp, lt, lstp, lst, rn, rtp, rt, rstp, rst))
2903		return true;
2904
2905	if (check_assign_pointer_integer(op, arg, ltp, lt, rtp, rt))
2906		return true;
2907
2908	if (check_assign_pointer(op, arg, ltp, lt, rtp, rt))
2909		return true;
2910
2911	warn_assign(op, arg, ltp, lt, rtp, rt);
2912	return false;
2913}
2914
2915static bool
2916has_side_effect(const tnode_t *tn) /* NOLINT(misc-no-recursion) */
2917{
2918	op_t op = tn->tn_op;
2919
2920	if (modtab[op].m_has_side_effect)
2921		return true;
2922
2923	if (op == CVT && tn->tn_type->t_tspec == VOID)
2924		return has_side_effect(tn->u.ops.left);
2925
2926	/* XXX: Why not has_side_effect(tn->u.ops.left) as well? */
2927	if (op == LOGAND || op == LOGOR)
2928		return has_side_effect(tn->u.ops.right);
2929
2930	/* XXX: Why not has_side_effect(tn->u.ops.left) as well? */
2931	if (op == QUEST)
2932		return has_side_effect(tn->u.ops.right);
2933
2934	if (op == COLON || op == COMMA) {
2935		return has_side_effect(tn->u.ops.left) ||
2936		    has_side_effect(tn->u.ops.right);
2937	}
2938
2939	return false;
2940}
2941
2942static bool
2943is_void_cast(const tnode_t *tn)
2944{
2945
2946	return tn->tn_op == CVT && tn->tn_cast &&
2947	    tn->tn_type->t_tspec == VOID;
2948}
2949
2950static bool
2951is_local_symbol(const tnode_t *tn)
2952{
2953
2954	return tn->tn_op == LOAD &&
2955	    tn->u.ops.left->tn_op == NAME &&
2956	    tn->u.ops.left->u.sym->s_scl == AUTO;
2957}
2958
2959static bool
2960is_int_constant_zero(const tnode_t *tn)
2961{
2962
2963	return tn->tn_op == CON &&
2964	    tn->tn_type->t_tspec == INT &&
2965	    tn->u.value.u.integer == 0;
2966}
2967
2968static void
2969check_null_effect(const tnode_t *tn)
2970{
2971
2972	if (hflag &&
2973	    !has_side_effect(tn) &&
2974	    !(is_void_cast(tn) && is_local_symbol(tn->u.ops.left)) &&
2975	    !(is_void_cast(tn) && is_int_constant_zero(tn->u.ops.left))) {
2976		/* expression has null effect */
2977		warning(129);
2978	}
2979}
2980
2981/*
2982 * Check the types for specific operators and type combinations.
2983 *
2984 * At this point, the operands already conform to the type requirements of
2985 * the operator, such as being integer, floating or scalar.
2986 */
2987static bool
2988typeok_op(op_t op, int arg,
2989	  const tnode_t *ln, const type_t *ltp, tspec_t lt,
2990	  const tnode_t *rn, const type_t *rtp, tspec_t rt)
2991{
2992	switch (op) {
2993	case ARROW:
2994		return typeok_arrow(lt);
2995	case POINT:
2996		return typeok_point(ln, ltp, lt);
2997	case INCBEF:
2998	case DECBEF:
2999	case INCAFT:
3000	case DECAFT:
3001		return typeok_incdec(op, ln, ltp);
3002	case INDIR:
3003		return typeok_indir(ltp, lt);
3004	case ADDR:
3005		return typeok_address(op, ln, ltp, lt);
3006	case PLUS:
3007		return typeok_plus(op, ltp, lt, rtp, rt);
3008	case MINUS:
3009		return typeok_minus(op, ltp, lt, rtp, rt);
3010	case SHL:
3011		typeok_shl(op, lt, rt);
3012		goto shift;
3013	case SHR:
3014		typeok_shr(op, ln, lt, rn, rt);
3015	shift:
3016		typeok_shift(ltp, lt, rn, rt);
3017		break;
3018	case LT:
3019	case LE:
3020	case GT:
3021	case GE:
3022	compare:
3023		return typeok_compare(op, ln, ltp, lt, rn, rtp, rt);
3024	case EQ:
3025	case NE:
3026		if (is_typeok_eq(ln, lt, rn, rt))
3027			break;
3028		goto compare;
3029	case QUEST:
3030		return typeok_quest(lt, rn);
3031	case COLON:
3032		return typeok_colon(ln, ltp, lt, rn, rtp, rt);
3033	case ASSIGN:
3034	case INIT:
3035	case FARG:
3036	case RETURN:
3037		if (!check_assign_types_compatible(op, arg, ln, rn))
3038			return false;
3039		goto assign;
3040	case MULASS:
3041	case DIVASS:
3042	case MODASS:
3043		goto assign;
3044	case ADDASS:
3045	case SUBASS:
3046		if ((lt == PTR && !is_integer(rt)) || rt == PTR) {
3047			warn_incompatible_types(op, ltp, lt, rtp, rt);
3048			return false;
3049		}
3050		goto assign;
3051	case SHLASS:
3052		goto assign;
3053	case SHRASS:
3054		if (pflag && !is_uinteger(lt) &&
3055		    !(!allow_c90 && is_uinteger(rt))) {
3056			/* bitwise '%s' on signed value possibly nonportable */
3057			warning(117, op_name(op));
3058		}
3059		goto assign;
3060	case ANDASS:
3061	case XORASS:
3062	case ORASS:
3063	assign:
3064		return typeok_assign(op, ln, ltp, lt);
3065	case COMMA:
3066		if (!modtab[ln->tn_op].m_has_side_effect)
3067			check_null_effect(ln);
3068		break;
3069	default:
3070		break;
3071	}
3072	return true;
3073}
3074
3075static void
3076check_bad_enum_operation(op_t op, const tnode_t *ln, const tnode_t *rn)
3077{
3078
3079	if (!eflag)
3080		return;
3081
3082	/* Allow enum in array indices. */
3083	if (op == PLUS &&
3084	    ((ln->tn_type->t_is_enum && rn->tn_type->t_tspec == PTR) ||
3085	     (rn->tn_type->t_is_enum && ln->tn_type->t_tspec == PTR))) {
3086		return;
3087	}
3088
3089	/* dubious operation '%s' on enum */
3090	warning(241, op_name(op));
3091}
3092
3093static void
3094check_enum_type_mismatch(op_t op, int arg, const tnode_t *ln, const tnode_t *rn)
3095{
3096	const mod_t *mp = &modtab[op];
3097
3098	if (ln->tn_type->u.enumer != rn->tn_type->u.enumer) {
3099		switch (op) {
3100		case INIT:
3101			/* enum type mismatch between '%s' and '%s' in ... */
3102			warning(210,
3103			    type_name(ln->tn_type), type_name(rn->tn_type));
3104			break;
3105		case FARG:
3106			/* function expects '%s', passing '%s' for arg #%d */
3107			warning(156,
3108			    type_name(ln->tn_type), type_name(rn->tn_type),
3109			    arg);
3110			break;
3111		case RETURN:
3112			/* function has return type '%s' but returns '%s' */
3113			warning(211,
3114			    type_name(ln->tn_type), type_name(rn->tn_type));
3115			break;
3116		default:
3117			/* enum type mismatch: '%s' '%s' '%s' */
3118			warning(130, type_name(ln->tn_type), op_name(op),
3119			    type_name(rn->tn_type));
3120			break;
3121		}
3122	} else if (Pflag && eflag && mp->m_comparison && op != EQ && op != NE)
3123		/* operator '%s' assumes that '%s' is ordered */
3124		warning(243, op_name(op), type_name(ln->tn_type));
3125}
3126
3127static void
3128check_enum_int_mismatch(op_t op, int arg, const tnode_t *ln, const tnode_t *rn)
3129{
3130
3131	if (!eflag)
3132		return;
3133
3134	switch (op) {
3135	case INIT:
3136		/*
3137		 * Initialization with 0 is allowed. Otherwise, all implicit
3138		 * initializations would need to be warned upon as well.
3139		 */
3140		if (!rn->tn_type->t_is_enum && rn->tn_op == CON &&
3141		    is_integer(rn->tn_type->t_tspec) &&
3142		    rn->u.value.u.integer == 0) {
3143			return;
3144		}
3145		/* initialization of '%s' with '%s' */
3146		warning(277, type_name(ln->tn_type), type_name(rn->tn_type));
3147		break;
3148	case FARG:
3149		/* combination of '%s' and '%s', arg #%d */
3150		warning(278,
3151		    type_name(ln->tn_type), type_name(rn->tn_type), arg);
3152		break;
3153	case RETURN:
3154		/* combination of '%s' and '%s' in return */
3155		warning(279, type_name(ln->tn_type), type_name(rn->tn_type));
3156		break;
3157	default:
3158		/* combination of '%s' and '%s', op '%s' */
3159		warning(242, type_name(ln->tn_type), type_name(rn->tn_type),
3160		    op_name(op));
3161		break;
3162	}
3163}
3164
3165static void
3166typeok_enum(op_t op, const mod_t *mp, int arg,
3167	    const tnode_t *ln, const type_t *ltp,
3168	    const tnode_t *rn, const type_t *rtp)
3169{
3170	if (mp->m_bad_on_enum &&
3171	    (ltp->t_is_enum || (mp->m_binary && rtp->t_is_enum))) {
3172		check_bad_enum_operation(op, ln, rn);
3173	} else if (mp->m_valid_on_enum &&
3174	    (ltp->t_is_enum && rtp != NULL && rtp->t_is_enum)) {
3175		check_enum_type_mismatch(op, arg, ln, rn);
3176	} else if (mp->m_valid_on_enum &&
3177	    (ltp->t_is_enum || (rtp != NULL && rtp->t_is_enum))) {
3178		check_enum_int_mismatch(op, arg, ln, rn);
3179	}
3180}
3181
3182/* Perform most type checks. Return whether the types are ok. */
3183bool
3184typeok(op_t op, int arg, const tnode_t *ln, const tnode_t *rn)
3185{
3186
3187	const mod_t *mp = &modtab[op];
3188
3189	type_t *ltp = ln->tn_type;
3190	tspec_t lt = ltp->t_tspec;
3191
3192	type_t *rtp = mp->m_binary ? rn->tn_type : NULL;
3193	tspec_t rt = mp->m_binary ? rtp->t_tspec : NO_TSPEC;
3194
3195	if (Tflag && !typeok_scalar_strict_bool(op, mp, arg, ln, rn))
3196		return false;
3197	if (!typeok_scalar(op, mp, ltp, lt, rtp, rt))
3198		return false;
3199
3200	if (!typeok_op(op, arg, ln, ltp, lt, rn, rtp, rt))
3201		return false;
3202
3203	typeok_enum(op, mp, arg, ln, ltp, rn, rtp);
3204	return true;
3205}
3206
3207/* In traditional C, keep unsigned and promote FLOAT to DOUBLE. */
3208static tspec_t
3209promote_trad(tspec_t t)
3210{
3211
3212	if (t == UCHAR || t == USHORT)
3213		return UINT;
3214	if (t == CHAR || t == SCHAR || t == SHORT)
3215		return INT;
3216	if (t == FLOAT)
3217		return DOUBLE;
3218	if (t == ENUM)
3219		return INT;
3220	return t;
3221}
3222
3223/*
3224 * C99 6.3.1.1p2 requires for types with lower rank than int that "If an int
3225 * can represent all the values of the original type, the value is converted
3226 * to an int; otherwise it is converted to an unsigned int", and that "All
3227 * other types are unchanged by the integer promotions".
3228 */
3229static tspec_t
3230promote_c90(const tnode_t *tn, tspec_t t, bool farg)
3231{
3232	if (tn->tn_type->t_bitfield) {
3233		unsigned int width = tn->tn_type->t_bit_field_width;
3234		unsigned int int_width = size_in_bits(INT);
3235		// XXX: What about _Bool bit-fields, since C99?
3236		if (width < int_width)
3237			return INT;
3238		if (width == int_width)
3239			return is_uinteger(t) ? UINT : INT;
3240		return t;
3241	}
3242
3243	if (t == CHAR || t == SCHAR)
3244		return INT;
3245	if (t == UCHAR)
3246		return size_in_bits(CHAR) < size_in_bits(INT) ? INT : UINT;
3247	if (t == SHORT)
3248		return INT;
3249	if (t == USHORT)
3250		return size_in_bits(SHORT) < size_in_bits(INT) ? INT : UINT;
3251	if (t == ENUM)
3252		return INT;
3253	if (farg && t == FLOAT)
3254		return DOUBLE;
3255	return t;
3256}
3257
3258/*
3259 * Performs the "integer promotions" (C99 6.3.1.1p2), which convert small
3260 * integer types to either int or unsigned int.
3261 *
3262 * If allow_c90 is unset or the operand is a function argument with no type
3263 * information (no prototype or variable # of args), converts float to double.
3264 */
3265tnode_t *
3266promote(op_t op, bool farg, tnode_t *tn)
3267{
3268
3269	const type_t *otp = tn->tn_type;
3270	tspec_t ot = otp->t_tspec;
3271	if (!is_arithmetic(ot))
3272		return tn;
3273
3274	tspec_t nt = allow_c90 ? promote_c90(tn, ot, farg) : promote_trad(ot);
3275	if (nt == ot)
3276		return tn;
3277
3278	type_t *ntp = expr_dup_type(gettyp(nt));
3279	ntp->t_tspec = nt;
3280	ntp->t_is_enum = otp->t_is_enum;
3281	if (ntp->t_is_enum)
3282		ntp->u.enumer = otp->u.enumer;
3283	ntp->t_bitfield = otp->t_bitfield;
3284	if (ntp->t_bitfield) {
3285		ntp->t_bit_field_width = otp->t_bit_field_width;
3286		ntp->t_bit_field_offset = otp->t_bit_field_offset;
3287	}
3288	if (ntp->t_bitfield && is_uinteger(ot) && !is_uinteger(nt))
3289		ntp->t_bit_field_width++;
3290	return convert(op, 0, ntp, tn);
3291}
3292
3293static void
3294convert_integer_from_floating(op_t op, const type_t *tp, const tnode_t *tn)
3295{
3296
3297	if (op == CVT)
3298		/* cast from floating point '%s' to integer '%s' */
3299		query_message(2, type_name(tn->tn_type), type_name(tp));
3300	else
3301		/* implicit conversion from floating point '%s' to ... */
3302		query_message(1, type_name(tn->tn_type), type_name(tp));
3303}
3304
3305static bool
3306should_warn_about_prototype_conversion(tspec_t nt,
3307				       tspec_t ot, const tnode_t *ptn)
3308{
3309
3310	if (nt == ot)
3311		return false;
3312
3313	if (nt == ENUM && ot == INT)
3314		return false;
3315
3316	if (is_floating(nt) != is_floating(ot) ||
3317	    portable_rank_cmp(nt, ot) != 0) {
3318		/* representation and/or width change */
3319		if (!is_integer(ot))
3320			return true;
3321		/*
3322		 * XXX: Investigate whether this rule makes sense; see
3323		 * tests/usr.bin/xlint/lint1/platform_long.c.
3324		 */
3325		return portable_rank_cmp(ot, INT) > 0;
3326	}
3327
3328	if (!hflag)
3329		return false;
3330
3331	/*
3332	 * If the types differ only in sign and the argument has the same
3333	 * representation in both types, print no warning.
3334	 */
3335	if (ptn->tn_op == CON && is_integer(nt) &&
3336	    signed_type(nt) == signed_type(ot) &&
3337	    !msb(ptn->u.value.u.integer, ot))
3338		return false;
3339
3340	return true;
3341}
3342
3343/*
3344 * Warn if a prototype causes a type conversion that is different from what
3345 * would happen to the same argument in the absence of a prototype.  This
3346 * check is intended for code that needs to stay compatible with pre-C90 C.
3347 *
3348 * Errors/warnings about illegal type combinations are already printed
3349 * in check_assign_types_compatible().
3350 */
3351static void
3352check_prototype_conversion(int arg, tspec_t nt, tspec_t ot, type_t *tp,
3353			   tnode_t *tn)
3354{
3355
3356	if (!is_arithmetic(nt) || !is_arithmetic(ot))
3357		return;
3358
3359	/*
3360	 * If the type of the formal parameter is char/short, a warning would
3361	 * be useless, because functions declared the old style can't expect
3362	 * char/short arguments.
3363	 */
3364	if (nt == CHAR || nt == SCHAR || nt == UCHAR ||
3365	    nt == SHORT || nt == USHORT)
3366		return;
3367
3368	tnode_t *ptn = promote(NOOP, true, tn);
3369	ot = ptn->tn_type->t_tspec;
3370
3371	if (should_warn_about_prototype_conversion(nt, ot, ptn)) {
3372		/* argument %d is converted from '%s' to '%s' ... */
3373		warning(259, arg, type_name(tn->tn_type), type_name(tp));
3374	}
3375}
3376
3377/*
3378 * When converting a large integer type to a small integer type, in some
3379 * cases the value of the actual expression is further restricted than the
3380 * type bounds, such as in (expr & 0xFF) or (expr % 100) or (expr >> 24).
3381 */
3382static bool
3383can_represent(const type_t *tp, const tnode_t *tn)
3384{
3385
3386	debug_step("%s: type '%s'", __func__, type_name(tp));
3387	debug_node(tn);
3388
3389	uint64_t nmask = value_bits(width_in_bits(tp));
3390	if (!is_uinteger(tp->t_tspec))
3391		nmask >>= 1;
3392
3393	integer_constraints c = ic_expr(tn);
3394	if ((~c.bclr & ~nmask) == 0)
3395		return true;
3396
3397	integer_constraints tpc = ic_any(tp);
3398	if (is_uinteger(tp->t_tspec)
3399	    ? tpc.umin <= c.umin && tpc.umax >= c.umax
3400	    : tpc.smin <= c.smin && tpc.smax >= c.smax)
3401		return true;
3402
3403	return false;
3404}
3405
3406static bool
3407should_warn_about_integer_conversion(const type_t *ntp, tspec_t nt,
3408				     const tnode_t *otn, tspec_t ot)
3409{
3410
3411	// XXX: The portable_rank_cmp aims at portable mode, independent of the
3412	// current platform, while can_represent acts on the actual type sizes
3413	// from the current platform.  This mix is inconsistent, but anything
3414	// else would make the exact conditions too complicated to grasp.
3415	if (aflag > 0 && portable_rank_cmp(nt, ot) < 0) {
3416		if (ot == LONG || ot == ULONG
3417		    || ot == LLONG || ot == ULLONG
3418#ifdef INT128_SIZE
3419		    || ot == INT128 || ot == UINT128
3420#endif
3421		    || aflag > 1)
3422			return !can_represent(ntp, otn);
3423	}
3424	return false;
3425}
3426
3427static void
3428convert_integer_from_integer(op_t op, int arg, tspec_t nt, tspec_t ot,
3429			     type_t *tp, tnode_t *tn)
3430{
3431
3432	if (tn->tn_op == CON)
3433		return;
3434
3435	if (op == CVT)
3436		return;
3437
3438	if (Pflag && pflag && aflag > 0 &&
3439	    portable_rank_cmp(nt, ot) > 0 &&
3440	    is_uinteger(nt) != is_uinteger(ot)) {
3441		if (op == FARG)
3442			/* conversion to '%s' may sign-extend ... */
3443			warning(297, type_name(tp), arg);
3444		else
3445			/* conversion to '%s' may sign-extend ... */
3446			warning(131, type_name(tp));
3447	}
3448
3449	if (Pflag && portable_rank_cmp(nt, ot) > 0 &&
3450	    (tn->tn_op == PLUS || tn->tn_op == MINUS || tn->tn_op == MULT ||
3451	     tn->tn_op == SHL)) {
3452		/* suggest cast from '%s' to '%s' on op '%s' to ... */
3453		warning(324, type_name(gettyp(ot)), type_name(tp),
3454		    op_name(tn->tn_op));
3455	}
3456
3457	if (should_warn_about_integer_conversion(tp, nt, tn, ot)) {
3458		if (op == FARG) {
3459			/* conversion from '%s' to '%s' may lose ... */
3460			warning(298,
3461			    type_name(tn->tn_type), type_name(tp), arg);
3462		} else {
3463			/* conversion from '%s' to '%s' may lose accuracy */
3464			warning(132,
3465			    type_name(tn->tn_type), type_name(tp));
3466		}
3467	}
3468
3469	if (any_query_enabled && is_uinteger(nt) != is_uinteger(ot))
3470		/* implicit conversion changes sign from '%s' to '%s' */
3471		query_message(3, type_name(tn->tn_type), type_name(tp));
3472}
3473
3474static void
3475convert_integer_from_pointer(op_t op, tspec_t nt, type_t *tp, tnode_t *tn)
3476{
3477
3478	if (tn->tn_op == CON)
3479		return;
3480	if (op != CVT)
3481		return;		/* We already got an error. */
3482	if (portable_rank_cmp(nt, PTR) >= 0)
3483		return;
3484
3485	if (pflag && size_in_bits(nt) >= size_in_bits(PTR)) {
3486		/* conversion of pointer to '%s' may lose bits */
3487		warning(134, type_name(tp));
3488	} else {
3489		/* conversion of pointer to '%s' loses bits */
3490		warning(133, type_name(tp));
3491	}
3492}
3493
3494static bool
3495struct_starts_with(const type_t *struct_tp, const type_t *member_tp)
3496{
3497
3498	return struct_tp->u.sou->sou_first_member != NULL &&
3499	    types_compatible(struct_tp->u.sou->sou_first_member->s_type,
3500		member_tp, true, false, NULL);
3501}
3502
3503static bool
3504is_byte_array(const type_t *tp)
3505{
3506
3507	return tp->t_tspec == ARRAY &&
3508	    (tp->t_subt->t_tspec == CHAR || tp->t_subt->t_tspec == UCHAR);
3509}
3510
3511static bool
3512union_contains(const type_t *utp, const type_t *mtp)
3513{
3514	for (const sym_t *mem = utp->u.sou->sou_first_member;
3515	    mem != NULL; mem = mem->s_next) {
3516		if (types_compatible(mem->s_type, mtp, true, false, NULL))
3517			return true;
3518	}
3519	return false;
3520}
3521
3522static bool
3523should_warn_about_pointer_cast(const type_t *nstp, tspec_t nst,
3524			       const type_t *ostp, tspec_t ost)
3525{
3526
3527	while (nst == ARRAY)
3528		nstp = nstp->t_subt, nst = nstp->t_tspec;
3529	while (ost == ARRAY)
3530		ostp = ostp->t_subt, ost = ostp->t_tspec;
3531
3532	if (nst == STRUCT && ost == STRUCT &&
3533	    (struct_starts_with(nstp, ostp) ||
3534	     struct_starts_with(ostp, nstp)))
3535		return false;
3536
3537	if (is_incomplete(nstp) || is_incomplete(ostp))
3538		return false;
3539
3540	if (nst == CHAR || nst == UCHAR)
3541		return false;	/* for the sake of traditional C code */
3542	if (ost == CHAR || ost == UCHAR)
3543		return false;	/* for the sake of traditional C code */
3544
3545	/* Allow cast between pointers to sockaddr variants. */
3546	if (nst == STRUCT && ost == STRUCT) {
3547		const sym_t *nmem = nstp->u.sou->sou_first_member;
3548		const sym_t *omem = ostp->u.sou->sou_first_member;
3549		while (nmem != NULL && omem != NULL &&
3550		    types_compatible(nmem->s_type, omem->s_type,
3551			true, false, NULL))
3552			nmem = nmem->s_next, omem = omem->s_next;
3553		if (nmem != NULL && is_byte_array(nmem->s_type))
3554			return false;
3555		if (omem != NULL && is_byte_array(omem->s_type))
3556			return false;
3557		if (nmem == NULL && omem == NULL)
3558			return false;
3559	}
3560
3561	if (nst == UNION || ost == UNION) {
3562		const type_t *union_tp = nst == UNION ? nstp : ostp;
3563		const type_t *other_tp = nst == UNION ? ostp : nstp;
3564		if (union_contains(union_tp, other_tp))
3565			return false;
3566	}
3567
3568	if (is_struct_or_union(nst) && is_struct_or_union(ost))
3569		return nstp->u.sou != ostp->u.sou;
3570
3571	enum rank_kind rk1 = type_properties(nst)->tt_rank_kind;
3572	enum rank_kind rk2 = type_properties(ost)->tt_rank_kind;
3573	if (rk1 != rk2 || rk1 == RK_NONE)
3574		return true;
3575
3576	return portable_rank_cmp(nst, ost) != 0;
3577}
3578
3579static void
3580convert_pointer_from_pointer(type_t *ntp, tnode_t *tn)
3581{
3582	const type_t *nstp = ntp->t_subt;
3583	const type_t *otp = tn->tn_type;
3584	const type_t *ostp = otp->t_subt;
3585	tspec_t nst = nstp->t_tspec;
3586	tspec_t ost = ostp->t_tspec;
3587
3588	if (nst == VOID || ost == VOID) {
3589		/* TODO: C99 behaves like C90 here. */
3590		if (!allow_trad && !allow_c99 && (nst == FUNC || ost == FUNC)) {
3591			const char *nts, *ots;
3592			/* null pointers are already handled in convert() */
3593			*(nst == FUNC ? &nts : &ots) = "function pointer";
3594			*(nst == VOID ? &nts : &ots) = "'void *'";
3595			/* conversion of %s to %s requires a cast */
3596			warning(303, ots, nts);
3597		}
3598		return;
3599	}
3600	if (nst == FUNC && ost == FUNC)
3601		return;
3602	if (nst == FUNC || ost == FUNC) {
3603		/* converting '%s' to '%s' is questionable */
3604		warning(229, type_name(otp), type_name(ntp));
3605		return;
3606	}
3607
3608	if (hflag && alignment(nstp) > alignment(ostp) &&
3609	    ost != CHAR && ost != UCHAR &&
3610	    !is_incomplete(ostp) &&
3611	    !(nst == UNION && union_contains(nstp, ostp))) {
3612		/* converting '%s' to '%s' increases alignment ... */
3613		warning(135, type_name(otp), type_name(ntp),
3614		    alignment(ostp), alignment(nstp));
3615	}
3616
3617	if (cflag && should_warn_about_pointer_cast(nstp, nst, ostp, ost)) {
3618		/* pointer cast from '%s' to '%s' may be troublesome */
3619		warning(247, type_name(otp), type_name(ntp));
3620	}
3621}
3622
3623/*
3624 * Insert a conversion operator, which converts the type of the node
3625 * to another given type.
3626 *
3627 * Possible values for 'op':
3628 *	CVT	a cast-expression
3629 *	binary	integer promotion for one of the operands, or a usual
3630 *		arithmetic conversion
3631 *	binary	plain or compound assignments to bit-fields
3632 *	FARG	'arg' is the number of the parameter (used for warnings)
3633 *	NOOP	several other implicit conversions
3634 *	...
3635 */
3636tnode_t *
3637convert(op_t op, int arg, type_t *tp, tnode_t *tn)
3638{
3639	tspec_t nt = tp->t_tspec;
3640	tspec_t ot = tn->tn_type->t_tspec;
3641
3642	if (allow_trad && allow_c90 && op == FARG)
3643		check_prototype_conversion(arg, nt, ot, tp, tn);
3644
3645	if (nt == BOOL) {
3646		/* No further checks. */
3647
3648	} else if (is_integer(nt)) {
3649		if (ot == BOOL) {
3650			/* No further checks. */
3651		} else if (is_integer(ot))
3652			convert_integer_from_integer(op, arg, nt, ot, tp, tn);
3653		else if (is_floating(ot))
3654			convert_integer_from_floating(op, tp, tn);
3655		else if (ot == PTR)
3656			convert_integer_from_pointer(op, nt, tp, tn);
3657
3658	} else if (is_floating(nt)) {
3659		if (is_integer(ot) && op != CVT) {
3660			/* implicit conversion from integer '%s' to ... */
3661			query_message(19,
3662			    type_name(tn->tn_type), type_name(tp));
3663		}
3664
3665	} else if (nt == PTR) {
3666		if (is_null_pointer(tn)) {
3667			/* a null pointer may be assigned to any pointer. */
3668		} else if (ot == PTR && op == CVT)
3669			convert_pointer_from_pointer(tp, tn);
3670	}
3671
3672	tnode_t *ntn = expr_alloc_tnode();
3673	ntn->tn_op = CVT;
3674	ntn->tn_type = tp;
3675	ntn->tn_cast = op == CVT;
3676	ntn->tn_sys |= tn->tn_sys;
3677	ntn->u.ops.right = NULL;
3678	if (tn->tn_op != CON || nt == VOID) {
3679		ntn->u.ops.left = tn;
3680	} else {
3681		ntn->tn_op = CON;
3682		convert_constant(op, arg, ntn->tn_type, &ntn->u.value,
3683		    &tn->u.value);
3684	}
3685
3686	return ntn;
3687}
3688
3689static void
3690convert_constant_from_floating(op_t op, int arg, const type_t *ntp,
3691			       tspec_t nt, val_t *nv, val_t *ov)
3692{
3693	long double max = 0.0, min = 0.0;
3694
3695	switch (nt) {
3696	case CHAR:
3697		max = TARG_CHAR_MAX;	min = TARG_CHAR_MIN;	break;
3698	case UCHAR:
3699		max = TARG_UCHAR_MAX;	min = 0;		break;
3700	case SCHAR:
3701		max = TARG_SCHAR_MAX;	min = TARG_SCHAR_MIN;	break;
3702	case SHORT:
3703		max = TARG_SHRT_MAX;	min = TARG_SHRT_MIN;	break;
3704	case USHORT:
3705		max = TARG_USHRT_MAX;	min = 0;		break;
3706	case ENUM:
3707	case INT:
3708		max = TARG_INT_MAX;	min = TARG_INT_MIN;	break;
3709	case UINT:
3710		max = TARG_UINT_MAX;	min = 0;		break;
3711	case LONG:
3712		max = TARG_LONG_MAX;	min = TARG_LONG_MIN;	break;
3713	case ULONG:
3714		max = TARG_ULONG_MAX;	min = 0;		break;
3715	case LLONG:
3716		max = LLONG_MAX;	min = LLONG_MIN;	break;
3717	case ULLONG:
3718		max = ULLONG_MAX;	min = 0;		break;
3719	case FLOAT:
3720	case FCOMPLEX:
3721		max = FLT_MAX;		min = -FLT_MAX;		break;
3722	case DOUBLE:
3723	case DCOMPLEX:
3724		max = DBL_MAX;		min = -DBL_MAX;		break;
3725	case LDOUBLE:
3726	case LCOMPLEX:
3727		/* LINTED 248; see floating_error_value. */
3728		max = LDBL_MAX;		min = -max;		break;
3729	default:
3730		lint_assert(/*CONSTCOND*/false);
3731	}
3732	if (ov->u.floating > max || ov->u.floating < min) {
3733		lint_assert(nt != LDOUBLE);
3734		const char *ot_name = type_name(gettyp(ov->v_tspec));
3735		const char *nt_name = type_name(ntp);
3736		if (op == FARG)
3737			/* conversion of '%s' to '%s' is out of range, ... */
3738			warning(295, ot_name, nt_name, arg);
3739		else
3740			/* conversion of '%s' to '%s' is out of range */
3741			warning(119, ot_name, nt_name);
3742		ov->u.floating = ov->u.floating > 0 ? max : min;
3743	}
3744
3745	if (nt == FLOAT || nt == FCOMPLEX)
3746		nv->u.floating = (float)ov->u.floating;
3747	else if (nt == DOUBLE || nt == DCOMPLEX)
3748		nv->u.floating = (double)ov->u.floating;
3749	else if (nt == LDOUBLE || nt == LCOMPLEX)
3750		nv->u.floating = ov->u.floating;
3751	else
3752		nv->u.integer = (int64_t)ov->u.floating;
3753}
3754
3755static bool
3756convert_constant_to_floating(tspec_t nt, val_t *nv,
3757			     tspec_t ot, const val_t *v)
3758{
3759	if (nt == FLOAT) {
3760		nv->u.floating = (ot == PTR || is_uinteger(ot)) ?
3761		    (float)(uint64_t)v->u.integer : (float)v->u.integer;
3762	} else if (nt == DOUBLE) {
3763		nv->u.floating = (ot == PTR || is_uinteger(ot)) ?
3764		    (double)(uint64_t)v->u.integer : (double)v->u.integer;
3765	} else if (nt == LDOUBLE) {
3766		nv->u.floating = (ot == PTR || is_uinteger(ot))
3767		    ? (long double)(uint64_t)v->u.integer
3768		    : (long double)v->u.integer;
3769	} else
3770		return false;
3771	return true;
3772}
3773
3774/*
3775 * Print a warning if bits which were set are lost due to the conversion.
3776 * This can happen with operator ORASS only.
3777 */
3778static void
3779convert_constant_check_range_bitor(size_t nsz, size_t osz, const val_t *v,
3780				   uint64_t xmask, op_t op)
3781{
3782	if (nsz < osz && (v->u.integer & xmask) != 0)
3783		/* constant truncated by conversion, op '%s' */
3784		warning(306, op_name(op));
3785}
3786
3787static void
3788convert_constant_check_range_bitand(size_t nsz, size_t osz,
3789				    uint64_t xmask, const val_t *nv,
3790				    tspec_t ot, const val_t *v,
3791				    const type_t *tp, op_t op)
3792{
3793	if (nsz > osz &&
3794	    (nv->u.integer & bit((unsigned int)(osz - 1))) != 0 &&
3795	    (nv->u.integer & xmask) != xmask) {
3796		/* extra bits set to 0 in conversion of '%s' to '%s', ... */
3797		warning(309, type_name(gettyp(ot)),
3798		    type_name(tp), op_name(op));
3799	} else if (nsz < osz &&
3800	    (v->u.integer & xmask) != xmask &&
3801	    (v->u.integer & xmask) != 0)
3802		/* constant truncated by conversion, op '%s' */
3803		warning(306, op_name(op));
3804}
3805
3806static void
3807convert_constant_check_range_signed(op_t op, int arg)
3808{
3809	if (op == ASSIGN)
3810		/* assignment of negative constant to unsigned type */
3811		warning(164);
3812	else if (op == INIT)
3813		/* initialization of unsigned with negative constant */
3814		warning(221);
3815	else if (op == FARG)
3816		/* conversion of negative constant to unsigned type, ... */
3817		warning(296, arg);
3818	else if (modtab[op].m_comparison) {
3819		/* handled by check_integer_comparison() */
3820	} else
3821		/* conversion of negative constant to unsigned type */
3822		warning(222);
3823}
3824
3825/*
3826 * Loss of significant bit(s). All truncated bits of unsigned types or all
3827 * truncated bits plus the msb of the target for signed types are considered
3828 * to be significant bits. Loss of significant bits means that at least one
3829 * of the bits was set in an unsigned type or that at least one but not all
3830 * of the bits was set in a signed type. Loss of significant bits means that
3831 * it is not possible, also not with necessary casts, to convert back to the
3832 * original type. An example for a necessary cast is:
3833 *	char c;	int	i; c = 128;
3834 *	i = c;			** yields -128 **
3835 *	i = (unsigned char)c;	** yields 128 **
3836 */
3837static void
3838warn_constant_check_range_truncated(op_t op, int arg, const type_t *tp,
3839				    tspec_t ot)
3840{
3841	if (op == ASSIGN && tp->t_bitfield)
3842		/* precision lost in bit-field assignment */
3843		warning(166);
3844	else if (op == ASSIGN)
3845		/* constant truncated by assignment */
3846		warning(165);
3847	else if (op == INIT && tp->t_bitfield)
3848		/* bit-field initializer does not fit */
3849		warning(180);
3850	else if (op == INIT)
3851		/* initializer does not fit */
3852		warning(178);
3853	else if (op == CASE)
3854		/* case label affected by conversion */
3855		warning(196);
3856	else if (op == FARG)
3857		/* conversion of '%s' to '%s' is out of range, arg #%d */
3858		warning(295, type_name(gettyp(ot)), type_name(tp), arg);
3859	else
3860		/* conversion of '%s' to '%s' is out of range */
3861		warning(119, type_name(gettyp(ot)), type_name(tp));
3862}
3863
3864static void
3865warn_constant_check_range_loss(op_t op, int arg, const type_t *tp,
3866				  tspec_t ot)
3867{
3868	if (op == ASSIGN && tp->t_bitfield)
3869		/* precision lost in bit-field assignment */
3870		warning(166);
3871	else if (op == INIT && tp->t_bitfield)
3872		/* bit-field initializer out of range */
3873		warning(11);
3874	else if (op == CASE)
3875		/* case label affected by conversion */
3876		warning(196);
3877	else if (op == FARG)
3878		/* conversion of '%s' to '%s' is out of range, arg #%d */
3879		warning(295, type_name(gettyp(ot)), type_name(tp), arg);
3880	else
3881		/* conversion of '%s' to '%s' is out of range */
3882		warning(119, type_name(gettyp(ot)), type_name(tp));
3883}
3884
3885static void
3886convert_constant_check_range(tspec_t ot, const type_t *tp, tspec_t nt,
3887			     op_t op, int arg, const val_t *v, val_t *nv)
3888{
3889	unsigned int obitsz, nbitsz;
3890	uint64_t xmask, xmsk1;
3891
3892	obitsz = size_in_bits(ot);
3893	nbitsz = tp->t_bitfield ? tp->t_bit_field_width : size_in_bits(nt);
3894	xmask = value_bits(nbitsz) ^ value_bits(obitsz);
3895	xmsk1 = value_bits(nbitsz) ^ value_bits(obitsz - 1);
3896	if (op == ORASS || op == BITOR || op == BITXOR) {
3897		convert_constant_check_range_bitor(
3898		    nbitsz, obitsz, v, xmask, op);
3899	} else if (op == ANDASS || op == BITAND) {
3900		convert_constant_check_range_bitand(
3901		    nbitsz, obitsz, xmask, nv, ot, v, tp, op);
3902	} else if (nt != PTR && is_uinteger(nt) &&
3903	    ot != PTR && !is_uinteger(ot) &&
3904	    v->u.integer < 0)
3905		convert_constant_check_range_signed(op, arg);
3906	else if (nv->u.integer != v->u.integer && nbitsz <= obitsz &&
3907	    (v->u.integer & xmask) != 0 &&
3908	    (is_uinteger(ot) || (v->u.integer & xmsk1) != xmsk1))
3909		warn_constant_check_range_truncated(op, arg, tp, ot);
3910	else if (nv->u.integer != v->u.integer)
3911		warn_constant_check_range_loss(op, arg, tp, ot);
3912}
3913
3914/* Converts a typed constant to a constant of another type. */
3915void
3916convert_constant(op_t op, int arg, const type_t *ntp, val_t *nv, val_t *ov)
3917{
3918	/*
3919	 * TODO: make 'ov' const; the name of this function does not suggest
3920	 *  that it modifies 'ov'.
3921	 */
3922	tspec_t ot = ov->v_tspec;
3923	tspec_t nt = nv->v_tspec = ntp->t_tspec;
3924	bool range_check = false;
3925
3926	if (nt == BOOL) {	/* C99 6.3.1.2 */
3927		nv->v_unsigned_since_c90 = false;
3928		nv->u.integer = is_nonzero_val(ov) ? 1 : 0;
3929		return;
3930	}
3931
3932	if (ot == FLOAT || ot == DOUBLE || ot == LDOUBLE)
3933		convert_constant_from_floating(op, arg, ntp, nt, nv, ov);
3934	else if (!convert_constant_to_floating(nt, nv, ot, ov)) {
3935		range_check = true;	/* Check for lost precision. */
3936		nv->u.integer = ov->u.integer;
3937	}
3938
3939	if (allow_trad && allow_c90 && ov->v_unsigned_since_c90 &&
3940	    (is_floating(nt) || (
3941		(is_integer(nt) && !is_uinteger(nt) &&
3942		    portable_rank_cmp(nt, ot) > 0)))) {
3943		/* C90 treats constant as unsigned */
3944		warning(157);
3945		ov->v_unsigned_since_c90 = false;
3946	}
3947
3948	if (is_integer(nt)) {
3949		unsigned int size = ntp->t_bitfield
3950		    ? ntp->t_bit_field_width : size_in_bits(nt);
3951		nv->u.integer = convert_integer(nv->u.integer, nt, size);
3952	}
3953
3954	if (range_check && op != CVT)
3955		convert_constant_check_range(ot, ntp, nt, op, arg, ov, nv);
3956}
3957
3958tnode_t *
3959build_sizeof(const type_t *tp)
3960{
3961	unsigned int size_in_bytes = type_size_in_bits(tp) / CHAR_SIZE;
3962	tnode_t *tn = build_integer_constant(SIZEOF_TSPEC, size_in_bytes);
3963	tn->tn_system_dependent = true;
3964	debug_step("build_sizeof '%s' = %u", type_name(tp), size_in_bytes);
3965	return tn;
3966}
3967
3968tnode_t *
3969build_offsetof(const type_t *tp, designation dn)
3970{
3971	unsigned int offset_in_bits = 0;
3972
3973	if (!is_struct_or_union(tp->t_tspec)) {
3974		/* unacceptable operand of '%s' */
3975		error(111, "offsetof");
3976		goto proceed;
3977	}
3978	for (size_t i = 0; i < dn.dn_len; i++) {
3979		const designator *dr = dn.dn_items + i;
3980		if (dr->dr_kind == DK_SUBSCRIPT) {
3981			if (tp->t_tspec != ARRAY)
3982				goto proceed;	/* silent error */
3983			tp = tp->t_subt;
3984			offset_in_bits += (unsigned) dr->dr_subscript
3985			    * type_size_in_bits(tp);
3986		} else {
3987			if (!is_struct_or_union(tp->t_tspec))
3988				goto proceed;	/* silent error */
3989			const char *name = dr->dr_member->s_name;
3990			sym_t *mem = find_member(tp->u.sou, name);
3991			if (mem == NULL) {
3992				/* type '%s' does not have member '%s' */
3993				error(101, name, type_name(tp));
3994				goto proceed;
3995			}
3996			tp = mem->s_type;
3997			offset_in_bits += mem->u.s_member.sm_offset_in_bits;
3998		}
3999	}
4000	free(dn.dn_items);
4001
4002proceed:;
4003	unsigned int offset_in_bytes = offset_in_bits / CHAR_SIZE;
4004	tnode_t *tn = build_integer_constant(SIZEOF_TSPEC, offset_in_bytes);
4005	tn->tn_system_dependent = true;
4006	return tn;
4007}
4008
4009unsigned int
4010type_size_in_bits(const type_t *tp)
4011{
4012
4013	unsigned int elem = 1;
4014	bool flex = false;
4015	lint_assert(tp != NULL);
4016	while (tp->t_tspec == ARRAY) {
4017		flex = true;	/* allow c99 flex arrays [] [0] */
4018		elem *= tp->u.dimension;
4019		tp = tp->t_subt;
4020	}
4021	if (elem == 0 && !flex) {
4022		/* cannot take size/alignment of incomplete type */
4023		error(143);
4024		elem = 1;
4025	}
4026
4027	unsigned int elsz;
4028	switch (tp->t_tspec) {
4029	case VOID:
4030		/* cannot take size/alignment of void */
4031		error(146);
4032		elsz = 1;
4033		break;
4034	case FUNC:
4035		/* cannot take size/alignment of function type '%s' */
4036		error(144, type_name(tp));
4037		elsz = 1;
4038		break;
4039	case STRUCT:
4040	case UNION:
4041		if (is_incomplete(tp)) {
4042			/* cannot take size/alignment of incomplete type */
4043			error(143);
4044			elsz = 1;
4045		} else
4046			elsz = tp->u.sou->sou_size_in_bits;
4047		break;
4048	case ENUM:
4049		if (is_incomplete(tp)) {
4050			/* cannot take size/alignment of incomplete type */
4051			warning(143);
4052		}
4053		/* FALLTHROUGH */
4054	default:
4055		if (tp->t_bitfield)
4056			/* cannot take size/alignment of bit-field */
4057			error(145);
4058		elsz = size_in_bits(tp->t_tspec);
4059		lint_assert(elsz > 0);
4060		break;
4061	}
4062
4063	return elem * elsz;
4064}
4065
4066/* C11 6.5.3.4, GCC */
4067tnode_t *
4068build_alignof(const type_t *tp)
4069{
4070	if (tp->t_tspec == FUNC) {
4071		/* cannot take size/alignment of function type '%s' */
4072		error(144, type_name(tp));
4073		return NULL;
4074	}
4075	if (tp->t_tspec == VOID) {
4076		/* cannot take size/alignment of void */
4077		error(146);
4078		return NULL;
4079	}
4080	if (is_incomplete(tp)) {
4081		/* cannot take size/alignment of incomplete type */
4082		error(143);
4083		return NULL;
4084	}
4085	if (tp->t_bitfield) {
4086		/* cannot take size/alignment of bit-field */
4087		error(145);
4088		return NULL;
4089	}
4090	return build_integer_constant(SIZEOF_TSPEC, (int64_t)alignment(tp));
4091}
4092
4093static tnode_t *
4094cast_to_union(tnode_t *otn, bool sys, type_t *ntp)
4095{
4096
4097	if (!allow_gcc) {
4098		/* union cast is a GCC extension */
4099		error(328);
4100		return NULL;
4101	}
4102
4103	for (const sym_t *m = ntp->u.sou->sou_first_member;
4104	    m != NULL; m = m->s_next) {
4105		if (types_compatible(m->s_type, otn->tn_type,
4106		    false, false, NULL)) {
4107			tnode_t *ntn = build_op(CVT, sys, ntp, otn, NULL);
4108			ntn->tn_cast = true;
4109			return ntn;
4110		}
4111	}
4112
4113	/* type '%s' is not a member of '%s' */
4114	error(329, type_name(otn->tn_type), type_name(ntp));
4115	return NULL;
4116}
4117
4118// In GCC mode, allow 'nullptr + offset' as a constant expression.
4119static tnode_t *
4120null_pointer_offset(tnode_t *tn)
4121{
4122	uint64_t off = 0;
4123	const tnode_t *n = tn;
4124	while ((n->tn_op == PLUS || n->tn_op == MINUS)
4125	    && is_integer(n->u.ops.right->tn_type->t_tspec)) {
4126		off += (uint64_t)n->u.ops.right->u.value.u.integer;
4127		n = n->u.ops.left;
4128	}
4129	if (n->tn_type->t_tspec == PTR
4130	    && n->tn_op == ADDR
4131	    && n->u.ops.left->tn_op == INDIR
4132	    && n->u.ops.left->u.ops.left->tn_op == CON
4133	    && n->u.ops.left->u.ops.left->tn_type->t_tspec == PTR) {
4134		off += (uint64_t)n->u.ops.left->u.ops.left->u.value.u.integer;
4135		return build_integer_constant(SIZEOF_TSPEC, (int64_t)off);
4136	}
4137	return tn;
4138}
4139
4140tnode_t *
4141cast(tnode_t *tn, bool sys, type_t *tp)
4142{
4143
4144	if (tn == NULL)
4145		return NULL;
4146
4147	tn = cconv(tn);
4148
4149	lint_assert(tp != NULL);
4150	tspec_t nt = tp->t_tspec;
4151	tspec_t ot = tn->tn_type->t_tspec;
4152
4153	if (nt == VOID) {
4154		/*
4155		 * C90 6.3.4, C99 6.5.4p2 and C11 6.5.4p2 allow any type to be
4156		 * cast to void.  The only other allowed casts are from a
4157		 * scalar type to a scalar type.
4158		 */
4159	} else if (nt == UNION)
4160		return cast_to_union(tn, sys, tp);
4161	else if (nt == STRUCT || nt == ARRAY || nt == FUNC) {
4162		/* Casting to a struct is an undocumented GCC extension. */
4163		if (!(allow_gcc && nt == STRUCT))
4164			goto invalid_cast;
4165	} else if (is_struct_or_union(ot))
4166		goto invalid_cast;
4167	else if (ot == VOID) {
4168		/* improper cast of void expression */
4169		error(148);
4170		return NULL;
4171	} else if (is_integer(nt) && is_scalar(ot)) {
4172		tn = null_pointer_offset(tn);
4173	} else if (is_floating(nt) && is_arithmetic(ot)) {
4174		/* ok */
4175	} else if (nt == PTR && is_integer(ot)) {
4176		/* ok */
4177	} else if (nt == PTR && ot == PTR) {
4178		if (!tp->t_subt->t_const && tn->tn_type->t_subt->t_const) {
4179			if (hflag)
4180				/* cast discards 'const' from type '%s' */
4181				warning(275, type_name(tn->tn_type));
4182		}
4183	} else
4184		goto invalid_cast;
4185
4186	if (any_query_enabled
4187	    && types_compatible(tp, tn->tn_type, false, false, NULL))
4188		/* no-op cast from '%s' to '%s' */
4189		query_message(6, type_name(tn->tn_type), type_name(tp));
4190
4191	tn = convert(CVT, 0, tp, tn);
4192	tn->tn_cast = true;
4193	tn->tn_sys = sys;
4194
4195	return tn;
4196
4197invalid_cast:
4198	/* invalid cast from '%s' to '%s' */
4199	error(147, type_name(tn->tn_type), type_name(tp));
4200	return NULL;
4201}
4202
4203void
4204add_function_argument(function_call *call, tnode_t *arg)
4205{
4206	/*
4207	 * If there was a serious error in the expression for the argument,
4208	 * create a dummy argument so the positions of the remaining arguments
4209	 * will not change.
4210	 */
4211	if (arg == NULL)
4212		arg = build_integer_constant(INT, 0);
4213
4214	if (call->args_len >= call->args_cap) {
4215		call->args_cap += 8;
4216		tnode_t **new_args = expr_zero_alloc(
4217		    call->args_cap * sizeof(*call->args), "tnode*[]");
4218		if (call->args_len > 0)
4219			memcpy(new_args, call->args,
4220			    call->args_len * sizeof(*call->args));
4221		call->args = new_args;
4222	}
4223	call->args[call->args_len++] = arg;
4224}
4225
4226/*
4227 * Compare the type of an argument with the corresponding type of a
4228 * prototype parameter. If it is a valid combination, but both types
4229 * are not the same, insert a conversion to convert the argument into
4230 * the type of the parameter.
4231 */
4232static tnode_t *
4233check_prototype_argument(
4234	int n,		/* pos of arg */
4235	type_t *tp,		/* expected type (from prototype) */
4236	tnode_t *tn)		/* argument */
4237{
4238	tnode_t *ln = xcalloc(1, sizeof(*ln));
4239	ln->tn_type = expr_unqualified_type(tp);
4240	ln->tn_lvalue = true;
4241	if (typeok(FARG, n, ln, tn)) {
4242		bool dowarn;
4243		if (!types_compatible(tp, tn->tn_type,
4244		    true, false, (dowarn = false, &dowarn)) || dowarn)
4245			tn = convert(FARG, n, tp, tn);
4246	}
4247	free(ln);
4248	return tn;
4249}
4250
4251/*
4252 * Check types of all function arguments and insert conversions,
4253 * if necessary.
4254 */
4255static void
4256check_function_arguments(const function_call *call)
4257{
4258	type_t *ftp = call->func->tn_type->t_subt;
4259
4260	/* get # of parameters in the prototype */
4261	int npar = 0;
4262	for (const sym_t *p = ftp->u.params; p != NULL; p = p->s_next)
4263		npar++;
4264
4265	int narg = (int)call->args_len;
4266
4267	const sym_t *param = ftp->u.params;
4268	if (ftp->t_proto && npar != narg && !(ftp->t_vararg && npar < narg)) {
4269		/* argument mismatch: %d %s passed, %d expected */
4270		error(150, narg, narg != 1 ? "arguments" : "argument", npar);
4271		param = NULL;
4272	}
4273
4274	for (int i = 0; i < narg; i++) {
4275		tnode_t *arg = call->args[i];
4276
4277		/* some things which are always not allowed */
4278		tspec_t at = arg->tn_type->t_tspec;
4279		if (at == VOID) {
4280			/* void expressions may not be arguments, arg #%d */
4281			error(151, i + 1);
4282			return;
4283		}
4284		if (is_struct_or_union(at) && is_incomplete(arg->tn_type)) {
4285			/* argument cannot have unknown size, arg #%d */
4286			error(152, i + 1);
4287			return;
4288		}
4289		if (is_integer(at) &&
4290		    arg->tn_type->t_is_enum &&
4291		    is_incomplete(arg->tn_type)) {
4292			/* argument cannot have unknown size, arg #%d */
4293			warning(152, i + 1);
4294		}
4295
4296		arg = cconv(arg);
4297		call->args[i] = arg;
4298
4299		arg = param != NULL
4300		    ? check_prototype_argument(i + 1, param->s_type, arg)
4301		    : promote(NOOP, true, arg);
4302		call->args[i] = arg;
4303
4304		if (param != NULL)
4305			param = param->s_next;
4306	}
4307}
4308
4309tnode_t *
4310build_function_call(tnode_t *func, bool sys, function_call *call)
4311{
4312
4313	if (func == NULL)
4314		return NULL;
4315
4316	call->func = func;
4317	check_ctype_function_call(call);
4318
4319	func = cconv(func);
4320	call->func = func;
4321
4322	if (func->tn_type->t_tspec != PTR ||
4323	    func->tn_type->t_subt->t_tspec != FUNC) {
4324		/* cannot call '%s', must be a function */
4325		error(149, type_name(func->tn_type));
4326		return NULL;
4327	}
4328
4329	check_function_arguments(call);
4330
4331	tnode_t *ntn = expr_alloc_tnode();
4332	ntn->tn_op = CALL;
4333	ntn->tn_type = func->tn_type->t_subt->t_subt;
4334	ntn->tn_sys = sys;
4335	ntn->u.call = call;
4336	return ntn;
4337}
4338
4339/*
4340 * Return the value of an integral constant expression.
4341 * If the expression is not constant or its type is not an integer
4342 * type, an error message is printed.
4343 */
4344val_t *
4345integer_constant(tnode_t *tn, bool required)
4346{
4347
4348	if (tn != NULL)
4349		tn = cconv(tn);
4350	if (tn != NULL)
4351		tn = promote(NOOP, false, tn);
4352
4353	val_t *v = xcalloc(1, sizeof(*v));
4354
4355	if (tn == NULL) {
4356		lint_assert(seen_error);
4357		debug_step("constant node is null; returning 1 instead");
4358		v->v_tspec = INT;
4359		v->u.integer = 1;
4360		return v;
4361	}
4362
4363	v->v_tspec = tn->tn_type->t_tspec;
4364
4365	if (tn->tn_op == CON) {
4366		lint_assert(tn->tn_type->t_tspec == tn->u.value.v_tspec);
4367		if (is_integer(tn->u.value.v_tspec)) {
4368			v->v_unsigned_since_c90 =
4369			    tn->u.value.v_unsigned_since_c90;
4370			v->u.integer = tn->u.value.u.integer;
4371			return v;
4372		}
4373		v->u.integer = (int64_t)tn->u.value.u.floating;
4374	} else
4375		v->u.integer = 1;
4376
4377	if (required)
4378		/* integral constant expression expected */
4379		error(55);
4380	else
4381		/* variable array dimension is a C99/GCC extension */
4382		c99ism(318);
4383
4384	if (!is_integer(v->v_tspec))
4385		v->v_tspec = INT;
4386
4387	return v;
4388}
4389
4390static bool
4391is_constcond_false(const tnode_t *tn, tspec_t t)
4392{
4393	return (t == BOOL || t == INT) &&
4394	    tn->tn_op == CON && tn->u.value.u.integer == 0;
4395}
4396
4397/*
4398 * Perform some tests on expressions which can't be done in build_binary()
4399 * and functions called by build_binary(). These tests must be done here
4400 * because we need some information about the context in which the operations
4401 * are performed.
4402 * After all tests are performed and dofreeblk is true, expr() frees the
4403 * memory which is used for the expression.
4404 */
4405void
4406expr(tnode_t *tn, bool vctx, bool cond, bool dofreeblk, bool is_do_while)
4407{
4408
4409	if (tn == NULL) {	/* in case of errors */
4410		expr_free_all();
4411		return;
4412	}
4413
4414	/* expr() is also called in global initializations */
4415	if (dcs->d_kind != DLK_EXTERN && !is_do_while)
4416		check_statement_reachable();
4417
4418	check_expr_misc(tn, vctx, cond, !cond, false, false, false);
4419	if (tn->tn_op == ASSIGN && !tn->tn_parenthesized) {
4420		if (hflag && cond)
4421			/* assignment in conditional context */
4422			warning(159);
4423	} else if (tn->tn_op == CON) {
4424		if (hflag && cond && !suppress_constcond &&
4425		    !tn->tn_system_dependent &&
4426		    !(is_do_while &&
4427		      is_constcond_false(tn, tn->tn_type->t_tspec)))
4428			/* constant in conditional context */
4429			warning(161);
4430	}
4431	if (!modtab[tn->tn_op].m_has_side_effect) {
4432		/*
4433		 * for left operands of COMMA this warning is already printed
4434		 */
4435		if (tn->tn_op != COMMA && !vctx && !cond)
4436			check_null_effect(tn);
4437	}
4438	debug_node(tn);
4439
4440	if (dofreeblk)
4441		expr_free_all();
4442}
4443
4444/* If the expression has the form '*(arr + idx)', check the array index. */
4445static void
4446check_array_index(const tnode_t *indir, bool taking_address)
4447{
4448	const tnode_t *plus, *arr, *idx;
4449
4450	if (indir->tn_op == INDIR
4451	    && (plus = indir->u.ops.left, plus->tn_op == PLUS)
4452	    && plus->u.ops.left->tn_op == ADDR
4453	    && (arr = plus->u.ops.left->u.ops.left, true)
4454	    && (arr->tn_op == STRING || arr->tn_op == NAME)
4455	    && arr->tn_type->t_tspec == ARRAY
4456	    && (idx = plus->u.ops.right, idx->tn_op == CON)
4457	    && (!is_incomplete(arr->tn_type) || idx->u.value.u.integer < 0))
4458		goto proceed;
4459	return;
4460
4461proceed:;
4462	int elsz = length_in_bits(arr->tn_type->t_subt, NULL);
4463	if (elsz == 0)
4464		return;
4465	elsz /= CHAR_SIZE;
4466
4467	/* Change the unit of the index from bytes to element size. */
4468	int64_t con = is_uinteger(idx->tn_type->t_tspec)
4469	    ? (int64_t)((uint64_t)idx->u.value.u.integer / elsz)
4470	    : idx->u.value.u.integer / elsz;
4471
4472	int dim = arr->tn_type->u.dimension + (taking_address ? 1 : 0);
4473
4474	if (!is_uinteger(idx->tn_type->t_tspec) && con < 0)
4475		/* array subscript %jd cannot be negative */
4476		warning(167, (intmax_t)con);
4477	else if (dim > 0 && (uint64_t)con >= (uint64_t)dim)
4478		/* array subscript %ju cannot be > %d */
4479		warning(168, (uintmax_t)con, dim - 1);
4480}
4481
4482static void
4483check_expr_addr(const tnode_t *ln, bool szof, bool fcall)
4484{
4485	/* XXX: Taking warn_about_unreachable into account here feels wrong. */
4486	if (ln->tn_op == NAME && (reached || !warn_about_unreachable)) {
4487		if (!szof)
4488			mark_as_set(ln->u.sym);
4489		mark_as_used(ln->u.sym, fcall, szof);
4490	}
4491	check_array_index(ln, true);
4492}
4493
4494/*
4495 * If there is an asm statement in one of the compound statements around,
4496 * there may be other side effects, so don't warn.
4497 */
4498static bool
4499is_asm_around(void)
4500{
4501	for (decl_level *dl = dcs; dl != NULL; dl = dl->d_enclosing)
4502		if (dl->d_asm)
4503			return true;
4504	return false;
4505}
4506
4507static void
4508check_expr_side_effect(const tnode_t *ln, bool szof)
4509{
4510
4511	/* XXX: Taking warn_about_unreachable into account here feels wrong. */
4512	if (ln->tn_op == NAME && (reached || !warn_about_unreachable)) {
4513		scl_t sc = ln->u.sym->s_scl;
4514		if (sc != EXTERN && sc != STATIC &&
4515		    !ln->u.sym->s_set && !szof && !is_asm_around()) {
4516			/* '%s' may be used before set */
4517			warning(158, ln->u.sym->s_name);
4518			mark_as_set(ln->u.sym);
4519		}
4520		mark_as_used(ln->u.sym, false, false);
4521	}
4522}
4523
4524static void
4525check_expr_assign(const tnode_t *ln, bool szof)
4526{
4527	/* XXX: Taking warn_about_unreachable into account here feels wrong. */
4528	if (ln->tn_op == NAME && !szof && (reached || !warn_about_unreachable)) {
4529		mark_as_set(ln->u.sym);
4530		if (ln->u.sym->s_scl == EXTERN)
4531			outusg(ln->u.sym);
4532	}
4533	check_array_index(ln, false);
4534}
4535
4536static void
4537check_expr_call(const tnode_t *tn, const tnode_t *ln,
4538		bool szof, bool vctx, bool cond, bool retval_discarded)
4539{
4540	lint_assert(ln->tn_op == ADDR);
4541	lint_assert(ln->u.ops.left->tn_op == NAME);
4542	if (!szof && !is_compiler_builtin(ln->u.ops.left->u.sym->s_name))
4543		outcall(tn, vctx || cond, retval_discarded);
4544
4545	const function_call *call = tn->u.call;
4546	if (call->args_len == 4 || call->args_len == 5)
4547		check_snprintb(call);
4548}
4549
4550static void
4551check_expr_op(op_t op, const tnode_t *ln, bool szof, bool fcall, bool eqwarn)
4552{
4553	switch (op) {
4554	case ADDR:
4555		check_expr_addr(ln, szof, fcall);
4556		break;
4557	case LOAD:
4558		check_array_index(ln, false);
4559		/* FALLTHROUGH */
4560	case INCBEF:
4561	case DECBEF:
4562	case INCAFT:
4563	case DECAFT:
4564	case ADDASS:
4565	case SUBASS:
4566	case MULASS:
4567	case DIVASS:
4568	case MODASS:
4569	case ANDASS:
4570	case ORASS:
4571	case XORASS:
4572	case SHLASS:
4573	case SHRASS:
4574	case REAL:
4575	case IMAG:
4576		check_expr_side_effect(ln, szof);
4577		break;
4578	case ASSIGN:
4579		check_expr_assign(ln, szof);
4580		break;
4581	case EQ:
4582		if (hflag && eqwarn)
4583			/* operator '==' found where '=' was expected */
4584			warning(160);
4585		break;
4586	default:
4587		break;
4588	}
4589}
4590
4591/*
4592 *	vctx			???
4593 *	cond			whether the expression is a condition that
4594 *				will be compared with 0
4595 *	eqwarn			whether the operator '==' might be a
4596 *				misspelled '='
4597 *	fcall			whether the expression is a function call
4598 *	retval_discarded	whether the return value of a function call
4599 *				is discarded; such calls will be analyzed by
4600 *				lint2 in messages 4, 8 and 9
4601 *	szof			whether the expression is part of a sizeof
4602 *				expression, which means that its value is
4603 *				discarded since only the type is relevant
4604 */
4605void
4606check_expr_misc(const tnode_t *tn, bool vctx, bool cond,
4607		bool eqwarn, bool fcall, bool retval_discarded, bool szof)
4608{
4609
4610	if (tn == NULL)
4611		return;
4612	op_t op = tn->tn_op;
4613	if (op == NAME || op == CON || op == STRING)
4614		return;
4615	bool is_direct = op == CALL
4616	    && tn->u.call->func->tn_op == ADDR
4617	    && tn->u.call->func->u.ops.left->tn_op == NAME;
4618	if (op == CALL) {
4619		const function_call *call = tn->u.call;
4620		if (is_direct)
4621			check_expr_call(tn, call->func,
4622			    szof, vctx, cond, retval_discarded);
4623		bool discard = op == CVT && tn->tn_type->t_tspec == VOID;
4624		check_expr_misc(call->func, false, false, false, is_direct,
4625		    discard, szof);
4626		for (size_t i = 0, n = call->args_len; i < n; i++)
4627			check_expr_misc(call->args[i],
4628			    false, false, false, false, false, szof);
4629		return;
4630	}
4631
4632	lint_assert(has_operands(tn));
4633	tnode_t *ln = tn->u.ops.left;
4634	tnode_t *rn = tn->u.ops.right;
4635	check_expr_op(op, ln, szof, fcall, eqwarn);
4636
4637	const mod_t *mp = &modtab[op];
4638	bool cvctx = mp->m_value_context;
4639	bool ccond = mp->m_compares_with_zero;
4640	bool eq = mp->m_warn_if_operand_eq &&
4641	    !ln->tn_parenthesized &&
4642	    rn != NULL && !rn->tn_parenthesized;
4643
4644	/*
4645	 * Values of operands of ':' are not used if the type of at least
4646	 * one of the operands (for GCC compatibility) is 'void'.
4647	 *
4648	 * XXX test/value context of QUEST should probably be used as
4649	 * context for both operands of COLON.
4650	 */
4651	if (op == COLON && tn->tn_type->t_tspec == VOID)
4652		cvctx = ccond = false;
4653	bool discard = op == CVT && tn->tn_type->t_tspec == VOID;
4654	check_expr_misc(ln, cvctx, ccond, eq, is_direct, discard, szof);
4655
4656	switch (op) {
4657	case LOGAND:
4658	case LOGOR:
4659		check_expr_misc(rn, false, true, eq, false, false, szof);
4660		break;
4661	case COLON:
4662		check_expr_misc(rn, cvctx, ccond, eq, false, false, szof);
4663		break;
4664	case COMMA:
4665		check_expr_misc(rn, vctx, cond, false, false, false, szof);
4666		break;
4667	default:
4668		if (mp->m_binary)
4669			check_expr_misc(rn, true, false, eq, false, false,
4670			    szof);
4671		break;
4672	}
4673}
4674
4675/*
4676 * Return whether the expression can be used for static initialization.
4677 *
4678 * Constant initialization expressions must be constant or an address
4679 * of a static object with an optional offset. In the first case,
4680 * the result is returned in *offsp. In the second case, the static
4681 * object is returned in *symp and the offset in *offsp.
4682 *
4683 * The expression can consist of PLUS, MINUS, ADDR, NAME, STRING and
4684 * CON. Type conversions are allowed if they do not change binary
4685 * representation (including width).
4686 *
4687 * C99 6.6 "Constant expressions"
4688 * C99 6.7.8p4 restricts initializers for static storage duration
4689 */
4690bool
4691constant_addr(const tnode_t *tn, const sym_t **symp, ptrdiff_t *offsp)
4692{
4693	const sym_t *sym;
4694	ptrdiff_t offs1, offs2;
4695	tspec_t t, ot;
4696
4697	switch (tn->tn_op) {
4698	case MINUS:
4699		if (tn->u.ops.right->tn_op == CVT)
4700			return constant_addr(tn->u.ops.right, symp, offsp);
4701		else if (tn->u.ops.right->tn_op != CON)
4702			return false;
4703		/* FALLTHROUGH */
4704	case PLUS:
4705		offs1 = offs2 = 0;
4706		if (tn->u.ops.left->tn_op == CON) {
4707			offs1 = (ptrdiff_t)tn->u.ops.left->u.value.u.integer;
4708			if (!constant_addr(tn->u.ops.right, &sym, &offs2))
4709				return false;
4710		} else if (tn->u.ops.right->tn_op == CON) {
4711			offs2 = (ptrdiff_t)tn->u.ops.right->u.value.u.integer;
4712			if (tn->tn_op == MINUS)
4713				offs2 = -offs2;
4714			if (!constant_addr(tn->u.ops.left, &sym, &offs1))
4715				return false;
4716		} else {
4717			return false;
4718		}
4719		*symp = sym;
4720		*offsp = offs1 + offs2;
4721		return true;
4722	case ADDR:
4723		if (tn->u.ops.left->tn_op == NAME) {
4724			*symp = tn->u.ops.left->u.sym;
4725			*offsp = 0;
4726			return true;
4727		} else {
4728			/*
4729			 * If this were the front end of a compiler, we would
4730			 * return a label instead of 0, at least if
4731			 * 'tn->u.ops.left->tn_op == STRING'.
4732			 */
4733			*symp = NULL;
4734			*offsp = 0;
4735			return true;
4736		}
4737	case CVT:
4738		t = tn->tn_type->t_tspec;
4739		ot = tn->u.ops.left->tn_type->t_tspec;
4740		if ((!is_integer(t) && t != PTR) ||
4741		    (!is_integer(ot) && ot != PTR)) {
4742			return false;
4743		}
4744#if 0
4745		/*-
4746		 * consider:
4747		 *	struct foo {
4748		 *		unsigned char a;
4749		 *	} f = {
4750		 *		(unsigned char)(unsigned long)
4751		 *		    (&(((struct foo *)0)->a))
4752		 *	};
4753		 * since psize(unsigned long) != psize(unsigned char),
4754		 * this fails.
4755		 */
4756		else if (psize(t) != psize(ot))
4757			return -1;
4758#endif
4759		return constant_addr(tn->u.ops.left, symp, offsp);
4760	default:
4761		return false;
4762	}
4763}
4764
4765/* Append s2 to s1, then free s2. */
4766buffer *
4767cat_strings(buffer *s1, buffer *s2)
4768{
4769
4770	if ((s1->data != NULL) != (s2->data != NULL)) {
4771		/* cannot concatenate wide and regular string literals */
4772		error(292);
4773		return s1;
4774	}
4775
4776	if (s1->data != NULL) {
4777		while (s1->len + s2->len + 1 > s1->cap)
4778			s1->cap *= 2;
4779		s1->data = xrealloc(s1->data, s1->cap);
4780		memcpy(s1->data + s1->len, s2->data, s2->len + 1);
4781		free(s2->data);
4782	}
4783	s1->len += s2->len;
4784	free(s2);
4785
4786	return s1;
4787}
4788
4789
4790typedef struct stmt_expr {
4791	memory_pool se_mem;
4792	sym_t *se_sym;
4793	struct stmt_expr *se_enclosing;
4794} stmt_expr;
4795
4796static stmt_expr *stmt_exprs;
4797
4798void
4799begin_statement_expr(void)
4800{
4801	debug_enter();
4802
4803	stmt_expr *se = xmalloc(sizeof(*se));
4804	se->se_mem = expr_save_memory();
4805	se->se_sym = NULL;
4806	se->se_enclosing = stmt_exprs;
4807	stmt_exprs = se;
4808}
4809
4810void
4811do_statement_expr(tnode_t *tn)
4812{
4813	block_level--;
4814	mem_block_level--;
4815	stmt_exprs->se_sym = tn != NULL
4816	    ? mktempsym(block_dup_type(tn->tn_type))
4817	    : NULL;		/* after a syntax error */
4818	mem_block_level++;
4819	block_level++;
4820	/* '({ ... })' is a GCC extension */
4821	gnuism(320);
4822}
4823
4824tnode_t *
4825end_statement_expr(void)
4826{
4827	tnode_t *tn;
4828
4829	stmt_expr *se = stmt_exprs;
4830	if (se->se_sym == NULL) {
4831		tn = NULL;	/* after a syntax error */
4832		goto end;
4833	}
4834
4835	tn = build_name(se->se_sym, false);
4836	(void)expr_save_memory();	/* leak */
4837	expr_restore_memory(se->se_mem);
4838	stmt_exprs = se->se_enclosing;
4839	free(se);
4840
4841end:
4842	debug_leave();
4843	return tn;
4844}
4845
4846bool
4847in_statement_expr(void)
4848{
4849	return stmt_exprs != NULL;
4850}
4851