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