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