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