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