tree.c revision 1.652 1 /* $NetBSD: tree.c,v 1.652 2024/09/28 19:09:37 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)
40 __RCSID("$NetBSD: tree.c,v 1.652 2024/09/28 19:09:37 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
52
53 typedef struct integer_constraints {
54 int64_t smin; /* signed minimum */
55 int64_t smax; /* signed maximum */
56 uint64_t umin; /* unsigned minimum */
57 uint64_t umax; /* unsigned maximum */
58 uint64_t bclr; /* bits that are definitely clear */
59 } integer_constraints;
60
61
62 static uint64_t
63 u64_fill_right(uint64_t x)
64 {
65 x |= x >> 1;
66 x |= x >> 2;
67 x |= x >> 4;
68 x |= x >> 8;
69 x |= x >> 16;
70 x |= x >> 32;
71 return x;
72 }
73
74 static bool
75 str_ends_with(const char *haystack, const char *needle)
76 {
77 size_t hlen = strlen(haystack);
78 size_t nlen = strlen(needle);
79
80 return nlen <= hlen &&
81 memcmp(haystack + hlen - nlen, needle, nlen) == 0;
82 }
83
84 static unsigned
85 width_in_bits(const type_t *tp)
86 {
87
88 lint_assert(is_integer(tp->t_tspec));
89 return tp->t_bitfield
90 ? tp->t_bit_field_width
91 : size_in_bits(tp->t_tspec);
92 }
93
94 static int
95 portable_rank_cmp(tspec_t t1, tspec_t t2)
96 {
97 const ttab_t *p1 = type_properties(t1), *p2 = type_properties(t2);
98 lint_assert(p1->tt_rank_kind == p2->tt_rank_kind);
99 lint_assert(p1->tt_rank_value > 0);
100 lint_assert(p2->tt_rank_value > 0);
101 return (int)p1->tt_rank_value - (int)p2->tt_rank_value;
102 }
103
104 static bool
105 ic_maybe_signed(const type_t *tp, const integer_constraints *ic)
106 {
107 return !is_uinteger(tp->t_tspec) && ic->bclr >> 63 == 0;
108 }
109
110 static integer_constraints
111 ic_any(const type_t *tp)
112 {
113 integer_constraints c;
114
115 uint64_t vbits = value_bits(width_in_bits(tp));
116 if (is_uinteger(tp->t_tspec)) {
117 c.smin = INT64_MIN;
118 c.smax = INT64_MAX;
119 c.umin = 0;
120 c.umax = vbits;
121 c.bclr = ~c.umax;
122 } else {
123 c.smin = (int64_t)-1 - (int64_t)(vbits >> 1);
124 c.smax = (int64_t)(vbits >> 1);
125 c.umin = 0;
126 c.umax = UINT64_MAX;
127 c.bclr = 0;
128 }
129 return c;
130 }
131
132 static integer_constraints
133 ic_con(const type_t *tp, const val_t *v)
134 {
135 integer_constraints c;
136
137 lint_assert(is_integer(tp->t_tspec));
138 int64_t si = v->u.integer;
139 uint64_t ui = (uint64_t)si;
140 c.smin = si;
141 c.smax = si;
142 c.umin = ui;
143 c.umax = ui;
144 c.bclr = ~ui;
145 return c;
146 }
147
148 static integer_constraints
149 ic_cvt(const type_t *ntp, const type_t *otp, integer_constraints a)
150 {
151 unsigned nw = width_in_bits(ntp);
152 unsigned ow = width_in_bits(otp);
153 bool nu = is_uinteger(ntp->t_tspec);
154 bool ou = is_uinteger(otp->t_tspec);
155
156 if (nw >= ow && nu == ou)
157 return a;
158 if (nw > ow && ou)
159 return a;
160 return ic_any(ntp);
161 }
162
163 static integer_constraints
164 ic_bitand(integer_constraints a, integer_constraints b)
165 {
166 integer_constraints c;
167
168 c.smin = INT64_MIN;
169 c.smax = INT64_MAX;
170 c.umin = 0;
171 c.umax = ~(a.bclr | b.bclr);
172 c.bclr = a.bclr | b.bclr;
173 return c;
174 }
175
176 static integer_constraints
177 ic_bitor(integer_constraints a, integer_constraints b)
178 {
179 integer_constraints c;
180
181 c.smin = INT64_MIN;
182 c.smax = INT64_MAX;
183 c.umin = 0;
184 c.umax = ~(a.bclr & b.bclr);
185 c.bclr = a.bclr & b.bclr;
186 return c;
187 }
188
189 static integer_constraints
190 ic_mod(const type_t *tp, integer_constraints a, integer_constraints b)
191 {
192 integer_constraints c;
193
194 if (ic_maybe_signed(tp, &a) || ic_maybe_signed(tp, &b))
195 return ic_any(tp);
196
197 c.smin = INT64_MIN;
198 c.smax = INT64_MAX;
199 c.umin = 0;
200 c.umax = b.umax - 1;
201 c.bclr = ~u64_fill_right(c.umax);
202 return c;
203 }
204
205 static integer_constraints
206 ic_div(const type_t *tp, integer_constraints a, integer_constraints b)
207 {
208 integer_constraints c;
209
210 if (ic_maybe_signed(tp, &a) || ic_maybe_signed(tp, &b) || b.umin == 0)
211 return ic_any(tp);
212
213 c.smin = INT64_MIN;
214 c.smax = INT64_MAX;
215 c.umin = a.umin / b.umax;
216 c.umax = a.umax / b.umin;
217 c.bclr = ~u64_fill_right(c.umax);
218 return c;
219 }
220
221 static integer_constraints
222 ic_shl(const type_t *tp, integer_constraints a, integer_constraints b)
223 {
224 integer_constraints c;
225 unsigned int amount;
226
227 if (ic_maybe_signed(tp, &a))
228 return ic_any(tp);
229
230 if (b.smin == b.smax && b.smin >= 0 && b.smin < 64)
231 amount = (unsigned int)b.smin;
232 else if (b.umin == b.umax && b.umin < 64)
233 amount = (unsigned int)b.umin;
234 else
235 return ic_any(tp);
236
237 c.smin = INT64_MIN;
238 c.smax = INT64_MAX;
239 c.umin = 0;
240 c.umax = UINT64_MAX;
241 c.bclr = a.bclr << amount | (((uint64_t)1 << amount) - 1);
242 return c;
243 }
244
245 static integer_constraints
246 ic_shr(const type_t *tp, integer_constraints a, integer_constraints b)
247 {
248 integer_constraints c;
249 unsigned int amount;
250
251 if (ic_maybe_signed(tp, &a))
252 return ic_any(tp);
253
254 if (b.smin == b.smax && b.smin >= 0 && b.smin < 64)
255 amount = (unsigned int)b.smin;
256 else if (b.umin == b.umax && b.umin < 64)
257 amount = (unsigned int)b.umin;
258 else
259 return ic_any(tp);
260
261 c.smin = INT64_MIN;
262 c.smax = INT64_MAX;
263 c.umin = 0;
264 c.umax = UINT64_MAX;
265 c.bclr = a.bclr >> amount | ~(~(uint64_t)0 >> amount);
266 return c;
267 }
268
269 static integer_constraints
270 ic_cond(integer_constraints a, integer_constraints b)
271 {
272 integer_constraints c;
273
274 c.smin = a.smin < b.smin ? a.smin : b.smin;
275 c.smax = a.smax > b.smax ? a.smax : b.smax;
276 c.umin = a.umin < b.umin ? a.umin : b.umin;
277 c.umax = a.umax > b.umax ? a.umax : b.umax;
278 c.bclr = a.bclr & b.bclr;
279 return c;
280 }
281
282 static integer_constraints
283 ic_expr(const tnode_t *tn)
284 {
285 integer_constraints lc, rc;
286
287 lint_assert(is_integer(tn->tn_type->t_tspec));
288
289 switch (tn->tn_op) {
290 case CON:
291 return ic_con(tn->tn_type, &tn->u.value);
292 case CVT:
293 if (!is_integer(tn->u.ops.left->tn_type->t_tspec))
294 return ic_any(tn->tn_type);
295 lc = ic_expr(tn->u.ops.left);
296 return ic_cvt(tn->tn_type, tn->u.ops.left->tn_type, lc);
297 case DIV:
298 lc = ic_expr(before_conversion(tn->u.ops.left));
299 rc = ic_expr(before_conversion(tn->u.ops.right));
300 return ic_div(tn->tn_type, lc, rc);
301 case MOD:
302 lc = ic_expr(before_conversion(tn->u.ops.left));
303 rc = ic_expr(before_conversion(tn->u.ops.right));
304 return ic_mod(tn->tn_type, lc, rc);
305 case SHL:
306 lc = ic_expr(tn->u.ops.left);
307 rc = ic_expr(tn->u.ops.right);
308 return ic_shl(tn->tn_type, lc, rc);
309 case SHR:
310 lc = ic_expr(tn->u.ops.left);
311 rc = ic_expr(tn->u.ops.right);
312 return ic_shr(tn->tn_type, lc, rc);
313 case BITAND:
314 lc = ic_expr(tn->u.ops.left);
315 rc = ic_expr(tn->u.ops.right);
316 return ic_bitand(lc, rc);
317 case BITOR:
318 lc = ic_expr(tn->u.ops.left);
319 rc = ic_expr(tn->u.ops.right);
320 return ic_bitor(lc, rc);
321 case QUEST:
322 lc = ic_expr(tn->u.ops.right->u.ops.left);
323 rc = ic_expr(tn->u.ops.right->u.ops.right);
324 return ic_cond(lc, rc);
325 default:
326 return ic_any(tn->tn_type);
327 }
328 }
329
330 uint64_t
331 possible_bits(const tnode_t *tn)
332 {
333 return ~ic_expr(tn).bclr;
334 }
335
336 bool
337 attributes_contain(const attribute_list *attrs, const char *str)
338 {
339 for (size_t i = 0, n = attrs->len; i < n; i++) {
340 const attribute *attr = attrs->attrs + i;
341 if (attr->prefix == NULL && strcmp(attr->name, str) == 0)
342 return true;
343 }
344 return false;
345 }
346
347 /* Build 'pointer to tp', 'array of tp' or 'function returning tp'. */
348 type_t *
349 block_derive_type(type_t *tp, tspec_t t)
350 {
351
352 type_t *tp2 = block_zero_alloc(sizeof(*tp2), "type");
353 tp2->t_tspec = t;
354 tp2->t_subt = tp;
355 return tp2;
356 }
357
358 /*
359 * Derive 'pointer to tp' or 'function returning tp'.
360 * The memory is freed at the end of the current expression.
361 */
362 type_t *
363 expr_derive_type(type_t *tp, tspec_t t)
364 {
365
366 type_t *tp2 = expr_zero_alloc(sizeof(*tp2), "type");
367 tp2->t_tspec = t;
368 tp2->t_subt = tp;
369 return tp2;
370 }
371
372 /* Create an expression from a unary or binary operator and its operands. */
373 static tnode_t *
374 build_op(op_t op, bool sys, type_t *type, tnode_t *ln, tnode_t *rn)
375 {
376
377 tnode_t *ntn = expr_alloc_tnode();
378 ntn->tn_op = op;
379 ntn->tn_type = type;
380 ntn->tn_sys = sys;
381 ntn->u.ops.left = ln;
382 ntn->u.ops.right = rn;
383
384 if (op == INDIR || op == FSEL) {
385 lint_assert(ln->tn_type->t_tspec == PTR);
386 tspec_t t = ln->tn_type->t_subt->t_tspec;
387 ntn->tn_lvalue = t != FUNC && t != VOID;
388 }
389
390 return ntn;
391 }
392
393 tnode_t *
394 build_constant(type_t *tp, val_t *v)
395 {
396
397 tnode_t *n = expr_alloc_tnode();
398 n->tn_op = CON;
399 n->tn_type = tp;
400 n->u.value = *v;
401 n->u.value.v_tspec = tp->t_tspec;
402 free(v);
403 return n;
404 }
405
406 static tnode_t *
407 build_integer_constant(tspec_t t, int64_t si)
408 {
409
410 tnode_t *n = expr_alloc_tnode();
411 n->tn_op = CON;
412 n->tn_type = gettyp(t);
413 n->u.value.v_tspec = t;
414 n->u.value.v_unsigned_since_c90 = false;
415 n->u.value.v_char_constant = false;
416 n->u.value.u.integer = si;
417 return n;
418 }
419
420 static void
421 fallback_symbol(sym_t *sym)
422 {
423
424 if (Tflag && fallback_symbol_strict_bool(sym))
425 return;
426
427 if (funcsym != NULL && (strcmp(sym->s_name, "__FUNCTION__") == 0 ||
428 strcmp(sym->s_name, "__PRETTY_FUNCTION__") == 0)) {
429 /* __FUNCTION__/__PRETTY_FUNCTION__ is a GCC extension */
430 gnuism(316);
431 goto return_function_name;
432 }
433
434 if (funcsym != NULL && strcmp(sym->s_name, "__func__") == 0) {
435 if (!allow_c99)
436 /* __func__ is a C99 feature */
437 warning(317);
438 /* C11 6.4.2.2 */
439 return_function_name:
440 sym->s_type = block_derive_type(gettyp(CHAR), ARRAY);
441 sym->s_type->t_const = true;
442 sym->s_type->u.dimension = (int)strlen(funcsym->s_name) + 1;
443 return;
444 }
445
446 /* '%s' undefined */
447 error(99, sym->s_name);
448 }
449
450 /*
451 * Functions that are predeclared by GCC or other compilers can be called
452 * with arbitrary arguments. Since lint usually runs after a successful
453 * compilation, it's the compiler's job to catch any errors.
454 */
455 bool
456 is_compiler_builtin(const char *name)
457 {
458 /* https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html */
459 if (allow_gcc) {
460 if (strncmp(name, "__atomic_", 9) == 0 ||
461 strncmp(name, "__builtin_", 10) == 0 ||
462 strcmp(name, "alloca") == 0 ||
463 /* obsolete but still in use, as of 2021 */
464 strncmp(name, "__sync_", 7) == 0)
465 return true;
466 }
467
468 /* https://software.intel.com/sites/landingpage/IntrinsicsGuide/ */
469 if (strncmp(name, "_mm_", 4) == 0)
470 return true;
471
472 return false;
473 }
474
475 /* https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html */
476 static bool
477 is_gcc_bool_builtin(const char *name)
478 {
479 return strncmp(name, "__builtin_", 10) == 0 &&
480 (str_ends_with(name, "_overflow") ||
481 str_ends_with(name, "_overflow_p"));
482 }
483
484 static void
485 build_name_call(sym_t *sym)
486 {
487
488 if (is_compiler_builtin(sym->s_name)) {
489 /*
490 * Do not warn about these, just assume that they are regular
491 * functions compatible with non-prototype calling conventions.
492 */
493 if (allow_gcc && is_gcc_bool_builtin(sym->s_name))
494 sym->s_type = gettyp(BOOL);
495 } else if (allow_c99)
496 /* function '%s' implicitly declared to return int */
497 error(215, sym->s_name);
498 else if (!allow_trad)
499 /* function '%s' implicitly declared to return int */
500 warning(215, sym->s_name);
501
502 /* XXX if !allow_c90, the symbol should be exported to level 0 */
503 sym->s_type = block_derive_type(sym->s_type, FUNC);
504 }
505
506 /* Create a node for a name (symbol table entry). */
507 tnode_t *
508 build_name(sym_t *sym, bool is_funcname)
509 {
510
511 if (sym->s_scl == NO_SCL && !in_gcc_attribute) {
512 sym->s_scl = EXTERN;
513 sym->s_def = DECL;
514 if (is_funcname)
515 build_name_call(sym);
516 else
517 fallback_symbol(sym);
518 }
519
520 lint_assert(sym->s_kind == SK_VCFT || sym->s_kind == SK_MEMBER);
521
522 tnode_t *n = expr_alloc_tnode();
523 n->tn_type = sym->s_type;
524 if (sym->s_scl == BOOL_CONST) {
525 n->tn_op = CON;
526 n->u.value.v_tspec = BOOL;
527 n->u.value.v_unsigned_since_c90 = false;
528 n->u.value.v_char_constant = false;
529 n->u.value.u.integer = sym->u.s_bool_constant ? 1 : 0;
530 } else if (sym->s_scl == ENUM_CONST) {
531 n->tn_op = CON;
532 n->u.value.v_tspec = INT; /* ENUM is in n->tn_type */
533 n->u.value.v_unsigned_since_c90 = false;
534 n->u.value.v_char_constant = false;
535 n->u.value.u.integer = sym->u.s_enum_constant;
536 } else {
537 n->tn_op = NAME;
538 n->u.sym = sym;
539 if (sym->s_kind == SK_VCFT && sym->s_type->t_tspec != FUNC)
540 n->tn_lvalue = true;
541 }
542
543 return n;
544 }
545
546 tnode_t *
547 build_string(buffer *lit)
548 {
549 size_t value_len = lit->len;
550 if (lit->data != NULL) {
551 quoted_iterator it = { .end = 0 };
552 for (value_len = 0; quoted_next(lit, &it); value_len++)
553 continue;
554 }
555
556 type_t *tp = expr_zero_alloc(sizeof(*tp), "type");
557 tp->t_tspec = ARRAY;
558 tp->t_subt = gettyp(lit->data != NULL ? CHAR : WCHAR_TSPEC);
559 tp->u.dimension = (int)(value_len + 1);
560
561 tnode_t *n = expr_alloc_tnode();
562 n->tn_op = STRING;
563 n->tn_type = tp;
564 n->tn_lvalue = true;
565
566 n->u.str_literals = expr_zero_alloc(sizeof(*n->u.str_literals), "tnode.string");
567 n->u.str_literals->len = lit->len;
568
569 if (lit->data != NULL) {
570 n->u.str_literals->data = expr_zero_alloc(lit->len + 1,
571 "tnode.string.data");
572 (void)memcpy(n->u.str_literals->data, lit->data, lit->len + 1);
573 free(lit->data);
574 }
575 free(lit);
576
577 return n;
578 }
579
580 tnode_t *
581 build_generic_selection(const tnode_t *expr,
582 struct generic_association *sel)
583 {
584 tnode_t *default_result = NULL;
585
586 for (; sel != NULL; sel = sel->ga_prev) {
587 if (expr != NULL &&
588 types_compatible(sel->ga_arg, expr->tn_type,
589 false, false, NULL))
590 return sel->ga_result;
591 else if (sel->ga_arg == NULL)
592 default_result = sel->ga_result;
593 }
594 return default_result;
595 }
596
597 static bool
598 is_out_of_char_range(const tnode_t *tn)
599 {
600 return tn->tn_op == CON &&
601 !tn->u.value.v_char_constant &&
602 !(0 <= tn->u.value.u.integer &&
603 tn->u.value.u.integer < 1 << (CHAR_SIZE - 1));
604 }
605
606 static bool
607 check_nonportable_char_comparison(op_t op,
608 const tnode_t *ln, tspec_t lt,
609 const tnode_t *rn, tspec_t rt)
610 {
611 if (!(hflag || pflag))
612 return true;
613
614 if (lt == CHAR && is_out_of_char_range(rn)) {
615 char buf[128];
616 (void)snprintf(buf, sizeof(buf), "%s %d",
617 op_name(op), (int)rn->u.value.u.integer);
618 /* nonportable character comparison '%s' */
619 warning(230, buf);
620 return false;
621 }
622 if (rt == CHAR && is_out_of_char_range(ln)) {
623 char buf[128];
624 (void)snprintf(buf, sizeof(buf), "%d %s ?",
625 (int)ln->u.value.u.integer, op_name(op));
626 /* nonportable character comparison '%s' */
627 warning(230, buf);
628 return false;
629 }
630 return true;
631 }
632
633 static void
634 check_integer_comparison(op_t op, tnode_t *ln, tnode_t *rn)
635 {
636
637 tspec_t lt = ln->tn_type->t_tspec;
638 tspec_t rt = rn->tn_type->t_tspec;
639
640 if (ln->tn_op != CON && rn->tn_op != CON)
641 return;
642
643 if (!is_integer(lt) || !is_integer(rt))
644 return;
645
646 if (any_query_enabled && !in_system_header) {
647 if (lt == CHAR && rn->tn_op == CON &&
648 !rn->u.value.v_char_constant) {
649 /* comparison '%s' of 'char' with plain integer %d */
650 query_message(14,
651 op_name(op), (int)rn->u.value.u.integer);
652 }
653 if (rt == CHAR && ln->tn_op == CON &&
654 !ln->u.value.v_char_constant) {
655 /* comparison '%s' of 'char' with plain integer %d */
656 query_message(14,
657 op_name(op), (int)ln->u.value.u.integer);
658 }
659 }
660
661 if (!check_nonportable_char_comparison(op, ln, lt, rn, rt))
662 return;
663
664 if (is_uinteger(lt) && !is_uinteger(rt) &&
665 rn->tn_op == CON && rn->u.value.u.integer <= 0) {
666 if (rn->u.value.u.integer < 0) {
667 /* operator '%s' compares '%s' with '%s' */
668 warning(162, op_name(op),
669 type_name(ln->tn_type), "negative constant");
670 } else if (op == LT || op == GE)
671 /* operator '%s' compares '%s' with '%s' */
672 warning(162, op_name(op), type_name(ln->tn_type), "0");
673 return;
674 }
675 if (is_uinteger(rt) && !is_uinteger(lt) &&
676 ln->tn_op == CON && ln->u.value.u.integer <= 0) {
677 if (ln->u.value.u.integer < 0) {
678 /* operator '%s' compares '%s' with '%s' */
679 warning(162, op_name(op),
680 "negative constant", type_name(rn->tn_type));
681 } else if (op == GT || op == LE)
682 /* operator '%s' compares '%s' with '%s' */
683 warning(162, op_name(op), "0", type_name(rn->tn_type));
684 return;
685 }
686 }
687
688 static const tspec_t arith_rank[] = {
689 LDOUBLE, DOUBLE, FLOAT,
690 #ifdef INT128_SIZE
691 UINT128, INT128,
692 #endif
693 ULLONG, LLONG,
694 ULONG, LONG,
695 UINT, INT,
696 };
697
698 /* Keep unsigned in traditional C */
699 static tspec_t
700 usual_arithmetic_conversion_trad(tspec_t lt, tspec_t rt)
701 {
702
703 size_t i;
704 for (i = 0; arith_rank[i] != INT; i++)
705 if (lt == arith_rank[i] || rt == arith_rank[i])
706 break;
707
708 tspec_t t = arith_rank[i];
709 if (is_uinteger(lt) || is_uinteger(rt))
710 if (is_integer(t) && !is_uinteger(t))
711 return unsigned_type(t);
712 return t;
713 }
714
715 static tspec_t
716 usual_arithmetic_conversion_c90(tspec_t lt, tspec_t rt)
717 {
718
719 if (lt == rt)
720 return lt;
721
722 if (lt == LCOMPLEX || rt == LCOMPLEX)
723 return LCOMPLEX;
724 if (lt == DCOMPLEX || rt == DCOMPLEX)
725 return DCOMPLEX;
726 if (lt == FCOMPLEX || rt == FCOMPLEX)
727 return FCOMPLEX;
728 if (lt == LDOUBLE || rt == LDOUBLE)
729 return LDOUBLE;
730 if (lt == DOUBLE || rt == DOUBLE)
731 return DOUBLE;
732 if (lt == FLOAT || rt == FLOAT)
733 return FLOAT;
734
735 if (size_in_bits(lt) > size_in_bits(rt))
736 return lt;
737 if (size_in_bits(lt) < size_in_bits(rt))
738 return rt;
739
740 size_t i;
741 for (i = 3; arith_rank[i] != INT; i++)
742 if (arith_rank[i] == lt || arith_rank[i] == rt)
743 break;
744 if ((is_uinteger(lt) || is_uinteger(rt)) &&
745 !is_uinteger(arith_rank[i]))
746 i--;
747 return arith_rank[i];
748 }
749
750 static tnode_t *
751 apply_usual_arithmetic_conversions(op_t op, tnode_t *tn, tspec_t t)
752 {
753 type_t *ntp = expr_dup_type(tn->tn_type);
754 ntp->t_tspec = t;
755 if (tn->tn_op != CON) {
756 /* usual arithmetic conversion for '%s' from '%s' to '%s' */
757 query_message(4, op_name(op),
758 type_name(tn->tn_type), type_name(ntp));
759 }
760 return convert(op, 0, ntp, tn);
761 }
762
763 /*
764 * Apply the "usual arithmetic conversions" (C99 6.3.1.8), which gives both
765 * operands the same type.
766 */
767 static void
768 balance(op_t op, tnode_t **lnp, tnode_t **rnp)
769 {
770
771 tspec_t lt = (*lnp)->tn_type->t_tspec;
772 tspec_t rt = (*rnp)->tn_type->t_tspec;
773 if (!is_arithmetic(lt) || !is_arithmetic(rt))
774 return;
775
776 tspec_t t = allow_c90
777 ? usual_arithmetic_conversion_c90(lt, rt)
778 : usual_arithmetic_conversion_trad(lt, rt);
779
780 if (modtab[op].m_comparison
781 && is_integer(lt) && (*lnp)->tn_op != CON
782 && is_floating(t) && (*rnp)->tn_op == CON)
783 /* comparing integer '%s' to floating point constant %Lg */
784 warning(379, type_name((*lnp)->tn_type),
785 (*rnp)->u.value.u.floating);
786
787 if (t != lt)
788 *lnp = apply_usual_arithmetic_conversions(op, *lnp, t);
789 if (t != rt)
790 *rnp = apply_usual_arithmetic_conversions(op, *rnp, t);
791
792 if (is_integer(t)) {
793 unsigned lw = width_in_bits((*lnp)->tn_type);
794 unsigned rw = width_in_bits((*rnp)->tn_type);
795 if (lw < rw)
796 *lnp = convert(NOOP, 0, (*rnp)->tn_type, *lnp);
797 if (rw < lw)
798 *rnp = convert(NOOP, 0, (*lnp)->tn_type, *rnp);
799 }
800 }
801
802 static tnode_t *
803 build_address(bool sys, tnode_t *tn, bool force)
804 {
805 tspec_t t;
806
807 if (!force && ((t = tn->tn_type->t_tspec) == ARRAY || t == FUNC)) {
808 if (!allow_c90)
809 /* '&' before array or function: ignored */
810 warning(127);
811 return tn;
812 }
813
814 /* eliminate '&*' */
815 if (tn->tn_op == INDIR &&
816 tn->u.ops.left->tn_type->t_tspec == PTR &&
817 tn->u.ops.left->tn_type->t_subt == tn->tn_type) {
818 return tn->u.ops.left;
819 }
820
821 return build_op(ADDR, sys, expr_derive_type(tn->tn_type, PTR),
822 tn, NULL);
823 }
824
825 static uint64_t
826 fold_unsigned_integer(op_t op, uint64_t l, uint64_t r,
827 uint64_t max_value, bool *overflow)
828 {
829 switch (op) {
830 case COMPL:
831 return ~l & max_value;
832 case UPLUS:
833 return +l;
834 case UMINUS:
835 return -l & max_value;
836 case MULT:
837 *overflow = r > 0 && l > max_value / r;
838 return l * r;
839 case DIV:
840 if (r == 0) {
841 /* division by 0 */
842 error(139);
843 return max_value;
844 }
845 return l / r;
846 case MOD:
847 if (r == 0) {
848 /* modulus by 0 */
849 error(140);
850 return 0;
851 }
852 return l % r;
853 case PLUS:
854 *overflow = l > max_value - r;
855 return l + r;
856 case MINUS:
857 *overflow = l < r;
858 return l - r;
859 case SHL:
860 /* TODO: warn about out-of-bounds 'r'. */
861 /* TODO: warn about overflow. */
862 return l << (r & 63);
863 case SHR:
864 /* TODO: warn about out-of-bounds 'r'. */
865 return l >> (r & 63);
866 case LT:
867 return l < r ? 1 : 0;
868 case LE:
869 return l <= r ? 1 : 0;
870 case GT:
871 return l > r ? 1 : 0;
872 case GE:
873 return l >= r ? 1 : 0;
874 case EQ:
875 return l == r ? 1 : 0;
876 case NE:
877 return l != r ? 1 : 0;
878 case BITAND:
879 return l & r;
880 case BITXOR:
881 return l ^ r;
882 case BITOR:
883 return l | r;
884 default:
885 lint_assert(/*CONSTCOND*/false);
886 /* NOTREACHED */
887 }
888 }
889
890 static int64_t
891 fold_signed_integer(op_t op, int64_t l, int64_t r,
892 int64_t min_value, int64_t max_value, bool *overflow)
893 {
894 switch (op) {
895 case COMPL:
896 return ~l;
897 case UPLUS:
898 return +l;
899 case UMINUS:
900 *overflow = l == min_value;
901 return *overflow ? l : -l;
902 case MULT:;
903 uint64_t al = l >= 0 ? (uint64_t)l : -(uint64_t)l;
904 uint64_t ar = r >= 0 ? (uint64_t)r : -(uint64_t)r;
905 bool neg = (l >= 0) != (r >= 0);
906 uint64_t max_prod = (uint64_t)max_value + (neg ? 1 : 0);
907 if (al > 0 && ar > max_prod / al) {
908 *overflow = true;
909 return neg ? min_value : max_value;
910 }
911 return l * r;
912 case DIV:
913 if (r == 0) {
914 /* division by 0 */
915 error(139);
916 return max_value;
917 }
918 if (l == min_value && r == -1) {
919 *overflow = true;
920 return l;
921 }
922 return l / r;
923 case MOD:
924 if (r == 0) {
925 /* modulus by 0 */
926 error(140);
927 return 0;
928 }
929 if (l == min_value && r == -1) {
930 *overflow = true;
931 return 0;
932 }
933 return l % r;
934 case PLUS:
935 if (r > 0 && l > max_value - r) {
936 *overflow = true;
937 return max_value;
938 }
939 if (r < 0 && l < min_value - r) {
940 *overflow = true;
941 return min_value;
942 }
943 return l + r;
944 case MINUS:
945 if (r > 0 && l < min_value + r) {
946 *overflow = true;
947 return min_value;
948 }
949 if (r < 0 && l > max_value + r) {
950 *overflow = true;
951 return max_value;
952 }
953 return l - r;
954 case SHL:
955 /* TODO: warn about out-of-bounds 'r'. */
956 /* TODO: warn about overflow. */
957 return l << (r & 63);
958 case SHR:
959 /* TODO: warn about out-of-bounds 'r'. */
960 if (l < 0)
961 return (int64_t)~(~(uint64_t)l >> (r & 63));
962 return (int64_t)((uint64_t)l >> (r & 63));
963 case LT:
964 return l < r ? 1 : 0;
965 case LE:
966 return l <= r ? 1 : 0;
967 case GT:
968 return l > r ? 1 : 0;
969 case GE:
970 return l >= r ? 1 : 0;
971 case EQ:
972 return l == r ? 1 : 0;
973 case NE:
974 return l != r ? 1 : 0;
975 case BITAND:
976 return l & r;
977 case BITXOR:
978 return l ^ r;
979 case BITOR:
980 return l | r;
981 default:
982 lint_assert(/*CONSTCOND*/false);
983 /* NOTREACHED */
984 }
985 }
986
987 static tnode_t *
988 fold_constant_integer(tnode_t *tn)
989 {
990
991 lint_assert(has_operands(tn));
992 tspec_t t = tn->u.ops.left->tn_type->t_tspec;
993 int64_t l = tn->u.ops.left->u.value.u.integer;
994 int64_t r = is_binary(tn) ? tn->u.ops.right->u.value.u.integer : 0;
995 uint64_t mask = value_bits(size_in_bits(t));
996
997 int64_t res;
998 bool overflow = false;
999 if (!is_integer(t) || is_uinteger(t)) {
1000 uint64_t u_res = fold_unsigned_integer(tn->tn_op,
1001 (uint64_t)l, (uint64_t)r, mask, &overflow);
1002 if (u_res > mask)
1003 overflow = true;
1004 res = (int64_t)u_res;
1005 if (overflow && hflag) {
1006 char buf[128];
1007 if (is_binary(tn)) {
1008 snprintf(buf, sizeof(buf), "%ju %s %ju",
1009 (uintmax_t)l, op_name(tn->tn_op),
1010 (uintmax_t)r);
1011 } else {
1012 snprintf(buf, sizeof(buf), "%s%ju",
1013 op_name(tn->tn_op), (uintmax_t)l);
1014 }
1015 /* '%s' overflows '%s' */
1016 warning(141, buf, type_name(tn->tn_type));
1017 }
1018 } else {
1019 int64_t max_value = (int64_t)(mask >> 1);
1020 int64_t min_value = -max_value - 1;
1021 res = fold_signed_integer(tn->tn_op,
1022 l, r, min_value, max_value, &overflow);
1023 if (res < min_value || res > max_value)
1024 overflow = true;
1025 if (overflow && hflag) {
1026 char buf[128];
1027 if (is_binary(tn)) {
1028 snprintf(buf, sizeof(buf), "%jd %s %jd",
1029 (intmax_t)l, op_name(tn->tn_op),
1030 (intmax_t)r);
1031 } else if (tn->tn_op == UMINUS && l < 0) {
1032 snprintf(buf, sizeof(buf), "-(%jd)",
1033 (intmax_t)l);
1034 } else {
1035 snprintf(buf, sizeof(buf), "%s%jd",
1036 op_name(tn->tn_op), (intmax_t)l);
1037 }
1038 /* '%s' overflows '%s' */
1039 warning(141, buf, type_name(tn->tn_type));
1040 }
1041 }
1042
1043 val_t *v = xcalloc(1, sizeof(*v));
1044 v->v_tspec = tn->tn_type->t_tspec;
1045 v->u.integer = convert_integer(res, t, size_in_bits(t));
1046
1047 tnode_t *cn = build_constant(tn->tn_type, v);
1048 if (tn->u.ops.left->tn_system_dependent)
1049 cn->tn_system_dependent = true;
1050 if (is_binary(tn) && tn->u.ops.right->tn_system_dependent)
1051 cn->tn_system_dependent = true;
1052
1053 return cn;
1054 }
1055
1056 static tnode_t *
1057 build_struct_access(op_t op, bool sys, tnode_t *ln, tnode_t *rn)
1058 {
1059
1060 lint_assert(rn->tn_op == NAME);
1061 lint_assert(is_member(rn->u.sym));
1062
1063 bool lvalue = op == ARROW || ln->tn_lvalue;
1064
1065 if (op == POINT)
1066 ln = build_address(sys, ln, true);
1067 else if (ln->tn_type->t_tspec != PTR) {
1068 lint_assert(!allow_c90);
1069 lint_assert(is_integer(ln->tn_type->t_tspec));
1070 ln = convert(NOOP, 0, expr_derive_type(gettyp(VOID), PTR), ln);
1071 }
1072
1073 tnode_t *ctn = build_integer_constant(PTRDIFF_TSPEC,
1074 rn->u.sym->u.s_member.sm_offset_in_bits / CHAR_SIZE);
1075
1076 type_t *ptr_tp = expr_derive_type(rn->tn_type, PTR);
1077 tnode_t *ntn = build_op(PLUS, sys, ptr_tp, ln, ctn);
1078 if (ln->tn_op == CON)
1079 ntn = fold_constant_integer(ntn);
1080
1081 op_t nop = rn->tn_type->t_bitfield ? FSEL : INDIR;
1082 ntn = build_op(nop, sys, ntn->tn_type->t_subt, ntn, NULL);
1083 if (!lvalue)
1084 ntn->tn_lvalue = false;
1085
1086 return ntn;
1087 }
1088
1089 /*
1090 * Get the size in bytes of type tp->t_subt, as a constant expression of type
1091 * ptrdiff_t as seen from the target platform.
1092 */
1093 static tnode_t *
1094 subt_size_in_bytes(type_t *tp)
1095 {
1096
1097 lint_assert(tp->t_tspec == PTR);
1098 tp = tp->t_subt;
1099
1100 int elem = 1;
1101 while (tp->t_tspec == ARRAY) {
1102 elem *= tp->u.dimension;
1103 tp = tp->t_subt;
1104 }
1105
1106 int elsz_in_bits = 0;
1107 switch (tp->t_tspec) {
1108 case FUNC:
1109 /* pointer to function is not allowed here */
1110 error(110);
1111 break;
1112 case VOID:
1113 /* cannot do pointer arithmetic on operand of unknown size */
1114 gnuism(136);
1115 break;
1116 case STRUCT:
1117 case UNION:
1118 if ((elsz_in_bits = (int)tp->u.sou->sou_size_in_bits) == 0)
1119 /* cannot do pointer arithmetic on operand of ... */
1120 error(136);
1121 break;
1122 case ENUM:
1123 if (is_incomplete(tp))
1124 /* cannot do pointer arithmetic on operand of ... */
1125 warning(136);
1126 /* FALLTHROUGH */
1127 default:
1128 if ((elsz_in_bits = size_in_bits(tp->t_tspec)) == 0)
1129 /* cannot do pointer arithmetic on operand of ... */
1130 error(136);
1131 else
1132 lint_assert(elsz_in_bits != -1);
1133 break;
1134 }
1135
1136 if (elem == 0 && elsz_in_bits != 0)
1137 /* cannot do pointer arithmetic on operand of unknown size */
1138 error(136);
1139
1140 if (elsz_in_bits == 0)
1141 elsz_in_bits = CHAR_SIZE;
1142
1143 return build_integer_constant(PTRDIFF_TSPEC,
1144 (int64_t)(elem * elsz_in_bits / CHAR_SIZE));
1145 }
1146
1147 static tnode_t *
1148 build_prepost_incdec(op_t op, bool sys, tnode_t *ln)
1149 {
1150
1151 lint_assert(ln != NULL);
1152 tnode_t *cn = ln->tn_type->t_tspec == PTR
1153 ? subt_size_in_bytes(ln->tn_type)
1154 : build_integer_constant(INT, 1);
1155 return build_op(op, sys, ln->tn_type, ln, cn);
1156 }
1157
1158 static void
1159 check_enum_array_index(const tnode_t *ln, const tnode_t *rn)
1160 {
1161
1162 if (ln->tn_op != ADDR || ln->u.ops.left->tn_op != NAME)
1163 return;
1164
1165 const type_t *ltp = ln->u.ops.left->tn_type;
1166 if (ltp->t_tspec != ARRAY || ltp->t_incomplete_array)
1167 return;
1168
1169 if (rn->tn_op != CVT || !rn->tn_type->t_is_enum)
1170 return;
1171 if (rn->u.ops.left->tn_op != LOAD)
1172 return;
1173
1174 const type_t *rtp = rn->u.ops.left->tn_type;
1175 const sym_t *ec = rtp->u.enumer->en_first_enumerator;
1176 const sym_t *max_ec = ec;
1177 lint_assert(ec != NULL);
1178 for (ec = ec->s_next; ec != NULL; ec = ec->s_next)
1179 if (ec->u.s_enum_constant > max_ec->u.s_enum_constant)
1180 max_ec = ec;
1181
1182 int64_t max_enum_value = max_ec->u.s_enum_constant;
1183 lint_assert(INT_MIN <= max_enum_value && max_enum_value <= INT_MAX);
1184
1185 int max_array_index = ltp->u.dimension - 1;
1186 if (max_enum_value == max_array_index)
1187 return;
1188
1189 if (max_enum_value == max_array_index + 1 &&
1190 (strstr(max_ec->s_name, "MAX") != NULL ||
1191 strstr(max_ec->s_name, "max") != NULL ||
1192 strstr(max_ec->s_name, "NUM") != NULL ||
1193 strstr(max_ec->s_name, "num") != NULL))
1194 return;
1195
1196 /* maximum value %d of '%s' does not match maximum array index %d */
1197 warning(348, (int)max_enum_value, type_name(rtp), max_array_index);
1198 print_previous_declaration(max_ec);
1199 }
1200
1201 static tnode_t *
1202 build_plus_minus(op_t op, bool sys, tnode_t *ln, tnode_t *rn)
1203 {
1204
1205 if (rn->tn_type->t_tspec == PTR && is_integer(ln->tn_type->t_tspec)) {
1206 tnode_t *tmp = ln;
1207 ln = rn;
1208 rn = tmp;
1209 /* pointer addition has integer on the left-hand side */
1210 query_message(5);
1211 }
1212
1213 /* pointer +- integer */
1214 tspec_t lt = ln->tn_type->t_tspec;
1215 tspec_t rt = rn->tn_type->t_tspec;
1216 if (lt == PTR && rt != PTR) {
1217 lint_assert(is_integer(rt));
1218
1219 check_ctype_macro_invocation(ln, rn);
1220 check_enum_array_index(ln, rn);
1221
1222 tnode_t *elsz = subt_size_in_bytes(ln->tn_type);
1223 tspec_t szt = elsz->tn_type->t_tspec;
1224 if (rt != szt && rt != unsigned_type(szt))
1225 rn = convert(NOOP, 0, elsz->tn_type, rn);
1226
1227 tnode_t *prod = build_op(MULT, sys, rn->tn_type, rn, elsz);
1228 if (rn->tn_op == CON)
1229 prod = fold_constant_integer(prod);
1230
1231 return build_op(op, sys, ln->tn_type, ln, prod);
1232 }
1233
1234 /* pointer - pointer */
1235 if (rt == PTR) {
1236 lint_assert(lt == PTR);
1237 lint_assert(op == MINUS);
1238
1239 type_t *ptrdiff = gettyp(PTRDIFF_TSPEC);
1240 tnode_t *raw_diff = build_op(op, sys, ptrdiff, ln, rn);
1241 if (ln->tn_op == CON && rn->tn_op == CON)
1242 raw_diff = fold_constant_integer(raw_diff);
1243
1244 tnode_t *elsz = subt_size_in_bytes(ln->tn_type);
1245 balance(NOOP, &raw_diff, &elsz);
1246
1247 return build_op(DIV, sys, ptrdiff, raw_diff, elsz);
1248 }
1249
1250 return build_op(op, sys, ln->tn_type, ln, rn);
1251 }
1252
1253 static tnode_t *
1254 build_bit_shift(op_t op, bool sys, tnode_t *ln, tnode_t *rn)
1255 {
1256
1257 if (!allow_c90 && rn->tn_type->t_tspec != INT)
1258 // XXX: C1978 7.5 says: "Both [operators] perform the usual
1259 // arithmetic conversions on their operands."
1260 // TODO: Add a test to exercise this part of the code.
1261 rn = convert(NOOP, 0, gettyp(INT), rn);
1262 return build_op(op, sys, ln->tn_type, ln, rn);
1263 }
1264
1265 static bool
1266 is_null_pointer(const tnode_t *tn)
1267 {
1268 tspec_t t = tn->tn_type->t_tspec;
1269
1270 // TODO: Investigate how other pointers are stored, in particular,
1271 // whether a pointer constant can have a non-zero value.
1272 // If not, simplify the code below.
1273 return ((t == PTR && tn->tn_type->t_subt->t_tspec == VOID)
1274 || is_integer(t))
1275 && (tn->tn_op == CON && tn->u.value.u.integer == 0);
1276 }
1277
1278 /* Return a type based on tp1, with added qualifiers from tp2. */
1279 static type_t *
1280 merge_qualifiers(type_t *tp1, const type_t *tp2)
1281 {
1282
1283 lint_assert(tp1->t_tspec == PTR);
1284 lint_assert(tp2->t_tspec == PTR);
1285
1286 bool c1 = tp1->t_subt->t_const;
1287 bool c2 = tp2->t_subt->t_const;
1288 bool v1 = tp1->t_subt->t_volatile;
1289 bool v2 = tp2->t_subt->t_volatile;
1290
1291 if (c1 == (c1 | c2) && v1 == (v1 | v2))
1292 return tp1;
1293
1294 type_t *nstp = expr_dup_type(tp1->t_subt);
1295 nstp->t_const |= c2;
1296 nstp->t_volatile |= v2;
1297
1298 type_t *ntp = expr_dup_type(tp1);
1299 ntp->t_subt = nstp;
1300 return ntp;
1301 }
1302
1303 /* See C99 6.5.15 "Conditional operator". */
1304 static tnode_t *
1305 build_colon(bool sys, tnode_t *ln, tnode_t *rn)
1306 {
1307 tspec_t lt = ln->tn_type->t_tspec;
1308 tspec_t rt = rn->tn_type->t_tspec;
1309
1310 type_t *tp;
1311 if (is_arithmetic(lt) && is_arithmetic(rt))
1312 /* The operands were already balanced in build_binary. */
1313 tp = ln->tn_type;
1314 else if (lt == BOOL && rt == BOOL)
1315 tp = ln->tn_type;
1316 else if (lt == VOID || rt == VOID)
1317 tp = gettyp(VOID);
1318 else if (is_struct_or_union(lt)) {
1319 lint_assert(is_struct_or_union(rt));
1320 lint_assert(ln->tn_type->u.sou == rn->tn_type->u.sou);
1321 if (is_incomplete(ln->tn_type)) {
1322 /* unknown operand size, op '%s' */
1323 error(138, op_name(COLON));
1324 return NULL;
1325 }
1326 tp = ln->tn_type;
1327 } else if (lt == PTR && is_integer(rt)) {
1328 if (rt != PTRDIFF_TSPEC)
1329 rn = convert(NOOP, 0, gettyp(PTRDIFF_TSPEC), rn);
1330 tp = ln->tn_type;
1331 } else if (rt == PTR && is_integer(lt)) {
1332 if (lt != PTRDIFF_TSPEC)
1333 ln = convert(NOOP, 0, gettyp(PTRDIFF_TSPEC), ln);
1334 tp = rn->tn_type;
1335 } else if (lt == PTR && is_null_pointer(rn))
1336 tp = merge_qualifiers(ln->tn_type, rn->tn_type);
1337 else if (rt == PTR && is_null_pointer(ln))
1338 tp = merge_qualifiers(rn->tn_type, ln->tn_type);
1339 else if (lt == PTR && ln->tn_type->t_subt->t_tspec == VOID)
1340 tp = merge_qualifiers(ln->tn_type, rn->tn_type);
1341 else if (rt == PTR && rn->tn_type->t_subt->t_tspec == VOID)
1342 tp = merge_qualifiers(rn->tn_type, ln->tn_type);
1343 else {
1344 /*
1345 * XXX For now we simply take the left type. This is probably
1346 * wrong, if one type contains a function prototype and the
1347 * other one, at the same place, only an old-style declaration.
1348 */
1349 tp = merge_qualifiers(ln->tn_type, rn->tn_type);
1350 }
1351
1352 return build_op(COLON, sys, tp, ln, rn);
1353 }
1354
1355 /* TODO: check for varargs */
1356 static bool
1357 is_cast_redundant(const tnode_t *tn)
1358 {
1359 const type_t *ntp = tn->tn_type, *otp = tn->u.ops.left->tn_type;
1360 tspec_t nt = ntp->t_tspec, ot = otp->t_tspec;
1361
1362 if (nt == BOOL || ot == BOOL)
1363 return nt == BOOL && ot == BOOL;
1364
1365 if (is_integer(nt) && is_integer(ot)) {
1366 unsigned int nw = width_in_bits(ntp), ow = width_in_bits(otp);
1367 if (is_uinteger(nt) == is_uinteger(ot))
1368 return nw >= ow;
1369 return is_uinteger(ot) && nw > ow;
1370 }
1371
1372 if (is_complex(nt) || is_complex(ot))
1373 return is_complex(nt) && is_complex(ot) &&
1374 size_in_bits(nt) >= size_in_bits(ot);
1375
1376 if (is_floating(nt) && is_floating(ot))
1377 return size_in_bits(nt) >= size_in_bits(ot);
1378
1379 if (nt == PTR && ot == PTR) {
1380 if (!ntp->t_subt->t_const && otp->t_subt->t_const)
1381 return false;
1382 if (!ntp->t_subt->t_volatile && otp->t_subt->t_volatile)
1383 return false;
1384
1385 if (ntp->t_subt->t_tspec == VOID ||
1386 otp->t_subt->t_tspec == VOID ||
1387 types_compatible(ntp->t_subt, otp->t_subt,
1388 false, false, NULL))
1389 return true;
1390 }
1391
1392 return false;
1393 }
1394
1395 static bool
1396 is_assignment(op_t op)
1397 {
1398
1399 return op == ASSIGN ||
1400 op == MULASS ||
1401 op == DIVASS ||
1402 op == MODASS ||
1403 op == ADDASS ||
1404 op == SUBASS ||
1405 op == SHLASS ||
1406 op == SHRASS ||
1407 op == ANDASS ||
1408 op == XORASS ||
1409 op == ORASS ||
1410 op == RETURN ||
1411 op == INIT;
1412 }
1413
1414 static tnode_t *
1415 build_assignment(op_t op, bool sys, tnode_t *ln, tnode_t *rn)
1416 {
1417
1418 tspec_t lt = ln->tn_type->t_tspec;
1419 tspec_t rt = rn->tn_type->t_tspec;
1420
1421 if (any_query_enabled && is_assignment(rn->tn_op)) {
1422 /* chained assignment with '%s' and '%s' */
1423 query_message(10, op_name(op), op_name(rn->tn_op));
1424 }
1425
1426 if ((op == ADDASS || op == SUBASS) && lt == PTR) {
1427 lint_assert(is_integer(rt));
1428 tnode_t *ctn = subt_size_in_bytes(ln->tn_type);
1429 if (rn->tn_type->t_tspec != ctn->tn_type->t_tspec)
1430 rn = convert(NOOP, 0, ctn->tn_type, rn);
1431 rn = build_op(MULT, sys, rn->tn_type, rn, ctn);
1432 if (rn->u.ops.left->tn_op == CON)
1433 rn = fold_constant_integer(rn);
1434 }
1435
1436 if ((op == ASSIGN || op == RETURN || op == INIT) &&
1437 (lt == STRUCT || rt == STRUCT)) {
1438 lint_assert(lt == rt);
1439 lint_assert(ln->tn_type->u.sou == rn->tn_type->u.sou);
1440 if (is_incomplete(ln->tn_type)) {
1441 if (op == RETURN)
1442 /* cannot return incomplete type */
1443 error(212);
1444 else
1445 /* unknown operand size, op '%s' */
1446 error(138, op_name(op));
1447 return NULL;
1448 }
1449 }
1450
1451 if (op == SHLASS && hflag && allow_trad && allow_c90
1452 && portable_rank_cmp(lt, rt) < 0)
1453 /* semantics of '%s' change in C90; ... */
1454 warning(118, "<<=");
1455
1456 if (op != SHLASS && op != SHRASS
1457 && (op == ASSIGN || lt != PTR)
1458 && (lt != rt || (ln->tn_type->t_bitfield && rn->tn_op == CON))) {
1459 rn = convert(op, 0, ln->tn_type, rn);
1460 rt = lt;
1461 }
1462
1463 if (is_query_enabled[20]
1464 && lt == PTR && ln->tn_type->t_subt->t_tspec != VOID
1465 && rt == PTR && rn->tn_type->t_subt->t_tspec == VOID
1466 && !is_null_pointer(rn))
1467 /* implicit narrowing conversion from void ... */
1468 query_message(20, type_name(ln->tn_type));
1469
1470 if (any_query_enabled && rn->tn_op == CVT && rn->tn_cast &&
1471 types_compatible(ln->tn_type, rn->tn_type, false, false, NULL) &&
1472 is_cast_redundant(rn)) {
1473 /* redundant cast from '%s' to '%s' before assignment */
1474 query_message(7, type_name(rn->u.ops.left->tn_type),
1475 type_name(rn->tn_type));
1476 }
1477
1478 return build_op(op, sys, ln->tn_type, ln, rn);
1479 }
1480
1481 static tnode_t *
1482 build_real_imag(op_t op, bool sys, tnode_t *ln)
1483 {
1484
1485 lint_assert(ln != NULL);
1486 if (ln->tn_op == NAME) {
1487 /*
1488 * This may be too much, but it avoids wrong warnings. See
1489 * d_c99_complex_split.c.
1490 */
1491 mark_as_used(ln->u.sym, false, false);
1492 mark_as_set(ln->u.sym);
1493 }
1494
1495 tspec_t t;
1496 switch (ln->tn_type->t_tspec) {
1497 case LCOMPLEX:
1498 t = LDOUBLE;
1499 break;
1500 case DCOMPLEX:
1501 t = DOUBLE;
1502 break;
1503 case FCOMPLEX:
1504 t = FLOAT;
1505 break;
1506 default:
1507 /* '__%s__' is illegal for type '%s' */
1508 error(276, op == REAL ? "real" : "imag",
1509 type_name(ln->tn_type));
1510 return NULL;
1511 }
1512
1513 tnode_t *ntn = build_op(op, sys, gettyp(t), ln, NULL);
1514 ntn->tn_lvalue = true;
1515 return ntn;
1516 }
1517
1518 static bool
1519 is_confusing_precedence(op_t op, op_t lop, bool lparen, op_t rop, bool rparen)
1520 {
1521
1522 if (op == SHL || op == SHR) {
1523 if (!lparen && (lop == PLUS || lop == MINUS))
1524 return true;
1525 if (!rparen && (rop == PLUS || rop == MINUS))
1526 return true;
1527 return false;
1528 }
1529
1530 if (op == LOGOR) {
1531 if (!lparen && lop == LOGAND)
1532 return true;
1533 if (!rparen && rop == LOGAND)
1534 return true;
1535 return false;
1536 }
1537
1538 lint_assert(op == BITAND || op == BITXOR || op == BITOR);
1539 if (!lparen && lop != op) {
1540 if (lop == PLUS || lop == MINUS)
1541 return true;
1542 if (lop == BITAND || lop == BITXOR)
1543 return true;
1544 }
1545 if (!rparen && rop != op) {
1546 if (rop == PLUS || rop == MINUS)
1547 return true;
1548 if (rop == BITAND || rop == BITXOR)
1549 return true;
1550 }
1551 return false;
1552 }
1553
1554 /*
1555 * Print a warning if the given node has operands which should be
1556 * parenthesized.
1557 *
1558 * XXX Does not work if an operand is a constant expression. Constant
1559 * expressions are already folded.
1560 */
1561 static void
1562 check_precedence_confusion(tnode_t *tn)
1563 {
1564 tnode_t *ln, *rn;
1565
1566 if (!hflag)
1567 return;
1568
1569 debug_node(tn);
1570
1571 lint_assert(is_binary(tn));
1572 for (ln = tn->u.ops.left; ln->tn_op == CVT; ln = ln->u.ops.left)
1573 continue;
1574 for (rn = tn->u.ops.right; rn->tn_op == CVT; rn = rn->u.ops.left)
1575 continue;
1576
1577 if (is_confusing_precedence(tn->tn_op,
1578 ln->tn_op, ln->tn_parenthesized,
1579 rn->tn_op, rn->tn_parenthesized)) {
1580 /* precedence confusion possible: parenthesize! */
1581 warning(169);
1582 }
1583 }
1584
1585 static tnode_t *
1586 fold_constant_compare_zero(tnode_t *tn)
1587 {
1588
1589 val_t *v = xcalloc(1, sizeof(*v));
1590 v->v_tspec = tn->tn_type->t_tspec;
1591 lint_assert(v->v_tspec == INT || (Tflag && v->v_tspec == BOOL));
1592
1593 lint_assert(has_operands(tn));
1594 bool l = constant_is_nonzero(tn->u.ops.left);
1595 bool r = is_binary(tn) && constant_is_nonzero(tn->u.ops.right);
1596
1597 switch (tn->tn_op) {
1598 case NOT:
1599 if (hflag && !suppress_constcond)
1600 /* constant operand to '!' */
1601 warning(239);
1602 v->u.integer = !l ? 1 : 0;
1603 break;
1604 case LOGAND:
1605 v->u.integer = l && r ? 1 : 0;
1606 break;
1607 case LOGOR:
1608 v->u.integer = l || r ? 1 : 0;
1609 break;
1610 default:
1611 lint_assert(/*CONSTCOND*/false);
1612 }
1613
1614 return build_constant(tn->tn_type, v);
1615 }
1616
1617 static long double
1618 floating_error_value(tspec_t t, long double lv)
1619 {
1620 if (t == FLOAT)
1621 return lv < 0 ? -FLT_MAX : FLT_MAX;
1622 if (t == DOUBLE)
1623 return lv < 0 ? -DBL_MAX : DBL_MAX;
1624 /*
1625 * When NetBSD is cross-built in MKLINT=yes mode on x86_64 for sparc64,
1626 * tools/lint checks this code while building usr.bin/xlint. In that
1627 * situation, lint uses the preprocessor for sparc64, in which the type
1628 * 'long double' is IEEE-754-binary128, affecting the macro LDBL_MAX
1629 * below. The type 'long double', as well as the strtold
1630 * implementation, comes from the host platform x86_64 though, where
1631 * 'long double' consumes 128 bits as well but only uses 80 of them.
1632 * The exponent range of the two 'long double' types is the same, but
1633 * the maximum finite value differs due to the extended precision on
1634 * sparc64.
1635 *
1636 * To properly handle the data types of the target platform, lint would
1637 * have to implement the floating-point types in a platform-independent
1638 * way, which is not worth the effort, given how few programs
1639 * practically use 'long double'.
1640 */
1641 /* LINTED 248: floating-point constant out of range */
1642 long double max = LDBL_MAX;
1643 return lv < 0 ? -max : max;
1644 }
1645
1646 static bool
1647 is_floating_overflow(tspec_t t, long double val)
1648 {
1649 if (fpe != 0 || isfinite(val) == 0)
1650 return true;
1651 if (t == FLOAT && (val > FLT_MAX || val < -FLT_MAX))
1652 return true;
1653 if (t == DOUBLE && (val > DBL_MAX || val < -DBL_MAX))
1654 return true;
1655 return false;
1656 }
1657
1658 static tnode_t *
1659 fold_constant_floating(tnode_t *tn)
1660 {
1661
1662 fpe = 0;
1663
1664 tspec_t t = tn->tn_type->t_tspec;
1665
1666 val_t *v = xcalloc(1, sizeof(*v));
1667 v->v_tspec = t;
1668
1669 lint_assert(is_floating(t));
1670 lint_assert(has_operands(tn));
1671 lint_assert(t == tn->u.ops.left->tn_type->t_tspec);
1672 lint_assert(!is_binary(tn) || t == tn->u.ops.right->tn_type->t_tspec);
1673
1674 long double lv = tn->u.ops.left->u.value.u.floating;
1675 long double rv = is_binary(tn) ? tn->u.ops.right->u.value.u.floating
1676 : 0.0;
1677
1678 switch (tn->tn_op) {
1679 case UPLUS:
1680 v->u.floating = lv;
1681 break;
1682 case UMINUS:
1683 v->u.floating = -lv;
1684 break;
1685 case MULT:
1686 v->u.floating = lv * rv;
1687 break;
1688 case DIV:
1689 if (rv == 0.0) {
1690 /* division by 0 */
1691 error(139);
1692 v->u.floating = floating_error_value(t, lv);
1693 } else {
1694 v->u.floating = lv / rv;
1695 }
1696 break;
1697 case PLUS:
1698 v->u.floating = lv + rv;
1699 break;
1700 case MINUS:
1701 v->u.floating = lv - rv;
1702 break;
1703 case LT:
1704 v->u.integer = lv < rv ? 1 : 0;
1705 break;
1706 case LE:
1707 v->u.integer = lv <= rv ? 1 : 0;
1708 break;
1709 case GE:
1710 v->u.integer = lv >= rv ? 1 : 0;
1711 break;
1712 case GT:
1713 v->u.integer = lv > rv ? 1 : 0;
1714 break;
1715 case EQ:
1716 v->u.integer = lv == rv ? 1 : 0;
1717 break;
1718 case NE:
1719 v->u.integer = lv != rv ? 1 : 0;
1720 break;
1721 default:
1722 lint_assert(/*CONSTCOND*/false);
1723 }
1724
1725 // XXX: Must not access u.floating after setting u.integer.
1726 lint_assert(fpe != 0 || isnan(v->u.floating) == 0);
1727 if (is_complex(v->v_tspec)) {
1728 /*
1729 * Don't warn, as lint doesn't model the imaginary part of
1730 * complex numbers.
1731 */
1732 fpe = 0;
1733 } else if (is_floating_overflow(t, v->u.floating)) {
1734 /* operator '%s' produces floating point overflow */
1735 warning(142, op_name(tn->tn_op));
1736 v->u.floating = floating_error_value(t, v->u.floating);
1737 fpe = 0;
1738 }
1739
1740 return build_constant(tn->tn_type, v);
1741 }
1742
1743 static void
1744 use(const tnode_t *tn)
1745 {
1746 if (tn == NULL)
1747 return;
1748 switch (tn->tn_op) {
1749 case NAME:
1750 mark_as_used(tn->u.sym, false /* XXX */, false /* XXX */);
1751 break;
1752 case CON:
1753 case STRING:
1754 break;
1755 case CALL:;
1756 const function_call *call = tn->u.call;
1757 for (size_t i = 0, n = call->args_len; i < n; i++)
1758 use(call->args[i]);
1759 break;
1760 default:
1761 lint_assert(has_operands(tn));
1762 use(tn->u.ops.left);
1763 if (is_binary(tn))
1764 use(tn->u.ops.right);
1765 }
1766 }
1767
1768 /*
1769 * Create a tree node for a binary operator and its two operands. Also called
1770 * for unary operators; in that case rn is NULL.
1771 *
1772 * Function calls, sizeof and casts are handled elsewhere.
1773 */
1774 tnode_t *
1775 build_binary(tnode_t *ln, op_t op, bool sys, tnode_t *rn)
1776 {
1777 const mod_t *mp = &modtab[op];
1778
1779 /* If there was an error in one of the operands, return. */
1780 if (ln == NULL || (mp->m_binary && rn == NULL))
1781 return NULL;
1782
1783 if (mp->m_value_context || mp->m_compares_with_zero)
1784 ln = cconv(ln);
1785 if (mp->m_binary && op != ARROW && op != POINT)
1786 rn = cconv(rn);
1787
1788 if (mp->m_comparison)
1789 check_integer_comparison(op, ln, rn);
1790
1791 if (mp->m_value_context || mp->m_compares_with_zero)
1792 ln = promote(op, false, ln);
1793 if (mp->m_binary && op != ARROW && op != POINT &&
1794 op != ASSIGN && op != RETURN && op != INIT)
1795 rn = promote(op, false, rn);
1796
1797 if (mp->m_warn_if_left_unsigned_in_c90 &&
1798 ln->tn_op == CON && ln->u.value.v_unsigned_since_c90) {
1799 /* C90 treats constant as unsigned, op '%s' */
1800 warning(218, op_name(op));
1801 ln->u.value.v_unsigned_since_c90 = false;
1802 }
1803 if (mp->m_warn_if_right_unsigned_in_c90 &&
1804 rn->tn_op == CON && rn->u.value.v_unsigned_since_c90) {
1805 /* C90 treats constant as unsigned, op '%s' */
1806 warning(218, op_name(op));
1807 rn->u.value.v_unsigned_since_c90 = false;
1808 }
1809
1810 if (mp->m_balance_operands || (!allow_c90 && (op == SHL || op == SHR)))
1811 balance(op, &ln, &rn);
1812
1813 if (!typeok(op, 0, ln, rn))
1814 return NULL;
1815
1816 tnode_t *ntn;
1817 switch (op) {
1818 case POINT:
1819 case ARROW:
1820 ntn = build_struct_access(op, sys, ln, rn);
1821 break;
1822 case NOT:
1823 if (ln->tn_op == ASSIGN && ln->u.ops.right->tn_op == CON) {
1824 /* constant assignment of type '%s' in operand ... */
1825 warning(382, type_name(ln->tn_type),
1826 is_nonzero_val(&ln->u.ops.right->u.value)
1827 ? "true" : "false");
1828 }
1829 ntn = build_op(op, sys, gettyp(Tflag ? BOOL : INT), ln, NULL);
1830 break;
1831 case INCAFT:
1832 case DECAFT:
1833 case INCBEF:
1834 case DECBEF:
1835 ntn = build_prepost_incdec(op, sys, ln);
1836 break;
1837 case ADDR:
1838 ntn = build_address(sys, ln, false);
1839 break;
1840 case INDIR:
1841 ntn = build_op(INDIR, sys, ln->tn_type->t_subt, ln, NULL);
1842 break;
1843 case PLUS:
1844 case MINUS:
1845 ntn = build_plus_minus(op, sys, ln, rn);
1846 break;
1847 case SHL:
1848 case SHR:
1849 ntn = build_bit_shift(op, sys, ln, rn);
1850 break;
1851 case COLON:
1852 ntn = build_colon(sys, ln, rn);
1853 break;
1854 case ASSIGN:
1855 case MULASS:
1856 case DIVASS:
1857 case MODASS:
1858 case ADDASS:
1859 case SUBASS:
1860 case SHLASS:
1861 case SHRASS:
1862 case ANDASS:
1863 case XORASS:
1864 case ORASS:
1865 case RETURN:
1866 case INIT:
1867 ntn = build_assignment(op, sys, ln, rn);
1868 break;
1869 case COMMA:
1870 if (any_query_enabled) {
1871 /* comma operator with types '%s' and '%s' */
1872 query_message(12,
1873 type_name(ln->tn_type), type_name(rn->tn_type));
1874 }
1875 /* FALLTHROUGH */
1876 case QUEST:
1877 ntn = build_op(op, sys, rn->tn_type, ln, rn);
1878 break;
1879 case REAL:
1880 case IMAG:
1881 ntn = build_real_imag(op, sys, ln);
1882 break;
1883 default:
1884 lint_assert(mp->m_binary == (rn != NULL));
1885 type_t *rettp = mp->m_returns_bool
1886 ? gettyp(Tflag ? BOOL : INT) : ln->tn_type;
1887 ntn = build_op(op, sys, rettp, ln, rn);
1888 break;
1889 }
1890
1891 if (ntn == NULL)
1892 return NULL;
1893
1894 if (mp->m_possible_precedence_confusion)
1895 check_precedence_confusion(ntn);
1896
1897 if (hflag && !suppress_constcond &&
1898 mp->m_compares_with_zero &&
1899 (ln->tn_op == CON ||
1900 (mp->m_binary && op != QUEST && rn->tn_op == CON)) &&
1901 /* XXX: rn->tn_system_dependent should be checked as well */
1902 !ln->tn_system_dependent)
1903 /* constant in conditional context */
1904 warning(161);
1905
1906 if (mp->m_fold_constant_operands && ln->tn_op == CON) {
1907 if (!mp->m_binary || rn->tn_op == CON) {
1908 if (mp->m_compares_with_zero)
1909 ntn = fold_constant_compare_zero(ntn);
1910 else if (is_floating(ntn->tn_type->t_tspec))
1911 ntn = fold_constant_floating(ntn);
1912 else
1913 ntn = fold_constant_integer(ntn);
1914 } else if (op == QUEST) {
1915 lint_assert(has_operands(rn));
1916 use(ln->u.value.u.integer != 0
1917 ? rn->u.ops.right : rn->u.ops.left);
1918 ntn = ln->u.value.u.integer != 0
1919 ? rn->u.ops.left : rn->u.ops.right;
1920 }
1921 }
1922
1923 return ntn;
1924 }
1925
1926 tnode_t *
1927 build_unary(op_t op, bool sys, tnode_t *tn)
1928 {
1929 return build_binary(tn, op, sys, NULL);
1930 }
1931
1932 static bool
1933 are_members_compatible(const sym_t *a, const sym_t *b)
1934 {
1935 if (a->u.s_member.sm_offset_in_bits != b->u.s_member.sm_offset_in_bits)
1936 return false;
1937
1938 const type_t *atp = a->s_type;
1939 const type_t *btp = b->s_type;
1940 bool w = false;
1941 if (!types_compatible(atp, btp, false, false, &w) && !w)
1942 return false;
1943 if (a->s_bitfield != b->s_bitfield)
1944 return false;
1945 if (a->s_bitfield) {
1946 if (atp->t_bit_field_width != btp->t_bit_field_width)
1947 return false;
1948 if (atp->t_bit_field_offset != btp->t_bit_field_offset)
1949 return false;
1950 }
1951 return true;
1952 }
1953
1954 /*
1955 * Return whether all struct/union members with the same name have the same
1956 * type and offset.
1957 */
1958 static bool
1959 all_members_compatible(const sym_t *msym)
1960 {
1961 for (const sym_t *csym = msym;
1962 csym != NULL; csym = csym->s_symtab_next) {
1963 if (!is_member(csym))
1964 continue;
1965 if (strcmp(msym->s_name, csym->s_name) != 0)
1966 continue;
1967
1968 for (const sym_t *sym = csym->s_symtab_next;
1969 sym != NULL; sym = sym->s_symtab_next) {
1970 if (is_member(sym)
1971 && strcmp(csym->s_name, sym->s_name) == 0
1972 && !are_members_compatible(csym, sym))
1973 return false;
1974 }
1975 }
1976 return true;
1977 }
1978
1979 sym_t *
1980 find_member(const struct_or_union *sou, const char *name)
1981 {
1982 for (sym_t *mem = sou->sou_first_member;
1983 mem != NULL; mem = mem->s_next) {
1984 lint_assert(is_member(mem));
1985 lint_assert(mem->u.s_member.sm_containing_type == sou);
1986 if (strcmp(mem->s_name, name) == 0)
1987 return mem;
1988 }
1989
1990 for (sym_t *mem = sou->sou_first_member;
1991 mem != NULL; mem = mem->s_next) {
1992 if (is_struct_or_union(mem->s_type->t_tspec)
1993 && mem->s_name == unnamed) {
1994 sym_t *nested_mem =
1995 find_member(mem->s_type->u.sou, name);
1996 if (nested_mem != NULL)
1997 return nested_mem;
1998 }
1999 }
2000 return NULL;
2001 }
2002
2003 /*
2004 * Remove the member if it was unknown until now, which means
2005 * that no defined struct or union has a member with the same name.
2006 */
2007 static void
2008 remove_unknown_member(tnode_t *tn, sym_t *msym)
2009 {
2010 /* type '%s' does not have member '%s' */
2011 error(101, type_name(tn->tn_type), msym->s_name);
2012 symtab_remove_forever(msym);
2013 msym->s_kind = SK_MEMBER;
2014 msym->s_scl = STRUCT_MEMBER;
2015
2016 struct_or_union *sou = expr_zero_alloc(sizeof(*sou),
2017 "struct_or_union");
2018 sou->sou_tag = expr_zero_alloc(sizeof(*sou->sou_tag), "sym");
2019 sou->sou_tag->s_name = unnamed;
2020
2021 msym->u.s_member.sm_containing_type = sou;
2022 /*
2023 * The member sm_offset_in_bits is not needed here since this symbol
2024 * can only be used for error reporting.
2025 */
2026 }
2027
2028 /*
2029 * Returns a symbol which has the same name as 'msym' and is a member of the
2030 * struct or union specified by 'tn'.
2031 */
2032 static sym_t *
2033 struct_or_union_member(tnode_t *tn, op_t op, sym_t *msym)
2034 {
2035
2036 /* Determine the tag type of which msym is expected to be a member. */
2037 const type_t *tp = NULL;
2038 if (op == POINT && is_struct_or_union(tn->tn_type->t_tspec))
2039 tp = tn->tn_type;
2040 if (op == ARROW && tn->tn_type->t_tspec == PTR
2041 && is_struct_or_union(tn->tn_type->t_subt->t_tspec))
2042 tp = tn->tn_type->t_subt;
2043 struct_or_union *sou = tp != NULL ? tp->u.sou : NULL;
2044
2045 if (sou != NULL) {
2046 sym_t *nested_mem = find_member(sou, msym->s_name);
2047 if (nested_mem != NULL)
2048 return nested_mem;
2049 }
2050
2051 if (msym->s_scl == NO_SCL) {
2052 remove_unknown_member(tn, msym);
2053 return msym;
2054 }
2055
2056 bool eq = all_members_compatible(msym);
2057
2058 /*
2059 * Now handle the case in which the left operand refers really to a
2060 * struct/union, but the right operand is not member of it.
2061 */
2062 if (sou != NULL) {
2063 if (eq && !allow_c90)
2064 /* illegal use of member '%s' */
2065 warning(102, msym->s_name);
2066 else
2067 /* illegal use of member '%s' */
2068 error(102, msym->s_name);
2069 return msym;
2070 }
2071
2072 if (eq) {
2073 if (op == POINT) {
2074 if (!allow_c90)
2075 /* left operand of '.' must be struct ... */
2076 warning(103, type_name(tn->tn_type));
2077 else
2078 /* left operand of '.' must be struct ... */
2079 error(103, type_name(tn->tn_type));
2080 } else {
2081 if (!allow_c90 && tn->tn_type->t_tspec == PTR)
2082 /* left operand of '->' must be pointer ... */
2083 warning(104, type_name(tn->tn_type));
2084 else
2085 /* left operand of '->' must be pointer ... */
2086 error(104, type_name(tn->tn_type));
2087 }
2088 } else {
2089 if (!allow_c90)
2090 /* non-unique member requires struct/union %s */
2091 error(105, op == POINT ? "object" : "pointer");
2092 else
2093 /* unacceptable operand of '%s' */
2094 error(111, op_name(op));
2095 }
2096
2097 return msym;
2098 }
2099
2100 tnode_t *
2101 build_member_access(tnode_t *ln, op_t op, bool sys, sbuf_t *member)
2102 {
2103 sym_t *msym;
2104
2105 if (ln == NULL)
2106 return NULL;
2107
2108 if (op == ARROW)
2109 /* must do this before struct_or_union_member is called */
2110 ln = cconv(ln);
2111 msym = struct_or_union_member(ln, op, getsym(member));
2112 return build_binary(ln, op, sys, build_name(msym, false));
2113 }
2114
2115 /*
2116 * Perform class conversions.
2117 *
2118 * Arrays of type T are converted into pointers to type T.
2119 * Functions are converted to pointers to functions.
2120 * Lvalues are converted to rvalues.
2121 *
2122 * C99 6.3 "Conversions"
2123 * C99 6.3.2 "Other operands"
2124 * C99 6.3.2.1 "Lvalues, arrays, and function designators"
2125 */
2126 tnode_t *
2127 cconv(tnode_t *tn)
2128 {
2129 if (tn->tn_type->t_tspec == ARRAY) {
2130 if (!tn->tn_lvalue) {
2131 /* XXX print correct operator */
2132 /* %soperand of '%s' must be lvalue */
2133 gnuism(114, "", op_name(ADDR));
2134 }
2135 tn = build_op(ADDR, tn->tn_sys,
2136 expr_derive_type(tn->tn_type->t_subt, PTR), tn, NULL);
2137 }
2138
2139 if (tn->tn_type->t_tspec == FUNC)
2140 tn = build_address(tn->tn_sys, tn, true);
2141
2142 if (tn->tn_lvalue) {
2143 type_t *tp = expr_dup_type(tn->tn_type);
2144 /* C99 6.3.2.1p2 sentence 2 says to remove the qualifiers. */
2145 tp->t_const = tp->t_volatile = false;
2146 tn = build_op(LOAD, tn->tn_sys, tp, tn, NULL);
2147 }
2148
2149 return tn;
2150 }
2151
2152 const tnode_t *
2153 before_conversion(const tnode_t *tn)
2154 {
2155 while (tn->tn_op == CVT && !tn->tn_cast)
2156 tn = tn->u.ops.left;
2157 return tn;
2158 }
2159
2160 /*
2161 * Most errors required by C90 are reported in struct_or_union_member().
2162 * Here we only check for totally wrong things.
2163 */
2164 static bool
2165 typeok_point(const tnode_t *ln, const type_t *ltp, tspec_t lt)
2166 {
2167 if (is_struct_or_union(lt))
2168 return true;
2169
2170 if (lt == FUNC || lt == VOID || ltp->t_bitfield)
2171 goto wrong;
2172
2173 /*
2174 * Some C dialects from before C90 tolerated any lvalue on the
2175 * left-hand side of the '.' operator, allowing things like 'char
2176 * st[100]; st.st_mtime', assuming that the member 'st_mtime' only
2177 * occurred in a single struct; see typeok_arrow.
2178 */
2179 if (ln->tn_lvalue)
2180 return true;
2181
2182 wrong:
2183 /* With allow_c90 we already got an error */
2184 if (!allow_c90)
2185 /* unacceptable operand of '%s' */
2186 error(111, op_name(POINT));
2187
2188 return false;
2189 }
2190
2191 static bool
2192 typeok_arrow(tspec_t lt)
2193 {
2194 /*
2195 * C1978 Appendix A 14.1 says: <quote>In fact, any lvalue is allowed
2196 * before '.', and that lvalue is then assumed to have the form of the
2197 * structure of which the name of the right is a member. [...] Such
2198 * constructions are non-portable.</quote>
2199 */
2200 if (lt == PTR || (!allow_c90 && is_integer(lt)))
2201 return true;
2202
2203 /* With allow_c90 we already got an error */
2204 if (!allow_c90)
2205 /* unacceptable operand of '%s' */
2206 error(111, op_name(ARROW));
2207 return false;
2208 }
2209
2210 static bool
2211 typeok_incdec(op_t op, const tnode_t *tn, const type_t *tp)
2212 {
2213 /* operand has scalar type (checked in typeok) */
2214 if (!tn->tn_lvalue) {
2215 if (tn->tn_op == CVT && tn->tn_cast &&
2216 tn->u.ops.left->tn_op == LOAD)
2217 /* a cast does not yield an lvalue */
2218 error(163);
2219 /* %soperand of '%s' must be lvalue */
2220 error(114, "", op_name(op));
2221 return false;
2222 }
2223 if (tp->t_const && allow_c90)
2224 /* %soperand of '%s' must be modifiable lvalue */
2225 warning(115, "", op_name(op));
2226 return true;
2227 }
2228
2229 static bool
2230 typeok_address(op_t op, const tnode_t *tn, const type_t *tp, tspec_t t)
2231 {
2232 if (t == ARRAY || t == FUNC) {
2233 /* ok, a warning comes later (in build_address()) */
2234 } else if (!tn->tn_lvalue) {
2235 if (tn->tn_op == CVT && tn->tn_cast &&
2236 tn->u.ops.left->tn_op == LOAD)
2237 /* a cast does not yield an lvalue */
2238 error(163);
2239 /* %soperand of '%s' must be lvalue */
2240 error(114, "", op_name(op));
2241 return false;
2242 } else if (is_scalar(t)) {
2243 if (tp->t_bitfield) {
2244 /* cannot take address of bit-field */
2245 error(112);
2246 return false;
2247 }
2248 } else if (t != STRUCT && t != UNION) {
2249 /* unacceptable operand of '%s' */
2250 error(111, op_name(op));
2251 return false;
2252 }
2253 if (tn->tn_op == NAME && tn->u.sym->s_register) {
2254 /* cannot take address of register '%s' */
2255 error(113, tn->u.sym->s_name);
2256 return false;
2257 }
2258 return true;
2259 }
2260
2261 static bool
2262 typeok_indir(const type_t *tp, tspec_t t)
2263 {
2264
2265 if (t != PTR) {
2266 /* cannot dereference non-pointer type '%s' */
2267 error(96, type_name(tp));
2268 return false;
2269 }
2270 return true;
2271 }
2272
2273 static void
2274 warn_incompatible_types(op_t op,
2275 const type_t *ltp, tspec_t lt,
2276 const type_t *rtp, tspec_t rt)
2277 {
2278 bool binary = modtab[op].m_binary;
2279
2280 if (lt == VOID || (binary && rt == VOID)) {
2281 /* void type illegal in expression */
2282 error(109);
2283 } else if (op == ASSIGN)
2284 /* cannot assign to '%s' from '%s' */
2285 error(171, type_name(ltp), type_name(rtp));
2286 else if (binary)
2287 /* operands of '%s' have incompatible types '%s' and '%s' */
2288 error(107, op_name(op), type_name(ltp), type_name(rtp));
2289 else {
2290 lint_assert(rt == NO_TSPEC);
2291 /* operand of '%s' has invalid type '%s' */
2292 error(108, op_name(op), type_name(ltp));
2293 }
2294 }
2295
2296 static bool
2297 typeok_plus(op_t op,
2298 const type_t *ltp, tspec_t lt,
2299 const type_t *rtp, tspec_t rt)
2300 {
2301 /* operands have scalar types (checked in typeok) */
2302 if ((lt == PTR && !is_integer(rt)) || (rt == PTR && !is_integer(lt))) {
2303 warn_incompatible_types(op, ltp, lt, rtp, rt);
2304 return false;
2305 }
2306 return true;
2307 }
2308
2309 static bool
2310 typeok_minus(op_t op,
2311 const type_t *ltp, tspec_t lt,
2312 const type_t *rtp, tspec_t rt)
2313 {
2314 /* operands have scalar types (checked in typeok) */
2315 if ((lt == PTR && rt != PTR && !is_integer(rt)) ||
2316 (lt != PTR && rt == PTR)) {
2317 warn_incompatible_types(op, ltp, lt, rtp, rt);
2318 return false;
2319 }
2320 if (lt == PTR && rt == PTR &&
2321 !types_compatible(ltp->t_subt, rtp->t_subt, true, false, NULL)) {
2322 /* illegal pointer subtraction */
2323 error(116);
2324 }
2325 return true;
2326 }
2327
2328 static void
2329 typeok_shr(op_t op,
2330 const tnode_t *ln, tspec_t lt,
2331 const tnode_t *rn, tspec_t rt)
2332 {
2333 tspec_t olt = before_conversion(ln)->tn_type->t_tspec;
2334 tspec_t ort = before_conversion(rn)->tn_type->t_tspec;
2335
2336 /* operands have integer types (checked in typeok) */
2337 if (pflag && !is_uinteger(olt)) {
2338 integer_constraints lc = ic_expr(ln);
2339 if (!ic_maybe_signed(ln->tn_type, &lc))
2340 return;
2341
2342 if (ln->tn_op != CON)
2343 /* bitwise '%s' on signed value possibly nonportable */
2344 warning(117, op_name(op));
2345 else if (ln->u.value.u.integer < 0)
2346 /* bitwise '%s' on signed value nonportable */
2347 warning(120, op_name(op));
2348 } else if (allow_trad && allow_c90 &&
2349 !is_uinteger(olt) && is_uinteger(ort)) {
2350 /* The left operand would become unsigned in traditional C. */
2351 if (hflag && (ln->tn_op != CON || ln->u.value.u.integer < 0)) {
2352 /* semantics of '%s' change in C90; use ... */
2353 warning(118, op_name(op));
2354 }
2355 } else if (allow_trad && allow_c90 &&
2356 !is_uinteger(olt) && !is_uinteger(ort) &&
2357 portable_rank_cmp(lt, rt) < 0) {
2358 /*
2359 * In traditional C, the left operand would be extended
2360 * (possibly sign-extended) and then shifted.
2361 */
2362 if (hflag && (ln->tn_op != CON || ln->u.value.u.integer < 0)) {
2363 /* semantics of '%s' change in C90; use ... */
2364 warning(118, op_name(op));
2365 }
2366 }
2367 }
2368
2369 static void
2370 typeok_shl(op_t op, tspec_t lt, tspec_t rt)
2371 {
2372 /*
2373 * C90 does not perform balancing for shift operations, but traditional
2374 * C does. If the width of the right operand is greater than the width
2375 * of the left operand, then in traditional C the left operand would be
2376 * extended to the width of the right operand. For SHL this may result
2377 * in different results.
2378 */
2379 if (portable_rank_cmp(lt, rt) < 0) {
2380 /*
2381 * XXX If both operands are constant, make sure that there is
2382 * really a difference between C90 and traditional C.
2383 */
2384 if (hflag && allow_trad && allow_c90)
2385 /* semantics of '%s' change in C90; use ... */
2386 warning(118, op_name(op));
2387 }
2388 }
2389
2390 static void
2391 typeok_shift(const type_t *ltp, tspec_t lt, const tnode_t *rn, tspec_t rt)
2392 {
2393 if (rn->tn_op != CON)
2394 return;
2395
2396 if (!is_uinteger(rt) && rn->u.value.u.integer < 0)
2397 /* negative shift */
2398 warning(121);
2399 else if ((uint64_t)rn->u.value.u.integer == size_in_bits(lt))
2400 /* shift amount %u equals bit-size of '%s' */
2401 warning(267, (unsigned)rn->u.value.u.integer, type_name(ltp));
2402 else if ((uint64_t)rn->u.value.u.integer > size_in_bits(lt)) {
2403 /* shift amount %llu is greater than bit-size %llu of '%s' */
2404 warning(122, (unsigned long long)rn->u.value.u.integer,
2405 (unsigned long long)size_in_bits(lt),
2406 tspec_name(lt));
2407 }
2408 }
2409
2410 static bool
2411 is_typeok_eq(const tnode_t *ln, tspec_t lt, const tnode_t *rn, tspec_t rt)
2412 {
2413 if (lt == PTR && is_null_pointer(rn))
2414 return true;
2415 if (rt == PTR && is_null_pointer(ln))
2416 return true;
2417 return false;
2418 }
2419
2420 static void
2421 warn_incompatible_pointers(op_t op, const type_t *ltp, const type_t *rtp)
2422 {
2423 lint_assert(ltp->t_tspec == PTR);
2424 lint_assert(rtp->t_tspec == PTR);
2425
2426 tspec_t lt = ltp->t_subt->t_tspec;
2427 tspec_t rt = rtp->t_subt->t_tspec;
2428
2429 if (is_struct_or_union(lt) && is_struct_or_union(rt)) {
2430 if (op == RETURN)
2431 /* illegal structure pointer combination */
2432 warning(244);
2433 else {
2434 /* incompatible structure pointers: '%s' '%s' '%s' */
2435 warning(245, type_name(ltp),
2436 op_name(op), type_name(rtp));
2437 }
2438 } else {
2439 if (op == RETURN)
2440 /* illegal combination of '%s' and '%s' */
2441 warning(184, type_name(ltp), type_name(rtp));
2442 else {
2443 /* illegal combination of '%s' and '%s', op '%s' */
2444 warning(124,
2445 type_name(ltp), type_name(rtp), op_name(op));
2446 }
2447 }
2448 }
2449
2450 static void
2451 check_pointer_comparison(op_t op, const tnode_t *ln, const tnode_t *rn)
2452 {
2453 type_t *ltp = ln->tn_type, *rtp = rn->tn_type;
2454 tspec_t lst = ltp->t_subt->t_tspec, rst = rtp->t_subt->t_tspec;
2455
2456 if (lst == VOID || rst == VOID) {
2457 /* TODO: C99 behaves like C90 here. */
2458 if (!allow_trad && !allow_c99 &&
2459 (lst == FUNC || rst == FUNC)) {
2460 /* (void *)0 is already handled in typeok() */
2461 const char *lsts, *rsts;
2462 *(lst == FUNC ? &lsts : &rsts) = "function pointer";
2463 *(lst == VOID ? &lsts : &rsts) = "'void *'";
2464 /* C90 or later forbid comparison of %s with %s */
2465 warning(274, lsts, rsts);
2466 }
2467 return;
2468 }
2469
2470 if (!types_compatible(ltp->t_subt, rtp->t_subt, true, false, NULL)) {
2471 warn_incompatible_pointers(op, ltp, rtp);
2472 return;
2473 }
2474
2475 if (lst == FUNC && rst == FUNC) {
2476 /* TODO: C99 behaves like C90 here, see C99 6.5.8p2. */
2477 if (!allow_trad && !allow_c99 && op != EQ && op != NE)
2478 /* pointers to functions can only be compared ... */
2479 warning(125);
2480 }
2481 }
2482
2483 static bool
2484 typeok_compare(op_t op,
2485 const tnode_t *ln, const type_t *ltp, tspec_t lt,
2486 const tnode_t *rn, const type_t *rtp, tspec_t rt)
2487 {
2488 if (lt == PTR && rt == PTR) {
2489 check_pointer_comparison(op, ln, rn);
2490 return true;
2491 }
2492
2493 if (lt != PTR && rt != PTR)
2494 return true;
2495
2496 if (!is_integer(lt) && !is_integer(rt)) {
2497 warn_incompatible_types(op, ltp, lt, rtp, rt);
2498 return false;
2499 }
2500
2501 const char *lx = lt == PTR ? "pointer" : "integer";
2502 const char *rx = rt == PTR ? "pointer" : "integer";
2503 /* illegal combination of %s '%s' and %s '%s', op '%s' */
2504 warning(123, lx, type_name(ltp), rx, type_name(rtp), op_name(op));
2505 return true;
2506 }
2507
2508 static bool
2509 typeok_quest(tspec_t lt, const tnode_t *rn)
2510 {
2511 if (!is_scalar(lt)) {
2512 /* first operand of '?' must have scalar type */
2513 error(170);
2514 return false;
2515 }
2516 lint_assert(before_conversion(rn)->tn_op == COLON);
2517 return true;
2518 }
2519
2520 static void
2521 typeok_colon_pointer(const type_t *ltp, const type_t *rtp)
2522 {
2523 type_t *lstp = ltp->t_subt;
2524 type_t *rstp = rtp->t_subt;
2525 tspec_t lst = lstp->t_tspec;
2526 tspec_t rst = rstp->t_tspec;
2527
2528 if ((lst == VOID && rst == FUNC) || (lst == FUNC && rst == VOID)) {
2529 /* (void *)0 is handled in typeok_colon */
2530 /* TODO: C99 behaves like C90 here. */
2531 if (!allow_trad && !allow_c99)
2532 /* conversion of %s to %s requires a cast, op %s */
2533 warning(305, "function pointer", "'void *'",
2534 op_name(COLON));
2535 return;
2536 }
2537
2538 if (pointer_types_are_compatible(lstp, rstp, true))
2539 return;
2540 if (!types_compatible(lstp, rstp, true, false, NULL))
2541 warn_incompatible_pointers(COLON, ltp, rtp);
2542 }
2543
2544 static bool
2545 typeok_colon(const tnode_t *ln, const type_t *ltp, tspec_t lt,
2546 const tnode_t *rn, const type_t *rtp, tspec_t rt)
2547 {
2548
2549 if (is_arithmetic(lt) && is_arithmetic(rt))
2550 return true;
2551 if (lt == BOOL && rt == BOOL)
2552 return true;
2553
2554 if (lt == STRUCT && rt == STRUCT && ltp->u.sou == rtp->u.sou)
2555 return true;
2556 if (lt == UNION && rt == UNION && ltp->u.sou == rtp->u.sou)
2557 return true;
2558
2559 if (lt == PTR && is_null_pointer(rn))
2560 return true;
2561 if (rt == PTR && is_null_pointer(ln))
2562 return true;
2563
2564 if ((lt == PTR && is_integer(rt)) || (is_integer(lt) && rt == PTR)) {
2565 const char *lx = lt == PTR ? "pointer" : "integer";
2566 const char *rx = rt == PTR ? "pointer" : "integer";
2567 /* illegal combination of %s '%s' and %s '%s', op '%s' */
2568 warning(123, lx, type_name(ltp),
2569 rx, type_name(rtp), op_name(COLON));
2570 return true;
2571 }
2572
2573 if (lt == VOID || rt == VOID) {
2574 if (lt != VOID || rt != VOID)
2575 /* incompatible types '%s' and '%s' in conditional */
2576 warning(126, type_name(ltp), type_name(rtp));
2577 return true;
2578 }
2579
2580 if (lt == PTR && rt == PTR) {
2581 typeok_colon_pointer(ltp, rtp);
2582 return true;
2583 }
2584
2585 /* incompatible types '%s' and '%s' in conditional */
2586 error(126, type_name(ltp), type_name(rtp));
2587 return false;
2588 }
2589
2590 static bool
2591 has_constant_member(const type_t *tp)
2592 {
2593 lint_assert(is_struct_or_union(tp->t_tspec));
2594
2595 for (sym_t *m = tp->u.sou->sou_first_member;
2596 m != NULL; m = m->s_next) {
2597 const type_t *mtp = m->s_type;
2598 if (mtp->t_const)
2599 return true;
2600 if (is_struct_or_union(mtp->t_tspec) &&
2601 has_constant_member(mtp))
2602 return true;
2603 }
2604 return false;
2605 }
2606
2607 static bool
2608 typeok_assign(op_t op, const tnode_t *ln, const type_t *ltp, tspec_t lt)
2609 {
2610 if (op == RETURN || op == INIT || op == FARG)
2611 return true;
2612
2613 if (!ln->tn_lvalue) {
2614 if (ln->tn_op == CVT && ln->tn_cast &&
2615 ln->u.ops.left->tn_op == LOAD)
2616 /* a cast does not yield an lvalue */
2617 error(163);
2618 /* %soperand of '%s' must be lvalue */
2619 error(114, "left ", op_name(op));
2620 return false;
2621 } else if (ltp->t_const
2622 || (is_struct_or_union(lt) && has_constant_member(ltp))) {
2623 if (allow_c90)
2624 /* %soperand of '%s' must be modifiable lvalue */
2625 warning(115, "left ", op_name(op));
2626 }
2627 return true;
2628 }
2629
2630 static bool
2631 typeok_scalar(op_t op, const mod_t *mp,
2632 const type_t *ltp, tspec_t lt,
2633 const type_t *rtp, tspec_t rt)
2634 {
2635 if (mp->m_takes_bool && lt == BOOL && rt == BOOL)
2636 return true;
2637 if (mp->m_requires_integer) {
2638 if (!is_integer(lt) || (mp->m_binary && !is_integer(rt))) {
2639 warn_incompatible_types(op, ltp, lt, rtp, rt);
2640 return false;
2641 }
2642 } else if (mp->m_requires_integer_or_complex) {
2643 if ((!is_integer(lt) && !is_complex(lt)) ||
2644 (mp->m_binary && (!is_integer(rt) && !is_complex(rt)))) {
2645 warn_incompatible_types(op, ltp, lt, rtp, rt);
2646 return false;
2647 }
2648 } else if (mp->m_requires_scalar) {
2649 if (!is_scalar(lt) || (mp->m_binary && !is_scalar(rt))) {
2650 warn_incompatible_types(op, ltp, lt, rtp, rt);
2651 return false;
2652 }
2653 } else if (mp->m_requires_arith) {
2654 if (!is_arithmetic(lt) ||
2655 (mp->m_binary && !is_arithmetic(rt))) {
2656 warn_incompatible_types(op, ltp, lt, rtp, rt);
2657 return false;
2658 }
2659 }
2660 return true;
2661 }
2662
2663 static void
2664 check_assign_void_pointer(op_t op, int arg,
2665 tspec_t lt, tspec_t lst,
2666 tspec_t rt, tspec_t rst)
2667 {
2668
2669 if (!(lt == PTR && rt == PTR && (lst == VOID || rst == VOID)))
2670 return;
2671 /* two pointers, at least one pointer to void */
2672
2673 /* TODO: C99 behaves like C90 here. */
2674 if (!(!allow_trad && !allow_c99 && (lst == FUNC || rst == FUNC)))
2675 return;
2676 /* comb. of ptr to func and ptr to void */
2677
2678 const char *lts, *rts;
2679 *(lst == FUNC ? <s : &rts) = "function pointer";
2680 *(lst == VOID ? <s : &rts) = "'void *'";
2681
2682 switch (op) {
2683 case INIT:
2684 case RETURN:
2685 /* conversion of %s to %s requires a cast */
2686 warning(303, rts, lts);
2687 break;
2688 case FARG:
2689 /* conversion of %s to %s requires a cast, arg #%d */
2690 warning(304, rts, lts, arg);
2691 break;
2692 default:
2693 /* conversion of %s to %s requires a cast, op %s */
2694 warning(305, rts, lts, op_name(op));
2695 break;
2696 }
2697 }
2698
2699 static bool
2700 is_direct_function_call(const tnode_t *tn, const char **out_name)
2701 {
2702
2703 if (tn->tn_op == CALL
2704 && tn->u.call->func->tn_op == ADDR
2705 && tn->u.call->func->u.ops.left->tn_op == NAME) {
2706 *out_name = tn->u.call->func->u.ops.left->u.sym->s_name;
2707 return true;
2708 }
2709 return false;
2710 }
2711
2712 static bool
2713 is_unconst_function(const char *name)
2714 {
2715
2716 return strcmp(name, "memchr") == 0 ||
2717 strcmp(name, "strchr") == 0 ||
2718 strcmp(name, "strpbrk") == 0 ||
2719 strcmp(name, "strrchr") == 0 ||
2720 strcmp(name, "strstr") == 0;
2721 }
2722
2723 static bool
2724 is_const_char_pointer(const tnode_t *tn)
2725 {
2726 /*
2727 * For traditional reasons, C99 6.4.5p5 defines that string literals
2728 * have type 'char[]'. They are often implicitly converted to 'char
2729 * *', for example when they are passed as function arguments.
2730 *
2731 * C99 6.4.5p6 further defines that modifying a string that is
2732 * constructed from a string literal invokes undefined behavior.
2733 *
2734 * Out of these reasons, string literals are treated as 'effectively
2735 * const' here.
2736 */
2737 if (tn->tn_op == CVT &&
2738 tn->u.ops.left->tn_op == ADDR &&
2739 tn->u.ops.left->u.ops.left->tn_op == STRING)
2740 return true;
2741
2742 const type_t *tp = before_conversion(tn)->tn_type;
2743 return tp->t_tspec == PTR &&
2744 tp->t_subt->t_tspec == CHAR &&
2745 tp->t_subt->t_const;
2746 }
2747
2748 static bool
2749 is_const_pointer(const tnode_t *tn)
2750 {
2751 const type_t *tp = before_conversion(tn)->tn_type;
2752 return tp->t_tspec == PTR && tp->t_subt->t_const;
2753 }
2754
2755 static void
2756 check_unconst_function(const type_t *lstp, const tnode_t *rn)
2757 {
2758 const char *function_name;
2759
2760 if (lstp->t_tspec == CHAR && !lstp->t_const &&
2761 is_direct_function_call(rn, &function_name) &&
2762 is_unconst_function(function_name) &&
2763 rn->u.call->args_len >= 1 &&
2764 is_const_char_pointer(rn->u.call->args[0])) {
2765 /* call to '%s' effectively discards 'const' from argument */
2766 warning(346, function_name);
2767 }
2768
2769 if (!lstp->t_const &&
2770 is_direct_function_call(rn, &function_name) &&
2771 strcmp(function_name, "bsearch") == 0 &&
2772 rn->u.call->args_len >= 2 &&
2773 is_const_pointer(rn->u.call->args[1])) {
2774 /* call to '%s' effectively discards 'const' from argument */
2775 warning(346, function_name);
2776 }
2777 }
2778
2779 static bool
2780 check_assign_void_pointer_compat(op_t op, int arg,
2781 const type_t *ltp, tspec_t lt,
2782 const type_t *lstp, tspec_t lst,
2783 const tnode_t *rn,
2784 const type_t *rtp, tspec_t rt,
2785 const type_t *rstp, tspec_t rst)
2786 {
2787 if (!(lt == PTR && rt == PTR && (lst == VOID || rst == VOID ||
2788 types_compatible(lstp, rstp,
2789 true, false, NULL))))
2790 return false;
2791
2792 /* compatible pointer types (qualifiers ignored) */
2793 if (allow_c90 &&
2794 ((!lstp->t_const && rstp->t_const) ||
2795 (!lstp->t_volatile && rstp->t_volatile))) {
2796 /* left side has not all qualifiers of right */
2797 switch (op) {
2798 case INIT:
2799 case RETURN:
2800 /* incompatible pointer types to '%s' and '%s' */
2801 warning(182, type_name(lstp), type_name(rstp));
2802 break;
2803 case FARG:
2804 /* converting '%s' to incompatible '%s' ... */
2805 warning(153,
2806 type_name(rtp), type_name(ltp), arg);
2807 break;
2808 default:
2809 /* operands of '%s' have incompatible pointer ... */
2810 warning(128, op_name(op),
2811 type_name(lstp), type_name(rstp));
2812 break;
2813 }
2814 }
2815
2816 if (allow_c90)
2817 check_unconst_function(lstp, rn);
2818
2819 return true;
2820 }
2821
2822 static bool
2823 check_assign_pointer_integer(op_t op, int arg,
2824 const type_t *ltp, tspec_t lt,
2825 const type_t *rtp, tspec_t rt)
2826 {
2827
2828 if (!((lt == PTR && is_integer(rt)) || (is_integer(lt) && rt == PTR)))
2829 return false;
2830
2831 const char *lx = lt == PTR ? "pointer" : "integer";
2832 const char *rx = rt == PTR ? "pointer" : "integer";
2833
2834 switch (op) {
2835 case INIT:
2836 case RETURN:
2837 /* illegal combination of %s '%s' and %s '%s' */
2838 warning(183, lx, type_name(ltp), rx, type_name(rtp));
2839 break;
2840 case FARG:
2841 /* illegal combination of %s '%s' and %s '%s', arg #%d */
2842 warning(154,
2843 lx, type_name(ltp), rx, type_name(rtp), arg);
2844 break;
2845 default:
2846 /* illegal combination of %s '%s' and %s '%s', op '%s' */
2847 warning(123,
2848 lx, type_name(ltp), rx, type_name(rtp), op_name(op));
2849 break;
2850 }
2851 return true;
2852 }
2853
2854 static bool
2855 check_assign_pointer(op_t op, int arg,
2856 const type_t *ltp, tspec_t lt,
2857 const type_t *rtp, tspec_t rt)
2858 {
2859 if (!(lt == PTR && rt == PTR))
2860 return false;
2861
2862 if (op == FARG)
2863 /* converting '%s' to incompatible '%s' for ... */
2864 warning(153, type_name(rtp), type_name(ltp), arg);
2865 else
2866 warn_incompatible_pointers(op, ltp, rtp);
2867 return true;
2868 }
2869
2870 static void
2871 warn_assign(op_t op, int arg,
2872 const type_t *ltp, tspec_t lt,
2873 const type_t *rtp, tspec_t rt)
2874 {
2875 switch (op) {
2876 case INIT:
2877 /* cannot initialize '%s' from '%s' */
2878 error(185, type_name(ltp), type_name(rtp));
2879 break;
2880 case RETURN:
2881 /* function has return type '%s' but returns '%s' */
2882 error(211, type_name(ltp), type_name(rtp));
2883 break;
2884 case FARG:
2885 /* passing '%s' to incompatible '%s', arg #%d */
2886 warning(155, type_name(rtp), type_name(ltp), arg);
2887 break;
2888 default:
2889 warn_incompatible_types(op, ltp, lt, rtp, rt);
2890 break;
2891 }
2892 }
2893
2894 /*
2895 * Checks type compatibility for ASSIGN, INIT, FARG and RETURN
2896 * and prints warnings/errors if necessary.
2897 * Returns whether the types are (almost) compatible.
2898 */
2899 static bool
2900 check_assign_types_compatible(op_t op, int arg,
2901 const tnode_t *ln, const tnode_t *rn)
2902 {
2903 tspec_t lt, rt, lst = NO_TSPEC, rst = NO_TSPEC;
2904 type_t *ltp, *rtp, *lstp = NULL, *rstp = NULL;
2905
2906 if ((lt = (ltp = ln->tn_type)->t_tspec) == PTR)
2907 lst = (lstp = ltp->t_subt)->t_tspec;
2908 if ((rt = (rtp = rn->tn_type)->t_tspec) == PTR)
2909 rst = (rstp = rtp->t_subt)->t_tspec;
2910
2911 if (lt == BOOL && is_scalar(rt)) /* C99 6.3.1.2 */
2912 return true;
2913
2914 if (is_arithmetic(lt) && (is_arithmetic(rt) || rt == BOOL))
2915 return true;
2916
2917 if (is_struct_or_union(lt) && is_struct_or_union(rt))
2918 return ltp->u.sou == rtp->u.sou;
2919
2920 if (lt == PTR && is_null_pointer(rn)) {
2921 if (is_integer(rn->tn_type->t_tspec))
2922 /* implicit conversion from integer 0 to pointer ... */
2923 query_message(15, type_name(ltp));
2924 return true;
2925 }
2926
2927 check_assign_void_pointer(op, arg, lt, lst, rt, rst);
2928
2929 if (check_assign_void_pointer_compat(op, arg,
2930 ltp, lt, lstp, lst, rn, rtp, rt, rstp, rst))
2931 return true;
2932
2933 if (check_assign_pointer_integer(op, arg, ltp, lt, rtp, rt))
2934 return true;
2935
2936 if (check_assign_pointer(op, arg, ltp, lt, rtp, rt))
2937 return true;
2938
2939 warn_assign(op, arg, ltp, lt, rtp, rt);
2940 return false;
2941 }
2942
2943 static bool
2944 has_side_effect(const tnode_t *tn) /* NOLINT(misc-no-recursion) */
2945 {
2946 op_t op = tn->tn_op;
2947
2948 if (modtab[op].m_has_side_effect)
2949 return true;
2950
2951 if (op == CVT && tn->tn_type->t_tspec == VOID)
2952 return has_side_effect(tn->u.ops.left);
2953
2954 /* XXX: Why not has_side_effect(tn->u.ops.left) as well? */
2955 if (op == LOGAND || op == LOGOR)
2956 return has_side_effect(tn->u.ops.right);
2957
2958 /* XXX: Why not has_side_effect(tn->u.ops.left) as well? */
2959 if (op == QUEST)
2960 return has_side_effect(tn->u.ops.right);
2961
2962 if (op == COLON || op == COMMA) {
2963 return has_side_effect(tn->u.ops.left) ||
2964 has_side_effect(tn->u.ops.right);
2965 }
2966
2967 return false;
2968 }
2969
2970 static bool
2971 is_void_cast(const tnode_t *tn)
2972 {
2973
2974 return tn->tn_op == CVT && tn->tn_cast &&
2975 tn->tn_type->t_tspec == VOID;
2976 }
2977
2978 static bool
2979 is_local_symbol(const tnode_t *tn)
2980 {
2981
2982 return tn->tn_op == LOAD &&
2983 tn->u.ops.left->tn_op == NAME &&
2984 tn->u.ops.left->u.sym->s_scl == AUTO;
2985 }
2986
2987 static bool
2988 is_int_constant_zero(const tnode_t *tn)
2989 {
2990
2991 return tn->tn_op == CON &&
2992 tn->tn_type->t_tspec == INT &&
2993 tn->u.value.u.integer == 0;
2994 }
2995
2996 static void
2997 check_null_effect(const tnode_t *tn)
2998 {
2999
3000 if (hflag &&
3001 !has_side_effect(tn) &&
3002 !(is_void_cast(tn) && is_local_symbol(tn->u.ops.left)) &&
3003 !(is_void_cast(tn) && is_int_constant_zero(tn->u.ops.left))) {
3004 /* expression has null effect */
3005 warning(129);
3006 }
3007 }
3008
3009 /*
3010 * Check the types for specific operators and type combinations.
3011 *
3012 * At this point, the operands already conform to the type requirements of
3013 * the operator, such as being integer, floating or scalar.
3014 */
3015 static bool
3016 typeok_op(op_t op, int arg,
3017 const tnode_t *ln, const type_t *ltp, tspec_t lt,
3018 const tnode_t *rn, const type_t *rtp, tspec_t rt)
3019 {
3020 switch (op) {
3021 case ARROW:
3022 return typeok_arrow(lt);
3023 case POINT:
3024 return typeok_point(ln, ltp, lt);
3025 case INCBEF:
3026 case DECBEF:
3027 case INCAFT:
3028 case DECAFT:
3029 return typeok_incdec(op, ln, ltp);
3030 case INDIR:
3031 return typeok_indir(ltp, lt);
3032 case ADDR:
3033 return typeok_address(op, ln, ltp, lt);
3034 case PLUS:
3035 return typeok_plus(op, ltp, lt, rtp, rt);
3036 case MINUS:
3037 return typeok_minus(op, ltp, lt, rtp, rt);
3038 case SHL:
3039 typeok_shl(op, lt, rt);
3040 goto shift;
3041 case SHR:
3042 typeok_shr(op, ln, lt, rn, rt);
3043 shift:
3044 typeok_shift(ltp, lt, rn, rt);
3045 break;
3046 case LT:
3047 case LE:
3048 case GT:
3049 case GE:
3050 compare:
3051 return typeok_compare(op, ln, ltp, lt, rn, rtp, rt);
3052 case EQ:
3053 case NE:
3054 if (is_typeok_eq(ln, lt, rn, rt))
3055 break;
3056 goto compare;
3057 case QUEST:
3058 return typeok_quest(lt, rn);
3059 case COLON:
3060 return typeok_colon(ln, ltp, lt, rn, rtp, rt);
3061 case ASSIGN:
3062 case INIT:
3063 case FARG:
3064 case RETURN:
3065 if (!check_assign_types_compatible(op, arg, ln, rn))
3066 return false;
3067 goto assign;
3068 case MULASS:
3069 case DIVASS:
3070 case MODASS:
3071 goto assign;
3072 case ADDASS:
3073 case SUBASS:
3074 if ((lt == PTR && !is_integer(rt)) || rt == PTR) {
3075 warn_incompatible_types(op, ltp, lt, rtp, rt);
3076 return false;
3077 }
3078 goto assign;
3079 case SHLASS:
3080 goto assign;
3081 case SHRASS:
3082 if (pflag && !is_uinteger(lt) &&
3083 !(!allow_c90 && is_uinteger(rt))) {
3084 /* bitwise '%s' on signed value possibly nonportable */
3085 warning(117, op_name(op));
3086 }
3087 goto assign;
3088 case ANDASS:
3089 case XORASS:
3090 case ORASS:
3091 assign:
3092 return typeok_assign(op, ln, ltp, lt);
3093 case COMMA:
3094 if (!modtab[ln->tn_op].m_has_side_effect)
3095 check_null_effect(ln);
3096 break;
3097 default:
3098 break;
3099 }
3100 return true;
3101 }
3102
3103 static void
3104 check_bad_enum_operation(op_t op, const tnode_t *ln, const tnode_t *rn)
3105 {
3106
3107 if (!eflag)
3108 return;
3109
3110 /* Allow enum in array indices. */
3111 if (op == PLUS &&
3112 ((ln->tn_type->t_is_enum && rn->tn_type->t_tspec == PTR) ||
3113 (rn->tn_type->t_is_enum && ln->tn_type->t_tspec == PTR))) {
3114 return;
3115 }
3116
3117 /* dubious operation '%s' on enum */
3118 warning(241, op_name(op));
3119 }
3120
3121 static void
3122 check_enum_type_mismatch(op_t op, int arg, const tnode_t *ln, const tnode_t *rn)
3123 {
3124 const mod_t *mp = &modtab[op];
3125
3126 if (ln->tn_type->u.enumer != rn->tn_type->u.enumer) {
3127 switch (op) {
3128 case INIT:
3129 /* enum type mismatch between '%s' and '%s' in ... */
3130 warning(210,
3131 type_name(ln->tn_type), type_name(rn->tn_type));
3132 break;
3133 case FARG:
3134 /* function expects '%s', passing '%s' for arg #%d */
3135 warning(156,
3136 type_name(ln->tn_type), type_name(rn->tn_type),
3137 arg);
3138 break;
3139 case RETURN:
3140 /* function has return type '%s' but returns '%s' */
3141 warning(211,
3142 type_name(ln->tn_type), type_name(rn->tn_type));
3143 break;
3144 default:
3145 /* enum type mismatch: '%s' '%s' '%s' */
3146 warning(130, type_name(ln->tn_type), op_name(op),
3147 type_name(rn->tn_type));
3148 break;
3149 }
3150 } else if (Pflag && eflag && mp->m_comparison && op != EQ && op != NE)
3151 /* operator '%s' assumes that '%s' is ordered */
3152 warning(243, op_name(op), type_name(ln->tn_type));
3153 }
3154
3155 static void
3156 check_enum_int_mismatch(op_t op, int arg, const tnode_t *ln, const tnode_t *rn)
3157 {
3158
3159 if (!eflag)
3160 return;
3161
3162 switch (op) {
3163 case INIT:
3164 /*
3165 * Initialization with 0 is allowed. Otherwise, all implicit
3166 * initializations would need to be warned upon as well.
3167 */
3168 if (!rn->tn_type->t_is_enum && rn->tn_op == CON &&
3169 is_integer(rn->tn_type->t_tspec) &&
3170 rn->u.value.u.integer == 0) {
3171 return;
3172 }
3173 /* initialization of '%s' with '%s' */
3174 warning(277, type_name(ln->tn_type), type_name(rn->tn_type));
3175 break;
3176 case FARG:
3177 /* combination of '%s' and '%s', arg #%d */
3178 warning(278,
3179 type_name(ln->tn_type), type_name(rn->tn_type), arg);
3180 break;
3181 case RETURN:
3182 /* combination of '%s' and '%s' in return */
3183 warning(279, type_name(ln->tn_type), type_name(rn->tn_type));
3184 break;
3185 default:
3186 /* combination of '%s' and '%s', op '%s' */
3187 warning(242, type_name(ln->tn_type), type_name(rn->tn_type),
3188 op_name(op));
3189 break;
3190 }
3191 }
3192
3193 static void
3194 typeok_enum(op_t op, const mod_t *mp, int arg,
3195 const tnode_t *ln, const type_t *ltp,
3196 const tnode_t *rn, const type_t *rtp)
3197 {
3198 if (mp->m_bad_on_enum &&
3199 (ltp->t_is_enum || (mp->m_binary && rtp->t_is_enum))) {
3200 check_bad_enum_operation(op, ln, rn);
3201 } else if (mp->m_valid_on_enum &&
3202 (ltp->t_is_enum && rtp != NULL && rtp->t_is_enum)) {
3203 check_enum_type_mismatch(op, arg, ln, rn);
3204 } else if (mp->m_valid_on_enum &&
3205 (ltp->t_is_enum || (rtp != NULL && rtp->t_is_enum))) {
3206 check_enum_int_mismatch(op, arg, ln, rn);
3207 }
3208 }
3209
3210 /* Perform most type checks. Return whether the types are ok. */
3211 bool
3212 typeok(op_t op, int arg, const tnode_t *ln, const tnode_t *rn)
3213 {
3214
3215 const mod_t *mp = &modtab[op];
3216
3217 type_t *ltp = ln->tn_type;
3218 tspec_t lt = ltp->t_tspec;
3219
3220 type_t *rtp = mp->m_binary ? rn->tn_type : NULL;
3221 tspec_t rt = mp->m_binary ? rtp->t_tspec : NO_TSPEC;
3222
3223 if (Tflag && !typeok_scalar_strict_bool(op, mp, arg, ln, rn))
3224 return false;
3225 if (!typeok_scalar(op, mp, ltp, lt, rtp, rt))
3226 return false;
3227
3228 if (!typeok_op(op, arg, ln, ltp, lt, rn, rtp, rt))
3229 return false;
3230
3231 typeok_enum(op, mp, arg, ln, ltp, rn, rtp);
3232 return true;
3233 }
3234
3235 /* In traditional C, keep unsigned and promote FLOAT to DOUBLE. */
3236 static tspec_t
3237 promote_trad(tspec_t t)
3238 {
3239
3240 if (t == UCHAR || t == USHORT)
3241 return UINT;
3242 if (t == CHAR || t == SCHAR || t == SHORT)
3243 return INT;
3244 if (t == FLOAT)
3245 return DOUBLE;
3246 if (t == ENUM)
3247 return INT;
3248 return t;
3249 }
3250
3251 /*
3252 * C99 6.3.1.1p2 requires for types with lower rank than int that "If an int
3253 * can represent all the values of the original type, the value is converted
3254 * to an int; otherwise it is converted to an unsigned int", and that "All
3255 * other types are unchanged by the integer promotions".
3256 */
3257 static tspec_t
3258 promote_c90(const tnode_t *tn, tspec_t t, bool farg)
3259 {
3260 if (tn->tn_type->t_bitfield) {
3261 unsigned int width = tn->tn_type->t_bit_field_width;
3262 unsigned int int_width = size_in_bits(INT);
3263 // XXX: What about _Bool bit-fields, since C99?
3264 if (width < int_width)
3265 return INT;
3266 if (width == int_width)
3267 return is_uinteger(t) ? UINT : INT;
3268 return t;
3269 }
3270
3271 if (t == CHAR || t == SCHAR)
3272 return INT;
3273 if (t == UCHAR)
3274 return size_in_bits(CHAR) < size_in_bits(INT) ? INT : UINT;
3275 if (t == SHORT)
3276 return INT;
3277 if (t == USHORT)
3278 return size_in_bits(SHORT) < size_in_bits(INT) ? INT : UINT;
3279 if (t == ENUM)
3280 return INT;
3281 if (farg && t == FLOAT)
3282 return DOUBLE;
3283 return t;
3284 }
3285
3286 /*
3287 * Performs the "integer promotions" (C99 6.3.1.1p2), which convert small
3288 * integer types to either int or unsigned int.
3289 *
3290 * If allow_c90 is unset or the operand is a function argument with no type
3291 * information (no prototype or variable # of args), converts float to double.
3292 */
3293 tnode_t *
3294 promote(op_t op, bool farg, tnode_t *tn)
3295 {
3296
3297 const type_t *otp = tn->tn_type;
3298 tspec_t ot = otp->t_tspec;
3299 if (!is_arithmetic(ot))
3300 return tn;
3301
3302 tspec_t nt = allow_c90 ? promote_c90(tn, ot, farg) : promote_trad(ot);
3303 if (nt == ot)
3304 return tn;
3305
3306 type_t *ntp = expr_dup_type(gettyp(nt));
3307 ntp->t_tspec = nt;
3308 ntp->t_is_enum = otp->t_is_enum;
3309 if (ntp->t_is_enum)
3310 ntp->u.enumer = otp->u.enumer;
3311 ntp->t_bitfield = otp->t_bitfield;
3312 if (ntp->t_bitfield) {
3313 ntp->t_bit_field_width = otp->t_bit_field_width;
3314 ntp->t_bit_field_offset = otp->t_bit_field_offset;
3315 }
3316 if (ntp->t_bitfield && is_uinteger(ot) && !is_uinteger(nt))
3317 ntp->t_bit_field_width++;
3318 return convert(op, 0, ntp, tn);
3319 }
3320
3321 static void
3322 check_lossy_floating_to_integer_conversion(
3323 op_t op, int arg, const type_t *tp, const tnode_t *tn)
3324 {
3325 long double x = tn->u.value.u.floating;
3326 integer_constraints ic = ic_any(tp);
3327 if (is_uinteger(tp->t_tspec)
3328 ? x >= ic.umin && x <= ic.umax && x == (uint64_t)x
3329 : x >= ic.smin && x <= ic.smax && x == (int64_t)x)
3330 return;
3331 if (op == FARG)
3332 /* lossy conversion of %Lg to '%s', arg #%d */
3333 warning(380, x, type_name(tp), arg);
3334 else
3335 /* lossy conversion of %Lg to '%s' */
3336 warning(381, x, type_name(tp));
3337 }
3338
3339 static void
3340 convert_integer_from_floating(
3341 op_t op, int arg, const type_t *tp, const tnode_t *tn)
3342 {
3343
3344 if (op == CVT)
3345 /* cast from floating point '%s' to integer '%s' */
3346 query_message(2, type_name(tn->tn_type), type_name(tp));
3347 else
3348 /* implicit conversion from floating point '%s' to ... */
3349 query_message(1, type_name(tn->tn_type), type_name(tp));
3350 if (tn->tn_op == CON)
3351 check_lossy_floating_to_integer_conversion(op, arg, tp, tn);
3352 }
3353
3354 static bool
3355 should_warn_about_prototype_conversion(tspec_t nt,
3356 tspec_t ot, const tnode_t *ptn)
3357 {
3358
3359 if (nt == ot)
3360 return false;
3361
3362 if (nt == ENUM && ot == INT)
3363 return false;
3364
3365 if (is_floating(nt) != is_floating(ot) ||
3366 portable_rank_cmp(nt, ot) != 0) {
3367 /* representation and/or width change */
3368 if (!is_integer(ot))
3369 return true;
3370 /*
3371 * XXX: Investigate whether this rule makes sense; see
3372 * tests/usr.bin/xlint/lint1/platform_long.c.
3373 */
3374 return portable_rank_cmp(ot, INT) > 0;
3375 }
3376
3377 if (!hflag)
3378 return false;
3379
3380 /*
3381 * If the types differ only in sign and the argument has the same
3382 * representation in both types, print no warning.
3383 */
3384 if (ptn->tn_op == CON && is_integer(nt) &&
3385 signed_type(nt) == signed_type(ot) &&
3386 !msb(ptn->u.value.u.integer, ot))
3387 return false;
3388
3389 return true;
3390 }
3391
3392 /*
3393 * Warn if a prototype causes a type conversion that is different from what
3394 * would happen to the same argument in the absence of a prototype. This
3395 * check is intended for code that needs to stay compatible with pre-C90 C.
3396 *
3397 * Errors/warnings about illegal type combinations are already printed
3398 * in check_assign_types_compatible().
3399 */
3400 static void
3401 check_prototype_conversion(int arg, tspec_t nt, tspec_t ot, type_t *tp,
3402 tnode_t *tn)
3403 {
3404
3405 if (!is_arithmetic(nt) || !is_arithmetic(ot))
3406 return;
3407
3408 /*
3409 * If the type of the formal parameter is char/short, a warning would
3410 * be useless, because functions declared the old style can't expect
3411 * char/short arguments.
3412 */
3413 if (nt == CHAR || nt == SCHAR || nt == UCHAR ||
3414 nt == SHORT || nt == USHORT)
3415 return;
3416
3417 tnode_t *ptn = promote(NOOP, true, tn);
3418 ot = ptn->tn_type->t_tspec;
3419
3420 if (should_warn_about_prototype_conversion(nt, ot, ptn)) {
3421 /* argument %d is converted from '%s' to '%s' ... */
3422 warning(259, arg, type_name(tn->tn_type), type_name(tp));
3423 }
3424 }
3425
3426 /*
3427 * When converting a large integer type to a small integer type, in some
3428 * cases the value of the actual expression is further restricted than the
3429 * type bounds, such as in (expr & 0xFF) or (expr % 100) or (expr >> 24).
3430 */
3431 static bool
3432 can_represent(const type_t *tp, const tnode_t *tn)
3433 {
3434
3435 debug_step("%s: type '%s'", __func__, type_name(tp));
3436 debug_node(tn);
3437
3438 uint64_t nmask = value_bits(width_in_bits(tp));
3439 if (!is_uinteger(tp->t_tspec))
3440 nmask >>= 1;
3441
3442 integer_constraints c = ic_expr(tn);
3443 if ((~c.bclr & ~nmask) == 0)
3444 return true;
3445
3446 integer_constraints tpc = ic_any(tp);
3447 if (is_uinteger(tp->t_tspec)
3448 ? tpc.umin <= c.umin && tpc.umax >= c.umax
3449 : tpc.smin <= c.smin && tpc.smax >= c.smax)
3450 return true;
3451
3452 return false;
3453 }
3454
3455 static bool
3456 should_warn_about_integer_conversion(const type_t *ntp, tspec_t nt,
3457 const tnode_t *otn, tspec_t ot)
3458 {
3459
3460 // XXX: The portable_rank_cmp aims at portable mode, independent of the
3461 // current platform, while can_represent acts on the actual type sizes
3462 // from the current platform. This mix is inconsistent, but anything
3463 // else would make the exact conditions too complicated to grasp.
3464 if (aflag > 0 && portable_rank_cmp(nt, ot) < 0) {
3465 if (ot == LONG || ot == ULONG
3466 || ot == LLONG || ot == ULLONG
3467 #ifdef INT128_SIZE
3468 || ot == INT128 || ot == UINT128
3469 #endif
3470 || aflag > 1)
3471 return !can_represent(ntp, otn);
3472 }
3473 return false;
3474 }
3475
3476 static void
3477 convert_integer_from_integer(op_t op, int arg, tspec_t nt, tspec_t ot,
3478 type_t *tp, tnode_t *tn)
3479 {
3480
3481 if (tn->tn_op == CON)
3482 return;
3483
3484 if (op == CVT)
3485 return;
3486
3487 if (Pflag && pflag && aflag > 0 &&
3488 portable_rank_cmp(nt, ot) > 0 &&
3489 is_uinteger(nt) != is_uinteger(ot)) {
3490 if (op == FARG)
3491 /* conversion to '%s' may sign-extend ... */
3492 warning(297, type_name(tp), arg);
3493 else
3494 /* conversion to '%s' may sign-extend ... */
3495 warning(131, type_name(tp));
3496 }
3497
3498 if (Pflag && portable_rank_cmp(nt, ot) > 0 &&
3499 (tn->tn_op == PLUS || tn->tn_op == MINUS || tn->tn_op == MULT ||
3500 tn->tn_op == SHL)) {
3501 /* suggest cast from '%s' to '%s' on op '%s' to ... */
3502 warning(324, type_name(gettyp(ot)), type_name(tp),
3503 op_name(tn->tn_op));
3504 }
3505
3506 if (should_warn_about_integer_conversion(tp, nt, tn, ot)) {
3507 if (op == FARG) {
3508 /* conversion from '%s' to '%s' may lose ... */
3509 warning(298,
3510 type_name(tn->tn_type), type_name(tp), arg);
3511 } else {
3512 /* conversion from '%s' to '%s' may lose accuracy */
3513 warning(132,
3514 type_name(tn->tn_type), type_name(tp));
3515 }
3516 }
3517
3518 if (any_query_enabled && is_uinteger(nt) != is_uinteger(ot))
3519 /* implicit conversion changes sign from '%s' to '%s' */
3520 query_message(3, type_name(tn->tn_type), type_name(tp));
3521 }
3522
3523 static void
3524 convert_integer_from_pointer(op_t op, tspec_t nt, type_t *tp, tnode_t *tn)
3525 {
3526
3527 if (tn->tn_op == CON)
3528 return;
3529 if (op != CVT)
3530 return; /* We already got an error. */
3531 if (portable_rank_cmp(nt, PTR) >= 0)
3532 return;
3533
3534 if (pflag && size_in_bits(nt) >= size_in_bits(PTR)) {
3535 /* conversion of pointer to '%s' may lose bits */
3536 warning(134, type_name(tp));
3537 } else {
3538 /* conversion of pointer to '%s' loses bits */
3539 warning(133, type_name(tp));
3540 }
3541 }
3542
3543 static bool
3544 struct_starts_with(const type_t *struct_tp, const type_t *member_tp)
3545 {
3546
3547 return struct_tp->u.sou->sou_first_member != NULL &&
3548 types_compatible(struct_tp->u.sou->sou_first_member->s_type,
3549 member_tp, true, false, NULL);
3550 }
3551
3552 static bool
3553 is_byte_array(const type_t *tp)
3554 {
3555
3556 return tp->t_tspec == ARRAY &&
3557 (tp->t_subt->t_tspec == CHAR || tp->t_subt->t_tspec == UCHAR);
3558 }
3559
3560 static bool
3561 union_contains(const type_t *utp, const type_t *mtp)
3562 {
3563 for (const sym_t *mem = utp->u.sou->sou_first_member;
3564 mem != NULL; mem = mem->s_next) {
3565 if (types_compatible(mem->s_type, mtp, true, false, NULL))
3566 return true;
3567 }
3568 return false;
3569 }
3570
3571 static bool
3572 should_warn_about_pointer_cast(const type_t *nstp, tspec_t nst,
3573 const type_t *ostp, tspec_t ost)
3574 {
3575
3576 while (nst == ARRAY)
3577 nstp = nstp->t_subt, nst = nstp->t_tspec;
3578 while (ost == ARRAY)
3579 ostp = ostp->t_subt, ost = ostp->t_tspec;
3580
3581 if (nst == STRUCT && ost == STRUCT &&
3582 (struct_starts_with(nstp, ostp) ||
3583 struct_starts_with(ostp, nstp)))
3584 return false;
3585
3586 if (is_incomplete(nstp) || is_incomplete(ostp))
3587 return false;
3588
3589 if (nst == CHAR || nst == UCHAR)
3590 return false; /* for the sake of traditional C code */
3591 if (ost == CHAR || ost == UCHAR)
3592 return false; /* for the sake of traditional C code */
3593
3594 /* Allow cast between pointers to sockaddr variants. */
3595 if (nst == STRUCT && ost == STRUCT) {
3596 const sym_t *nmem = nstp->u.sou->sou_first_member;
3597 const sym_t *omem = ostp->u.sou->sou_first_member;
3598 while (nmem != NULL && omem != NULL &&
3599 types_compatible(nmem->s_type, omem->s_type,
3600 true, false, NULL))
3601 nmem = nmem->s_next, omem = omem->s_next;
3602 if (nmem != NULL && is_byte_array(nmem->s_type))
3603 return false;
3604 if (omem != NULL && is_byte_array(omem->s_type))
3605 return false;
3606 if (nmem == NULL && omem == NULL)
3607 return false;
3608 }
3609
3610 if (nst == UNION || ost == UNION) {
3611 const type_t *union_tp = nst == UNION ? nstp : ostp;
3612 const type_t *other_tp = nst == UNION ? ostp : nstp;
3613 if (union_contains(union_tp, other_tp))
3614 return false;
3615 }
3616
3617 if (is_struct_or_union(nst) && is_struct_or_union(ost))
3618 return nstp->u.sou != ostp->u.sou;
3619
3620 enum rank_kind rk1 = type_properties(nst)->tt_rank_kind;
3621 enum rank_kind rk2 = type_properties(ost)->tt_rank_kind;
3622 if (rk1 != rk2 || rk1 == RK_NONE)
3623 return true;
3624
3625 return portable_rank_cmp(nst, ost) != 0;
3626 }
3627
3628 static void
3629 convert_pointer_from_pointer(type_t *ntp, tnode_t *tn)
3630 {
3631 const type_t *nstp = ntp->t_subt;
3632 const type_t *otp = tn->tn_type;
3633 const type_t *ostp = otp->t_subt;
3634 tspec_t nst = nstp->t_tspec;
3635 tspec_t ost = ostp->t_tspec;
3636
3637 if (nst == VOID || ost == VOID) {
3638 /* TODO: C99 behaves like C90 here. */
3639 if (!allow_trad && !allow_c99 && (nst == FUNC || ost == FUNC)) {
3640 const char *nts, *ots;
3641 /* null pointers are already handled in convert() */
3642 *(nst == FUNC ? &nts : &ots) = "function pointer";
3643 *(nst == VOID ? &nts : &ots) = "'void *'";
3644 /* conversion of %s to %s requires a cast */
3645 warning(303, ots, nts);
3646 }
3647 return;
3648 }
3649 if (nst == FUNC && ost == FUNC)
3650 return;
3651 if (nst == FUNC || ost == FUNC) {
3652 /* converting '%s' to '%s' is questionable */
3653 warning(229, type_name(otp), type_name(ntp));
3654 return;
3655 }
3656
3657 if (hflag && alignment(nstp) > alignment(ostp) &&
3658 ost != CHAR && ost != UCHAR &&
3659 !is_incomplete(ostp) &&
3660 !(nst == UNION && union_contains(nstp, ostp))) {
3661 /* converting '%s' to '%s' increases alignment ... */
3662 warning(135, type_name(otp), type_name(ntp),
3663 alignment(ostp), alignment(nstp));
3664 }
3665
3666 if (cflag && should_warn_about_pointer_cast(nstp, nst, ostp, ost)) {
3667 /* pointer cast from '%s' to unrelated '%s' */
3668 warning(247, type_name(ostp), type_name(nstp));
3669 }
3670 }
3671
3672 /*
3673 * Insert a conversion operator, which converts the type of the node
3674 * to another given type.
3675 *
3676 * Possible values for 'op':
3677 * CVT a cast-expression
3678 * binary integer promotion for one of the operands, or a usual
3679 * arithmetic conversion
3680 * binary plain or compound assignments to bit-fields
3681 * FARG 'arg' is the number of the parameter (used for warnings)
3682 * NOOP several other implicit conversions
3683 * ...
3684 */
3685 tnode_t *
3686 convert(op_t op, int arg, type_t *tp, tnode_t *tn)
3687 {
3688 tspec_t nt = tp->t_tspec;
3689 tspec_t ot = tn->tn_type->t_tspec;
3690
3691 if (allow_trad && allow_c90 && op == FARG)
3692 check_prototype_conversion(arg, nt, ot, tp, tn);
3693
3694 if (nt == BOOL) {
3695 /* No further checks. */
3696
3697 } else if (is_integer(nt)) {
3698 if (ot == BOOL) {
3699 /* No further checks. */
3700 } else if (is_integer(ot))
3701 convert_integer_from_integer(op, arg, nt, ot, tp, tn);
3702 else if (is_floating(ot))
3703 convert_integer_from_floating(op, arg, tp, tn);
3704 else if (ot == PTR)
3705 convert_integer_from_pointer(op, nt, tp, tn);
3706
3707 } else if (is_floating(nt)) {
3708 if (is_integer(ot) && op != CVT) {
3709 /* implicit conversion from integer '%s' to ... */
3710 query_message(19,
3711 type_name(tn->tn_type), type_name(tp));
3712 }
3713
3714 } else if (nt == PTR) {
3715 if (is_null_pointer(tn)) {
3716 /* a null pointer may be assigned to any pointer. */
3717 } else if (ot == PTR && op == CVT)
3718 convert_pointer_from_pointer(tp, tn);
3719 }
3720
3721 tnode_t *ntn = expr_alloc_tnode();
3722 ntn->tn_op = CVT;
3723 ntn->tn_type = tp;
3724 ntn->tn_cast = op == CVT;
3725 ntn->tn_sys |= tn->tn_sys;
3726 ntn->u.ops.right = NULL;
3727 if (tn->tn_op != CON || nt == VOID) {
3728 ntn->u.ops.left = tn;
3729 } else {
3730 ntn->tn_op = CON;
3731 convert_constant(op, arg, ntn->tn_type, &ntn->u.value,
3732 &tn->u.value);
3733 }
3734
3735 return ntn;
3736 }
3737
3738 static void
3739 convert_constant_from_floating(op_t op, int arg, const type_t *ntp,
3740 tspec_t nt, val_t *nv, val_t *ov)
3741 {
3742 long double max = 0.0, min = 0.0;
3743
3744 switch (nt) {
3745 case CHAR:
3746 max = TARG_CHAR_MAX; min = TARG_CHAR_MIN; break;
3747 case UCHAR:
3748 max = TARG_UCHAR_MAX; min = 0; break;
3749 case SCHAR:
3750 max = TARG_SCHAR_MAX; min = TARG_SCHAR_MIN; break;
3751 case SHORT:
3752 max = TARG_SHRT_MAX; min = TARG_SHRT_MIN; break;
3753 case USHORT:
3754 max = TARG_USHRT_MAX; min = 0; break;
3755 case ENUM:
3756 case INT:
3757 max = TARG_INT_MAX; min = TARG_INT_MIN; break;
3758 case UINT:
3759 max = TARG_UINT_MAX; min = 0; break;
3760 case LONG:
3761 max = TARG_LONG_MAX; min = TARG_LONG_MIN; break;
3762 case ULONG:
3763 max = TARG_ULONG_MAX; min = 0; break;
3764 case LLONG:
3765 max = LLONG_MAX; min = LLONG_MIN; break;
3766 case ULLONG:
3767 max = ULLONG_MAX; min = 0; break;
3768 case FLOAT:
3769 case FCOMPLEX:
3770 max = FLT_MAX; min = -FLT_MAX; break;
3771 case DOUBLE:
3772 case DCOMPLEX:
3773 max = DBL_MAX; min = -DBL_MAX; break;
3774 case LDOUBLE:
3775 case LCOMPLEX:
3776 /* LINTED 248; see floating_error_value. */
3777 max = LDBL_MAX; min = -max; break;
3778 default:
3779 lint_assert(/*CONSTCOND*/false);
3780 }
3781 if (ov->u.floating > max || ov->u.floating < min) {
3782 lint_assert(nt != LDOUBLE);
3783 const char *ot_name = type_name(gettyp(ov->v_tspec));
3784 const char *nt_name = type_name(ntp);
3785 if (is_integer(nt))
3786 goto after_warning;
3787 if (op == FARG)
3788 /* conversion of '%s' to '%s' is out of range, ... */
3789 warning(295, ot_name, nt_name, arg);
3790 else
3791 /* conversion of '%s' to '%s' is out of range */
3792 warning(119, ot_name, nt_name);
3793 after_warning:
3794 ov->u.floating = ov->u.floating > 0 ? max : min;
3795 }
3796
3797 if (nt == FLOAT || nt == FCOMPLEX)
3798 nv->u.floating = (float)ov->u.floating;
3799 else if (nt == DOUBLE || nt == DCOMPLEX)
3800 nv->u.floating = (double)ov->u.floating;
3801 else if (nt == LDOUBLE || nt == LCOMPLEX)
3802 nv->u.floating = ov->u.floating;
3803 else
3804 nv->u.integer = (int64_t)ov->u.floating;
3805 }
3806
3807 static bool
3808 convert_constant_to_floating(tspec_t nt, val_t *nv,
3809 tspec_t ot, const val_t *v)
3810 {
3811 if (nt == FLOAT) {
3812 nv->u.floating = (ot == PTR || is_uinteger(ot)) ?
3813 (float)(uint64_t)v->u.integer : (float)v->u.integer;
3814 } else if (nt == DOUBLE) {
3815 nv->u.floating = (ot == PTR || is_uinteger(ot)) ?
3816 (double)(uint64_t)v->u.integer : (double)v->u.integer;
3817 } else if (nt == LDOUBLE) {
3818 nv->u.floating = (ot == PTR || is_uinteger(ot))
3819 ? (long double)(uint64_t)v->u.integer
3820 : (long double)v->u.integer;
3821 } else
3822 return false;
3823 return true;
3824 }
3825
3826 /*
3827 * Print a warning if bits which were set are lost due to the conversion.
3828 * This can happen with operator ORASS only.
3829 */
3830 static void
3831 convert_constant_check_range_bitor(size_t nsz, size_t osz, const val_t *v,
3832 uint64_t xmask, op_t op)
3833 {
3834 if (nsz < osz && (v->u.integer & xmask) != 0)
3835 /* constant truncated by conversion, op '%s' */
3836 warning(306, op_name(op));
3837 }
3838
3839 static void
3840 convert_constant_check_range_bitand(size_t nsz, size_t osz,
3841 uint64_t xmask, const val_t *nv,
3842 tspec_t ot, const val_t *v,
3843 const type_t *tp, op_t op)
3844 {
3845 if (nsz > osz &&
3846 (nv->u.integer & bit((unsigned int)(osz - 1))) != 0 &&
3847 (nv->u.integer & xmask) != xmask) {
3848 /* extra bits set to 0 in conversion of '%s' to '%s', ... */
3849 warning(309, type_name(gettyp(ot)),
3850 type_name(tp), op_name(op));
3851 } else if (nsz < osz &&
3852 (v->u.integer & xmask) != xmask &&
3853 (v->u.integer & xmask) != 0)
3854 /* constant truncated by conversion, op '%s' */
3855 warning(306, op_name(op));
3856 }
3857
3858 static void
3859 convert_constant_check_range_signed(op_t op, int arg,
3860 const type_t *ntp, int64_t ov)
3861 {
3862 if (op == ASSIGN)
3863 /* assignment of negative constant %lld to unsigned ... */
3864 warning(164, (long long)ov, type_name(ntp));
3865 else if (op == INIT)
3866 /* initialization of unsigned type '%s' with negative ... */
3867 warning(221, type_name(ntp), (long long)ov);
3868 else if (op == FARG)
3869 /* conversion of negative constant %lld to unsigned ... */
3870 warning(296, (long long)ov, type_name(ntp), arg);
3871 else if (modtab[op].m_comparison) {
3872 /* handled by check_integer_comparison() */
3873 } else
3874 /* conversion of negative constant %lld to unsigned ... */
3875 warning(222, (long long)ov, type_name(ntp));
3876 }
3877
3878 /*
3879 * Loss of significant bit(s). All truncated bits of unsigned types or all
3880 * truncated bits plus the msb of the target for signed types are considered
3881 * to be significant bits. Loss of significant bits means that at least one
3882 * of the bits was set in an unsigned type or that at least one but not all
3883 * of the bits was set in a signed type. Loss of significant bits means that
3884 * it is not possible, also not with necessary casts, to convert back to the
3885 * original type. An example for a necessary cast is:
3886 * char c; int i; c = 128;
3887 * i = c; ** yields -128 **
3888 * i = (unsigned char)c; ** yields 128 **
3889 */
3890 static void
3891 warn_constant_check_range_truncated(op_t op, int arg, const type_t *tp,
3892 tspec_t ot)
3893 {
3894 if (op == ASSIGN && tp->t_bitfield)
3895 /* precision lost in bit-field assignment */
3896 warning(166);
3897 else if (op == ASSIGN)
3898 /* constant truncated by assignment */
3899 warning(165);
3900 else if (op == INIT && tp->t_bitfield)
3901 /* bit-field initializer does not fit */
3902 warning(180);
3903 else if (op == INIT)
3904 /* initializer does not fit */
3905 warning(178);
3906 else if (op == CASE)
3907 /* case label affected by conversion */
3908 warning(196);
3909 else if (op == FARG)
3910 /* conversion of '%s' to '%s' is out of range, arg #%d */
3911 warning(295, type_name(gettyp(ot)), type_name(tp), arg);
3912 else
3913 /* conversion of '%s' to '%s' is out of range */
3914 warning(119, type_name(gettyp(ot)), type_name(tp));
3915 }
3916
3917 static void
3918 warn_constant_check_range_loss(op_t op, int arg, const type_t *tp,
3919 tspec_t ot)
3920 {
3921 if (op == ASSIGN && tp->t_bitfield)
3922 /* precision lost in bit-field assignment */
3923 warning(166);
3924 else if (op == INIT && tp->t_bitfield)
3925 /* bit-field initializer out of range */
3926 warning(11);
3927 else if (op == CASE)
3928 /* case label affected by conversion */
3929 warning(196);
3930 else if (op == FARG)
3931 /* conversion of '%s' to '%s' is out of range, arg #%d */
3932 warning(295, type_name(gettyp(ot)), type_name(tp), arg);
3933 else
3934 /* conversion of '%s' to '%s' is out of range */
3935 warning(119, type_name(gettyp(ot)), type_name(tp));
3936 }
3937
3938 static void
3939 convert_constant_check_range(tspec_t ot, const type_t *tp, tspec_t nt,
3940 op_t op, int arg, const val_t *v, val_t *nv)
3941 {
3942 unsigned int obitsz, nbitsz;
3943 uint64_t xmask, xmsk1;
3944
3945 obitsz = size_in_bits(ot);
3946 nbitsz = tp->t_bitfield ? tp->t_bit_field_width : size_in_bits(nt);
3947 xmask = value_bits(nbitsz) ^ value_bits(obitsz);
3948 xmsk1 = value_bits(nbitsz) ^ value_bits(obitsz - 1);
3949 if (op == ORASS || op == BITOR || op == BITXOR) {
3950 convert_constant_check_range_bitor(
3951 nbitsz, obitsz, v, xmask, op);
3952 } else if (op == ANDASS || op == BITAND) {
3953 convert_constant_check_range_bitand(
3954 nbitsz, obitsz, xmask, nv, ot, v, tp, op);
3955 } else if (nt != PTR && is_uinteger(nt) &&
3956 ot != PTR && !is_uinteger(ot) &&
3957 v->u.integer < 0)
3958 convert_constant_check_range_signed(op, arg,
3959 tp, v->u.integer);
3960 else if (nv->u.integer != v->u.integer && nbitsz <= obitsz &&
3961 (v->u.integer & xmask) != 0 &&
3962 (is_uinteger(ot) || (v->u.integer & xmsk1) != xmsk1))
3963 warn_constant_check_range_truncated(op, arg, tp, ot);
3964 else if (nv->u.integer != v->u.integer)
3965 warn_constant_check_range_loss(op, arg, tp, ot);
3966 }
3967
3968 /* Converts a typed constant to a constant of another type. */
3969 void
3970 convert_constant(op_t op, int arg, const type_t *ntp, val_t *nv, val_t *ov)
3971 {
3972 /*
3973 * TODO: make 'ov' const; the name of this function does not suggest
3974 * that it modifies 'ov'.
3975 */
3976 tspec_t ot = ov->v_tspec;
3977 tspec_t nt = nv->v_tspec = ntp->t_tspec;
3978 bool range_check = false;
3979
3980 if (nt == BOOL) { /* C99 6.3.1.2 */
3981 nv->v_unsigned_since_c90 = false;
3982 nv->u.integer = is_nonzero_val(ov) ? 1 : 0;
3983 return;
3984 }
3985
3986 if (ot == FLOAT || ot == DOUBLE || ot == LDOUBLE)
3987 convert_constant_from_floating(op, arg, ntp, nt, nv, ov);
3988 else if (!convert_constant_to_floating(nt, nv, ot, ov)) {
3989 range_check = true; /* Check for lost precision. */
3990 nv->u.integer = ov->u.integer;
3991 }
3992
3993 if (allow_trad && allow_c90 && ov->v_unsigned_since_c90 &&
3994 (is_floating(nt) || (
3995 (is_integer(nt) && !is_uinteger(nt) &&
3996 portable_rank_cmp(nt, ot) > 0)))) {
3997 /* C90 treats constant as unsigned */
3998 warning(157);
3999 ov->v_unsigned_since_c90 = false;
4000 }
4001
4002 if (is_integer(nt)) {
4003 unsigned int size = ntp->t_bitfield
4004 ? ntp->t_bit_field_width : size_in_bits(nt);
4005 nv->u.integer = convert_integer(nv->u.integer, nt, size);
4006 }
4007
4008 if (range_check && op != CVT)
4009 convert_constant_check_range(ot, ntp, nt, op, arg, ov, nv);
4010 }
4011
4012 tnode_t *
4013 build_sizeof(const type_t *tp)
4014 {
4015 unsigned int size_in_bytes = type_size_in_bits(tp) / CHAR_SIZE;
4016 tnode_t *tn = build_integer_constant(SIZEOF_TSPEC, size_in_bytes);
4017 tn->tn_system_dependent = true;
4018 debug_step("build_sizeof '%s' = %u", type_name(tp), size_in_bytes);
4019 return tn;
4020 }
4021
4022 tnode_t *
4023 build_offsetof(const type_t *tp, designation dn)
4024 {
4025 unsigned int offset_in_bits = 0;
4026
4027 if (!is_struct_or_union(tp->t_tspec)) {
4028 /* unacceptable operand of '%s' */
4029 error(111, "offsetof");
4030 goto proceed;
4031 }
4032 for (size_t i = 0; i < dn.dn_len; i++) {
4033 const designator *dr = dn.dn_items + i;
4034 if (dr->dr_kind == DK_SUBSCRIPT) {
4035 if (tp->t_tspec != ARRAY)
4036 goto proceed; /* silent error */
4037 tp = tp->t_subt;
4038 offset_in_bits += (unsigned) dr->dr_subscript
4039 * type_size_in_bits(tp);
4040 } else {
4041 if (!is_struct_or_union(tp->t_tspec))
4042 goto proceed; /* silent error */
4043 const char *name = dr->dr_member->s_name;
4044 sym_t *mem = find_member(tp->u.sou, name);
4045 if (mem == NULL) {
4046 /* type '%s' does not have member '%s' */
4047 error(101, name, type_name(tp));
4048 goto proceed;
4049 }
4050 tp = mem->s_type;
4051 offset_in_bits += mem->u.s_member.sm_offset_in_bits;
4052 }
4053 }
4054 free(dn.dn_items);
4055
4056 proceed:;
4057 unsigned int offset_in_bytes = offset_in_bits / CHAR_SIZE;
4058 tnode_t *tn = build_integer_constant(SIZEOF_TSPEC, offset_in_bytes);
4059 tn->tn_system_dependent = true;
4060 return tn;
4061 }
4062
4063 unsigned int
4064 type_size_in_bits(const type_t *tp)
4065 {
4066
4067 unsigned int elem = 1;
4068 bool flex = false;
4069 lint_assert(tp != NULL);
4070 while (tp->t_tspec == ARRAY) {
4071 flex = true; /* allow c99 flex arrays [] [0] */
4072 elem *= tp->u.dimension;
4073 tp = tp->t_subt;
4074 }
4075 if (elem == 0 && !flex) {
4076 /* cannot take size/alignment of incomplete type */
4077 error(143);
4078 elem = 1;
4079 }
4080
4081 unsigned int elsz;
4082 switch (tp->t_tspec) {
4083 case VOID:
4084 /* cannot take size/alignment of void */
4085 error(146);
4086 elsz = 1;
4087 break;
4088 case FUNC:
4089 /* cannot take size/alignment of function type '%s' */
4090 error(144, type_name(tp));
4091 elsz = 1;
4092 break;
4093 case STRUCT:
4094 case UNION:
4095 if (is_incomplete(tp)) {
4096 /* cannot take size/alignment of incomplete type */
4097 error(143);
4098 elsz = 1;
4099 } else
4100 elsz = tp->u.sou->sou_size_in_bits;
4101 break;
4102 case ENUM:
4103 if (is_incomplete(tp)) {
4104 /* cannot take size/alignment of incomplete type */
4105 warning(143);
4106 }
4107 /* FALLTHROUGH */
4108 default:
4109 if (tp->t_bitfield)
4110 /* cannot take size/alignment of bit-field */
4111 error(145);
4112 elsz = size_in_bits(tp->t_tspec);
4113 lint_assert(elsz > 0);
4114 break;
4115 }
4116
4117 return elem * elsz;
4118 }
4119
4120 /* C11 6.5.3.4, GCC */
4121 tnode_t *
4122 build_alignof(const type_t *tp)
4123 {
4124 if (tp->t_tspec == FUNC) {
4125 /* cannot take size/alignment of function type '%s' */
4126 error(144, type_name(tp));
4127 return NULL;
4128 }
4129 if (tp->t_tspec == VOID) {
4130 /* cannot take size/alignment of void */
4131 error(146);
4132 return NULL;
4133 }
4134 if (is_incomplete(tp)) {
4135 /* cannot take size/alignment of incomplete type */
4136 error(143);
4137 return NULL;
4138 }
4139 if (tp->t_bitfield) {
4140 /* cannot take size/alignment of bit-field */
4141 error(145);
4142 return NULL;
4143 }
4144 return build_integer_constant(SIZEOF_TSPEC, (int64_t)alignment(tp));
4145 }
4146
4147 static tnode_t *
4148 cast_to_union(tnode_t *otn, bool sys, type_t *ntp)
4149 {
4150
4151 if (!allow_gcc) {
4152 /* union cast is a GCC extension */
4153 error(328);
4154 return NULL;
4155 }
4156
4157 for (const sym_t *m = ntp->u.sou->sou_first_member;
4158 m != NULL; m = m->s_next) {
4159 if (types_compatible(m->s_type, otn->tn_type,
4160 false, false, NULL)) {
4161 tnode_t *ntn = build_op(CVT, sys, ntp, otn, NULL);
4162 ntn->tn_cast = true;
4163 return ntn;
4164 }
4165 }
4166
4167 /* type '%s' is not a member of '%s' */
4168 error(329, type_name(otn->tn_type), type_name(ntp));
4169 return NULL;
4170 }
4171
4172 // In GCC mode, allow 'nullptr + offset' as a constant expression.
4173 static tnode_t *
4174 null_pointer_offset(tnode_t *tn)
4175 {
4176 uint64_t off = 0;
4177 const tnode_t *n = tn;
4178 while ((n->tn_op == PLUS || n->tn_op == MINUS)
4179 && is_integer(n->u.ops.right->tn_type->t_tspec)) {
4180 off += (uint64_t)n->u.ops.right->u.value.u.integer;
4181 n = n->u.ops.left;
4182 }
4183 if (n->tn_type->t_tspec == PTR
4184 && n->tn_op == ADDR
4185 && n->u.ops.left->tn_op == INDIR
4186 && n->u.ops.left->u.ops.left->tn_op == CON
4187 && n->u.ops.left->u.ops.left->tn_type->t_tspec == PTR) {
4188 off += (uint64_t)n->u.ops.left->u.ops.left->u.value.u.integer;
4189 return build_integer_constant(SIZEOF_TSPEC, (int64_t)off);
4190 }
4191 return tn;
4192 }
4193
4194 tnode_t *
4195 cast(tnode_t *tn, bool sys, type_t *tp)
4196 {
4197
4198 if (tn == NULL)
4199 return NULL;
4200
4201 tn = cconv(tn);
4202
4203 lint_assert(tp != NULL);
4204 tspec_t nt = tp->t_tspec;
4205 tspec_t ot = tn->tn_type->t_tspec;
4206
4207 if (nt == VOID) {
4208 /*
4209 * C90 6.3.4, C99 6.5.4p2 and C11 6.5.4p2 allow any type to be
4210 * cast to void. The only other allowed casts are from a
4211 * scalar type to a scalar type.
4212 */
4213 } else if (nt == UNION)
4214 return cast_to_union(tn, sys, tp);
4215 else if (nt == STRUCT || nt == ARRAY || nt == FUNC) {
4216 /* Casting to a struct is an undocumented GCC extension. */
4217 if (!(allow_gcc && nt == STRUCT))
4218 goto invalid_cast;
4219 } else if (is_struct_or_union(ot))
4220 goto invalid_cast;
4221 else if (ot == VOID) {
4222 /* improper cast of void expression */
4223 error(148);
4224 return NULL;
4225 } else if (is_integer(nt) && is_scalar(ot)) {
4226 tn = null_pointer_offset(tn);
4227 } else if (is_floating(nt) && is_arithmetic(ot)) {
4228 /* ok */
4229 } else if (nt == PTR && is_integer(ot)) {
4230 /* ok */
4231 } else if (nt == PTR && ot == PTR) {
4232 if (!tp->t_subt->t_const && tn->tn_type->t_subt->t_const) {
4233 if (hflag)
4234 /* cast discards 'const' from type '%s' */
4235 warning(275, type_name(tn->tn_type));
4236 }
4237 } else
4238 goto invalid_cast;
4239
4240 if (any_query_enabled
4241 && types_compatible(tp, tn->tn_type, false, false, NULL))
4242 /* no-op cast from '%s' to '%s' */
4243 query_message(6, type_name(tn->tn_type), type_name(tp));
4244
4245 tn = convert(CVT, 0, tp, tn);
4246 tn->tn_cast = true;
4247 tn->tn_sys = sys;
4248
4249 return tn;
4250
4251 invalid_cast:
4252 /* invalid cast from '%s' to '%s' */
4253 error(147, type_name(tn->tn_type), type_name(tp));
4254 return NULL;
4255 }
4256
4257 void
4258 add_function_argument(function_call *call, tnode_t *arg)
4259 {
4260 /*
4261 * If there was a serious error in the expression for the argument,
4262 * create a dummy argument so the positions of the remaining arguments
4263 * will not change.
4264 */
4265 if (arg == NULL)
4266 arg = build_integer_constant(INT, 0);
4267
4268 if (call->args_len >= call->args_cap) {
4269 call->args_cap += 8;
4270 tnode_t **new_args = expr_zero_alloc(
4271 call->args_cap * sizeof(*call->args), "tnode*[]");
4272 if (call->args_len > 0)
4273 memcpy(new_args, call->args,
4274 call->args_len * sizeof(*call->args));
4275 call->args = new_args;
4276 }
4277 call->args[call->args_len++] = arg;
4278 }
4279
4280 /*
4281 * Compare the type of an argument with the corresponding type of a
4282 * prototype parameter. If it is a valid combination, but both types
4283 * are not the same, insert a conversion to convert the argument into
4284 * the type of the parameter.
4285 */
4286 static tnode_t *
4287 check_prototype_argument(
4288 int n, /* pos of arg */
4289 type_t *tp, /* expected type (from prototype) */
4290 tnode_t *tn) /* argument */
4291 {
4292 tnode_t *ln = xcalloc(1, sizeof(*ln));
4293 ln->tn_type = expr_unqualified_type(tp);
4294 ln->tn_lvalue = true;
4295 if (typeok(FARG, n, ln, tn)) {
4296 bool dowarn;
4297 if (!types_compatible(tp, tn->tn_type,
4298 true, false, (dowarn = false, &dowarn)) || dowarn)
4299 tn = convert(FARG, n, tp, tn);
4300 }
4301 free(ln);
4302 return tn;
4303 }
4304
4305 /*
4306 * Check types of all function arguments and insert conversions,
4307 * if necessary.
4308 */
4309 static void
4310 check_function_arguments(const function_call *call)
4311 {
4312 type_t *ftp = call->func->tn_type->t_subt;
4313
4314 /* get # of parameters in the prototype */
4315 int npar = 0;
4316 for (const sym_t *p = ftp->u.params; p != NULL; p = p->s_next)
4317 npar++;
4318
4319 int narg = (int)call->args_len;
4320
4321 const sym_t *param = ftp->u.params;
4322 if (ftp->t_proto && npar != narg && !(ftp->t_vararg && npar < narg)) {
4323 /* argument mismatch: %d %s passed, %d expected */
4324 error(150, narg, narg != 1 ? "arguments" : "argument", npar);
4325 param = NULL;
4326 }
4327
4328 for (int i = 0; i < narg; i++) {
4329 tnode_t *arg = call->args[i];
4330
4331 /* some things which are always not allowed */
4332 tspec_t at = arg->tn_type->t_tspec;
4333 if (at == VOID) {
4334 /* void expressions may not be arguments, arg #%d */
4335 error(151, i + 1);
4336 return;
4337 }
4338 if (is_struct_or_union(at) && is_incomplete(arg->tn_type)) {
4339 /* argument cannot have unknown size, arg #%d */
4340 error(152, i + 1);
4341 return;
4342 }
4343 if (is_integer(at) &&
4344 arg->tn_type->t_is_enum &&
4345 is_incomplete(arg->tn_type)) {
4346 /* argument cannot have unknown size, arg #%d */
4347 warning(152, i + 1);
4348 }
4349
4350 arg = cconv(arg);
4351 call->args[i] = arg;
4352
4353 arg = param != NULL
4354 ? check_prototype_argument(i + 1, param->s_type, arg)
4355 : promote(NOOP, true, arg);
4356 call->args[i] = arg;
4357
4358 if (param != NULL)
4359 param = param->s_next;
4360 }
4361 }
4362
4363 tnode_t *
4364 build_function_call(tnode_t *func, bool sys, function_call *call)
4365 {
4366
4367 if (func == NULL)
4368 return NULL;
4369
4370 call->func = func;
4371 check_ctype_function_call(call);
4372
4373 func = cconv(func);
4374 call->func = func;
4375
4376 if (func->tn_type->t_tspec != PTR ||
4377 func->tn_type->t_subt->t_tspec != FUNC) {
4378 /* cannot call '%s', must be a function */
4379 error(149, type_name(func->tn_type));
4380 return NULL;
4381 }
4382
4383 check_function_arguments(call);
4384
4385 tnode_t *ntn = expr_alloc_tnode();
4386 ntn->tn_op = CALL;
4387 ntn->tn_type = func->tn_type->t_subt->t_subt;
4388 ntn->tn_sys = sys;
4389 ntn->u.call = call;
4390 return ntn;
4391 }
4392
4393 /*
4394 * Return the value of an integral constant expression.
4395 * If the expression is not constant or its type is not an integer
4396 * type, an error message is printed.
4397 */
4398 val_t *
4399 integer_constant(tnode_t *tn, bool required)
4400 {
4401
4402 if (tn != NULL)
4403 tn = cconv(tn);
4404 if (tn != NULL)
4405 tn = promote(NOOP, false, tn);
4406
4407 val_t *v = xcalloc(1, sizeof(*v));
4408
4409 if (tn == NULL) {
4410 lint_assert(seen_error);
4411 debug_step("constant node is null; returning 1 instead");
4412 v->v_tspec = INT;
4413 v->u.integer = 1;
4414 return v;
4415 }
4416
4417 v->v_tspec = tn->tn_type->t_tspec;
4418
4419 if (tn->tn_op == CON) {
4420 lint_assert(tn->tn_type->t_tspec == tn->u.value.v_tspec);
4421 if (is_integer(tn->u.value.v_tspec)) {
4422 v->v_unsigned_since_c90 =
4423 tn->u.value.v_unsigned_since_c90;
4424 v->u.integer = tn->u.value.u.integer;
4425 return v;
4426 }
4427 v->u.integer = (int64_t)tn->u.value.u.floating;
4428 } else
4429 v->u.integer = 1;
4430
4431 if (required)
4432 /* integral constant expression expected */
4433 error(55);
4434 else
4435 /* variable array dimension is a C99/GCC extension */
4436 c99ism(318);
4437
4438 if (!is_integer(v->v_tspec))
4439 v->v_tspec = INT;
4440
4441 return v;
4442 }
4443
4444 static bool
4445 is_constcond_false(const tnode_t *tn, tspec_t t)
4446 {
4447 return (t == BOOL || t == INT) &&
4448 tn->tn_op == CON && tn->u.value.u.integer == 0;
4449 }
4450
4451 /*
4452 * Perform some tests on expressions which can't be done in build_binary()
4453 * and functions called by build_binary(). These tests must be done here
4454 * because we need some information about the context in which the operations
4455 * are performed.
4456 * After all tests are performed and dofreeblk is true, expr() frees the
4457 * memory which is used for the expression.
4458 */
4459 void
4460 expr(tnode_t *tn, bool vctx, bool cond, bool dofreeblk, bool is_do_while)
4461 {
4462
4463 if (tn == NULL) { /* in case of errors */
4464 expr_free_all();
4465 return;
4466 }
4467
4468 /* expr() is also called in global initializations */
4469 if (dcs->d_kind != DLK_EXTERN && !is_do_while)
4470 check_statement_reachable();
4471
4472 check_expr_misc(tn, vctx, cond, !cond, false, false, false);
4473 if (tn->tn_op == ASSIGN && !tn->tn_parenthesized) {
4474 if (hflag && cond)
4475 /* assignment in conditional context */
4476 warning(159);
4477 } else if (tn->tn_op == CON) {
4478 if (hflag && cond && !suppress_constcond &&
4479 !tn->tn_system_dependent &&
4480 !(is_do_while &&
4481 is_constcond_false(tn, tn->tn_type->t_tspec)))
4482 /* constant in conditional context */
4483 warning(161);
4484 }
4485 if (!modtab[tn->tn_op].m_has_side_effect) {
4486 /*
4487 * for left operands of COMMA this warning is already printed
4488 */
4489 if (tn->tn_op != COMMA && !vctx && !cond)
4490 check_null_effect(tn);
4491 }
4492 debug_node(tn);
4493
4494 if (dofreeblk)
4495 expr_free_all();
4496 }
4497
4498 /* If the expression has the form '*(arr + idx)', check the array index. */
4499 static void
4500 check_array_index(const tnode_t *indir, bool taking_address)
4501 {
4502 const tnode_t *plus, *arr, *idx;
4503
4504 if (indir->tn_op == INDIR
4505 && (plus = indir->u.ops.left, plus->tn_op == PLUS)
4506 && plus->u.ops.left->tn_op == ADDR
4507 && (arr = plus->u.ops.left->u.ops.left, true)
4508 && (arr->tn_op == STRING || arr->tn_op == NAME)
4509 && arr->tn_type->t_tspec == ARRAY
4510 && (idx = plus->u.ops.right, idx->tn_op == CON)
4511 && (!is_incomplete(arr->tn_type) || idx->u.value.u.integer < 0))
4512 goto proceed;
4513 return;
4514
4515 proceed:;
4516 int elsz = length_in_bits(arr->tn_type->t_subt, NULL);
4517 if (elsz == 0)
4518 return;
4519 elsz /= CHAR_SIZE;
4520
4521 /* Change the unit of the index from bytes to element size. */
4522 int64_t con = is_uinteger(idx->tn_type->t_tspec)
4523 ? (int64_t)((uint64_t)idx->u.value.u.integer / elsz)
4524 : idx->u.value.u.integer / elsz;
4525
4526 int dim = arr->tn_type->u.dimension + (taking_address ? 1 : 0);
4527
4528 if (!is_uinteger(idx->tn_type->t_tspec) && con < 0)
4529 /* array subscript %jd cannot be negative */
4530 warning(167, (intmax_t)con);
4531 else if (dim > 0 && (uint64_t)con >= (uint64_t)dim)
4532 /* array subscript %ju cannot be > %d */
4533 warning(168, (uintmax_t)con, dim - 1);
4534 }
4535
4536 static void
4537 check_expr_addr(const tnode_t *ln, bool szof, bool fcall)
4538 {
4539 /* XXX: Taking warn_about_unreachable into account here feels wrong. */
4540 if (ln->tn_op == NAME && (reached || !warn_about_unreachable)) {
4541 if (!szof)
4542 mark_as_set(ln->u.sym);
4543 mark_as_used(ln->u.sym, fcall, szof);
4544 }
4545 check_array_index(ln, true);
4546 }
4547
4548 /*
4549 * If there is an asm statement in one of the compound statements around,
4550 * there may be other side effects, so don't warn.
4551 */
4552 static bool
4553 is_asm_around(void)
4554 {
4555 for (decl_level *dl = dcs; dl != NULL; dl = dl->d_enclosing)
4556 if (dl->d_asm)
4557 return true;
4558 return false;
4559 }
4560
4561 static void
4562 check_expr_side_effect(const tnode_t *ln, bool szof)
4563 {
4564
4565 /* XXX: Taking warn_about_unreachable into account here feels wrong. */
4566 if (ln->tn_op == NAME && (reached || !warn_about_unreachable)) {
4567 scl_t sc = ln->u.sym->s_scl;
4568 if (sc != EXTERN && sc != STATIC &&
4569 !ln->u.sym->s_set && !szof && !is_asm_around()) {
4570 /* '%s' may be used before set */
4571 warning(158, ln->u.sym->s_name);
4572 mark_as_set(ln->u.sym);
4573 }
4574 mark_as_used(ln->u.sym, false, false);
4575 }
4576 }
4577
4578 static void
4579 check_expr_assign(const tnode_t *ln, bool szof)
4580 {
4581 /* XXX: Taking warn_about_unreachable into account here feels wrong. */
4582 if (ln->tn_op == NAME && !szof && (reached || !warn_about_unreachable)) {
4583 mark_as_set(ln->u.sym);
4584 if (ln->u.sym->s_scl == EXTERN)
4585 outusg(ln->u.sym);
4586 }
4587 check_array_index(ln, false);
4588 }
4589
4590 static void
4591 check_expr_call(const tnode_t *tn, const tnode_t *ln,
4592 bool szof, bool vctx, bool cond, bool retval_discarded)
4593 {
4594 lint_assert(ln->tn_op == ADDR);
4595 lint_assert(ln->u.ops.left->tn_op == NAME);
4596 if (!szof && !is_compiler_builtin(ln->u.ops.left->u.sym->s_name))
4597 outcall(tn, vctx || cond, retval_discarded);
4598
4599 const function_call *call = tn->u.call;
4600 if (call->args_len == 4 || call->args_len == 5)
4601 check_snprintb(call);
4602 }
4603
4604 static void
4605 check_expr_op(op_t op, const tnode_t *ln, bool szof, bool fcall, bool eqwarn)
4606 {
4607 switch (op) {
4608 case ADDR:
4609 check_expr_addr(ln, szof, fcall);
4610 break;
4611 case LOAD:
4612 check_array_index(ln, false);
4613 /* FALLTHROUGH */
4614 case INCBEF:
4615 case DECBEF:
4616 case INCAFT:
4617 case DECAFT:
4618 case ADDASS:
4619 case SUBASS:
4620 case MULASS:
4621 case DIVASS:
4622 case MODASS:
4623 case ANDASS:
4624 case ORASS:
4625 case XORASS:
4626 case SHLASS:
4627 case SHRASS:
4628 case REAL:
4629 case IMAG:
4630 check_expr_side_effect(ln, szof);
4631 break;
4632 case ASSIGN:
4633 check_expr_assign(ln, szof);
4634 break;
4635 case EQ:
4636 if (hflag && eqwarn)
4637 /* operator '==' found where '=' was expected */
4638 warning(160);
4639 break;
4640 default:
4641 break;
4642 }
4643 }
4644
4645 /*
4646 * vctx ???
4647 * cond whether the expression is a condition that
4648 * will be compared with 0
4649 * eqwarn whether the operator '==' might be a
4650 * misspelled '='
4651 * fcall whether the expression is a function call
4652 * retval_discarded whether the return value of a function call
4653 * is discarded; such calls will be analyzed by
4654 * lint2 in messages 4, 8 and 9
4655 * szof whether the expression is part of a sizeof
4656 * expression, which means that its value is
4657 * discarded since only the type is relevant
4658 */
4659 void
4660 check_expr_misc(const tnode_t *tn, bool vctx, bool cond,
4661 bool eqwarn, bool fcall, bool retval_discarded, bool szof)
4662 {
4663
4664 if (tn == NULL)
4665 return;
4666 op_t op = tn->tn_op;
4667 if (op == NAME || op == CON || op == STRING)
4668 return;
4669 bool is_direct = op == CALL
4670 && tn->u.call->func->tn_op == ADDR
4671 && tn->u.call->func->u.ops.left->tn_op == NAME;
4672 if (op == CALL) {
4673 const function_call *call = tn->u.call;
4674 if (is_direct)
4675 check_expr_call(tn, call->func,
4676 szof, vctx, cond, retval_discarded);
4677 bool discard = op == CVT && tn->tn_type->t_tspec == VOID;
4678 check_expr_misc(call->func, false, false, false, is_direct,
4679 discard, szof);
4680 for (size_t i = 0, n = call->args_len; i < n; i++)
4681 check_expr_misc(call->args[i],
4682 true, false, false, false, false, szof);
4683 return;
4684 }
4685
4686 lint_assert(has_operands(tn));
4687 tnode_t *ln = tn->u.ops.left;
4688 tnode_t *rn = tn->u.ops.right;
4689 check_expr_op(op, ln, szof, fcall, eqwarn);
4690
4691 const mod_t *mp = &modtab[op];
4692 bool cvctx = mp->m_value_context;
4693 bool ccond = mp->m_compares_with_zero;
4694 bool eq = mp->m_warn_if_operand_eq &&
4695 !ln->tn_parenthesized &&
4696 rn != NULL && !rn->tn_parenthesized;
4697
4698 /*
4699 * Values of operands of ':' are not used if the type of at least
4700 * one of the operands (for GCC compatibility) is 'void'.
4701 *
4702 * XXX test/value context of QUEST should probably be used as
4703 * context for both operands of COLON.
4704 */
4705 if (op == COLON && tn->tn_type->t_tspec == VOID)
4706 cvctx = ccond = false;
4707 bool discard = op == CVT && tn->tn_type->t_tspec == VOID;
4708 check_expr_misc(ln, cvctx, ccond, eq, is_direct, discard, szof);
4709
4710 switch (op) {
4711 case LOGAND:
4712 case LOGOR:
4713 check_expr_misc(rn, false, true, eq, false, false, szof);
4714 break;
4715 case COLON:
4716 check_expr_misc(rn, cvctx, ccond, eq, false, false, szof);
4717 break;
4718 case COMMA:
4719 check_expr_misc(rn, vctx, cond, false, false, false, szof);
4720 break;
4721 default:
4722 if (mp->m_binary)
4723 check_expr_misc(rn, true, false, eq, false, false,
4724 szof);
4725 break;
4726 }
4727 }
4728
4729 /*
4730 * Return whether the expression can be used for static initialization.
4731 *
4732 * Constant initialization expressions must be constant or an address
4733 * of a static object with an optional offset. In the first case,
4734 * the result is returned in *offsp. In the second case, the static
4735 * object is returned in *symp and the offset in *offsp.
4736 *
4737 * The expression can consist of PLUS, MINUS, ADDR, NAME, STRING and
4738 * CON. Type conversions are allowed if they do not change binary
4739 * representation (including width).
4740 *
4741 * C99 6.6 "Constant expressions"
4742 * C99 6.7.8p4 restricts initializers for static storage duration
4743 */
4744 bool
4745 constant_addr(const tnode_t *tn, const sym_t **symp, ptrdiff_t *offsp)
4746 {
4747 const sym_t *sym;
4748 ptrdiff_t offs1, offs2;
4749 tspec_t t, ot;
4750
4751 switch (tn->tn_op) {
4752 case MINUS:
4753 if (tn->u.ops.right->tn_op == CVT)
4754 return constant_addr(tn->u.ops.right, symp, offsp);
4755 else if (tn->u.ops.right->tn_op != CON)
4756 return false;
4757 /* FALLTHROUGH */
4758 case PLUS:
4759 offs1 = offs2 = 0;
4760 if (tn->u.ops.left->tn_op == CON) {
4761 offs1 = (ptrdiff_t)tn->u.ops.left->u.value.u.integer;
4762 if (!constant_addr(tn->u.ops.right, &sym, &offs2))
4763 return false;
4764 } else if (tn->u.ops.right->tn_op == CON) {
4765 offs2 = (ptrdiff_t)tn->u.ops.right->u.value.u.integer;
4766 if (tn->tn_op == MINUS)
4767 offs2 = -offs2;
4768 if (!constant_addr(tn->u.ops.left, &sym, &offs1))
4769 return false;
4770 } else {
4771 return false;
4772 }
4773 *symp = sym;
4774 *offsp = offs1 + offs2;
4775 return true;
4776 case ADDR:
4777 if (tn->u.ops.left->tn_op == NAME) {
4778 *symp = tn->u.ops.left->u.sym;
4779 *offsp = 0;
4780 return true;
4781 } else {
4782 /*
4783 * If this were the front end of a compiler, we would
4784 * return a label instead of 0, at least if
4785 * 'tn->u.ops.left->tn_op == STRING'.
4786 */
4787 *symp = NULL;
4788 *offsp = 0;
4789 return true;
4790 }
4791 case CVT:
4792 t = tn->tn_type->t_tspec;
4793 ot = tn->u.ops.left->tn_type->t_tspec;
4794 if ((!is_integer(t) && t != PTR) ||
4795 (!is_integer(ot) && ot != PTR)) {
4796 return false;
4797 }
4798 #if 0
4799 /*-
4800 * consider:
4801 * struct foo {
4802 * unsigned char a;
4803 * } f = {
4804 * (unsigned char)(unsigned long)
4805 * (&(((struct foo *)0)->a))
4806 * };
4807 * since psize(unsigned long) != psize(unsigned char),
4808 * this fails.
4809 */
4810 else if (psize(t) != psize(ot))
4811 return -1;
4812 #endif
4813 return constant_addr(tn->u.ops.left, symp, offsp);
4814 default:
4815 return false;
4816 }
4817 }
4818
4819 /* Append s2 to s1, then free s2. */
4820 buffer *
4821 cat_strings(buffer *s1, buffer *s2)
4822 {
4823
4824 if ((s1->data != NULL) != (s2->data != NULL)) {
4825 /* cannot concatenate wide and regular string literals */
4826 error(292);
4827 return s1;
4828 }
4829
4830 if (s1->data != NULL) {
4831 while (s1->len + s2->len + 1 > s1->cap)
4832 s1->cap *= 2;
4833 s1->data = xrealloc(s1->data, s1->cap);
4834 memcpy(s1->data + s1->len, s2->data, s2->len + 1);
4835 free(s2->data);
4836 }
4837 s1->len += s2->len;
4838 free(s2);
4839
4840 return s1;
4841 }
4842
4843
4844 typedef struct stmt_expr {
4845 memory_pool se_mem;
4846 sym_t *se_sym;
4847 struct stmt_expr *se_enclosing;
4848 } stmt_expr;
4849
4850 static stmt_expr *stmt_exprs;
4851
4852 void
4853 begin_statement_expr(void)
4854 {
4855 debug_enter();
4856
4857 stmt_expr *se = xmalloc(sizeof(*se));
4858 se->se_mem = expr_save_memory();
4859 se->se_sym = NULL;
4860 se->se_enclosing = stmt_exprs;
4861 stmt_exprs = se;
4862 }
4863
4864 void
4865 do_statement_expr(tnode_t *tn)
4866 {
4867 block_level--;
4868 mem_block_level--;
4869 stmt_exprs->se_sym = tn != NULL
4870 ? mktempsym(block_dup_type(tn->tn_type))
4871 : NULL; /* after a syntax error */
4872 mem_block_level++;
4873 block_level++;
4874 /* '({ ... })' is a GCC extension */
4875 gnuism(320);
4876 }
4877
4878 tnode_t *
4879 end_statement_expr(void)
4880 {
4881 tnode_t *tn;
4882
4883 stmt_expr *se = stmt_exprs;
4884 if (se->se_sym == NULL) {
4885 tn = NULL; /* after a syntax error */
4886 goto end;
4887 }
4888
4889 tn = build_name(se->se_sym, false);
4890 (void)expr_save_memory(); /* leak */
4891 expr_restore_memory(se->se_mem);
4892 stmt_exprs = se->se_enclosing;
4893 free(se);
4894
4895 end:
4896 debug_leave();
4897 return tn;
4898 }
4899
4900 bool
4901 in_statement_expr(void)
4902 {
4903 return stmt_exprs != NULL;
4904 }
4905