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