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