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