Fri Apr 14 18:42:31 2023 UTC ()
lint: document suppressed LDBL_MAX warning more accurately

The crucial point is not that lint is cross-compiled but that tools/lint
is run on the usr.bin/xlint code, and in that situation, the platform
mismatch happens.


(rillig)
diff -r1.512 -r1.513 src/usr.bin/xlint/lint1/tree.c

cvs diff -r1.512 -r1.513 src/usr.bin/xlint/lint1/tree.c (switch to unified diff)

--- src/usr.bin/xlint/lint1/tree.c 2023/04/12 19:09:48 1.512
+++ src/usr.bin/xlint/lint1/tree.c 2023/04/14 18:42:31 1.513
@@ -1,2521 +1,2524 @@ @@ -1,2521 +1,2524 @@
1/* $NetBSD: tree.c,v 1.512 2023/04/12 19:09:48 rillig Exp $ */ 1/* $NetBSD: tree.c,v 1.513 2023/04/14 18:42:31 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1994, 1995 Jochen Pohl 4 * Copyright (c) 1994, 1995 Jochen Pohl
5 * All Rights Reserved. 5 * All Rights Reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement: 16 * must display the following acknowledgement:
17 * This product includes software developed by Jochen Pohl for 17 * This product includes software developed by Jochen Pohl for
18 * The NetBSD Project. 18 * The NetBSD Project.
19 * 4. The name of the author may not be used to endorse or promote products 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. 20 * derived from this software without specific prior written permission.
21 * 21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 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 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 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 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 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 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. 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34#if HAVE_NBTOOL_CONFIG_H 34#if HAVE_NBTOOL_CONFIG_H
35#include "nbtool_config.h" 35#include "nbtool_config.h"
36#endif 36#endif
37 37
38#include <sys/cdefs.h> 38#include <sys/cdefs.h>
39#if defined(__RCSID) 39#if defined(__RCSID)
40__RCSID("$NetBSD: tree.c,v 1.512 2023/04/12 19:09:48 rillig Exp $"); 40__RCSID("$NetBSD: tree.c,v 1.513 2023/04/14 18:42:31 rillig Exp $");
41#endif 41#endif
42 42
43#include <float.h> 43#include <float.h>
44#include <limits.h> 44#include <limits.h>
45#include <math.h> 45#include <math.h>
46#include <signal.h> 46#include <signal.h>
47#include <stdlib.h> 47#include <stdlib.h>
48#include <string.h> 48#include <string.h>
49 49
50#include "lint1.h" 50#include "lint1.h"
51 51
52 52
53typedef struct integer_constraints { 53typedef struct integer_constraints {
54 int64_t smin; /* signed minimum */ 54 int64_t smin; /* signed minimum */
55 int64_t smax; /* signed maximum */ 55 int64_t smax; /* signed maximum */
56 uint64_t umin; /* unsigned minimum */ 56 uint64_t umin; /* unsigned minimum */
57 uint64_t umax; /* unsigned maximum */ 57 uint64_t umax; /* unsigned maximum */
58 uint64_t bset; /* bits that are definitely set */ 58 uint64_t bset; /* bits that are definitely set */
59 uint64_t bclr; /* bits that are definitely clear */ 59 uint64_t bclr; /* bits that are definitely clear */
60} integer_constraints; 60} integer_constraints;
61 61
62 62
63static uint64_t 63static uint64_t
64u64_fill_right(uint64_t x) 64u64_fill_right(uint64_t x)
65{ 65{
66 x |= x >> 1; 66 x |= x >> 1;
67 x |= x >> 2; 67 x |= x >> 2;
68 x |= x >> 4; 68 x |= x >> 4;
69 x |= x >> 8; 69 x |= x >> 8;
70 x |= x >> 16; 70 x |= x >> 16;
71 x |= x >> 32; 71 x |= x >> 32;
72 return x; 72 return x;
73} 73}
74 74
75static bool 75static bool
76str_endswith(const char *haystack, const char *needle) 76str_endswith(const char *haystack, const char *needle)
77{ 77{
78 size_t hlen = strlen(haystack); 78 size_t hlen = strlen(haystack);
79 size_t nlen = strlen(needle); 79 size_t nlen = strlen(needle);
80 80
81 return nlen <= hlen && 81 return nlen <= hlen &&
82 memcmp(haystack + hlen - nlen, needle, nlen) == 0; 82 memcmp(haystack + hlen - nlen, needle, nlen) == 0;
83} 83}
84static const char * 84static const char *
85op_name(op_t op) 85op_name(op_t op)
86{ 86{
87 return modtab[op].m_name; 87 return modtab[op].m_name;
88} 88}
89 89
90static unsigned 90static unsigned
91width_in_bits(const type_t *tp) 91width_in_bits(const type_t *tp)
92{ 92{
93 93
94 lint_assert(is_integer(tp->t_tspec)); 94 lint_assert(is_integer(tp->t_tspec));
95 return tp->t_bitfield ? tp->t_flen : size_in_bits(tp->t_tspec); 95 return tp->t_bitfield ? tp->t_flen : size_in_bits(tp->t_tspec);
96} 96}
97 97
98static bool 98static bool
99ic_maybe_signed(const type_t *tp, const integer_constraints *ic) 99ic_maybe_signed(const type_t *tp, const integer_constraints *ic)
100{ 100{
101 101
102 return !is_uinteger(tp->t_tspec) && 102 return !is_uinteger(tp->t_tspec) &&
103 (ic->bclr & ((uint64_t)1 << 63)) == 0; 103 (ic->bclr & ((uint64_t)1 << 63)) == 0;
104} 104}
105 105
106static integer_constraints 106static integer_constraints
107ic_any(const type_t *tp) 107ic_any(const type_t *tp)
108{ 108{
109 integer_constraints c; 109 integer_constraints c;
110 110
111 uint64_t vbits = value_bits(width_in_bits(tp)); 111 uint64_t vbits = value_bits(width_in_bits(tp));
112 if (is_uinteger(tp->t_tspec)) { 112 if (is_uinteger(tp->t_tspec)) {
113 c.smin = INT64_MIN; 113 c.smin = INT64_MIN;
114 c.smax = INT64_MAX; 114 c.smax = INT64_MAX;
115 c.umin = 0; 115 c.umin = 0;
116 c.umax = vbits; 116 c.umax = vbits;
117 c.bset = 0; 117 c.bset = 0;
118 c.bclr = ~c.umax; 118 c.bclr = ~c.umax;
119 } else { 119 } else {
120 c.smin = (int64_t)-1 - (int64_t)(vbits >> 1); 120 c.smin = (int64_t)-1 - (int64_t)(vbits >> 1);
121 c.smax = (int64_t)(vbits >> 1); 121 c.smax = (int64_t)(vbits >> 1);
122 c.umin = 0; 122 c.umin = 0;
123 c.umax = UINT64_MAX; 123 c.umax = UINT64_MAX;
124 c.bset = 0; 124 c.bset = 0;
125 c.bclr = 0; 125 c.bclr = 0;
126 } 126 }
127 return c; 127 return c;
128} 128}
129 129
130static integer_constraints 130static integer_constraints
131ic_con(const type_t *tp, const val_t *v) 131ic_con(const type_t *tp, const val_t *v)
132{ 132{
133 integer_constraints c; 133 integer_constraints c;
134 134
135 lint_assert(is_integer(tp->t_tspec)); 135 lint_assert(is_integer(tp->t_tspec));
136 int64_t s = v->v_quad; 136 int64_t s = v->v_quad;
137 uint64_t u = (uint64_t)s; 137 uint64_t u = (uint64_t)s;
138 c.smin = s; 138 c.smin = s;
139 c.smax = s; 139 c.smax = s;
140 c.umin = u; 140 c.umin = u;
141 c.umax = u; 141 c.umax = u;
142 c.bset = u; 142 c.bset = u;
143 c.bclr = ~u; 143 c.bclr = ~u;
144 return c; 144 return c;
145} 145}
146 146
147static integer_constraints 147static integer_constraints
148ic_cvt(const type_t *ntp, const type_t *otp, integer_constraints a) 148ic_cvt(const type_t *ntp, const type_t *otp, integer_constraints a)
149{ 149{
150 150
151 if (width_in_bits(ntp) > width_in_bits(otp) && 151 if (width_in_bits(ntp) > width_in_bits(otp) &&
152 is_uinteger(otp->t_tspec)) 152 is_uinteger(otp->t_tspec))
153 return a; 153 return a;
154 return ic_any(ntp); 154 return ic_any(ntp);
155} 155}
156 156
157static integer_constraints 157static integer_constraints
158ic_bitand(integer_constraints a, integer_constraints b) 158ic_bitand(integer_constraints a, integer_constraints b)
159{ 159{
160 integer_constraints c; 160 integer_constraints c;
161 161
162 c.smin = INT64_MIN; 162 c.smin = INT64_MIN;
163 c.smax = INT64_MAX; 163 c.smax = INT64_MAX;
164 c.umin = 0; 164 c.umin = 0;
165 c.umax = UINT64_MAX; 165 c.umax = UINT64_MAX;
166 c.bset = a.bset & b.bset; 166 c.bset = a.bset & b.bset;
167 c.bclr = a.bclr | b.bclr; 167 c.bclr = a.bclr | b.bclr;
168 return c; 168 return c;
169} 169}
170 170
171static integer_constraints 171static integer_constraints
172ic_bitor(integer_constraints a, integer_constraints b) 172ic_bitor(integer_constraints a, integer_constraints b)
173{ 173{
174 integer_constraints c; 174 integer_constraints c;
175 175
176 c.smin = INT64_MIN; 176 c.smin = INT64_MIN;
177 c.smax = INT64_MAX; 177 c.smax = INT64_MAX;
178 c.umin = 0; 178 c.umin = 0;
179 c.umax = UINT64_MAX; 179 c.umax = UINT64_MAX;
180 c.bset = a.bset | b.bset; 180 c.bset = a.bset | b.bset;
181 c.bclr = a.bclr & b.bclr; 181 c.bclr = a.bclr & b.bclr;
182 return c; 182 return c;
183} 183}
184 184
185static integer_constraints 185static integer_constraints
186ic_mod(const type_t *tp, integer_constraints a, integer_constraints b) 186ic_mod(const type_t *tp, integer_constraints a, integer_constraints b)
187{ 187{
188 integer_constraints c; 188 integer_constraints c;
189 189
190 if (ic_maybe_signed(tp, &a) || ic_maybe_signed(tp, &b)) 190 if (ic_maybe_signed(tp, &a) || ic_maybe_signed(tp, &b))
191 return ic_any(tp); 191 return ic_any(tp);
192 192
193 c.smin = INT64_MIN; 193 c.smin = INT64_MIN;
194 c.smax = INT64_MAX; 194 c.smax = INT64_MAX;
195 c.umin = 0; 195 c.umin = 0;
196 c.umax = b.umax - 1; 196 c.umax = b.umax - 1;
197 c.bset = 0; 197 c.bset = 0;
198 c.bclr = ~u64_fill_right(c.umax); 198 c.bclr = ~u64_fill_right(c.umax);
199 return c; 199 return c;
200} 200}
201 201
202static integer_constraints 202static integer_constraints
203ic_shl(const type_t *tp, integer_constraints a, integer_constraints b) 203ic_shl(const type_t *tp, integer_constraints a, integer_constraints b)
204{ 204{
205 integer_constraints c; 205 integer_constraints c;
206 unsigned int amount; 206 unsigned int amount;
207 207
208 if (ic_maybe_signed(tp, &a)) 208 if (ic_maybe_signed(tp, &a))
209 return ic_any(tp); 209 return ic_any(tp);
210 210
211 if (b.smin == b.smax && b.smin >= 0 && b.smin < 64) 211 if (b.smin == b.smax && b.smin >= 0 && b.smin < 64)
212 amount = (unsigned int)b.smin; 212 amount = (unsigned int)b.smin;
213 else if (b.umin == b.umax && b.umin < 64) 213 else if (b.umin == b.umax && b.umin < 64)
214 amount = (unsigned int)b.umin; 214 amount = (unsigned int)b.umin;
215 else 215 else
216 return ic_any(tp); 216 return ic_any(tp);
217 217
218 c.smin = INT64_MIN; 218 c.smin = INT64_MIN;
219 c.smax = INT64_MAX; 219 c.smax = INT64_MAX;
220 c.umin = 0; 220 c.umin = 0;
221 c.umax = UINT64_MAX; 221 c.umax = UINT64_MAX;
222 c.bset = a.bset << amount; 222 c.bset = a.bset << amount;
223 c.bclr = a.bclr << amount | (((uint64_t)1 << amount) - 1); 223 c.bclr = a.bclr << amount | (((uint64_t)1 << amount) - 1);
224 return c; 224 return c;
225} 225}
226 226
227static integer_constraints 227static integer_constraints
228ic_shr(const type_t *tp, integer_constraints a, integer_constraints b) 228ic_shr(const type_t *tp, integer_constraints a, integer_constraints b)
229{ 229{
230 integer_constraints c; 230 integer_constraints c;
231 unsigned int amount; 231 unsigned int amount;
232 232
233 if (ic_maybe_signed(tp, &a)) 233 if (ic_maybe_signed(tp, &a))
234 return ic_any(tp); 234 return ic_any(tp);
235 235
236 if (b.smin == b.smax && b.smin >= 0 && b.smin < 64) 236 if (b.smin == b.smax && b.smin >= 0 && b.smin < 64)
237 amount = (unsigned int)b.smin; 237 amount = (unsigned int)b.smin;
238 else if (b.umin == b.umax && b.umin < 64) 238 else if (b.umin == b.umax && b.umin < 64)
239 amount = (unsigned int)b.umin; 239 amount = (unsigned int)b.umin;
240 else 240 else
241 return ic_any(tp); 241 return ic_any(tp);
242 242
243 c.smin = INT64_MIN; 243 c.smin = INT64_MIN;
244 c.smax = INT64_MAX; 244 c.smax = INT64_MAX;
245 c.umin = 0; 245 c.umin = 0;
246 c.umax = UINT64_MAX; 246 c.umax = UINT64_MAX;
247 c.bset = a.bset >> amount; 247 c.bset = a.bset >> amount;
248 c.bclr = a.bclr >> amount | ~(~(uint64_t)0 >> amount); 248 c.bclr = a.bclr >> amount | ~(~(uint64_t)0 >> amount);
249 return c; 249 return c;
250} 250}
251 251
252static integer_constraints 252static integer_constraints
253ic_expr(const tnode_t *tn) 253ic_expr(const tnode_t *tn)
254{ 254{
255 integer_constraints lc, rc; 255 integer_constraints lc, rc;
256 256
257 lint_assert(is_integer(tn->tn_type->t_tspec)); 257 lint_assert(is_integer(tn->tn_type->t_tspec));
258 258
259 switch (tn->tn_op) { 259 switch (tn->tn_op) {
260 case CON: 260 case CON:
261 return ic_con(tn->tn_type, tn->tn_val); 261 return ic_con(tn->tn_type, tn->tn_val);
262 case CVT: 262 case CVT:
263 if (!is_integer(tn->tn_left->tn_type->t_tspec)) 263 if (!is_integer(tn->tn_left->tn_type->t_tspec))
264 return ic_any(tn->tn_type); 264 return ic_any(tn->tn_type);
265 lc = ic_expr(tn->tn_left); 265 lc = ic_expr(tn->tn_left);
266 return ic_cvt(tn->tn_type, tn->tn_left->tn_type, lc); 266 return ic_cvt(tn->tn_type, tn->tn_left->tn_type, lc);
267 case MOD: 267 case MOD:
268 lc = ic_expr(before_conversion(tn->tn_left)); 268 lc = ic_expr(before_conversion(tn->tn_left));
269 rc = ic_expr(before_conversion(tn->tn_right)); 269 rc = ic_expr(before_conversion(tn->tn_right));
270 return ic_mod(tn->tn_type, lc, rc); 270 return ic_mod(tn->tn_type, lc, rc);
271 case SHL: 271 case SHL:
272 lc = ic_expr(tn->tn_left); 272 lc = ic_expr(tn->tn_left);
273 rc = ic_expr(tn->tn_right); 273 rc = ic_expr(tn->tn_right);
274 return ic_shl(tn->tn_type, lc, rc); 274 return ic_shl(tn->tn_type, lc, rc);
275 case SHR: 275 case SHR:
276 lc = ic_expr(tn->tn_left); 276 lc = ic_expr(tn->tn_left);
277 rc = ic_expr(tn->tn_right); 277 rc = ic_expr(tn->tn_right);
278 return ic_shr(tn->tn_type, lc, rc); 278 return ic_shr(tn->tn_type, lc, rc);
279 case BITAND: 279 case BITAND:
280 lc = ic_expr(tn->tn_left); 280 lc = ic_expr(tn->tn_left);
281 rc = ic_expr(tn->tn_right); 281 rc = ic_expr(tn->tn_right);
282 return ic_bitand(lc, rc); 282 return ic_bitand(lc, rc);
283 case BITOR: 283 case BITOR:
284 lc = ic_expr(tn->tn_left); 284 lc = ic_expr(tn->tn_left);
285 rc = ic_expr(tn->tn_right); 285 rc = ic_expr(tn->tn_right);
286 return ic_bitor(lc, rc); 286 return ic_bitor(lc, rc);
287 default: 287 default:
288 return ic_any(tn->tn_type); 288 return ic_any(tn->tn_type);
289 } 289 }
290} 290}
291 291
292/* Build 'pointer to tp', 'array of tp' or 'function returning tp'. */ 292/* Build 'pointer to tp', 'array of tp' or 'function returning tp'. */
293type_t * 293type_t *
294block_derive_type(type_t *tp, tspec_t t) 294block_derive_type(type_t *tp, tspec_t t)
295{ 295{
296 type_t *tp2; 296 type_t *tp2;
297 297
298 tp2 = block_zero_alloc(sizeof(*tp2)); 298 tp2 = block_zero_alloc(sizeof(*tp2));
299 tp2->t_tspec = t; 299 tp2->t_tspec = t;
300 tp2->t_subt = tp; 300 tp2->t_subt = tp;
301 return tp2; 301 return tp2;
302} 302}
303 303
304/* 304/*
305 * Derive 'pointer to tp' or 'function returning tp'. 305 * Derive 'pointer to tp' or 'function returning tp'.
306 * The memory is freed at the end of the current expression. 306 * The memory is freed at the end of the current expression.
307 */ 307 */
308type_t * 308type_t *
309expr_derive_type(type_t *tp, tspec_t t) 309expr_derive_type(type_t *tp, tspec_t t)
310{ 310{
311 type_t *tp2; 311 type_t *tp2;
312 312
313 tp2 = expr_zero_alloc(sizeof(*tp2)); 313 tp2 = expr_zero_alloc(sizeof(*tp2));
314 tp2->t_tspec = t; 314 tp2->t_tspec = t;
315 tp2->t_subt = tp; 315 tp2->t_subt = tp;
316 return tp2; 316 return tp2;
317} 317}
318 318
319/* 319/*
320 * Build and initialize a new node. 320 * Build and initialize a new node.
321 */ 321 */
322static tnode_t * 322static tnode_t *
323new_tnode(op_t op, bool sys, type_t *type, tnode_t *ln, tnode_t *rn) 323new_tnode(op_t op, bool sys, type_t *type, tnode_t *ln, tnode_t *rn)
324{ 324{
325 325
326 tnode_t *ntn = expr_alloc_tnode(); 326 tnode_t *ntn = expr_alloc_tnode();
327 ntn->tn_op = op; 327 ntn->tn_op = op;
328 ntn->tn_type = type; 328 ntn->tn_type = type;
329 ntn->tn_sys = sys; 329 ntn->tn_sys = sys;
330 ntn->tn_left = ln; 330 ntn->tn_left = ln;
331 ntn->tn_right = rn; 331 ntn->tn_right = rn;
332 332
333 if (op == INDIR || op == FSEL) { 333 if (op == INDIR || op == FSEL) {
334 lint_assert(ln->tn_type->t_tspec == PTR); 334 lint_assert(ln->tn_type->t_tspec == PTR);
335 tspec_t t = ln->tn_type->t_subt->t_tspec; 335 tspec_t t = ln->tn_type->t_subt->t_tspec;
336 if (t != FUNC && t != VOID) 336 if (t != FUNC && t != VOID)
337 ntn->tn_lvalue = true; 337 ntn->tn_lvalue = true;
338 } 338 }
339 339
340 return ntn; 340 return ntn;
341} 341}
342 342
343/* 343/*
344 * Create a node for a constant. 344 * Create a node for a constant.
345 */ 345 */
346tnode_t * 346tnode_t *
347build_constant(type_t *tp, val_t *v) 347build_constant(type_t *tp, val_t *v)
348{ 348{
349 tnode_t *n; 349 tnode_t *n;
350 350
351 n = expr_alloc_tnode(); 351 n = expr_alloc_tnode();
352 n->tn_op = CON; 352 n->tn_op = CON;
353 n->tn_type = tp; 353 n->tn_type = tp;
354 n->tn_val = expr_zero_alloc(sizeof(*n->tn_val)); 354 n->tn_val = expr_zero_alloc(sizeof(*n->tn_val));
355 n->tn_val->v_tspec = tp->t_tspec; 355 n->tn_val->v_tspec = tp->t_tspec;
356 n->tn_val->v_unsigned_since_c90 = v->v_unsigned_since_c90; 356 n->tn_val->v_unsigned_since_c90 = v->v_unsigned_since_c90;
357 n->tn_val->v_u = v->v_u; 357 n->tn_val->v_u = v->v_u;
358 free(v); 358 free(v);
359 return n; 359 return n;
360} 360}
361 361
362static tnode_t * 362static tnode_t *
363build_integer_constant(tspec_t t, int64_t q) 363build_integer_constant(tspec_t t, int64_t q)
364{ 364{
365 tnode_t *n; 365 tnode_t *n;
366 366
367 n = expr_alloc_tnode(); 367 n = expr_alloc_tnode();
368 n->tn_op = CON; 368 n->tn_op = CON;
369 n->tn_type = gettyp(t); 369 n->tn_type = gettyp(t);
370 n->tn_val = expr_zero_alloc(sizeof(*n->tn_val)); 370 n->tn_val = expr_zero_alloc(sizeof(*n->tn_val));
371 n->tn_val->v_tspec = t; 371 n->tn_val->v_tspec = t;
372 n->tn_val->v_quad = q; 372 n->tn_val->v_quad = q;
373 return n; 373 return n;
374} 374}
375 375
376static void 376static void
377fallback_symbol(sym_t *sym) 377fallback_symbol(sym_t *sym)
378{ 378{
379 379
380 if (Tflag && fallback_symbol_strict_bool(sym)) 380 if (Tflag && fallback_symbol_strict_bool(sym))
381 return; 381 return;
382 382
383 if (block_level > 0 && (strcmp(sym->s_name, "__FUNCTION__") == 0 || 383 if (block_level > 0 && (strcmp(sym->s_name, "__FUNCTION__") == 0 ||
384 strcmp(sym->s_name, "__PRETTY_FUNCTION__") == 0)) { 384 strcmp(sym->s_name, "__PRETTY_FUNCTION__") == 0)) {
385 /* __FUNCTION__/__PRETTY_FUNCTION__ is a GCC extension */ 385 /* __FUNCTION__/__PRETTY_FUNCTION__ is a GCC extension */
386 gnuism(316); 386 gnuism(316);
387 sym->s_type = block_derive_type(gettyp(CHAR), PTR); 387 sym->s_type = block_derive_type(gettyp(CHAR), PTR);
388 sym->s_type->t_const = true; 388 sym->s_type->t_const = true;
389 return; 389 return;
390 } 390 }
391 391
392 if (block_level > 0 && strcmp(sym->s_name, "__func__") == 0) { 392 if (block_level > 0 && strcmp(sym->s_name, "__func__") == 0) {
393 if (!allow_c99) 393 if (!allow_c99)
394 /* __func__ is a C99 feature */ 394 /* __func__ is a C99 feature */
395 warning(317); 395 warning(317);
396 /* C11 6.4.2.2 */ 396 /* C11 6.4.2.2 */
397 sym->s_type = block_derive_type(gettyp(CHAR), ARRAY); 397 sym->s_type = block_derive_type(gettyp(CHAR), ARRAY);
398 sym->s_type->t_const = true; 398 sym->s_type->t_const = true;
399 sym->s_type->t_dim = (int)strlen(funcsym->s_name) + 1; 399 sym->s_type->t_dim = (int)strlen(funcsym->s_name) + 1;
400 return; 400 return;
401 } 401 }
402 402
403 /* '%s' undefined */ 403 /* '%s' undefined */
404 error(99, sym->s_name); 404 error(99, sym->s_name);
405} 405}
406 406
407/* 407/*
408 * Functions that are predeclared by GCC or other compilers can be called 408 * Functions that are predeclared by GCC or other compilers can be called
409 * with arbitrary arguments. Since lint usually runs after a successful 409 * with arbitrary arguments. Since lint usually runs after a successful
410 * compilation, it's the compiler's job to catch any errors. 410 * compilation, it's the compiler's job to catch any errors.
411 */ 411 */
412bool 412bool
413is_compiler_builtin(const char *name) 413is_compiler_builtin(const char *name)
414{ 414{
415 /* https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html */ 415 /* https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html */
416 if (allow_gcc) { 416 if (allow_gcc) {
417 if (strncmp(name, "__atomic_", 9) == 0 || 417 if (strncmp(name, "__atomic_", 9) == 0 ||
418 strncmp(name, "__builtin_", 10) == 0 || 418 strncmp(name, "__builtin_", 10) == 0 ||
419 strcmp(name, "alloca") == 0 || 419 strcmp(name, "alloca") == 0 ||
420 /* obsolete but still in use, as of 2021 */ 420 /* obsolete but still in use, as of 2021 */
421 strncmp(name, "__sync_", 7) == 0) 421 strncmp(name, "__sync_", 7) == 0)
422 return true; 422 return true;
423 } 423 }
424 424
425 /* https://software.intel.com/sites/landingpage/IntrinsicsGuide/ */ 425 /* https://software.intel.com/sites/landingpage/IntrinsicsGuide/ */
426 if (strncmp(name, "_mm_", 4) == 0) 426 if (strncmp(name, "_mm_", 4) == 0)
427 return true; 427 return true;
428 428
429 return false; 429 return false;
430} 430}
431 431
432/* https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html */ 432/* https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html */
433static bool 433static bool
434is_gcc_bool_builtin(const char *name) 434is_gcc_bool_builtin(const char *name)
435{ 435{
436 return strncmp(name, "__builtin_", 10) == 0 && 436 return strncmp(name, "__builtin_", 10) == 0 &&
437 (str_endswith(name, "_overflow") || 437 (str_endswith(name, "_overflow") ||
438 str_endswith(name, "_overflow_p")); 438 str_endswith(name, "_overflow_p"));
439} 439}
440 440
441static void 441static void
442build_name_call(sym_t *sym) 442build_name_call(sym_t *sym)
443{ 443{
444 444
445 if (is_compiler_builtin(sym->s_name)) { 445 if (is_compiler_builtin(sym->s_name)) {
446 /* 446 /*
447 * Do not warn about these, just assume that 447 * Do not warn about these, just assume that
448 * they are regular functions compatible with 448 * they are regular functions compatible with
449 * non-prototype calling conventions. 449 * non-prototype calling conventions.
450 */ 450 */
451 if (allow_gcc && is_gcc_bool_builtin(sym->s_name)) 451 if (allow_gcc && is_gcc_bool_builtin(sym->s_name))
452 sym->s_type = gettyp(BOOL); 452 sym->s_type = gettyp(BOOL);
453 453
454 } else if (allow_c99) { 454 } else if (allow_c99) {
455 /* function '%s' implicitly declared to return int */ 455 /* function '%s' implicitly declared to return int */
456 error(215, sym->s_name); 456 error(215, sym->s_name);
457 } else if (!allow_trad) { 457 } else if (!allow_trad) {
458 /* function '%s' implicitly declared to return int */ 458 /* function '%s' implicitly declared to return int */
459 warning(215, sym->s_name); 459 warning(215, sym->s_name);
460 } 460 }
461 461
462 /* XXX if !allow_c90, the symbol should be exported to level 0 */ 462 /* XXX if !allow_c90, the symbol should be exported to level 0 */
463 sym->s_type = block_derive_type(sym->s_type, FUNC); 463 sym->s_type = block_derive_type(sym->s_type, FUNC);
464} 464}
465 465
466/* Create a node for a name (symbol table entry). */ 466/* Create a node for a name (symbol table entry). */
467tnode_t * 467tnode_t *
468build_name(sym_t *sym, bool is_funcname) 468build_name(sym_t *sym, bool is_funcname)
469{ 469{
470 tnode_t *n; 470 tnode_t *n;
471 471
472 if (sym->s_scl == NOSCL && !in_gcc_attribute) { 472 if (sym->s_scl == NOSCL && !in_gcc_attribute) {
473 sym->s_scl = EXTERN; 473 sym->s_scl = EXTERN;
474 sym->s_def = DECL; 474 sym->s_def = DECL;
475 if (is_funcname) 475 if (is_funcname)
476 build_name_call(sym); 476 build_name_call(sym);
477 else 477 else
478 fallback_symbol(sym); 478 fallback_symbol(sym);
479 } 479 }
480 480
481 lint_assert(sym->s_kind == FVFT || sym->s_kind == FMEMBER); 481 lint_assert(sym->s_kind == FVFT || sym->s_kind == FMEMBER);
482 482
483 n = expr_alloc_tnode(); 483 n = expr_alloc_tnode();
484 n->tn_type = sym->s_type; 484 n->tn_type = sym->s_type;
485 if (sym->s_scl == BOOL_CONST) { 485 if (sym->s_scl == BOOL_CONST) {
486 n->tn_op = CON; 486 n->tn_op = CON;
487 n->tn_val = expr_zero_alloc(sizeof(*n->tn_val)); 487 n->tn_val = expr_zero_alloc(sizeof(*n->tn_val));
488 n->tn_val->v_tspec = BOOL; 488 n->tn_val->v_tspec = BOOL;
489 n->tn_val->v_quad = sym->u.s_bool_constant ? 1 : 0; 489 n->tn_val->v_quad = sym->u.s_bool_constant ? 1 : 0;
490 } else if (sym->s_scl == ENUM_CONST) { 490 } else if (sym->s_scl == ENUM_CONST) {
491 n->tn_op = CON; 491 n->tn_op = CON;
492 n->tn_val = expr_zero_alloc(sizeof(*n->tn_val)); 492 n->tn_val = expr_zero_alloc(sizeof(*n->tn_val));
493 n->tn_val->v_tspec = INT; /* ENUM is in n->tn_type */ 493 n->tn_val->v_tspec = INT; /* ENUM is in n->tn_type */
494 n->tn_val->v_quad = sym->u.s_enum_constant; 494 n->tn_val->v_quad = sym->u.s_enum_constant;
495 } else { 495 } else {
496 n->tn_op = NAME; 496 n->tn_op = NAME;
497 n->tn_sym = sym; 497 n->tn_sym = sym;
498 if (sym->s_kind == FVFT && sym->s_type->t_tspec != FUNC) 498 if (sym->s_kind == FVFT && sym->s_type->t_tspec != FUNC)
499 n->tn_lvalue = true; 499 n->tn_lvalue = true;
500 } 500 }
501 501
502 return n; 502 return n;
503} 503}
504 504
505tnode_t * 505tnode_t *
506build_string(strg_t *strg) 506build_string(strg_t *strg)
507{ 507{
508 size_t len; 508 size_t len;
509 tnode_t *n; 509 tnode_t *n;
510 type_t *tp; 510 type_t *tp;
511 511
512 len = strg->st_len; 512 len = strg->st_len;
513 513
514 n = expr_alloc_tnode(); 514 n = expr_alloc_tnode();
515 515
516 tp = expr_zero_alloc(sizeof(*tp)); 516 tp = expr_zero_alloc(sizeof(*tp));
517 tp->t_tspec = ARRAY; 517 tp->t_tspec = ARRAY;
518 tp->t_subt = gettyp(strg->st_char ? CHAR : WCHAR); 518 tp->t_subt = gettyp(strg->st_char ? CHAR : WCHAR);
519 tp->t_dim = (int)(len + 1); 519 tp->t_dim = (int)(len + 1);
520 520
521 n->tn_op = STRING; 521 n->tn_op = STRING;
522 n->tn_type = tp; 522 n->tn_type = tp;
523 n->tn_lvalue = true; 523 n->tn_lvalue = true;
524 524
525 n->tn_string = expr_zero_alloc(sizeof(*n->tn_string)); 525 n->tn_string = expr_zero_alloc(sizeof(*n->tn_string));
526 n->tn_string->st_char = strg->st_char; 526 n->tn_string->st_char = strg->st_char;
527 n->tn_string->st_len = len; 527 n->tn_string->st_len = len;
528 528
529 size_t chsize = strg->st_char ? sizeof(char) : sizeof(wchar_t); 529 size_t chsize = strg->st_char ? sizeof(char) : sizeof(wchar_t);
530 size_t size = (len + 1) * chsize; 530 size_t size = (len + 1) * chsize;
531 n->tn_string->st_mem = expr_zero_alloc(size); 531 n->tn_string->st_mem = expr_zero_alloc(size);
532 (void)memcpy(n->tn_string->st_mem, strg->st_mem, size); 532 (void)memcpy(n->tn_string->st_mem, strg->st_mem, size);
533 free(strg->st_mem); 533 free(strg->st_mem);
534 free(strg); 534 free(strg);
535 535
536 return n; 536 return n;
537} 537}
538 538
539tnode_t * 539tnode_t *
540build_generic_selection(const tnode_t *expr, 540build_generic_selection(const tnode_t *expr,
541 struct generic_association *sel) 541 struct generic_association *sel)
542{ 542{
543 tnode_t *default_result = NULL; 543 tnode_t *default_result = NULL;
544 544
545 for (; sel != NULL; sel = sel->ga_prev) { 545 for (; sel != NULL; sel = sel->ga_prev) {
546 if (expr != NULL && 546 if (expr != NULL &&
547 types_compatible(sel->ga_arg, expr->tn_type, 547 types_compatible(sel->ga_arg, expr->tn_type,
548 false, false, NULL)) 548 false, false, NULL))
549 return sel->ga_result; 549 return sel->ga_result;
550 else if (sel->ga_arg == NULL) 550 else if (sel->ga_arg == NULL)
551 default_result = sel->ga_result; 551 default_result = sel->ga_result;
552 } 552 }
553 return default_result; 553 return default_result;
554} 554}
555 555
556static bool 556static bool
557is_out_of_char_range(const tnode_t *tn) 557is_out_of_char_range(const tnode_t *tn)
558{ 558{
559 return tn->tn_op == CON && 559 return tn->tn_op == CON &&
560 !(0 <= tn->tn_val->v_quad && 560 !(0 <= tn->tn_val->v_quad &&
561 tn->tn_val->v_quad < 1 << (CHAR_SIZE - 1)); 561 tn->tn_val->v_quad < 1 << (CHAR_SIZE - 1));
562} 562}
563 563
564/* 564/*
565 * Check for ordered comparisons of unsigned values with 0. 565 * Check for ordered comparisons of unsigned values with 0.
566 */ 566 */
567static void 567static void
568check_integer_comparison(op_t op, tnode_t *ln, tnode_t *rn) 568check_integer_comparison(op_t op, tnode_t *ln, tnode_t *rn)
569{ 569{
570 tspec_t lt, rt; 570 tspec_t lt, rt;
571 571
572 lt = ln->tn_type->t_tspec; 572 lt = ln->tn_type->t_tspec;
573 rt = rn->tn_type->t_tspec; 573 rt = rn->tn_type->t_tspec;
574 574
575 if (ln->tn_op != CON && rn->tn_op != CON) 575 if (ln->tn_op != CON && rn->tn_op != CON)
576 return; 576 return;
577 577
578 if (!is_integer(lt) || !is_integer(rt)) 578 if (!is_integer(lt) || !is_integer(rt))
579 return; 579 return;
580 580
581 if (hflag || pflag) { 581 if (hflag || pflag) {
582 if (lt == CHAR && is_out_of_char_range(rn)) { 582 if (lt == CHAR && is_out_of_char_range(rn)) {
583 char buf[128]; 583 char buf[128];
584 (void)snprintf(buf, sizeof(buf), "%s %d", 584 (void)snprintf(buf, sizeof(buf), "%s %d",
585 op_name(op), (int)rn->tn_val->v_quad); 585 op_name(op), (int)rn->tn_val->v_quad);
586 /* nonportable character comparison '%s' */ 586 /* nonportable character comparison '%s' */
587 warning(230, buf); 587 warning(230, buf);
588 return; 588 return;
589 } 589 }
590 if (rt == CHAR && is_out_of_char_range(ln)) { 590 if (rt == CHAR && is_out_of_char_range(ln)) {
591 char buf[128]; 591 char buf[128];
592 (void)snprintf(buf, sizeof(buf), "%d %s ?", 592 (void)snprintf(buf, sizeof(buf), "%d %s ?",
593 (int)ln->tn_val->v_quad, op_name(op)); 593 (int)ln->tn_val->v_quad, op_name(op));
594 /* nonportable character comparison '%s' */ 594 /* nonportable character comparison '%s' */
595 warning(230, buf); 595 warning(230, buf);
596 return; 596 return;
597 } 597 }
598 } 598 }
599 599
600 if (is_uinteger(lt) && !is_uinteger(rt) && 600 if (is_uinteger(lt) && !is_uinteger(rt) &&
601 rn->tn_op == CON && rn->tn_val->v_quad <= 0) { 601 rn->tn_op == CON && rn->tn_val->v_quad <= 0) {
602 if (rn->tn_val->v_quad < 0) { 602 if (rn->tn_val->v_quad < 0) {
603 /* operator '%s' compares '%s' with '%s' */ 603 /* operator '%s' compares '%s' with '%s' */
604 warning(162, op_name(op), 604 warning(162, op_name(op),
605 type_name(ln->tn_type), "negative constant"); 605 type_name(ln->tn_type), "negative constant");
606 } else if (op == LT || op == GE) { 606 } else if (op == LT || op == GE) {
607 /* operator '%s' compares '%s' with '%s' */ 607 /* operator '%s' compares '%s' with '%s' */
608 warning(162, op_name(op), type_name(ln->tn_type), "0"); 608 warning(162, op_name(op), type_name(ln->tn_type), "0");
609 } 609 }
610 return; 610 return;
611 } 611 }
612 if (is_uinteger(rt) && !is_uinteger(lt) && 612 if (is_uinteger(rt) && !is_uinteger(lt) &&
613 ln->tn_op == CON && ln->tn_val->v_quad <= 0) { 613 ln->tn_op == CON && ln->tn_val->v_quad <= 0) {
614 if (ln->tn_val->v_quad < 0) { 614 if (ln->tn_val->v_quad < 0) {
615 /* operator '%s' compares '%s' with '%s' */ 615 /* operator '%s' compares '%s' with '%s' */
616 warning(162, op_name(op), 616 warning(162, op_name(op),
617 "negative constant", type_name(rn->tn_type)); 617 "negative constant", type_name(rn->tn_type));
618 } else if (op == GT || op == LE) { 618 } else if (op == GT || op == LE) {
619 /* operator '%s' compares '%s' with '%s' */ 619 /* operator '%s' compares '%s' with '%s' */
620 warning(162, op_name(op), "0", type_name(rn->tn_type)); 620 warning(162, op_name(op), "0", type_name(rn->tn_type));
621 } 621 }
622 return; 622 return;
623 } 623 }
624} 624}
625 625
626static const tspec_t arith_rank[] = { 626static const tspec_t arith_rank[] = {
627 LDOUBLE, DOUBLE, FLOAT, 627 LDOUBLE, DOUBLE, FLOAT,
628#ifdef INT128_SIZE 628#ifdef INT128_SIZE
629 UINT128, INT128, 629 UINT128, INT128,
630#endif 630#endif
631 UQUAD, QUAD, 631 UQUAD, QUAD,
632 ULONG, LONG, 632 ULONG, LONG,
633 UINT, INT, 633 UINT, INT,
634}; 634};
635 635
636/* Keep unsigned in traditional C */ 636/* Keep unsigned in traditional C */
637static tspec_t 637static tspec_t
638usual_arithmetic_conversion_trad(tspec_t lt, tspec_t rt) 638usual_arithmetic_conversion_trad(tspec_t lt, tspec_t rt)
639{ 639{
640 640
641 size_t i; 641 size_t i;
642 for (i = 0; arith_rank[i] != INT; i++) 642 for (i = 0; arith_rank[i] != INT; i++)
643 if (lt == arith_rank[i] || rt == arith_rank[i]) 643 if (lt == arith_rank[i] || rt == arith_rank[i])
644 break; 644 break;
645 645
646 tspec_t t = arith_rank[i]; 646 tspec_t t = arith_rank[i];
647 if (is_uinteger(lt) || is_uinteger(rt)) 647 if (is_uinteger(lt) || is_uinteger(rt))
648 if (is_integer(t) && !is_uinteger(t)) 648 if (is_integer(t) && !is_uinteger(t))
649 return unsigned_type(t); 649 return unsigned_type(t);
650 return t; 650 return t;
651} 651}
652 652
653static tspec_t 653static tspec_t
654usual_arithmetic_conversion_c90(tspec_t lt, tspec_t rt) 654usual_arithmetic_conversion_c90(tspec_t lt, tspec_t rt)
655{ 655{
656 656
657 if (lt == rt) 657 if (lt == rt)
658 return lt; 658 return lt;
659 659
660 if (lt == LCOMPLEX || rt == LCOMPLEX) 660 if (lt == LCOMPLEX || rt == LCOMPLEX)
661 return LCOMPLEX; 661 return LCOMPLEX;
662 if (lt == DCOMPLEX || rt == DCOMPLEX) 662 if (lt == DCOMPLEX || rt == DCOMPLEX)
663 return DCOMPLEX; 663 return DCOMPLEX;
664 if (lt == FCOMPLEX || rt == FCOMPLEX) 664 if (lt == FCOMPLEX || rt == FCOMPLEX)
665 return FCOMPLEX; 665 return FCOMPLEX;
666 if (lt == LDOUBLE || rt == LDOUBLE) 666 if (lt == LDOUBLE || rt == LDOUBLE)
667 return LDOUBLE; 667 return LDOUBLE;
668 if (lt == DOUBLE || rt == DOUBLE) 668 if (lt == DOUBLE || rt == DOUBLE)
669 return DOUBLE; 669 return DOUBLE;
670 if (lt == FLOAT || rt == FLOAT) 670 if (lt == FLOAT || rt == FLOAT)
671 return FLOAT; 671 return FLOAT;
672 672
673 /* 673 /*
674 * If type A has more bits than type B, it should be able to hold all 674 * If type A has more bits than type B, it should be able to hold all
675 * possible values of type B. 675 * possible values of type B.
676 */ 676 */
677 if (size_in_bits(lt) > size_in_bits(rt)) 677 if (size_in_bits(lt) > size_in_bits(rt))
678 return lt; 678 return lt;
679 if (size_in_bits(lt) < size_in_bits(rt)) 679 if (size_in_bits(lt) < size_in_bits(rt))
680 return rt; 680 return rt;
681 681
682 size_t i; 682 size_t i;
683 for (i = 3; arith_rank[i] != INT; i++) 683 for (i = 3; arith_rank[i] != INT; i++)
684 if (arith_rank[i] == lt || arith_rank[i] == rt) 684 if (arith_rank[i] == lt || arith_rank[i] == rt)
685 break; 685 break;
686 if ((is_uinteger(lt) || is_uinteger(rt)) && 686 if ((is_uinteger(lt) || is_uinteger(rt)) &&
687 !is_uinteger(arith_rank[i])) 687 !is_uinteger(arith_rank[i]))
688 i--; 688 i--;
689 return arith_rank[i]; 689 return arith_rank[i];
690} 690}
691 691
692static tnode_t * 692static tnode_t *
693apply_usual_arithmetic_conversions(op_t op, tnode_t *tn, tspec_t t) 693apply_usual_arithmetic_conversions(op_t op, tnode_t *tn, tspec_t t)
694{ 694{
695 type_t *ntp = expr_dup_type(tn->tn_type); 695 type_t *ntp = expr_dup_type(tn->tn_type);
696 ntp->t_tspec = t; 696 ntp->t_tspec = t;
697 if (tn->tn_op != CON) { 697 if (tn->tn_op != CON) {
698 /* usual arithmetic conversion for '%s' from '%s' to '%s' */ 698 /* usual arithmetic conversion for '%s' from '%s' to '%s' */
699 query_message(4, op_name(op), 699 query_message(4, op_name(op),
700 type_name(tn->tn_type), type_name(ntp)); 700 type_name(tn->tn_type), type_name(ntp));
701 } 701 }
702 return convert(op, 0, ntp, tn); 702 return convert(op, 0, ntp, tn);
703} 703}
704 704
705/* 705/*
706 * Apply the "usual arithmetic conversions" (C99 6.3.1.8), which gives both 706 * Apply the "usual arithmetic conversions" (C99 6.3.1.8), which gives both
707 * operands the same type. 707 * operands the same type.
708 */ 708 */
709static void 709static void
710balance(op_t op, tnode_t **lnp, tnode_t **rnp) 710balance(op_t op, tnode_t **lnp, tnode_t **rnp)
711{ 711{
712 712
713 tspec_t lt = (*lnp)->tn_type->t_tspec; 713 tspec_t lt = (*lnp)->tn_type->t_tspec;
714 tspec_t rt = (*rnp)->tn_type->t_tspec; 714 tspec_t rt = (*rnp)->tn_type->t_tspec;
715 if (!is_arithmetic(lt) || !is_arithmetic(rt)) 715 if (!is_arithmetic(lt) || !is_arithmetic(rt))
716 return; 716 return;
717 717
718 tspec_t t = allow_c90 718 tspec_t t = allow_c90
719 ? usual_arithmetic_conversion_c90(lt, rt) 719 ? usual_arithmetic_conversion_c90(lt, rt)
720 : usual_arithmetic_conversion_trad(lt, rt); 720 : usual_arithmetic_conversion_trad(lt, rt);
721 721
722 if (t != lt) 722 if (t != lt)
723 *lnp = apply_usual_arithmetic_conversions(op, *lnp, t); 723 *lnp = apply_usual_arithmetic_conversions(op, *lnp, t);
724 if (t != rt) 724 if (t != rt)
725 *rnp = apply_usual_arithmetic_conversions(op, *rnp, t); 725 *rnp = apply_usual_arithmetic_conversions(op, *rnp, t);
726} 726}
727 727
728/* 728/*
729 * Create a tree node for the unary & operator 729 * Create a tree node for the unary & operator
730 */ 730 */
731static tnode_t * 731static tnode_t *
732build_address(bool sys, tnode_t *tn, bool noign) 732build_address(bool sys, tnode_t *tn, bool noign)
733{ 733{
734 tspec_t t; 734 tspec_t t;
735 735
736 if (!noign && ((t = tn->tn_type->t_tspec) == ARRAY || t == FUNC)) { 736 if (!noign && ((t = tn->tn_type->t_tspec) == ARRAY || t == FUNC)) {
737 if (!allow_c90) 737 if (!allow_c90)
738 /* '&' before array or function: ignored */ 738 /* '&' before array or function: ignored */
739 warning(127); 739 warning(127);
740 return tn; 740 return tn;
741 } 741 }
742 742
743 /* eliminate &* */ 743 /* eliminate &* */
744 if (tn->tn_op == INDIR && 744 if (tn->tn_op == INDIR &&
745 tn->tn_left->tn_type->t_tspec == PTR && 745 tn->tn_left->tn_type->t_tspec == PTR &&
746 tn->tn_left->tn_type->t_subt == tn->tn_type) { 746 tn->tn_left->tn_type->t_subt == tn->tn_type) {
747 return tn->tn_left; 747 return tn->tn_left;
748 } 748 }
749 749
750 return new_tnode(ADDR, sys, expr_derive_type(tn->tn_type, PTR), 750 return new_tnode(ADDR, sys, expr_derive_type(tn->tn_type, PTR),
751 tn, NULL); 751 tn, NULL);
752} 752}
753 753
754/* 754/*
755 * XXX 755 * XXX
756 * Note: There appear to be a number of bugs in detecting overflow in 756 * Note: There appear to be a number of bugs in detecting overflow in
757 * this function. An audit and a set of proper regression tests are needed. 757 * this function. An audit and a set of proper regression tests are needed.
758 * --Perry Metzger, Nov. 16, 2001 758 * --Perry Metzger, Nov. 16, 2001
759 */ 759 */
760/* 760/*
761 * Do only as much as necessary to compute constant expressions. 761 * Do only as much as necessary to compute constant expressions.
762 * Called only if the operator allows folding and all operands are constants. 762 * Called only if the operator allows folding and all operands are constants.
763 */ 763 */
764static tnode_t * 764static tnode_t *
765fold(tnode_t *tn) 765fold(tnode_t *tn)
766{ 766{
767 val_t *v; 767 val_t *v;
768 tspec_t t; 768 tspec_t t;
769 bool utyp, ovfl; 769 bool utyp, ovfl;
770 int64_t sl, sr = 0, q = 0, mask; 770 int64_t sl, sr = 0, q = 0, mask;
771 uint64_t ul, ur = 0; 771 uint64_t ul, ur = 0;
772 tnode_t *cn; 772 tnode_t *cn;
773 773
774 v = xcalloc(1, sizeof(*v)); 774 v = xcalloc(1, sizeof(*v));
775 v->v_tspec = tn->tn_type->t_tspec; 775 v->v_tspec = tn->tn_type->t_tspec;
776 776
777 t = tn->tn_left->tn_type->t_tspec; 777 t = tn->tn_left->tn_type->t_tspec;
778 utyp = !is_integer(t) || is_uinteger(t); 778 utyp = !is_integer(t) || is_uinteger(t);
779 ul = sl = tn->tn_left->tn_val->v_quad; 779 ul = sl = tn->tn_left->tn_val->v_quad;
780 if (is_binary(tn)) 780 if (is_binary(tn))
781 ur = sr = tn->tn_right->tn_val->v_quad; 781 ur = sr = tn->tn_right->tn_val->v_quad;
782 782
783 mask = value_bits(size_in_bits(t)); 783 mask = value_bits(size_in_bits(t));
784 ovfl = false; 784 ovfl = false;
785 785
786 switch (tn->tn_op) { 786 switch (tn->tn_op) {
787 case UPLUS: 787 case UPLUS:
788 q = sl; 788 q = sl;
789 break; 789 break;
790 case UMINUS: 790 case UMINUS:
791 q = sl == INT64_MIN ? sl : -sl; 791 q = sl == INT64_MIN ? sl : -sl;
792 if (sl != 0 && msb(q, t) == msb(sl, t)) 792 if (sl != 0 && msb(q, t) == msb(sl, t))
793 ovfl = true; 793 ovfl = true;
794 break; 794 break;
795 case COMPL: 795 case COMPL:
796 q = ~sl; 796 q = ~sl;
797 break; 797 break;
798 case MULT: 798 case MULT:
799 if (utyp) { 799 if (utyp) {
800 q = ul * ur; 800 q = ul * ur;
801 if (q != (q & mask)) 801 if (q != (q & mask))
802 ovfl = true; 802 ovfl = true;
803 else if ((ul != 0) && ((q / ul) != ur)) 803 else if ((ul != 0) && ((q / ul) != ur))
804 ovfl = true; 804 ovfl = true;
805 } else { 805 } else {
806 q = sl * sr; 806 q = sl * sr;
807 if (msb(q, t) != (msb(sl, t) ^ msb(sr, t))) 807 if (msb(q, t) != (msb(sl, t) ^ msb(sr, t)))
808 ovfl = true; 808 ovfl = true;
809 } 809 }
810 break; 810 break;
811 case DIV: 811 case DIV:
812 if (sr == 0) { 812 if (sr == 0) {
813 /* division by 0 */ 813 /* division by 0 */
814 error(139); 814 error(139);
815 q = utyp ? -1 : INT64_MAX; 815 q = utyp ? -1 : INT64_MAX;
816 } else { 816 } else {
817 q = utyp ? (int64_t)(ul / ur) : sl / sr; 817 q = utyp ? (int64_t)(ul / ur) : sl / sr;
818 } 818 }
819 break; 819 break;
820 case MOD: 820 case MOD:
821 if (sr == 0) { 821 if (sr == 0) {
822 /* modulus by 0 */ 822 /* modulus by 0 */
823 error(140); 823 error(140);
824 q = 0; 824 q = 0;
825 } else { 825 } else {
826 q = utyp ? (int64_t)(ul % ur) : sl % sr; 826 q = utyp ? (int64_t)(ul % ur) : sl % sr;
827 } 827 }
828 break; 828 break;
829 case PLUS: 829 case PLUS:
830 q = utyp ? (int64_t)(ul + ur) : sl + sr; 830 q = utyp ? (int64_t)(ul + ur) : sl + sr;
831 if (msb(sl, t) && msb(sr, t) && !msb(q, t)) 831 if (msb(sl, t) && msb(sr, t) && !msb(q, t))
832 ovfl = true; 832 ovfl = true;
833 if (!utyp && !msb(sl, t) && !msb(sr, t) && msb(q, t)) 833 if (!utyp && !msb(sl, t) && !msb(sr, t) && msb(q, t))
834 ovfl = true; 834 ovfl = true;
835 break; 835 break;
836 case MINUS: 836 case MINUS:
837 q = utyp ? (int64_t)(ul - ur) : sl - sr; 837 q = utyp ? (int64_t)(ul - ur) : sl - sr;
838 if (!utyp && msb(sl, t) && !msb(sr, t) && !msb(q, t)) 838 if (!utyp && msb(sl, t) && !msb(sr, t) && !msb(q, t))
839 ovfl = true; 839 ovfl = true;
840 if (!msb(sl, t) && msb(sr, t) && msb(q, t)) 840 if (!msb(sl, t) && msb(sr, t) && msb(q, t))
841 ovfl = true; 841 ovfl = true;
842 break; 842 break;
843 case SHL: 843 case SHL:
844 /* TODO: warn about out-of-bounds 'sr'. */ 844 /* TODO: warn about out-of-bounds 'sr'. */
845 /* TODO: warn about overflow in signed '<<'. */ 845 /* TODO: warn about overflow in signed '<<'. */
846 q = utyp ? (int64_t)(ul << (sr & 63)) : sl << (sr & 63); 846 q = utyp ? (int64_t)(ul << (sr & 63)) : sl << (sr & 63);
847 break; 847 break;
848 case SHR: 848 case SHR:
849 /* 849 /*
850 * The sign must be explicitly extended because 850 * The sign must be explicitly extended because
851 * shifts of signed values are implementation dependent. 851 * shifts of signed values are implementation dependent.
852 */ 852 */
853 /* TODO: warn about out-of-bounds 'sr'. */ 853 /* TODO: warn about out-of-bounds 'sr'. */
854 q = ul >> (sr & 63); 854 q = ul >> (sr & 63);
855 q = convert_integer(q, t, size_in_bits(t) - (int)sr); 855 q = convert_integer(q, t, size_in_bits(t) - (int)sr);
856 break; 856 break;
857 case LT: 857 case LT:
858 q = (utyp ? ul < ur : sl < sr) ? 1 : 0; 858 q = (utyp ? ul < ur : sl < sr) ? 1 : 0;
859 break; 859 break;
860 case LE: 860 case LE:
861 q = (utyp ? ul <= ur : sl <= sr) ? 1 : 0; 861 q = (utyp ? ul <= ur : sl <= sr) ? 1 : 0;
862 break; 862 break;
863 case GE: 863 case GE:
864 q = (utyp ? ul >= ur : sl >= sr) ? 1 : 0; 864 q = (utyp ? ul >= ur : sl >= sr) ? 1 : 0;
865 break; 865 break;
866 case GT: 866 case GT:
867 q = (utyp ? ul > ur : sl > sr) ? 1 : 0; 867 q = (utyp ? ul > ur : sl > sr) ? 1 : 0;
868 break; 868 break;
869 case EQ: 869 case EQ:
870 q = (utyp ? ul == ur : sl == sr) ? 1 : 0; 870 q = (utyp ? ul == ur : sl == sr) ? 1 : 0;
871 break; 871 break;
872 case NE: 872 case NE:
873 q = (utyp ? ul != ur : sl != sr) ? 1 : 0; 873 q = (utyp ? ul != ur : sl != sr) ? 1 : 0;
874 break; 874 break;
875 case BITAND: 875 case BITAND:
876 q = utyp ? (int64_t)(ul & ur) : sl & sr; 876 q = utyp ? (int64_t)(ul & ur) : sl & sr;
877 break; 877 break;
878 case BITXOR: 878 case BITXOR:
879 q = utyp ? (int64_t)(ul ^ ur) : sl ^ sr; 879 q = utyp ? (int64_t)(ul ^ ur) : sl ^ sr;
880 break; 880 break;
881 case BITOR: 881 case BITOR:
882 q = utyp ? (int64_t)(ul | ur) : sl | sr; 882 q = utyp ? (int64_t)(ul | ur) : sl | sr;
883 break; 883 break;
884 default: 884 default:
885 lint_assert(/*CONSTCOND*/false); 885 lint_assert(/*CONSTCOND*/false);
886 } 886 }
887 887
888 /* XXX does not work for quads. */ 888 /* XXX does not work for quads. */
889 if (ovfl || 889 if (ovfl ||
890 ((uint64_t)(q | mask) != ~(uint64_t)0 && (q & ~mask) != 0)) { 890 ((uint64_t)(q | mask) != ~(uint64_t)0 && (q & ~mask) != 0)) {
891 if (hflag) 891 if (hflag)
892 /* integer overflow detected, op '%s' */ 892 /* integer overflow detected, op '%s' */
893 warning(141, op_name(tn->tn_op)); 893 warning(141, op_name(tn->tn_op));
894 } 894 }
895 895
896 v->v_quad = convert_integer(q, t, 0); 896 v->v_quad = convert_integer(q, t, 0);
897 897
898 cn = build_constant(tn->tn_type, v); 898 cn = build_constant(tn->tn_type, v);
899 if (tn->tn_left->tn_system_dependent) 899 if (tn->tn_left->tn_system_dependent)
900 cn->tn_system_dependent = true; 900 cn->tn_system_dependent = true;
901 if (is_binary(tn) && tn->tn_right->tn_system_dependent) 901 if (is_binary(tn) && tn->tn_right->tn_system_dependent)
902 cn->tn_system_dependent = true; 902 cn->tn_system_dependent = true;
903 903
904 return cn; 904 return cn;
905} 905}
906 906
907/* 907/*
908 * Create a new node for one of the operators POINT and ARROW. 908 * Create a new node for one of the operators POINT and ARROW.
909 */ 909 */
910static tnode_t * 910static tnode_t *
911build_struct_access(op_t op, bool sys, tnode_t *ln, tnode_t *rn) 911build_struct_access(op_t op, bool sys, tnode_t *ln, tnode_t *rn)
912{ 912{
913 tnode_t *ntn, *ctn; 913 tnode_t *ntn, *ctn;
914 bool nolval; 914 bool nolval;
915 915
916 lint_assert(rn->tn_op == NAME); 916 lint_assert(rn->tn_op == NAME);
917 lint_assert(is_member(rn->tn_sym)); 917 lint_assert(is_member(rn->tn_sym));
918 918
919 /* 919 /*
920 * Remember if the left operand is an lvalue (structure members 920 * Remember if the left operand is an lvalue (structure members
921 * are lvalues if and only if the structure itself is an lvalue). 921 * are lvalues if and only if the structure itself is an lvalue).
922 */ 922 */
923 nolval = op == POINT && !ln->tn_lvalue; 923 nolval = op == POINT && !ln->tn_lvalue;
924 924
925 if (op == POINT) { 925 if (op == POINT) {
926 ln = build_address(sys, ln, true); 926 ln = build_address(sys, ln, true);
927 } else if (ln->tn_type->t_tspec != PTR) { 927 } else if (ln->tn_type->t_tspec != PTR) {
928 lint_assert(!allow_c90); 928 lint_assert(!allow_c90);
929 lint_assert(is_integer(ln->tn_type->t_tspec)); 929 lint_assert(is_integer(ln->tn_type->t_tspec));
930 ln = convert(NOOP, 0, expr_derive_type(gettyp(VOID), PTR), ln); 930 ln = convert(NOOP, 0, expr_derive_type(gettyp(VOID), PTR), ln);
931 } 931 }
932 932
933 ctn = build_integer_constant(PTRDIFF_TSPEC, 933 ctn = build_integer_constant(PTRDIFF_TSPEC,
934 rn->tn_sym->u.s_member.sm_offset_in_bits / CHAR_SIZE); 934 rn->tn_sym->u.s_member.sm_offset_in_bits / CHAR_SIZE);
935 935
936 ntn = new_tnode(PLUS, sys, expr_derive_type(rn->tn_type, PTR), 936 ntn = new_tnode(PLUS, sys, expr_derive_type(rn->tn_type, PTR),
937 ln, ctn); 937 ln, ctn);
938 if (ln->tn_op == CON) 938 if (ln->tn_op == CON)
939 ntn = fold(ntn); 939 ntn = fold(ntn);
940 940
941 if (rn->tn_type->t_bitfield) { 941 if (rn->tn_type->t_bitfield) {
942 ntn = new_tnode(FSEL, sys, ntn->tn_type->t_subt, ntn, NULL); 942 ntn = new_tnode(FSEL, sys, ntn->tn_type->t_subt, ntn, NULL);
943 } else { 943 } else {
944 ntn = new_tnode(INDIR, sys, ntn->tn_type->t_subt, ntn, NULL); 944 ntn = new_tnode(INDIR, sys, ntn->tn_type->t_subt, ntn, NULL);
945 } 945 }
946 946
947 if (nolval) 947 if (nolval)
948 ntn->tn_lvalue = false; 948 ntn->tn_lvalue = false;
949 949
950 return ntn; 950 return ntn;
951} 951}
952 952
953/* 953/*
954 * Get the size in bytes of type tp->t_subt, as a constant expression of type 954 * Get the size in bytes of type tp->t_subt, as a constant expression of type
955 * ptrdiff_t as seen from the target platform. 955 * ptrdiff_t as seen from the target platform.
956 */ 956 */
957static tnode_t * 957static tnode_t *
958subt_size_in_bytes(type_t *tp) 958subt_size_in_bytes(type_t *tp)
959{ 959{
960 int elem, elsz_in_bits; 960 int elem, elsz_in_bits;
961 961
962 lint_assert(tp->t_tspec == PTR); 962 lint_assert(tp->t_tspec == PTR);
963 tp = tp->t_subt; 963 tp = tp->t_subt;
964 964
965 elem = 1; 965 elem = 1;
966 elsz_in_bits = 0; 966 elsz_in_bits = 0;
967 967
968 while (tp->t_tspec == ARRAY) { 968 while (tp->t_tspec == ARRAY) {
969 elem *= tp->t_dim; 969 elem *= tp->t_dim;
970 tp = tp->t_subt; 970 tp = tp->t_subt;
971 } 971 }
972 972
973 switch (tp->t_tspec) { 973 switch (tp->t_tspec) {
974 case FUNC: 974 case FUNC:
975 /* pointer to function is not allowed here */ 975 /* pointer to function is not allowed here */
976 error(110); 976 error(110);
977 break; 977 break;
978 case VOID: 978 case VOID:
979 /* cannot do pointer arithmetic on operand of unknown size */ 979 /* cannot do pointer arithmetic on operand of unknown size */
980 gnuism(136); 980 gnuism(136);
981 break; 981 break;
982 case STRUCT: 982 case STRUCT:
983 case UNION: 983 case UNION:
984 if ((elsz_in_bits = tp->t_str->sou_size_in_bits) == 0) 984 if ((elsz_in_bits = tp->t_str->sou_size_in_bits) == 0)
985 /* cannot do pointer arithmetic on operand of ... */ 985 /* cannot do pointer arithmetic on operand of ... */
986 error(136); 986 error(136);
987 break; 987 break;
988 case ENUM: 988 case ENUM:
989 if (is_incomplete(tp)) { 989 if (is_incomplete(tp)) {
990 /* cannot do pointer arithmetic on operand of ... */ 990 /* cannot do pointer arithmetic on operand of ... */
991 warning(136); 991 warning(136);
992 } 992 }
993 /* FALLTHROUGH */ 993 /* FALLTHROUGH */
994 default: 994 default:
995 if ((elsz_in_bits = size_in_bits(tp->t_tspec)) == 0) { 995 if ((elsz_in_bits = size_in_bits(tp->t_tspec)) == 0) {
996 /* cannot do pointer arithmetic on operand of ... */ 996 /* cannot do pointer arithmetic on operand of ... */
997 error(136); 997 error(136);
998 } else { 998 } else {
999 lint_assert(elsz_in_bits != -1); 999 lint_assert(elsz_in_bits != -1);
1000 } 1000 }
1001 break; 1001 break;
1002 } 1002 }
1003 1003
1004 if (elem == 0 && elsz_in_bits != 0) { 1004 if (elem == 0 && elsz_in_bits != 0) {
1005 /* cannot do pointer arithmetic on operand of unknown size */ 1005 /* cannot do pointer arithmetic on operand of unknown size */
1006 error(136); 1006 error(136);
1007 } 1007 }
1008 1008
1009 if (elsz_in_bits == 0) 1009 if (elsz_in_bits == 0)
1010 elsz_in_bits = CHAR_SIZE; 1010 elsz_in_bits = CHAR_SIZE;
1011 1011
1012 return build_integer_constant(PTRDIFF_TSPEC, 1012 return build_integer_constant(PTRDIFF_TSPEC,
1013 (int64_t)(elem * elsz_in_bits / CHAR_SIZE)); 1013 (int64_t)(elem * elsz_in_bits / CHAR_SIZE));
1014} 1014}
1015 1015
1016/* 1016/*
1017 * Create a node for INCAFT, INCBEF, DECAFT and DECBEF. 1017 * Create a node for INCAFT, INCBEF, DECAFT and DECBEF.
1018 */ 1018 */
1019static tnode_t * 1019static tnode_t *
1020build_prepost_incdec(op_t op, bool sys, tnode_t *ln) 1020build_prepost_incdec(op_t op, bool sys, tnode_t *ln)
1021{ 1021{
1022 tnode_t *cn, *ntn; 1022 tnode_t *cn, *ntn;
1023 1023
1024 lint_assert(ln != NULL); 1024 lint_assert(ln != NULL);
1025 1025
1026 if (ln->tn_type->t_tspec == PTR) { 1026 if (ln->tn_type->t_tspec == PTR) {
1027 cn = subt_size_in_bytes(ln->tn_type); 1027 cn = subt_size_in_bytes(ln->tn_type);
1028 } else { 1028 } else {
1029 cn = build_integer_constant(INT, (int64_t)1); 1029 cn = build_integer_constant(INT, (int64_t)1);
1030 } 1030 }
1031 ntn = new_tnode(op, sys, ln->tn_type, ln, cn); 1031 ntn = new_tnode(op, sys, ln->tn_type, ln, cn);
1032 1032
1033 return ntn; 1033 return ntn;
1034} 1034}
1035 1035
1036static void 1036static void
1037check_enum_array_index(const tnode_t *ln, const tnode_t *rn) 1037check_enum_array_index(const tnode_t *ln, const tnode_t *rn)
1038{ 1038{
1039 int max_array_index; 1039 int max_array_index;
1040 int64_t max_enum_value; 1040 int64_t max_enum_value;
1041 const struct sym *ec, *max_ec; 1041 const struct sym *ec, *max_ec;
1042 const type_t *lt, *rt; 1042 const type_t *lt, *rt;
1043 1043
1044 if (ln->tn_op != ADDR || ln->tn_left->tn_op != NAME) 1044 if (ln->tn_op != ADDR || ln->tn_left->tn_op != NAME)
1045 return; 1045 return;
1046 1046
1047 lt = ln->tn_left->tn_type; 1047 lt = ln->tn_left->tn_type;
1048 if (lt->t_tspec != ARRAY || lt->t_incomplete_array) 1048 if (lt->t_tspec != ARRAY || lt->t_incomplete_array)
1049 return; 1049 return;
1050 1050
1051 if (rn->tn_op != CVT || !rn->tn_type->t_is_enum) 1051 if (rn->tn_op != CVT || !rn->tn_type->t_is_enum)
1052 return; 1052 return;
1053 if (rn->tn_left->tn_op != LOAD) 1053 if (rn->tn_left->tn_op != LOAD)
1054 return; 1054 return;
1055 1055
1056 rt = rn->tn_left->tn_type; 1056 rt = rn->tn_left->tn_type;
1057 ec = rt->t_enum->en_first_enumerator; 1057 ec = rt->t_enum->en_first_enumerator;
1058 max_ec = ec; 1058 max_ec = ec;
1059 lint_assert(ec != NULL); 1059 lint_assert(ec != NULL);
1060 for (ec = ec->s_next; ec != NULL; ec = ec->s_next) 1060 for (ec = ec->s_next; ec != NULL; ec = ec->s_next)
1061 if (ec->u.s_enum_constant > max_ec->u.s_enum_constant) 1061 if (ec->u.s_enum_constant > max_ec->u.s_enum_constant)
1062 max_ec = ec; 1062 max_ec = ec;
1063 1063
1064 max_enum_value = max_ec->u.s_enum_constant; 1064 max_enum_value = max_ec->u.s_enum_constant;
1065 lint_assert(INT_MIN <= max_enum_value && max_enum_value <= INT_MAX); 1065 lint_assert(INT_MIN <= max_enum_value && max_enum_value <= INT_MAX);
1066 1066
1067 max_array_index = lt->t_dim - 1; 1067 max_array_index = lt->t_dim - 1;
1068 if (max_enum_value == max_array_index) 1068 if (max_enum_value == max_array_index)
1069 return; 1069 return;
1070 1070
1071 /* 1071 /*
1072 * If the name of the largest enum constant contains 'MAX' or 'NUM', 1072 * If the name of the largest enum constant contains 'MAX' or 'NUM',
1073 * that constant is typically not part of the allowed enum values but 1073 * that constant is typically not part of the allowed enum values but
1074 * a marker for the number of actual enum values. 1074 * a marker for the number of actual enum values.
1075 */ 1075 */
1076 if (max_enum_value == max_array_index + 1 && 1076 if (max_enum_value == max_array_index + 1 &&
1077 (strstr(max_ec->s_name, "MAX") != NULL || 1077 (strstr(max_ec->s_name, "MAX") != NULL ||
1078 strstr(max_ec->s_name, "max") != NULL || 1078 strstr(max_ec->s_name, "max") != NULL ||
1079 strstr(max_ec->s_name, "NUM") != NULL || 1079 strstr(max_ec->s_name, "NUM") != NULL ||
1080 strstr(max_ec->s_name, "num") != NULL)) 1080 strstr(max_ec->s_name, "num") != NULL))
1081 return; 1081 return;
1082 1082
1083 /* maximum value %d of '%s' does not match maximum array index %d */ 1083 /* maximum value %d of '%s' does not match maximum array index %d */
1084 warning(348, (int)max_enum_value, type_name(rt), max_array_index); 1084 warning(348, (int)max_enum_value, type_name(rt), max_array_index);
1085 print_previous_declaration(max_ec); 1085 print_previous_declaration(max_ec);
1086} 1086}
1087 1087
1088/* 1088/*
1089 * Create a node for operators PLUS and MINUS. 1089 * Create a node for operators PLUS and MINUS.
1090 */ 1090 */
1091static tnode_t * 1091static tnode_t *
1092build_plus_minus(op_t op, bool sys, tnode_t *ln, tnode_t *rn) 1092build_plus_minus(op_t op, bool sys, tnode_t *ln, tnode_t *rn)
1093{ 1093{
1094 1094
1095 /* If pointer and integer, then pointer to the lhs. */ 1095 /* If pointer and integer, then pointer to the lhs. */
1096 if (rn->tn_type->t_tspec == PTR && is_integer(ln->tn_type->t_tspec)) { 1096 if (rn->tn_type->t_tspec == PTR && is_integer(ln->tn_type->t_tspec)) {
1097 tnode_t *tmp = ln; 1097 tnode_t *tmp = ln;
1098 ln = rn; 1098 ln = rn;
1099 rn = tmp; 1099 rn = tmp;
1100 /* pointer addition has integer on the left-hand side */ 1100 /* pointer addition has integer on the left-hand side */
1101 query_message(5); 1101 query_message(5);
1102 } 1102 }
1103 1103
1104 /* pointer +- integer */ 1104 /* pointer +- integer */
1105 if (ln->tn_type->t_tspec == PTR && rn->tn_type->t_tspec != PTR) { 1105 if (ln->tn_type->t_tspec == PTR && rn->tn_type->t_tspec != PTR) {
1106 lint_assert(is_integer(rn->tn_type->t_tspec)); 1106 lint_assert(is_integer(rn->tn_type->t_tspec));
1107 1107
1108 check_ctype_macro_invocation(ln, rn); 1108 check_ctype_macro_invocation(ln, rn);
1109 check_enum_array_index(ln, rn); 1109 check_enum_array_index(ln, rn);
1110 1110
1111 tnode_t *elsz = subt_size_in_bytes(ln->tn_type); 1111 tnode_t *elsz = subt_size_in_bytes(ln->tn_type);
1112 if (rn->tn_type->t_tspec != elsz->tn_type->t_tspec) 1112 if (rn->tn_type->t_tspec != elsz->tn_type->t_tspec)
1113 rn = convert(NOOP, 0, elsz->tn_type, rn); 1113 rn = convert(NOOP, 0, elsz->tn_type, rn);
1114 1114
1115 tnode_t *prod = new_tnode(MULT, sys, rn->tn_type, rn, elsz); 1115 tnode_t *prod = new_tnode(MULT, sys, rn->tn_type, rn, elsz);
1116 if (rn->tn_op == CON) 1116 if (rn->tn_op == CON)
1117 prod = fold(prod); 1117 prod = fold(prod);
1118 1118
1119 return new_tnode(op, sys, ln->tn_type, ln, prod); 1119 return new_tnode(op, sys, ln->tn_type, ln, prod);
1120 } 1120 }
1121 1121
1122 /* pointer - pointer */ 1122 /* pointer - pointer */
1123 if (rn->tn_type->t_tspec == PTR) { 1123 if (rn->tn_type->t_tspec == PTR) {
1124 lint_assert(ln->tn_type->t_tspec == PTR); 1124 lint_assert(ln->tn_type->t_tspec == PTR);
1125 lint_assert(op == MINUS); 1125 lint_assert(op == MINUS);
1126 1126
1127 type_t *ptrdiff = gettyp(PTRDIFF_TSPEC); 1127 type_t *ptrdiff = gettyp(PTRDIFF_TSPEC);
1128 tnode_t *raw_diff = new_tnode(op, sys, ptrdiff, ln, rn); 1128 tnode_t *raw_diff = new_tnode(op, sys, ptrdiff, ln, rn);
1129 if (ln->tn_op == CON && rn->tn_op == CON) 1129 if (ln->tn_op == CON && rn->tn_op == CON)
1130 raw_diff = fold(raw_diff); 1130 raw_diff = fold(raw_diff);
1131 1131
1132 tnode_t *elsz = subt_size_in_bytes(ln->tn_type); 1132 tnode_t *elsz = subt_size_in_bytes(ln->tn_type);
1133 balance(NOOP, &raw_diff, &elsz); 1133 balance(NOOP, &raw_diff, &elsz);
1134 1134
1135 return new_tnode(DIV, sys, ptrdiff, raw_diff, elsz); 1135 return new_tnode(DIV, sys, ptrdiff, raw_diff, elsz);
1136 } 1136 }
1137 1137
1138 return new_tnode(op, sys, ln->tn_type, ln, rn); 1138 return new_tnode(op, sys, ln->tn_type, ln, rn);
1139} 1139}
1140 1140
1141/* 1141/*
1142 * Create a node for operators SHL and SHR. 1142 * Create a node for operators SHL and SHR.
1143 */ 1143 */
1144static tnode_t * 1144static tnode_t *
1145build_bit_shift(op_t op, bool sys, tnode_t *ln, tnode_t *rn) 1145build_bit_shift(op_t op, bool sys, tnode_t *ln, tnode_t *rn)
1146{ 1146{
1147 1147
1148 if (!allow_c90 && rn->tn_type->t_tspec != INT) 1148 if (!allow_c90 && rn->tn_type->t_tspec != INT)
1149 rn = convert(NOOP, 0, gettyp(INT), rn); 1149 rn = convert(NOOP, 0, gettyp(INT), rn);
1150 return new_tnode(op, sys, ln->tn_type, ln, rn); 1150 return new_tnode(op, sys, ln->tn_type, ln, rn);
1151} 1151}
1152 1152
1153static bool 1153static bool
1154is_null_pointer(const tnode_t *tn) 1154is_null_pointer(const tnode_t *tn)
1155{ 1155{
1156 tspec_t t = tn->tn_type->t_tspec; 1156 tspec_t t = tn->tn_type->t_tspec;
1157 1157
1158 return ((t == PTR && tn->tn_type->t_subt->t_tspec == VOID) || 1158 return ((t == PTR && tn->tn_type->t_subt->t_tspec == VOID) ||
1159 is_integer(t)) 1159 is_integer(t))
1160 && (tn->tn_op == CON && tn->tn_val->v_quad == 0); 1160 && (tn->tn_op == CON && tn->tn_val->v_quad == 0);
1161} 1161}
1162 1162
1163/* Return a type based on tp1, with added qualifiers from tp2. */ 1163/* Return a type based on tp1, with added qualifiers from tp2. */
1164static type_t * 1164static type_t *
1165merge_qualifiers(type_t *tp1, const type_t *tp2) 1165merge_qualifiers(type_t *tp1, const type_t *tp2)
1166{ 1166{
1167 type_t *ntp, *nstp; 1167 type_t *ntp, *nstp;
1168 bool c1, c2, v1, v2; 1168 bool c1, c2, v1, v2;
1169 1169
1170 lint_assert(tp1->t_tspec == PTR); 1170 lint_assert(tp1->t_tspec == PTR);
1171 lint_assert(tp2->t_tspec == PTR); 1171 lint_assert(tp2->t_tspec == PTR);
1172 1172
1173 c1 = tp1->t_subt->t_const; 1173 c1 = tp1->t_subt->t_const;
1174 c2 = tp2->t_subt->t_const; 1174 c2 = tp2->t_subt->t_const;
1175 v1 = tp1->t_subt->t_volatile; 1175 v1 = tp1->t_subt->t_volatile;
1176 v2 = tp2->t_subt->t_volatile; 1176 v2 = tp2->t_subt->t_volatile;
1177 1177
1178 if (c1 == (c1 | c2) && v1 == (v1 | v2)) 1178 if (c1 == (c1 | c2) && v1 == (v1 | v2))
1179 return tp1; 1179 return tp1;
1180 1180
1181 nstp = expr_dup_type(tp1->t_subt); 1181 nstp = expr_dup_type(tp1->t_subt);
1182 nstp->t_const |= c2; 1182 nstp->t_const |= c2;
1183 nstp->t_volatile |= v2; 1183 nstp->t_volatile |= v2;
1184 1184
1185 ntp = expr_dup_type(tp1); 1185 ntp = expr_dup_type(tp1);
1186 ntp->t_subt = nstp; 1186 ntp->t_subt = nstp;
1187 return ntp; 1187 return ntp;
1188} 1188}
1189 1189
1190/* See C99 6.5.15 "Conditional operator". */ 1190/* See C99 6.5.15 "Conditional operator". */
1191static tnode_t * 1191static tnode_t *
1192build_colon(bool sys, tnode_t *ln, tnode_t *rn) 1192build_colon(bool sys, tnode_t *ln, tnode_t *rn)
1193{ 1193{
1194 tspec_t lt, rt; 1194 tspec_t lt, rt;
1195 type_t *tp; 1195 type_t *tp;
1196 1196
1197 lt = ln->tn_type->t_tspec; 1197 lt = ln->tn_type->t_tspec;
1198 rt = rn->tn_type->t_tspec; 1198 rt = rn->tn_type->t_tspec;
1199 1199
1200 if (is_arithmetic(lt) && is_arithmetic(rt)) { 1200 if (is_arithmetic(lt) && is_arithmetic(rt)) {
1201 /* The operands were already balanced in build_binary. */ 1201 /* The operands were already balanced in build_binary. */
1202 tp = ln->tn_type; 1202 tp = ln->tn_type;
1203 } else if (lt == BOOL && rt == BOOL) { 1203 } else if (lt == BOOL && rt == BOOL) {
1204 tp = ln->tn_type; 1204 tp = ln->tn_type;
1205 } else if (lt == VOID || rt == VOID) { 1205 } else if (lt == VOID || rt == VOID) {
1206 tp = gettyp(VOID); 1206 tp = gettyp(VOID);
1207 } else if (is_struct_or_union(lt)) { 1207 } else if (is_struct_or_union(lt)) {
1208 /* Both types must be identical. */ 1208 /* Both types must be identical. */
1209 lint_assert(is_struct_or_union(rt)); 1209 lint_assert(is_struct_or_union(rt));
1210 lint_assert(ln->tn_type->t_str == rn->tn_type->t_str); 1210 lint_assert(ln->tn_type->t_str == rn->tn_type->t_str);
1211 if (is_incomplete(ln->tn_type)) { 1211 if (is_incomplete(ln->tn_type)) {
1212 /* unknown operand size, op '%s' */ 1212 /* unknown operand size, op '%s' */
1213 error(138, op_name(COLON)); 1213 error(138, op_name(COLON));
1214 return NULL; 1214 return NULL;
1215 } 1215 }
1216 tp = ln->tn_type; 1216 tp = ln->tn_type;
1217 } else if (lt == PTR && is_integer(rt)) { 1217 } else if (lt == PTR && is_integer(rt)) {
1218 if (rt != PTRDIFF_TSPEC) 1218 if (rt != PTRDIFF_TSPEC)
1219 rn = convert(NOOP, 0, gettyp(PTRDIFF_TSPEC), rn); 1219 rn = convert(NOOP, 0, gettyp(PTRDIFF_TSPEC), rn);
1220 tp = ln->tn_type; 1220 tp = ln->tn_type;
1221 } else if (rt == PTR && is_integer(lt)) { 1221 } else if (rt == PTR && is_integer(lt)) {
1222 if (lt != PTRDIFF_TSPEC) 1222 if (lt != PTRDIFF_TSPEC)
1223 ln = convert(NOOP, 0, gettyp(PTRDIFF_TSPEC), ln); 1223 ln = convert(NOOP, 0, gettyp(PTRDIFF_TSPEC), ln);
1224 tp = rn->tn_type; 1224 tp = rn->tn_type;
1225 } else if (lt == PTR && is_null_pointer(rn)) { 1225 } else if (lt == PTR && is_null_pointer(rn)) {
1226 tp = merge_qualifiers(ln->tn_type, rn->tn_type); 1226 tp = merge_qualifiers(ln->tn_type, rn->tn_type);
1227 } else if (rt == PTR && is_null_pointer(ln)) { 1227 } else if (rt == PTR && is_null_pointer(ln)) {
1228 tp = merge_qualifiers(rn->tn_type, ln->tn_type); 1228 tp = merge_qualifiers(rn->tn_type, ln->tn_type);
1229 } else if (lt == PTR && ln->tn_type->t_subt->t_tspec == VOID) { 1229 } else if (lt == PTR && ln->tn_type->t_subt->t_tspec == VOID) {
1230 tp = merge_qualifiers(ln->tn_type, rn->tn_type); 1230 tp = merge_qualifiers(ln->tn_type, rn->tn_type);
1231 } else if (rt == PTR && rn->tn_type->t_subt->t_tspec == VOID) { 1231 } else if (rt == PTR && rn->tn_type->t_subt->t_tspec == VOID) {
1232 tp = merge_qualifiers(rn->tn_type, ln->tn_type); 1232 tp = merge_qualifiers(rn->tn_type, ln->tn_type);
1233 } else { 1233 } else {
1234 /* 1234 /*
1235 * XXX For now we simply take the left type. This is 1235 * XXX For now we simply take the left type. This is
1236 * probably wrong, if one type contains a function prototype 1236 * probably wrong, if one type contains a function prototype
1237 * and the other one, at the same place, only an old-style 1237 * and the other one, at the same place, only an old-style
1238 * declaration. 1238 * declaration.
1239 */ 1239 */
1240 tp = merge_qualifiers(ln->tn_type, rn->tn_type); 1240 tp = merge_qualifiers(ln->tn_type, rn->tn_type);
1241 } 1241 }
1242 1242
1243 return new_tnode(COLON, sys, tp, ln, rn); 1243 return new_tnode(COLON, sys, tp, ln, rn);
1244} 1244}
1245 1245
1246/* TODO: check for varargs */ 1246/* TODO: check for varargs */
1247static bool 1247static bool
1248is_cast_redundant(const tnode_t *tn) 1248is_cast_redundant(const tnode_t *tn)
1249{ 1249{
1250 const type_t *ntp = tn->tn_type, *otp = tn->tn_left->tn_type; 1250 const type_t *ntp = tn->tn_type, *otp = tn->tn_left->tn_type;
1251 tspec_t nt = ntp->t_tspec, ot = otp->t_tspec; 1251 tspec_t nt = ntp->t_tspec, ot = otp->t_tspec;
1252 1252
1253 if (nt == BOOL || ot == BOOL) 1253 if (nt == BOOL || ot == BOOL)
1254 return nt == BOOL && ot == BOOL; 1254 return nt == BOOL && ot == BOOL;
1255 1255
1256 if (is_integer(nt) && is_integer(ot)) { 1256 if (is_integer(nt) && is_integer(ot)) {
1257 unsigned int nw = width_in_bits(ntp), ow = width_in_bits(otp); 1257 unsigned int nw = width_in_bits(ntp), ow = width_in_bits(otp);
1258 if (is_uinteger(nt) == is_uinteger(ot)) 1258 if (is_uinteger(nt) == is_uinteger(ot))
1259 return nw >= ow; 1259 return nw >= ow;
1260 return is_uinteger(ot) && nw > ow; 1260 return is_uinteger(ot) && nw > ow;
1261 } 1261 }
1262 1262
1263 if (is_complex(nt) || is_complex(ot)) 1263 if (is_complex(nt) || is_complex(ot))
1264 return is_complex(nt) && is_complex(ot) && 1264 return is_complex(nt) && is_complex(ot) &&
1265 size_in_bits(nt) >= size_in_bits(ot); 1265 size_in_bits(nt) >= size_in_bits(ot);
1266 1266
1267 if (is_floating(nt) && is_floating(ot)) 1267 if (is_floating(nt) && is_floating(ot))
1268 return size_in_bits(nt) >= size_in_bits(ot); 1268 return size_in_bits(nt) >= size_in_bits(ot);
1269 1269
1270 if (nt == PTR && ot == PTR) { 1270 if (nt == PTR && ot == PTR) {
1271 if (!ntp->t_subt->t_const && otp->t_subt->t_const) 1271 if (!ntp->t_subt->t_const && otp->t_subt->t_const)
1272 return false; 1272 return false;
1273 if (!ntp->t_subt->t_volatile && otp->t_subt->t_volatile) 1273 if (!ntp->t_subt->t_volatile && otp->t_subt->t_volatile)
1274 return false; 1274 return false;
1275 1275
1276 if (ntp->t_subt->t_tspec == VOID || 1276 if (ntp->t_subt->t_tspec == VOID ||
1277 otp->t_subt->t_tspec == VOID || 1277 otp->t_subt->t_tspec == VOID ||
1278 types_compatible(ntp->t_subt, otp->t_subt, 1278 types_compatible(ntp->t_subt, otp->t_subt,
1279 false, false, NULL)) 1279 false, false, NULL))
1280 return true; 1280 return true;
1281 } 1281 }
1282 1282
1283 return false; 1283 return false;
1284} 1284}
1285 1285
1286/* 1286/*
1287 * Create a node for an assignment operator (both = and op= ). 1287 * Create a node for an assignment operator (both = and op= ).
1288 */ 1288 */
1289static tnode_t * 1289static tnode_t *
1290build_assignment(op_t op, bool sys, tnode_t *ln, tnode_t *rn) 1290build_assignment(op_t op, bool sys, tnode_t *ln, tnode_t *rn)
1291{ 1291{
1292 tspec_t lt, rt; 1292 tspec_t lt, rt;
1293 tnode_t *ntn, *ctn; 1293 tnode_t *ntn, *ctn;
1294 1294
1295 lint_assert(ln != NULL); 1295 lint_assert(ln != NULL);
1296 lint_assert(rn != NULL); 1296 lint_assert(rn != NULL);
1297 1297
1298 lt = ln->tn_type->t_tspec; 1298 lt = ln->tn_type->t_tspec;
1299 rt = rn->tn_type->t_tspec; 1299 rt = rn->tn_type->t_tspec;
1300 1300
1301 if ((op == ADDASS || op == SUBASS) && lt == PTR) { 1301 if ((op == ADDASS || op == SUBASS) && lt == PTR) {
1302 lint_assert(is_integer(rt)); 1302 lint_assert(is_integer(rt));
1303 ctn = subt_size_in_bytes(ln->tn_type); 1303 ctn = subt_size_in_bytes(ln->tn_type);
1304 if (rn->tn_type->t_tspec != ctn->tn_type->t_tspec) 1304 if (rn->tn_type->t_tspec != ctn->tn_type->t_tspec)
1305 rn = convert(NOOP, 0, ctn->tn_type, rn); 1305 rn = convert(NOOP, 0, ctn->tn_type, rn);
1306 rn = new_tnode(MULT, sys, rn->tn_type, rn, ctn); 1306 rn = new_tnode(MULT, sys, rn->tn_type, rn, ctn);
1307 if (rn->tn_left->tn_op == CON) 1307 if (rn->tn_left->tn_op == CON)
1308 rn = fold(rn); 1308 rn = fold(rn);
1309 } 1309 }
1310 1310
1311 if ((op == ASSIGN || op == RETURN || op == INIT) && 1311 if ((op == ASSIGN || op == RETURN || op == INIT) &&
1312 (lt == STRUCT || rt == STRUCT)) { 1312 (lt == STRUCT || rt == STRUCT)) {
1313 lint_assert(lt == rt); 1313 lint_assert(lt == rt);
1314 lint_assert(ln->tn_type->t_str == rn->tn_type->t_str); 1314 lint_assert(ln->tn_type->t_str == rn->tn_type->t_str);
1315 if (is_incomplete(ln->tn_type)) { 1315 if (is_incomplete(ln->tn_type)) {
1316 if (op == RETURN) { 1316 if (op == RETURN) {
1317 /* cannot return incomplete type */ 1317 /* cannot return incomplete type */
1318 error(212); 1318 error(212);
1319 } else { 1319 } else {
1320 /* unknown operand size, op '%s' */ 1320 /* unknown operand size, op '%s' */
1321 error(138, op_name(op)); 1321 error(138, op_name(op));
1322 } 1322 }
1323 return NULL; 1323 return NULL;
1324 } 1324 }
1325 } 1325 }
1326 1326
1327 if (op == SHLASS) { 1327 if (op == SHLASS) {
1328 if (portable_size_in_bits(lt) < portable_size_in_bits(rt)) { 1328 if (portable_size_in_bits(lt) < portable_size_in_bits(rt)) {
1329 if (hflag) 1329 if (hflag)
1330 /* semantics of '%s' change in ANSI C; ... */ 1330 /* semantics of '%s' change in ANSI C; ... */
1331 warning(118, "<<="); 1331 warning(118, "<<=");
1332 } 1332 }
1333 } else if (op != SHRASS) { 1333 } else if (op != SHRASS) {
1334 if (op == ASSIGN || lt != PTR) { 1334 if (op == ASSIGN || lt != PTR) {
1335 if (lt != rt || 1335 if (lt != rt ||
1336 (ln->tn_type->t_bitfield && rn->tn_op == CON)) { 1336 (ln->tn_type->t_bitfield && rn->tn_op == CON)) {
1337 rn = convert(op, 0, ln->tn_type, rn); 1337 rn = convert(op, 0, ln->tn_type, rn);
1338 rt = lt; 1338 rt = lt;
1339 } 1339 }
1340 } 1340 }
1341 } 1341 }
1342 1342
1343 if (any_query_enabled && rn->tn_op == CVT && rn->tn_cast && 1343 if (any_query_enabled && rn->tn_op == CVT && rn->tn_cast &&
1344 types_compatible(ln->tn_type, rn->tn_type, false, false, NULL) && 1344 types_compatible(ln->tn_type, rn->tn_type, false, false, NULL) &&
1345 is_cast_redundant(rn)) { 1345 is_cast_redundant(rn)) {
1346 /* redundant cast from '%s' to '%s' before assignment */ 1346 /* redundant cast from '%s' to '%s' before assignment */
1347 query_message(7, 1347 query_message(7,
1348 type_name(rn->tn_left->tn_type), type_name(rn->tn_type)); 1348 type_name(rn->tn_left->tn_type), type_name(rn->tn_type));
1349 } 1349 }
1350 1350
1351 ntn = new_tnode(op, sys, ln->tn_type, ln, rn); 1351 ntn = new_tnode(op, sys, ln->tn_type, ln, rn);
1352 1352
1353 return ntn; 1353 return ntn;
1354} 1354}
1355 1355
1356/* 1356/*
1357 * Create a node for REAL, IMAG 1357 * Create a node for REAL, IMAG
1358 */ 1358 */
1359static tnode_t * 1359static tnode_t *
1360build_real_imag(op_t op, bool sys, tnode_t *ln) 1360build_real_imag(op_t op, bool sys, tnode_t *ln)
1361{ 1361{
1362 tnode_t *cn, *ntn; 1362 tnode_t *cn, *ntn;
1363 1363
1364 lint_assert(ln != NULL); 1364 lint_assert(ln != NULL);
1365 1365
1366 if (ln->tn_op == NAME) { 1366 if (ln->tn_op == NAME) {
1367 /* 1367 /*
1368 * This may be too much, but it avoids wrong warnings. 1368 * This may be too much, but it avoids wrong warnings.
1369 * See d_c99_complex_split.c. 1369 * See d_c99_complex_split.c.
1370 */ 1370 */
1371 mark_as_used(ln->tn_sym, false, false); 1371 mark_as_used(ln->tn_sym, false, false);
1372 mark_as_set(ln->tn_sym); 1372 mark_as_set(ln->tn_sym);
1373 } 1373 }
1374 1374
1375 switch (ln->tn_type->t_tspec) { 1375 switch (ln->tn_type->t_tspec) {
1376 case LCOMPLEX: 1376 case LCOMPLEX:
1377 /* XXX: integer and LDOUBLE don't match. */ 1377 /* XXX: integer and LDOUBLE don't match. */
1378 cn = build_integer_constant(LDOUBLE, (int64_t)1); 1378 cn = build_integer_constant(LDOUBLE, (int64_t)1);
1379 break; 1379 break;
1380 case DCOMPLEX: 1380 case DCOMPLEX:
1381 /* XXX: integer and DOUBLE don't match. */ 1381 /* XXX: integer and DOUBLE don't match. */
1382 cn = build_integer_constant(DOUBLE, (int64_t)1); 1382 cn = build_integer_constant(DOUBLE, (int64_t)1);
1383 break; 1383 break;
1384 case FCOMPLEX: 1384 case FCOMPLEX:
1385 /* XXX: integer and FLOAT don't match. */ 1385 /* XXX: integer and FLOAT don't match. */
1386 cn = build_integer_constant(FLOAT, (int64_t)1); 1386 cn = build_integer_constant(FLOAT, (int64_t)1);
1387 break; 1387 break;
1388 default: 1388 default:
1389 /* '__%s__' is illegal for type '%s' */ 1389 /* '__%s__' is illegal for type '%s' */
1390 error(276, op == REAL ? "real" : "imag", 1390 error(276, op == REAL ? "real" : "imag",
1391 type_name(ln->tn_type)); 1391 type_name(ln->tn_type));
1392 return NULL; 1392 return NULL;
1393 } 1393 }
1394 ntn = new_tnode(op, sys, cn->tn_type, ln, cn); 1394 ntn = new_tnode(op, sys, cn->tn_type, ln, cn);
1395 ntn->tn_lvalue = true; 1395 ntn->tn_lvalue = true;
1396 1396
1397 return ntn; 1397 return ntn;
1398} 1398}
1399 1399
1400static bool 1400static bool
1401is_confusing_precedence(op_t op, op_t lop, bool lparen, op_t rop, bool rparen) 1401is_confusing_precedence(op_t op, op_t lop, bool lparen, op_t rop, bool rparen)
1402{ 1402{
1403 1403
1404 if (op == SHL || op == SHR) { 1404 if (op == SHL || op == SHR) {
1405 if (!lparen && (lop == PLUS || lop == MINUS)) 1405 if (!lparen && (lop == PLUS || lop == MINUS))
1406 return true; 1406 return true;
1407 if (!rparen && (rop == PLUS || rop == MINUS)) 1407 if (!rparen && (rop == PLUS || rop == MINUS))
1408 return true; 1408 return true;
1409 return false; 1409 return false;
1410 } 1410 }
1411 1411
1412 if (op == LOGOR) { 1412 if (op == LOGOR) {
1413 if (!lparen && lop == LOGAND) 1413 if (!lparen && lop == LOGAND)
1414 return true; 1414 return true;
1415 if (!rparen && rop == LOGAND) 1415 if (!rparen && rop == LOGAND)
1416 return true; 1416 return true;
1417 return false; 1417 return false;
1418 } 1418 }
1419 1419
1420 lint_assert(op == BITAND || op == BITXOR || op == BITOR); 1420 lint_assert(op == BITAND || op == BITXOR || op == BITOR);
1421 if (!lparen && lop != op) { 1421 if (!lparen && lop != op) {
1422 if (lop == PLUS || lop == MINUS) 1422 if (lop == PLUS || lop == MINUS)
1423 return true; 1423 return true;
1424 if (lop == BITAND || lop == BITXOR) 1424 if (lop == BITAND || lop == BITXOR)
1425 return true; 1425 return true;
1426 } 1426 }
1427 if (!rparen && rop != op) { 1427 if (!rparen && rop != op) {
1428 if (rop == PLUS || rop == MINUS) 1428 if (rop == PLUS || rop == MINUS)
1429 return true; 1429 return true;
1430 if (rop == BITAND || rop == BITXOR) 1430 if (rop == BITAND || rop == BITXOR)
1431 return true; 1431 return true;
1432 } 1432 }
1433 return false; 1433 return false;
1434} 1434}
1435 1435
1436/* 1436/*
1437 * Print a warning if the given node has operands which should be 1437 * Print a warning if the given node has operands which should be
1438 * parenthesized. 1438 * parenthesized.
1439 * 1439 *
1440 * XXX Does not work if an operand is a constant expression. Constant 1440 * XXX Does not work if an operand is a constant expression. Constant
1441 * expressions are already folded. 1441 * expressions are already folded.
1442 */ 1442 */
1443static void 1443static void
1444check_precedence_confusion(tnode_t *tn) 1444check_precedence_confusion(tnode_t *tn)
1445{ 1445{
1446 tnode_t *ln, *rn; 1446 tnode_t *ln, *rn;
1447 1447
1448 if (!hflag) 1448 if (!hflag)
1449 return; 1449 return;
1450 1450
1451 debug_node(tn); 1451 debug_node(tn);
1452 1452
1453 lint_assert(is_binary(tn)); 1453 lint_assert(is_binary(tn));
1454 for (ln = tn->tn_left; ln->tn_op == CVT; ln = ln->tn_left) 1454 for (ln = tn->tn_left; ln->tn_op == CVT; ln = ln->tn_left)
1455 continue; 1455 continue;
1456 for (rn = tn->tn_right; rn->tn_op == CVT; rn = rn->tn_left) 1456 for (rn = tn->tn_right; rn->tn_op == CVT; rn = rn->tn_left)
1457 continue; 1457 continue;
1458 1458
1459 if (is_confusing_precedence(tn->tn_op, 1459 if (is_confusing_precedence(tn->tn_op,
1460 ln->tn_op, ln->tn_parenthesized, 1460 ln->tn_op, ln->tn_parenthesized,
1461 rn->tn_op, rn->tn_parenthesized)) { 1461 rn->tn_op, rn->tn_parenthesized)) {
1462 /* precedence confusion possible: parenthesize! */ 1462 /* precedence confusion possible: parenthesize! */
1463 warning(169); 1463 warning(169);
1464 } 1464 }
1465} 1465}
1466 1466
1467/* 1467/*
1468 * Fold constant nodes, as much as is needed for comparing the value with 0. 1468 * Fold constant nodes, as much as is needed for comparing the value with 0.
1469 */ 1469 */
1470static tnode_t * 1470static tnode_t *
1471fold_bool(tnode_t *tn) 1471fold_bool(tnode_t *tn)
1472{ 1472{
1473 bool l, r; 1473 bool l, r;
1474 val_t *v; 1474 val_t *v;
1475 1475
1476 v = xcalloc(1, sizeof(*v)); 1476 v = xcalloc(1, sizeof(*v));
1477 v->v_tspec = tn->tn_type->t_tspec; 1477 v->v_tspec = tn->tn_type->t_tspec;
1478 lint_assert(v->v_tspec == INT || (Tflag && v->v_tspec == BOOL)); 1478 lint_assert(v->v_tspec == INT || (Tflag && v->v_tspec == BOOL));
1479 1479
1480 l = constant_is_nonzero(tn->tn_left); 1480 l = constant_is_nonzero(tn->tn_left);
1481 r = is_binary(tn) && constant_is_nonzero(tn->tn_right); 1481 r = is_binary(tn) && constant_is_nonzero(tn->tn_right);
1482 1482
1483 switch (tn->tn_op) { 1483 switch (tn->tn_op) {
1484 case NOT: 1484 case NOT:
1485 if (hflag && !constcond_flag) 1485 if (hflag && !constcond_flag)
1486 /* constant argument to '!' */ 1486 /* constant argument to '!' */
1487 warning(239); 1487 warning(239);
1488 v->v_quad = !l ? 1 : 0; 1488 v->v_quad = !l ? 1 : 0;
1489 break; 1489 break;
1490 case LOGAND: 1490 case LOGAND:
1491 v->v_quad = l && r ? 1 : 0; 1491 v->v_quad = l && r ? 1 : 0;
1492 break; 1492 break;
1493 case LOGOR: 1493 case LOGOR:
1494 v->v_quad = l || r ? 1 : 0; 1494 v->v_quad = l || r ? 1 : 0;
1495 break; 1495 break;
1496 default: 1496 default:
1497 lint_assert(/*CONSTCOND*/false); 1497 lint_assert(/*CONSTCOND*/false);
1498 } 1498 }
1499 1499
1500 return build_constant(tn->tn_type, v); 1500 return build_constant(tn->tn_type, v);
1501} 1501}
1502 1502
1503static ldbl_t 1503static ldbl_t
1504floating_error_value(tspec_t t, ldbl_t lv) 1504floating_error_value(tspec_t t, ldbl_t lv)
1505{ 1505{
1506 if (t == FLOAT) 1506 if (t == FLOAT)
1507 return lv < 0 ? -FLT_MAX : FLT_MAX; 1507 return lv < 0 ? -FLT_MAX : FLT_MAX;
1508 if (t == DOUBLE) 1508 if (t == DOUBLE)
1509 return lv < 0 ? -DBL_MAX : DBL_MAX; 1509 return lv < 0 ? -DBL_MAX : DBL_MAX;
1510 /* 1510 /*
1511 * When lint is compiled on x86_64 to check for sparc64, it uses the 1511 * When NetBSD is cross-built in MKLINT=yes mode on x86_64 for
1512 * type 'long double' from x86_64, which is the Intel 80-bit format. 1512 * sparc64, tools/lint checks this code while building usr.bin/xlint.
1513 * The constant LDBL_MAX comes from the sparc64 preprocessor though 1513 * In that situation, lint uses the preprocessor for sparc64, in which
1514 * and uses the IEEE-754-binary128 format, with the same exponent 1514 * the type 'long double' is IEEE-754-binary128, affecting the macro
1515 * range but a wider mantissa. 1515 * LDBL_MAX below. The type 'long double', as well as the strtold
 1516 * implementation, comes from the host platform x86_64 though, where
 1517 * 'long double' consumes 128 bits as well but only uses 80 of them.
 1518 * The exponent range of the two 'long double' types is the same, but
 1519 * the maximum finite value differs due to the extended precision on
 1520 * sparc64.
1516 * 1521 *
1517 * To properly handle this situation, lint would have to implement the 1522 * To properly handle the data types of the target platform, lint
1518 * floating-point types in a platform-independent way, which is not 1523 * would have to implement the floating-point types in a
1519 * worth the effort, given how few programs practically use 'long 1524 * platform-independent way, which is not worth the effort, given how
1520 * double'. 1525 * few programs practically use 'long double'.
1521 * 
1522 * This caveat only affects cross builds. 
1523 */ 1526 */
1524 /* LINTED 248: floating-point constant out of range */ 1527 /* LINTED 248: floating-point constant out of range */
1525 ldbl_t max = LDBL_MAX; 1528 ldbl_t max = LDBL_MAX;
1526 return lv < 0 ? -max : max; 1529 return lv < 0 ? -max : max;
1527} 1530}
1528 1531
1529/* 1532/*
1530 * Fold constant nodes having operands with floating point type. 1533 * Fold constant nodes having operands with floating point type.
1531 */ 1534 */
1532static tnode_t * 1535static tnode_t *
1533fold_float(tnode_t *tn) 1536fold_float(tnode_t *tn)
1534{ 1537{
1535 val_t *v; 1538 val_t *v;
1536 tspec_t t; 1539 tspec_t t;
1537 ldbl_t lv, rv = 0; 1540 ldbl_t lv, rv = 0;
1538 1541
1539 fpe = 0; 1542 fpe = 0;
1540 v = xcalloc(1, sizeof(*v)); 1543 v = xcalloc(1, sizeof(*v));
1541 v->v_tspec = t = tn->tn_type->t_tspec; 1544 v->v_tspec = t = tn->tn_type->t_tspec;
1542 1545
1543 lint_assert(is_floating(t)); 1546 lint_assert(is_floating(t));
1544 lint_assert(t == tn->tn_left->tn_type->t_tspec); 1547 lint_assert(t == tn->tn_left->tn_type->t_tspec);
1545 lint_assert(!is_binary(tn) || t == tn->tn_right->tn_type->t_tspec); 1548 lint_assert(!is_binary(tn) || t == tn->tn_right->tn_type->t_tspec);
1546 1549
1547 lv = tn->tn_left->tn_val->v_ldbl; 1550 lv = tn->tn_left->tn_val->v_ldbl;
1548 if (is_binary(tn)) 1551 if (is_binary(tn))
1549 rv = tn->tn_right->tn_val->v_ldbl; 1552 rv = tn->tn_right->tn_val->v_ldbl;
1550 1553
1551 switch (tn->tn_op) { 1554 switch (tn->tn_op) {
1552 case UPLUS: 1555 case UPLUS:
1553 v->v_ldbl = lv; 1556 v->v_ldbl = lv;
1554 break; 1557 break;
1555 case UMINUS: 1558 case UMINUS:
1556 v->v_ldbl = -lv; 1559 v->v_ldbl = -lv;
1557 break; 1560 break;
1558 case MULT: 1561 case MULT:
1559 v->v_ldbl = lv * rv; 1562 v->v_ldbl = lv * rv;
1560 break; 1563 break;
1561 case DIV: 1564 case DIV:
1562 if (rv == 0.0) { 1565 if (rv == 0.0) {
1563 /* division by 0 */ 1566 /* division by 0 */
1564 error(139); 1567 error(139);
1565 v->v_ldbl = floating_error_value(t, lv); 1568 v->v_ldbl = floating_error_value(t, lv);
1566 } else { 1569 } else {
1567 v->v_ldbl = lv / rv; 1570 v->v_ldbl = lv / rv;
1568 } 1571 }
1569 break; 1572 break;
1570 case PLUS: 1573 case PLUS:
1571 v->v_ldbl = lv + rv; 1574 v->v_ldbl = lv + rv;
1572 break; 1575 break;
1573 case MINUS: 1576 case MINUS:
1574 v->v_ldbl = lv - rv; 1577 v->v_ldbl = lv - rv;
1575 break; 1578 break;
1576 case LT: 1579 case LT:
1577 v->v_quad = lv < rv ? 1 : 0; 1580 v->v_quad = lv < rv ? 1 : 0;
1578 break; 1581 break;
1579 case LE: 1582 case LE:
1580 v->v_quad = lv <= rv ? 1 : 0; 1583 v->v_quad = lv <= rv ? 1 : 0;
1581 break; 1584 break;
1582 case GE: 1585 case GE:
1583 v->v_quad = lv >= rv ? 1 : 0; 1586 v->v_quad = lv >= rv ? 1 : 0;
1584 break; 1587 break;
1585 case GT: 1588 case GT:
1586 v->v_quad = lv > rv ? 1 : 0; 1589 v->v_quad = lv > rv ? 1 : 0;
1587 break; 1590 break;
1588 case EQ: 1591 case EQ:
1589 v->v_quad = lv == rv ? 1 : 0; 1592 v->v_quad = lv == rv ? 1 : 0;
1590 break; 1593 break;
1591 case NE: 1594 case NE:
1592 v->v_quad = lv != rv ? 1 : 0; 1595 v->v_quad = lv != rv ? 1 : 0;
1593 break; 1596 break;
1594 default: 1597 default:
1595 lint_assert(/*CONSTCOND*/false); 1598 lint_assert(/*CONSTCOND*/false);
1596 } 1599 }
1597 1600
1598 lint_assert(fpe != 0 || isnan(v->v_ldbl) == 0); 1601 lint_assert(fpe != 0 || isnan(v->v_ldbl) == 0);
1599 if (is_complex(v->v_tspec)) { 1602 if (is_complex(v->v_tspec)) {
1600 /* 1603 /*
1601 * Don't warn, as lint doesn't model the imaginary part of 1604 * Don't warn, as lint doesn't model the imaginary part of
1602 * complex numbers. 1605 * complex numbers.
1603 */ 1606 */
1604 fpe = 0; 1607 fpe = 0;
1605 } else if (fpe != 0 || isfinite(v->v_ldbl) == 0 || 1608 } else if (fpe != 0 || isfinite(v->v_ldbl) == 0 ||
1606 (t == FLOAT && 1609 (t == FLOAT &&
1607 (v->v_ldbl > FLT_MAX || v->v_ldbl < -FLT_MAX)) || 1610 (v->v_ldbl > FLT_MAX || v->v_ldbl < -FLT_MAX)) ||
1608 (t == DOUBLE && 1611 (t == DOUBLE &&
1609 (v->v_ldbl > DBL_MAX || v->v_ldbl < -DBL_MAX))) { 1612 (v->v_ldbl > DBL_MAX || v->v_ldbl < -DBL_MAX))) {
1610 /* floating point overflow on operator '%s' */ 1613 /* floating point overflow on operator '%s' */
1611 warning(142, op_name(tn->tn_op)); 1614 warning(142, op_name(tn->tn_op));
1612 v->v_ldbl = floating_error_value(t, v->v_ldbl); 1615 v->v_ldbl = floating_error_value(t, v->v_ldbl);
1613 fpe = 0; 1616 fpe = 0;
1614 } 1617 }
1615 1618
1616 return build_constant(tn->tn_type, v); 1619 return build_constant(tn->tn_type, v);
1617} 1620}
1618 1621
1619/* 1622/*
1620 * Create a tree node for a binary operator and its two operands. Also called 1623 * Create a tree node for a binary operator and its two operands. Also called
1621 * for unary operators; in that case rn is NULL. 1624 * for unary operators; in that case rn is NULL.
1622 * 1625 *
1623 * Function calls, sizeof and casts are handled elsewhere. 1626 * Function calls, sizeof and casts are handled elsewhere.
1624 */ 1627 */
1625tnode_t * 1628tnode_t *
1626build_binary(tnode_t *ln, op_t op, bool sys, tnode_t *rn) 1629build_binary(tnode_t *ln, op_t op, bool sys, tnode_t *rn)
1627{ 1630{
1628 const mod_t *mp; 1631 const mod_t *mp;
1629 tnode_t *ntn; 1632 tnode_t *ntn;
1630 type_t *rettp; 1633 type_t *rettp;
1631 1634
1632 mp = &modtab[op]; 1635 mp = &modtab[op];
1633 1636
1634 /* If there was an error in one of the operands, return. */ 1637 /* If there was an error in one of the operands, return. */
1635 if (ln == NULL || (mp->m_binary && rn == NULL)) 1638 if (ln == NULL || (mp->m_binary && rn == NULL))
1636 return NULL; 1639 return NULL;
1637 1640
1638 /* 1641 /*
1639 * Apply class conversions to the left operand, but only if its 1642 * Apply class conversions to the left operand, but only if its
1640 * value is needed or it is compared with zero. 1643 * value is needed or it is compared with zero.
1641 */ 1644 */
1642 if (mp->m_value_context || mp->m_compares_with_zero) 1645 if (mp->m_value_context || mp->m_compares_with_zero)
1643 ln = cconv(ln); 1646 ln = cconv(ln);
1644 /* 1647 /*
1645 * The right operand is almost always in a test or value context, 1648 * The right operand is almost always in a test or value context,
1646 * except if it is a struct or union member. 1649 * except if it is a struct or union member.
1647 */ 1650 */
1648 if (mp->m_binary && op != ARROW && op != POINT) 1651 if (mp->m_binary && op != ARROW && op != POINT)
1649 rn = cconv(rn); 1652 rn = cconv(rn);
1650 1653
1651 /* 1654 /*
1652 * Print some warnings for comparisons of unsigned values with 1655 * Print some warnings for comparisons of unsigned values with
1653 * constants lower than or equal to null. This must be done 1656 * constants lower than or equal to null. This must be done
1654 * before promote() because otherwise unsigned char and unsigned 1657 * before promote() because otherwise unsigned char and unsigned
1655 * short would be promoted to int. Types are also tested to be 1658 * short would be promoted to int. Types are also tested to be
1656 * CHAR, which would also become int. 1659 * CHAR, which would also become int.
1657 */ 1660 */
1658 if (mp->m_comparison) 1661 if (mp->m_comparison)
1659 check_integer_comparison(op, ln, rn); 1662 check_integer_comparison(op, ln, rn);
1660 1663
1661 if (mp->m_value_context || mp->m_compares_with_zero) 1664 if (mp->m_value_context || mp->m_compares_with_zero)
1662 ln = promote(op, false, ln); 1665 ln = promote(op, false, ln);
1663 if (mp->m_binary && op != ARROW && op != POINT && 1666 if (mp->m_binary && op != ARROW && op != POINT &&
1664 op != ASSIGN && op != RETURN && op != INIT) { 1667 op != ASSIGN && op != RETURN && op != INIT) {
1665 rn = promote(op, false, rn); 1668 rn = promote(op, false, rn);
1666 } 1669 }
1667 1670
1668 /* 1671 /*
1669 * If the result of the operation is different for signed or 1672 * If the result of the operation is different for signed or
1670 * unsigned operands and one of the operands is signed only in 1673 * unsigned operands and one of the operands is signed only in
1671 * ANSI C, print a warning. 1674 * ANSI C, print a warning.
1672 */ 1675 */
1673 if (mp->m_warn_if_left_unsigned_in_c90 && 1676 if (mp->m_warn_if_left_unsigned_in_c90 &&
1674 ln->tn_op == CON && ln->tn_val->v_unsigned_since_c90) { 1677 ln->tn_op == CON && ln->tn_val->v_unsigned_since_c90) {
1675 /* ANSI C treats constant as unsigned, op '%s' */ 1678 /* ANSI C treats constant as unsigned, op '%s' */
1676 warning(218, mp->m_name); 1679 warning(218, mp->m_name);
1677 ln->tn_val->v_unsigned_since_c90 = false; 1680 ln->tn_val->v_unsigned_since_c90 = false;
1678 } 1681 }
1679 if (mp->m_warn_if_right_unsigned_in_c90 && 1682 if (mp->m_warn_if_right_unsigned_in_c90 &&
1680 rn->tn_op == CON && rn->tn_val->v_unsigned_since_c90) { 1683 rn->tn_op == CON && rn->tn_val->v_unsigned_since_c90) {
1681 /* ANSI C treats constant as unsigned, op '%s' */ 1684 /* ANSI C treats constant as unsigned, op '%s' */
1682 warning(218, mp->m_name); 1685 warning(218, mp->m_name);
1683 rn->tn_val->v_unsigned_since_c90 = false; 1686 rn->tn_val->v_unsigned_since_c90 = false;
1684 } 1687 }
1685 1688
1686 /* Make sure both operands are of the same type */ 1689 /* Make sure both operands are of the same type */
1687 if (mp->m_balance_operands || (!allow_c90 && (op == SHL || op == SHR))) 1690 if (mp->m_balance_operands || (!allow_c90 && (op == SHL || op == SHR)))
1688 balance(op, &ln, &rn); 1691 balance(op, &ln, &rn);
1689 1692
1690 /* 1693 /*
1691 * Check types for compatibility with the operation and mutual 1694 * Check types for compatibility with the operation and mutual
1692 * compatibility. Return if there are serious problems. 1695 * compatibility. Return if there are serious problems.
1693 */ 1696 */
1694 if (!typeok(op, 0, ln, rn)) 1697 if (!typeok(op, 0, ln, rn))
1695 return NULL; 1698 return NULL;
1696 1699
1697 /* And now create the node. */ 1700 /* And now create the node. */
1698 switch (op) { 1701 switch (op) {
1699 case POINT: 1702 case POINT:
1700 case ARROW: 1703 case ARROW:
1701 ntn = build_struct_access(op, sys, ln, rn); 1704 ntn = build_struct_access(op, sys, ln, rn);
1702 break; 1705 break;
1703 case INCAFT: 1706 case INCAFT:
1704 case DECAFT: 1707 case DECAFT:
1705 case INCBEF: 1708 case INCBEF:
1706 case DECBEF: 1709 case DECBEF:
1707 ntn = build_prepost_incdec(op, sys, ln); 1710 ntn = build_prepost_incdec(op, sys, ln);
1708 break; 1711 break;
1709 case ADDR: 1712 case ADDR:
1710 ntn = build_address(sys, ln, false); 1713 ntn = build_address(sys, ln, false);
1711 break; 1714 break;
1712 case INDIR: 1715 case INDIR:
1713 ntn = new_tnode(INDIR, sys, ln->tn_type->t_subt, ln, NULL); 1716 ntn = new_tnode(INDIR, sys, ln->tn_type->t_subt, ln, NULL);
1714 break; 1717 break;
1715 case PLUS: 1718 case PLUS:
1716 case MINUS: 1719 case MINUS:
1717 ntn = build_plus_minus(op, sys, ln, rn); 1720 ntn = build_plus_minus(op, sys, ln, rn);
1718 break; 1721 break;
1719 case SHL: 1722 case SHL:
1720 case SHR: 1723 case SHR:
1721 ntn = build_bit_shift(op, sys, ln, rn); 1724 ntn = build_bit_shift(op, sys, ln, rn);
1722 break; 1725 break;
1723 case COLON: 1726 case COLON:
1724 ntn = build_colon(sys, ln, rn); 1727 ntn = build_colon(sys, ln, rn);
1725 break; 1728 break;
1726 case ASSIGN: 1729 case ASSIGN:
1727 case MULASS: 1730 case MULASS:
1728 case DIVASS: 1731 case DIVASS:
1729 case MODASS: 1732 case MODASS:
1730 case ADDASS: 1733 case ADDASS:
1731 case SUBASS: 1734 case SUBASS:
1732 case SHLASS: 1735 case SHLASS:
1733 case SHRASS: 1736 case SHRASS:
1734 case ANDASS: 1737 case ANDASS:
1735 case XORASS: 1738 case XORASS:
1736 case ORASS: 1739 case ORASS:
1737 case RETURN: 1740 case RETURN:
1738 case INIT: 1741 case INIT:
1739 ntn = build_assignment(op, sys, ln, rn); 1742 ntn = build_assignment(op, sys, ln, rn);
1740 break; 1743 break;
1741 case COMMA: 1744 case COMMA:
1742 case QUEST: 1745 case QUEST:
1743 ntn = new_tnode(op, sys, rn->tn_type, ln, rn); 1746 ntn = new_tnode(op, sys, rn->tn_type, ln, rn);
1744 break; 1747 break;
1745 case REAL: 1748 case REAL:
1746 case IMAG: 1749 case IMAG:
1747 ntn = build_real_imag(op, sys, ln); 1750 ntn = build_real_imag(op, sys, ln);
1748 break; 1751 break;
1749 default: 1752 default:
1750 rettp = mp->m_returns_bool 1753 rettp = mp->m_returns_bool
1751 ? gettyp(Tflag ? BOOL : INT) : ln->tn_type; 1754 ? gettyp(Tflag ? BOOL : INT) : ln->tn_type;
1752 lint_assert(mp->m_binary == (rn != NULL)); 1755 lint_assert(mp->m_binary == (rn != NULL));
1753 ntn = new_tnode(op, sys, rettp, ln, rn); 1756 ntn = new_tnode(op, sys, rettp, ln, rn);
1754 break; 1757 break;
1755 } 1758 }
1756 1759
1757 /* Return if an error occurred. */ 1760 /* Return if an error occurred. */
1758 if (ntn == NULL) 1761 if (ntn == NULL)
1759 return NULL; 1762 return NULL;
1760 1763
1761 /* Print a warning if precedence confusion is possible */ 1764 /* Print a warning if precedence confusion is possible */
1762 if (mp->m_possible_precedence_confusion) 1765 if (mp->m_possible_precedence_confusion)
1763 check_precedence_confusion(ntn); 1766 check_precedence_confusion(ntn);
1764 1767
1765 /* 1768 /*
1766 * Print a warning if one of the operands is in a context where 1769 * Print a warning if one of the operands is in a context where
1767 * it is compared with zero and if this operand is a constant. 1770 * it is compared with zero and if this operand is a constant.
1768 */ 1771 */
1769 if (hflag && !constcond_flag && 1772 if (hflag && !constcond_flag &&
1770 mp->m_compares_with_zero && 1773 mp->m_compares_with_zero &&
1771 (ln->tn_op == CON || 1774 (ln->tn_op == CON ||
1772 ((mp->m_binary && op != QUEST) && rn->tn_op == CON)) && 1775 ((mp->m_binary && op != QUEST) && rn->tn_op == CON)) &&
1773 /* XXX: rn->tn_system_dependent should be checked as well */ 1776 /* XXX: rn->tn_system_dependent should be checked as well */
1774 !ln->tn_system_dependent) { 1777 !ln->tn_system_dependent) {
1775 /* constant in conditional context */ 1778 /* constant in conditional context */
1776 warning(161); 1779 warning(161);
1777 } 1780 }
1778 1781
1779 /* Fold if the operator requires it */ 1782 /* Fold if the operator requires it */
1780 if (mp->m_fold_constant_operands) { 1783 if (mp->m_fold_constant_operands) {
1781 if (ln->tn_op == CON && (!mp->m_binary || rn->tn_op == CON)) { 1784 if (ln->tn_op == CON && (!mp->m_binary || rn->tn_op == CON)) {
1782 if (mp->m_compares_with_zero) { 1785 if (mp->m_compares_with_zero) {
1783 ntn = fold_bool(ntn); 1786 ntn = fold_bool(ntn);
1784 } else if (is_floating(ntn->tn_type->t_tspec)) { 1787 } else if (is_floating(ntn->tn_type->t_tspec)) {
1785 ntn = fold_float(ntn); 1788 ntn = fold_float(ntn);
1786 } else { 1789 } else {
1787 ntn = fold(ntn); 1790 ntn = fold(ntn);
1788 } 1791 }
1789 } else if (op == QUEST && ln->tn_op == CON) { 1792 } else if (op == QUEST && ln->tn_op == CON) {
1790 ntn = ln->tn_val->v_quad != 0 1793 ntn = ln->tn_val->v_quad != 0
1791 ? rn->tn_left : rn->tn_right; 1794 ? rn->tn_left : rn->tn_right;
1792 } 1795 }
1793 } 1796 }
1794 1797
1795 return ntn; 1798 return ntn;
1796} 1799}
1797 1800
1798tnode_t * 1801tnode_t *
1799build_unary(op_t op, bool sys, tnode_t *tn) 1802build_unary(op_t op, bool sys, tnode_t *tn)
1800{ 1803{
1801 return build_binary(tn, op, sys, NULL); 1804 return build_binary(tn, op, sys, NULL);
1802} 1805}
1803 1806
1804/* 1807/*
1805 * Return whether all struct/union members with the same name have the same 1808 * Return whether all struct/union members with the same name have the same
1806 * type and offset. 1809 * type and offset.
1807 */ 1810 */
1808static bool 1811static bool
1809all_members_compatible(const sym_t *msym) 1812all_members_compatible(const sym_t *msym)
1810{ 1813{
1811 for (const sym_t *csym = msym; 1814 for (const sym_t *csym = msym;
1812 csym != NULL; csym = csym->s_symtab_next) { 1815 csym != NULL; csym = csym->s_symtab_next) {
1813 if (!is_member(csym)) 1816 if (!is_member(csym))
1814 continue; 1817 continue;
1815 if (strcmp(msym->s_name, csym->s_name) != 0) 1818 if (strcmp(msym->s_name, csym->s_name) != 0)
1816 continue; 1819 continue;
1817 1820
1818 for (const sym_t *sym = csym->s_symtab_next; 1821 for (const sym_t *sym = csym->s_symtab_next;
1819 sym != NULL; sym = sym->s_symtab_next) { 1822 sym != NULL; sym = sym->s_symtab_next) {
1820 1823
1821 if (!is_member(sym)) 1824 if (!is_member(sym))
1822 continue; 1825 continue;
1823 if (strcmp(csym->s_name, sym->s_name) != 0) 1826 if (strcmp(csym->s_name, sym->s_name) != 0)
1824 continue; 1827 continue;
1825 if (csym->u.s_member.sm_offset_in_bits != 1828 if (csym->u.s_member.sm_offset_in_bits !=
1826 sym->u.s_member.sm_offset_in_bits) 1829 sym->u.s_member.sm_offset_in_bits)
1827 return false; 1830 return false;
1828 1831
1829 bool w = false; 1832 bool w = false;
1830 if (!types_compatible(csym->s_type, sym->s_type, 1833 if (!types_compatible(csym->s_type, sym->s_type,
1831 false, false, &w) && !w) 1834 false, false, &w) && !w)
1832 return false; 1835 return false;
1833 if (csym->s_bitfield != sym->s_bitfield) 1836 if (csym->s_bitfield != sym->s_bitfield)
1834 return false; 1837 return false;
1835 if (csym->s_bitfield) { 1838 if (csym->s_bitfield) {
1836 type_t *tp1 = csym->s_type; 1839 type_t *tp1 = csym->s_type;
1837 type_t *tp2 = sym->s_type; 1840 type_t *tp2 = sym->s_type;
1838 if (tp1->t_flen != tp2->t_flen) 1841 if (tp1->t_flen != tp2->t_flen)
1839 return false; 1842 return false;
1840 if (tp1->t_foffs != tp2->t_foffs) 1843 if (tp1->t_foffs != tp2->t_foffs)
1841 return false; 1844 return false;
1842 } 1845 }
1843 } 1846 }
1844 } 1847 }
1845 return true; 1848 return true;
1846} 1849}
1847 1850
1848/* 1851/*
1849 * Returns a symbol which has the same name as the msym argument and is a 1852 * Returns a symbol which has the same name as the msym argument and is a
1850 * member of the struct or union specified by the tn argument. 1853 * member of the struct or union specified by the tn argument.
1851 */ 1854 */
1852static sym_t * 1855static sym_t *
1853struct_or_union_member(tnode_t *tn, op_t op, sym_t *msym) 1856struct_or_union_member(tnode_t *tn, op_t op, sym_t *msym)
1854{ 1857{
1855 struct_or_union *str; 1858 struct_or_union *str;
1856 type_t *tp; 1859 type_t *tp;
1857 tspec_t t; 1860 tspec_t t;
1858 1861
1859 /* 1862 /*
1860 * Remove the member if it was unknown until now, which means 1863 * Remove the member if it was unknown until now, which means
1861 * that no defined struct or union has a member with the same name. 1864 * that no defined struct or union has a member with the same name.
1862 */ 1865 */
1863 if (msym->s_scl == NOSCL) { 1866 if (msym->s_scl == NOSCL) {
1864 /* type '%s' does not have member '%s' */ 1867 /* type '%s' does not have member '%s' */
1865 error(101, type_name(tn->tn_type), msym->s_name); 1868 error(101, type_name(tn->tn_type), msym->s_name);
1866 rmsym(msym); 1869 rmsym(msym);
1867 msym->s_kind = FMEMBER; 1870 msym->s_kind = FMEMBER;
1868 msym->s_scl = STRUCT_MEMBER; 1871 msym->s_scl = STRUCT_MEMBER;
1869 1872
1870 struct_or_union *sou = expr_zero_alloc(sizeof(*sou)); 1873 struct_or_union *sou = expr_zero_alloc(sizeof(*sou));
1871 sou->sou_tag = expr_zero_alloc(sizeof(*sou->sou_tag)); 1874 sou->sou_tag = expr_zero_alloc(sizeof(*sou->sou_tag));
1872 sou->sou_tag->s_name = unnamed; 1875 sou->sou_tag->s_name = unnamed;
1873 1876
1874 msym->u.s_member.sm_sou_type = sou; 1877 msym->u.s_member.sm_sou_type = sou;
1875 /* 1878 /*
1876 * The member sm_offset_in_bits is not needed here since this 1879 * The member sm_offset_in_bits is not needed here since this
1877 * symbol can only be used for error reporting. 1880 * symbol can only be used for error reporting.
1878 */ 1881 */
1879 return msym; 1882 return msym;
1880 } 1883 }
1881 1884
1882 /* Set str to the tag of which msym is expected to be a member. */ 1885 /* Set str to the tag of which msym is expected to be a member. */
1883 str = NULL; 1886 str = NULL;
1884 t = (tp = tn->tn_type)->t_tspec; 1887 t = (tp = tn->tn_type)->t_tspec;
1885 if (op == POINT) { 1888 if (op == POINT) {
1886 if (is_struct_or_union(t)) 1889 if (is_struct_or_union(t))
1887 str = tp->t_str; 1890 str = tp->t_str;
1888 } else if (op == ARROW && t == PTR) { 1891 } else if (op == ARROW && t == PTR) {
1889 t = (tp = tp->t_subt)->t_tspec; 1892 t = (tp = tp->t_subt)->t_tspec;
1890 if (is_struct_or_union(t)) 1893 if (is_struct_or_union(t))
1891 str = tp->t_str; 1894 str = tp->t_str;
1892 } 1895 }
1893 1896
1894 /* 1897 /*
1895 * If this struct/union has a member with the name of msym, return it. 1898 * If this struct/union has a member with the name of msym, return it.
1896 */ 1899 */
1897 if (str != NULL) { 1900 if (str != NULL) {
1898 for (sym_t *sym = msym; 1901 for (sym_t *sym = msym;
1899 sym != NULL; sym = sym->s_symtab_next) { 1902 sym != NULL; sym = sym->s_symtab_next) {
1900 if (is_member(sym) && 1903 if (is_member(sym) &&
1901 sym->u.s_member.sm_sou_type == str && 1904 sym->u.s_member.sm_sou_type == str &&
1902 strcmp(sym->s_name, msym->s_name) == 0) 1905 strcmp(sym->s_name, msym->s_name) == 0)
1903 return sym; 1906 return sym;
1904 } 1907 }
1905 } 1908 }
1906 1909
1907 bool eq = all_members_compatible(msym); 1910 bool eq = all_members_compatible(msym);
1908 1911
1909 /* 1912 /*
1910 * Now handle the case in which the left operand refers really 1913 * Now handle the case in which the left operand refers really
1911 * to a struct/union, but the right operand is not member of it. 1914 * to a struct/union, but the right operand is not member of it.
1912 */ 1915 */
1913 if (str != NULL) { 1916 if (str != NULL) {
1914 if (eq && !allow_c90) { 1917 if (eq && !allow_c90) {
1915 /* illegal use of member '%s' */ 1918 /* illegal use of member '%s' */
1916 warning(102, msym->s_name); 1919 warning(102, msym->s_name);
1917 } else { 1920 } else {
1918 /* illegal use of member '%s' */ 1921 /* illegal use of member '%s' */
1919 error(102, msym->s_name); 1922 error(102, msym->s_name);
1920 } 1923 }
1921 return msym; 1924 return msym;
1922 } 1925 }
1923 1926
1924 /* 1927 /*
1925 * Now the left operand of ARROW does not point to a struct/union 1928 * Now the left operand of ARROW does not point to a struct/union
1926 * or the left operand of POINT is no struct/union. 1929 * or the left operand of POINT is no struct/union.
1927 */ 1930 */
1928 if (eq) { 1931 if (eq) {
1929 if (op == POINT) { 1932 if (op == POINT) {
1930 if (!allow_c90) { 1933 if (!allow_c90) {
1931 /* left operand of '.' must be struct ... */ 1934 /* left operand of '.' must be struct ... */
1932 warning(103, type_name(tn->tn_type)); 1935 warning(103, type_name(tn->tn_type));
1933 } else { 1936 } else {
1934 /* left operand of '.' must be struct ... */ 1937 /* left operand of '.' must be struct ... */
1935 error(103, type_name(tn->tn_type)); 1938 error(103, type_name(tn->tn_type));
1936 } 1939 }
1937 } else { 1940 } else {
1938 if (!allow_c90 && tn->tn_type->t_tspec == PTR) { 1941 if (!allow_c90 && tn->tn_type->t_tspec == PTR) {
1939 /* left operand of '->' must be pointer ... */ 1942 /* left operand of '->' must be pointer ... */
1940 warning(104, type_name(tn->tn_type)); 1943 warning(104, type_name(tn->tn_type));
1941 } else { 1944 } else {
1942 /* left operand of '->' must be pointer ... */ 1945 /* left operand of '->' must be pointer ... */
1943 error(104, type_name(tn->tn_type)); 1946 error(104, type_name(tn->tn_type));
1944 } 1947 }
1945 } 1948 }
1946 } else { 1949 } else {
1947 if (!allow_c90) { 1950 if (!allow_c90) {
1948 /* non-unique member requires struct/union %s */ 1951 /* non-unique member requires struct/union %s */
1949 error(105, op == POINT ? "object" : "pointer"); 1952 error(105, op == POINT ? "object" : "pointer");
1950 } else { 1953 } else {
1951 /* unacceptable operand of '%s' */ 1954 /* unacceptable operand of '%s' */
1952 error(111, op_name(op)); 1955 error(111, op_name(op));
1953 } 1956 }
1954 } 1957 }
1955 1958
1956 return msym; 1959 return msym;
1957} 1960}
1958 1961
1959tnode_t * 1962tnode_t *
1960build_member_access(tnode_t *ln, op_t op, bool sys, sbuf_t *member) 1963build_member_access(tnode_t *ln, op_t op, bool sys, sbuf_t *member)
1961{ 1964{
1962 sym_t *msym; 1965 sym_t *msym;
1963 1966
1964 if (ln == NULL) 1967 if (ln == NULL)
1965 return NULL; 1968 return NULL;
1966 1969
1967 if (op == ARROW) { 1970 if (op == ARROW) {
1968 /* must do this before struct_or_union_member is called */ 1971 /* must do this before struct_or_union_member is called */
1969 ln = cconv(ln); 1972 ln = cconv(ln);
1970 } 1973 }
1971 msym = struct_or_union_member(ln, op, getsym(member)); 1974 msym = struct_or_union_member(ln, op, getsym(member));
1972 return build_binary(ln, op, sys, build_name(msym, false)); 1975 return build_binary(ln, op, sys, build_name(msym, false));
1973} 1976}
1974 1977
1975/* 1978/*
1976 * Perform class conversions. 1979 * Perform class conversions.
1977 * 1980 *
1978 * Arrays of type T are converted into pointers to type T. 1981 * Arrays of type T are converted into pointers to type T.
1979 * Functions are converted to pointers to functions. 1982 * Functions are converted to pointers to functions.
1980 * Lvalues are converted to rvalues. 1983 * Lvalues are converted to rvalues.
1981 * 1984 *
1982 * C99 6.3 "Conversions" 1985 * C99 6.3 "Conversions"
1983 * C99 6.3.2 "Other operands" 1986 * C99 6.3.2 "Other operands"
1984 * C99 6.3.2.1 "Lvalues, arrays, and function designators" 1987 * C99 6.3.2.1 "Lvalues, arrays, and function designators"
1985 */ 1988 */
1986tnode_t * 1989tnode_t *
1987cconv(tnode_t *tn) 1990cconv(tnode_t *tn)
1988{ 1991{
1989 /* 1992 /*
1990 * Array-lvalue (array of type T) is converted into rvalue 1993 * Array-lvalue (array of type T) is converted into rvalue
1991 * (pointer to type T) 1994 * (pointer to type T)
1992 */ 1995 */
1993 if (tn->tn_type->t_tspec == ARRAY) { 1996 if (tn->tn_type->t_tspec == ARRAY) {
1994 if (!tn->tn_lvalue) { 1997 if (!tn->tn_lvalue) {
1995 /* XXX print correct operator */ 1998 /* XXX print correct operator */
1996 /* %soperand of '%s' must be lvalue */ 1999 /* %soperand of '%s' must be lvalue */
1997 gnuism(114, "", op_name(ADDR)); 2000 gnuism(114, "", op_name(ADDR));
1998 } 2001 }
1999 tn = new_tnode(ADDR, tn->tn_sys, 2002 tn = new_tnode(ADDR, tn->tn_sys,
2000 expr_derive_type(tn->tn_type->t_subt, PTR), tn, NULL); 2003 expr_derive_type(tn->tn_type->t_subt, PTR), tn, NULL);
2001 } 2004 }
2002 2005
2003 /* 2006 /*
2004 * Expression of type function (function with return value of type T) 2007 * Expression of type function (function with return value of type T)
2005 * in rvalue-expression (pointer to function with return value 2008 * in rvalue-expression (pointer to function with return value
2006 * of type T) 2009 * of type T)
2007 */ 2010 */
2008 if (tn->tn_type->t_tspec == FUNC) 2011 if (tn->tn_type->t_tspec == FUNC)
2009 tn = build_address(tn->tn_sys, tn, true); 2012 tn = build_address(tn->tn_sys, tn, true);
2010 2013
2011 /* lvalue to rvalue */ 2014 /* lvalue to rvalue */
2012 if (tn->tn_lvalue) { 2015 if (tn->tn_lvalue) {
2013 type_t *tp = expr_dup_type(tn->tn_type); 2016 type_t *tp = expr_dup_type(tn->tn_type);
2014 /* C99 6.3.2.1p2 sentence 2 says to remove the qualifiers. */ 2017 /* C99 6.3.2.1p2 sentence 2 says to remove the qualifiers. */
2015 tp->t_const = tp->t_volatile = false; 2018 tp->t_const = tp->t_volatile = false;
2016 tn = new_tnode(LOAD, tn->tn_sys, tp, tn, NULL); 2019 tn = new_tnode(LOAD, tn->tn_sys, tp, tn, NULL);
2017 } 2020 }
2018 2021
2019 return tn; 2022 return tn;
2020} 2023}
2021 2024
2022const tnode_t * 2025const tnode_t *
2023before_conversion(const tnode_t *tn) 2026before_conversion(const tnode_t *tn)
2024{ 2027{
2025 while (tn->tn_op == CVT && !tn->tn_cast) 2028 while (tn->tn_op == CVT && !tn->tn_cast)
2026 tn = tn->tn_left; 2029 tn = tn->tn_left;
2027 return tn; 2030 return tn;
2028} 2031}
2029 2032
2030/* 2033/*
2031 * Most errors required by ANSI C are reported in struct_or_union_member(). 2034 * Most errors required by ANSI C are reported in struct_or_union_member().
2032 * Here we only check for totally wrong things. 2035 * Here we only check for totally wrong things.
2033 */ 2036 */
2034static bool 2037static bool
2035typeok_point(const tnode_t *ln, const type_t *ltp, tspec_t lt) 2038typeok_point(const tnode_t *ln, const type_t *ltp, tspec_t lt)
2036{ 2039{
2037 if (is_struct_or_union(lt)) 2040 if (is_struct_or_union(lt))
2038 return true; 2041 return true;
2039 2042
2040 if (lt == FUNC || lt == VOID || ltp->t_bitfield) 2043 if (lt == FUNC || lt == VOID || ltp->t_bitfield)
2041 goto wrong; 2044 goto wrong;
2042 2045
2043 /* 2046 /*
2044 * Some C dialects from before C90 tolerated any lvalue on the 2047 * Some C dialects from before C90 tolerated any lvalue on the
2045 * left-hand side of the '.' operator, allowing things like 2048 * left-hand side of the '.' operator, allowing things like
2046 * char st[100]; st.st_mtime, assuming that the member 'st_mtime' 2049 * char st[100]; st.st_mtime, assuming that the member 'st_mtime'
2047 * only occurred in a single struct; see typeok_arrow. 2050 * only occurred in a single struct; see typeok_arrow.
2048 */ 2051 */
2049 if (ln->tn_lvalue) 2052 if (ln->tn_lvalue)
2050 return true; 2053 return true;
2051 2054
2052wrong: 2055wrong:
2053 /* With allow_c90 we already got an error */ 2056 /* With allow_c90 we already got an error */
2054 if (!allow_c90) 2057 if (!allow_c90)
2055 /* unacceptable operand of '%s' */ 2058 /* unacceptable operand of '%s' */
2056 error(111, op_name(POINT)); 2059 error(111, op_name(POINT));
2057 2060
2058 return false; 2061 return false;
2059} 2062}
2060 2063
2061static bool 2064static bool
2062typeok_arrow(tspec_t lt) 2065typeok_arrow(tspec_t lt)
2063{ 2066{
2064 /* 2067 /*
2065 * C1978 Appendix A 14.1 says: <quote>In fact, any lvalue is allowed 2068 * C1978 Appendix A 14.1 says: <quote>In fact, any lvalue is allowed
2066 * before '.', and that lvalue is then assumed to have the form of 2069 * before '.', and that lvalue is then assumed to have the form of
2067 * the structure of which the name of the right is a member. [...] 2070 * the structure of which the name of the right is a member. [...]
2068 * Such constructions are non-portable.</quote> 2071 * Such constructions are non-portable.</quote>
2069 */ 2072 */
2070 if (lt == PTR || (!allow_c90 && is_integer(lt))) 2073 if (lt == PTR || (!allow_c90 && is_integer(lt)))
2071 return true; 2074 return true;
2072 2075
2073 /* With allow_c90 we already got an error */ 2076 /* With allow_c90 we already got an error */
2074 if (!allow_c90) 2077 if (!allow_c90)
2075 /* unacceptable operand of '%s' */ 2078 /* unacceptable operand of '%s' */
2076 error(111, op_name(ARROW)); 2079 error(111, op_name(ARROW));
2077 return false; 2080 return false;
2078} 2081}
2079 2082
2080static bool 2083static bool
2081typeok_incdec(op_t op, const tnode_t *tn, const type_t *tp) 2084typeok_incdec(op_t op, const tnode_t *tn, const type_t *tp)
2082{ 2085{
2083 /* operand has scalar type (checked in typeok) */ 2086 /* operand has scalar type (checked in typeok) */
2084 if (!tn->tn_lvalue) { 2087 if (!tn->tn_lvalue) {
2085 if (tn->tn_op == CVT && tn->tn_cast && 2088 if (tn->tn_op == CVT && tn->tn_cast &&
2086 tn->tn_left->tn_op == LOAD) { 2089 tn->tn_left->tn_op == LOAD) {
2087 /* a cast does not yield an lvalue */ 2090 /* a cast does not yield an lvalue */
2088 error(163); 2091 error(163);
2089 } 2092 }
2090 /* %soperand of '%s' must be lvalue */ 2093 /* %soperand of '%s' must be lvalue */
2091 error(114, "", op_name(op)); 2094 error(114, "", op_name(op));
2092 return false; 2095 return false;
2093 } 2096 }
2094 if (tp->t_const && allow_c90) { 2097 if (tp->t_const && allow_c90) {
2095 /* %soperand of '%s' must be modifiable lvalue */ 2098 /* %soperand of '%s' must be modifiable lvalue */
2096 warning(115, "", op_name(op)); 2099 warning(115, "", op_name(op));
2097 } 2100 }
2098 return true; 2101 return true;
2099} 2102}
2100 2103
2101static bool 2104static bool
2102typeok_address(const mod_t *mp, 2105typeok_address(const mod_t *mp,
2103 const tnode_t *tn, const type_t *tp, tspec_t t) 2106 const tnode_t *tn, const type_t *tp, tspec_t t)
2104{ 2107{
2105 if (t == ARRAY || t == FUNC) { 2108 if (t == ARRAY || t == FUNC) {
2106 /* ok, a warning comes later (in build_address()) */ 2109 /* ok, a warning comes later (in build_address()) */
2107 } else if (!tn->tn_lvalue) { 2110 } else if (!tn->tn_lvalue) {
2108 if (tn->tn_op == CVT && tn->tn_cast && 2111 if (tn->tn_op == CVT && tn->tn_cast &&
2109 tn->tn_left->tn_op == LOAD) { 2112 tn->tn_left->tn_op == LOAD) {
2110 /* a cast does not yield an lvalue */ 2113 /* a cast does not yield an lvalue */
2111 error(163); 2114 error(163);
2112 } 2115 }
2113 /* %soperand of '%s' must be lvalue */ 2116 /* %soperand of '%s' must be lvalue */
2114 error(114, "", mp->m_name); 2117 error(114, "", mp->m_name);
2115 return false; 2118 return false;
2116 } else if (is_scalar(t)) { 2119 } else if (is_scalar(t)) {
2117 if (tp->t_bitfield) { 2120 if (tp->t_bitfield) {
2118 /* cannot take address of bit-field */ 2121 /* cannot take address of bit-field */
2119 error(112); 2122 error(112);
2120 return false; 2123 return false;
2121 } 2124 }
2122 } else if (t != STRUCT && t != UNION) { 2125 } else if (t != STRUCT && t != UNION) {
2123 /* unacceptable operand of '%s' */ 2126 /* unacceptable operand of '%s' */
2124 error(111, mp->m_name); 2127 error(111, mp->m_name);
2125 return false; 2128 return false;
2126 } 2129 }
2127 if (tn->tn_op == NAME && tn->tn_sym->s_register) { 2130 if (tn->tn_op == NAME && tn->tn_sym->s_register) {
2128 /* cannot take address of register '%s' */ 2131 /* cannot take address of register '%s' */
2129 error(113, tn->tn_sym->s_name); 2132 error(113, tn->tn_sym->s_name);
2130 return false; 2133 return false;
2131 } 2134 }
2132 return true; 2135 return true;
2133} 2136}
2134 2137
2135static bool 2138static bool
2136typeok_indir(const type_t *tp, tspec_t t) 2139typeok_indir(const type_t *tp, tspec_t t)
2137{ 2140{
2138 2141
2139 if (t != PTR) { 2142 if (t != PTR) {
2140 /* cannot dereference non-pointer type '%s' */ 2143 /* cannot dereference non-pointer type '%s' */
2141 error(96, type_name(tp)); 2144 error(96, type_name(tp));
2142 return false; 2145 return false;
2143 } 2146 }
2144 return true; 2147 return true;
2145} 2148}
2146 2149
2147static void 2150static void
2148warn_incompatible_types(op_t op, 2151warn_incompatible_types(op_t op,
2149 const type_t *ltp, tspec_t lt, 2152 const type_t *ltp, tspec_t lt,
2150 const type_t *rtp, tspec_t rt) 2153 const type_t *rtp, tspec_t rt)
2151{ 2154{
2152 const mod_t *mp = &modtab[op]; 2155 const mod_t *mp = &modtab[op];
2153 2156
2154 if (lt == VOID || (mp->m_binary && rt == VOID)) { 2157 if (lt == VOID || (mp->m_binary && rt == VOID)) {
2155 /* void type illegal in expression */ 2158 /* void type illegal in expression */
2156 error(109); 2159 error(109);
2157 } else if (op == ASSIGN) { 2160 } else if (op == ASSIGN) {
2158 /* cannot assign to '%s' from '%s' */ 2161 /* cannot assign to '%s' from '%s' */
2159 error(171, type_name(ltp), type_name(rtp)); 2162 error(171, type_name(ltp), type_name(rtp));
2160 } else if (mp->m_binary) { 2163 } else if (mp->m_binary) {
2161 /* operands of '%s' have incompatible types '%s' and '%s' */ 2164 /* operands of '%s' have incompatible types '%s' and '%s' */
2162 error(107, mp->m_name, tspec_name(lt), tspec_name(rt)); 2165 error(107, mp->m_name, tspec_name(lt), tspec_name(rt));
2163 } else { 2166 } else {
2164 lint_assert(rt == NOTSPEC); 2167 lint_assert(rt == NOTSPEC);
2165 /* operand of '%s' has invalid type '%s' */ 2168 /* operand of '%s' has invalid type '%s' */
2166 error(108, mp->m_name, type_name(ltp)); 2169 error(108, mp->m_name, type_name(ltp));
2167 } 2170 }
2168} 2171}
2169 2172
2170static bool 2173static bool
2171typeok_plus(op_t op, 2174typeok_plus(op_t op,
2172 const type_t *ltp, tspec_t lt, 2175 const type_t *ltp, tspec_t lt,
2173 const type_t *rtp, tspec_t rt) 2176 const type_t *rtp, tspec_t rt)
2174{ 2177{
2175 /* operands have scalar types (checked in typeok) */ 2178 /* operands have scalar types (checked in typeok) */
2176 if ((lt == PTR && !is_integer(rt)) || (rt == PTR && !is_integer(lt))) { 2179 if ((lt == PTR && !is_integer(rt)) || (rt == PTR && !is_integer(lt))) {
2177 warn_incompatible_types(op, ltp, lt, rtp, rt); 2180 warn_incompatible_types(op, ltp, lt, rtp, rt);
2178 return false; 2181 return false;
2179 } 2182 }
2180 return true; 2183 return true;
2181} 2184}
2182 2185
2183static bool 2186static bool
2184typeok_minus(op_t op, 2187typeok_minus(op_t op,
2185 const type_t *ltp, tspec_t lt, 2188 const type_t *ltp, tspec_t lt,
2186 const type_t *rtp, tspec_t rt) 2189 const type_t *rtp, tspec_t rt)
2187{ 2190{
2188 /* operands have scalar types (checked in typeok) */ 2191 /* operands have scalar types (checked in typeok) */
2189 if ((lt == PTR && rt != PTR && !is_integer(rt)) || 2192 if ((lt == PTR && rt != PTR && !is_integer(rt)) ||
2190 (lt != PTR && rt == PTR)) { 2193 (lt != PTR && rt == PTR)) {
2191 warn_incompatible_types(op, ltp, lt, rtp, rt); 2194 warn_incompatible_types(op, ltp, lt, rtp, rt);
2192 return false; 2195 return false;
2193 } 2196 }
2194 if (lt == PTR && rt == PTR && 2197 if (lt == PTR && rt == PTR &&
2195 !types_compatible(ltp->t_subt, rtp->t_subt, true, false, NULL)) { 2198 !types_compatible(ltp->t_subt, rtp->t_subt, true, false, NULL)) {
2196 /* illegal pointer subtraction */ 2199 /* illegal pointer subtraction */
2197 error(116); 2200 error(116);
2198 } 2201 }
2199 return true; 2202 return true;
2200} 2203}
2201 2204
2202static void 2205static void
2203typeok_shr(const mod_t *mp, 2206typeok_shr(const mod_t *mp,
2204 const tnode_t *ln, tspec_t lt, 2207 const tnode_t *ln, tspec_t lt,
2205 const tnode_t *rn, tspec_t rt) 2208 const tnode_t *rn, tspec_t rt)
2206{ 2209{
2207 tspec_t olt, ort; 2210 tspec_t olt, ort;
2208 2211
2209 olt = before_conversion(ln)->tn_type->t_tspec; 2212 olt = before_conversion(ln)->tn_type->t_tspec;
2210 ort = before_conversion(rn)->tn_type->t_tspec; 2213 ort = before_conversion(rn)->tn_type->t_tspec;
2211 2214
2212 /* operands have integer types (checked in typeok) */ 2215 /* operands have integer types (checked in typeok) */
2213 if (pflag && !is_uinteger(olt)) { 2216 if (pflag && !is_uinteger(olt)) {
2214 integer_constraints lc = ic_expr(ln); 2217 integer_constraints lc = ic_expr(ln);
2215 if (!ic_maybe_signed(ln->tn_type, &lc)) 2218 if (!ic_maybe_signed(ln->tn_type, &lc))
2216 return; 2219 return;
2217 2220
2218 /* 2221 /*
2219 * The left operand is signed. This means that 2222 * The left operand is signed. This means that
2220 * the operation is (possibly) nonportable. 2223 * the operation is (possibly) nonportable.
2221 */ 2224 */
2222 if (ln->tn_op != CON) { 2225 if (ln->tn_op != CON) {
2223 /* bitwise '%s' on signed value possibly nonportable */ 2226 /* bitwise '%s' on signed value possibly nonportable */
2224 warning(117, mp->m_name); 2227 warning(117, mp->m_name);
2225 } else if (ln->tn_val->v_quad < 0) { 2228 } else if (ln->tn_val->v_quad < 0) {
2226 /* bitwise '%s' on signed value nonportable */ 2229 /* bitwise '%s' on signed value nonportable */
2227 warning(120, mp->m_name); 2230 warning(120, mp->m_name);
2228 } 2231 }
2229 } else if (allow_trad && allow_c90 && 2232 } else if (allow_trad && allow_c90 &&
2230 !is_uinteger(olt) && is_uinteger(ort)) { 2233 !is_uinteger(olt) && is_uinteger(ort)) {
2231 /* The left operand would become unsigned in traditional C. */ 2234 /* The left operand would become unsigned in traditional C. */
2232 if (hflag && (ln->tn_op != CON || ln->tn_val->v_quad < 0)) { 2235 if (hflag && (ln->tn_op != CON || ln->tn_val->v_quad < 0)) {
2233 /* semantics of '%s' change in ANSI C; use ... */ 2236 /* semantics of '%s' change in ANSI C; use ... */
2234 warning(118, mp->m_name); 2237 warning(118, mp->m_name);
2235 } 2238 }
2236 } else if (allow_trad && allow_c90 && 2239 } else if (allow_trad && allow_c90 &&
2237 !is_uinteger(olt) && !is_uinteger(ort) && 2240 !is_uinteger(olt) && !is_uinteger(ort) &&
2238 portable_size_in_bits(lt) < portable_size_in_bits(rt)) { 2241 portable_size_in_bits(lt) < portable_size_in_bits(rt)) {
2239 /* 2242 /*
2240 * In traditional C the left operand would be extended 2243 * In traditional C the left operand would be extended
2241 * (possibly sign-extended) and then shifted. 2244 * (possibly sign-extended) and then shifted.
2242 */ 2245 */
2243 if (hflag && (ln->tn_op != CON || ln->tn_val->v_quad < 0)) { 2246 if (hflag && (ln->tn_op != CON || ln->tn_val->v_quad < 0)) {
2244 /* semantics of '%s' change in ANSI C; use ... */ 2247 /* semantics of '%s' change in ANSI C; use ... */
2245 warning(118, mp->m_name); 2248 warning(118, mp->m_name);
2246 } 2249 }
2247 } 2250 }
2248} 2251}
2249 2252
2250static void 2253static void
2251typeok_shl(const mod_t *mp, tspec_t lt, tspec_t rt) 2254typeok_shl(const mod_t *mp, tspec_t lt, tspec_t rt)
2252{ 2255{
2253 /* 2256 /*
2254 * C90 does not perform balancing for shift operations, 2257 * C90 does not perform balancing for shift operations,
2255 * but traditional C does. If the width of the right operand 2258 * but traditional C does. If the width of the right operand
2256 * is greater than the width of the left operand, then in 2259 * is greater than the width of the left operand, then in
2257 * traditional C the left operand would be extended to the 2260 * traditional C the left operand would be extended to the
2258 * width of the right operand. For SHL this may result in 2261 * width of the right operand. For SHL this may result in
2259 * different results. 2262 * different results.
2260 */ 2263 */
2261 if (portable_size_in_bits(lt) < portable_size_in_bits(rt)) { 2264 if (portable_size_in_bits(lt) < portable_size_in_bits(rt)) {
2262 /* 2265 /*
2263 * XXX If both operands are constant, make sure 2266 * XXX If both operands are constant, make sure
2264 * that there is really a difference between 2267 * that there is really a difference between
2265 * ANSI C and traditional C. 2268 * ANSI C and traditional C.
2266 */ 2269 */
2267 if (hflag && !allow_c99) 2270 if (hflag && !allow_c99)
2268 /* semantics of '%s' change in ANSI C; use ... */ 2271 /* semantics of '%s' change in ANSI C; use ... */
2269 warning(118, mp->m_name); 2272 warning(118, mp->m_name);
2270 } 2273 }
2271} 2274}
2272 2275
2273static void 2276static void
2274typeok_shift(const type_t *ltp, tspec_t lt, const tnode_t *rn, tspec_t rt) 2277typeok_shift(const type_t *ltp, tspec_t lt, const tnode_t *rn, tspec_t rt)
2275{ 2278{
2276 if (rn->tn_op != CON) 2279 if (rn->tn_op != CON)
2277 return; 2280 return;
2278 2281
2279 if (!is_uinteger(rt) && rn->tn_val->v_quad < 0) { 2282 if (!is_uinteger(rt) && rn->tn_val->v_quad < 0) {
2280 /* negative shift */ 2283 /* negative shift */
2281 warning(121); 2284 warning(121);
2282 } else if ((uint64_t)rn->tn_val->v_quad == 2285 } else if ((uint64_t)rn->tn_val->v_quad ==
2283 (uint64_t)size_in_bits(lt)) { 2286 (uint64_t)size_in_bits(lt)) {
2284 /* shift amount %u equals bit-size of '%s' */ 2287 /* shift amount %u equals bit-size of '%s' */
2285 warning(267, (unsigned)rn->tn_val->v_quad, type_name(ltp)); 2288 warning(267, (unsigned)rn->tn_val->v_quad, type_name(ltp));
2286 } else if ((uint64_t)rn->tn_val->v_quad > (uint64_t)size_in_bits(lt)) { 2289 } else if ((uint64_t)rn->tn_val->v_quad > (uint64_t)size_in_bits(lt)) {
2287 /* shift amount %llu is greater than bit-size %llu of '%s' */ 2290 /* shift amount %llu is greater than bit-size %llu of '%s' */
2288 warning(122, (unsigned long long)rn->tn_val->v_quad, 2291 warning(122, (unsigned long long)rn->tn_val->v_quad,
2289 (unsigned long long)size_in_bits(lt), 2292 (unsigned long long)size_in_bits(lt),
2290 tspec_name(lt)); 2293 tspec_name(lt));
2291 } 2294 }
2292} 2295}
2293 2296
2294static bool 2297static bool
2295is_typeok_eq(const tnode_t *ln, tspec_t lt, const tnode_t *rn, tspec_t rt) 2298is_typeok_eq(const tnode_t *ln, tspec_t lt, const tnode_t *rn, tspec_t rt)
2296{ 2299{
2297 if (lt == PTR && is_null_pointer(rn)) 2300 if (lt == PTR && is_null_pointer(rn))
2298 return true; 2301 return true;
2299 if (rt == PTR && is_null_pointer(ln)) 2302 if (rt == PTR && is_null_pointer(ln))
2300 return true; 2303 return true;
2301 return false; 2304 return false;
2302} 2305}
2303 2306
2304/* 2307/*
2305 * Called if incompatible pointer types are detected. 2308 * Called if incompatible pointer types are detected.
2306 * Print an appropriate warning. 2309 * Print an appropriate warning.
2307 */ 2310 */
2308static void 2311static void
2309warn_incompatible_pointers(const mod_t *mp, 2312warn_incompatible_pointers(const mod_t *mp,
2310 const type_t *ltp, const type_t *rtp) 2313 const type_t *ltp, const type_t *rtp)
2311{ 2314{
2312 lint_assert(ltp->t_tspec == PTR); 2315 lint_assert(ltp->t_tspec == PTR);
2313 lint_assert(rtp->t_tspec == PTR); 2316 lint_assert(rtp->t_tspec == PTR);
2314 2317
2315 tspec_t lt = ltp->t_subt->t_tspec; 2318 tspec_t lt = ltp->t_subt->t_tspec;
2316 tspec_t rt = rtp->t_subt->t_tspec; 2319 tspec_t rt = rtp->t_subt->t_tspec;
2317 2320
2318 if (is_struct_or_union(lt) && is_struct_or_union(rt)) { 2321 if (is_struct_or_union(lt) && is_struct_or_union(rt)) {
2319 if (mp == NULL) { 2322 if (mp == NULL) {
2320 /* illegal structure pointer combination */ 2323 /* illegal structure pointer combination */
2321 warning(244); 2324 warning(244);
2322 } else { 2325 } else {
2323 /* incompatible structure pointers: '%s' '%s' '%s' */ 2326 /* incompatible structure pointers: '%s' '%s' '%s' */
2324 warning(245, type_name(ltp), mp->m_name, type_name(rtp)); 2327 warning(245, type_name(ltp), mp->m_name, type_name(rtp));
2325 } 2328 }
2326 } else { 2329 } else {
2327 if (mp == NULL) { 2330 if (mp == NULL) {
2328 /* illegal combination of '%s' and '%s' */ 2331 /* illegal combination of '%s' and '%s' */
2329 warning(184, type_name(ltp), type_name(rtp)); 2332 warning(184, type_name(ltp), type_name(rtp));
2330 } else { 2333 } else {
2331 /* illegal combination of '%s' and '%s', op '%s' */ 2334 /* illegal combination of '%s' and '%s', op '%s' */
2332 warning(124, 2335 warning(124,
2333 type_name(ltp), type_name(rtp), mp->m_name); 2336 type_name(ltp), type_name(rtp), mp->m_name);
2334 } 2337 }
2335 } 2338 }
2336} 2339}
2337 2340
2338static void 2341static void
2339check_pointer_comparison(op_t op, const tnode_t *ln, const tnode_t *rn) 2342check_pointer_comparison(op_t op, const tnode_t *ln, const tnode_t *rn)
2340{ 2343{
2341 type_t *ltp = ln->tn_type, *rtp = rn->tn_type; 2344 type_t *ltp = ln->tn_type, *rtp = rn->tn_type;
2342 tspec_t lst = ltp->t_subt->t_tspec, rst = rtp->t_subt->t_tspec; 2345 tspec_t lst = ltp->t_subt->t_tspec, rst = rtp->t_subt->t_tspec;
2343 2346
2344 if (lst == VOID || rst == VOID) { 2347 if (lst == VOID || rst == VOID) {
2345 /* TODO: C99 behaves like C90 here. */ 2348 /* TODO: C99 behaves like C90 here. */
2346 if ((!allow_trad && !allow_c99) && 2349 if ((!allow_trad && !allow_c99) &&
2347 (lst == FUNC || rst == FUNC)) { 2350 (lst == FUNC || rst == FUNC)) {
2348 /* (void *)0 is already handled in typeok() */ 2351 /* (void *)0 is already handled in typeok() */
2349 const char *lsts, *rsts; 2352 const char *lsts, *rsts;
2350 *(lst == FUNC ? &lsts : &rsts) = "function pointer"; 2353 *(lst == FUNC ? &lsts : &rsts) = "function pointer";
2351 *(lst == VOID ? &lsts : &rsts) = "'void *'"; 2354 *(lst == VOID ? &lsts : &rsts) = "'void *'";
2352 /* ANSI C forbids comparison of %s with %s */ 2355 /* ANSI C forbids comparison of %s with %s */
2353 warning(274, lsts, rsts); 2356 warning(274, lsts, rsts);
2354 } 2357 }
2355 return; 2358 return;
2356 } 2359 }
2357 2360
2358 if (!types_compatible(ltp->t_subt, rtp->t_subt, true, false, NULL)) { 2361 if (!types_compatible(ltp->t_subt, rtp->t_subt, true, false, NULL)) {
2359 warn_incompatible_pointers(&modtab[op], ltp, rtp); 2362 warn_incompatible_pointers(&modtab[op], ltp, rtp);
2360 return; 2363 return;
2361 } 2364 }
2362 2365
2363 if (lst == FUNC && rst == FUNC) { 2366 if (lst == FUNC && rst == FUNC) {
2364 /* TODO: C99 behaves like C90 here, see C99 6.5.8p2. */ 2367 /* TODO: C99 behaves like C90 here, see C99 6.5.8p2. */
2365 if ((!allow_trad && !allow_c99) && op != EQ && op != NE) 2368 if ((!allow_trad && !allow_c99) && op != EQ && op != NE)
2366 /* ANSI C forbids ordered comparisons of ... */ 2369 /* ANSI C forbids ordered comparisons of ... */
2367 warning(125); 2370 warning(125);
2368 } 2371 }
2369} 2372}
2370 2373
2371static bool 2374static bool
2372typeok_compare(op_t op, 2375typeok_compare(op_t op,
2373 const tnode_t *ln, const type_t *ltp, tspec_t lt, 2376 const tnode_t *ln, const type_t *ltp, tspec_t lt,
2374 const tnode_t *rn, const type_t *rtp, tspec_t rt) 2377 const tnode_t *rn, const type_t *rtp, tspec_t rt)
2375{ 2378{
2376 if (lt == PTR && rt == PTR) { 2379 if (lt == PTR && rt == PTR) {
2377 check_pointer_comparison(op, ln, rn); 2380 check_pointer_comparison(op, ln, rn);
2378 return true; 2381 return true;
2379 } 2382 }
2380 2383
2381 if (lt != PTR && rt != PTR) 2384 if (lt != PTR && rt != PTR)
2382 return true; 2385 return true;
2383 2386
2384 if (!is_integer(lt) && !is_integer(rt)) { 2387 if (!is_integer(lt) && !is_integer(rt)) {
2385 warn_incompatible_types(op, ltp, lt, rtp, rt); 2388 warn_incompatible_types(op, ltp, lt, rtp, rt);
2386 return false; 2389 return false;
2387 } 2390 }
2388 2391
2389 const char *lx = lt == PTR ? "pointer" : "integer"; 2392 const char *lx = lt == PTR ? "pointer" : "integer";
2390 const char *rx = rt == PTR ? "pointer" : "integer"; 2393 const char *rx = rt == PTR ? "pointer" : "integer";
2391 /* illegal combination of %s '%s' and %s '%s', op '%s' */ 2394 /* illegal combination of %s '%s' and %s '%s', op '%s' */
2392 warning(123, lx, type_name(ltp), rx, type_name(rtp), op_name(op)); 2395 warning(123, lx, type_name(ltp), rx, type_name(rtp), op_name(op));
2393 return true; 2396 return true;
2394} 2397}
2395 2398
2396static bool 2399static bool
2397typeok_quest(tspec_t lt, const tnode_t *rn) 2400typeok_quest(tspec_t lt, const tnode_t *rn)
2398{ 2401{
2399 if (!is_scalar(lt)) { 2402 if (!is_scalar(lt)) {
2400 /* first operand must have scalar type, op ? : */ 2403 /* first operand must have scalar type, op ? : */
2401 error(170); 2404 error(170);
2402 return false; 2405 return false;
2403 } 2406 }
2404 lint_assert(before_conversion(rn)->tn_op == COLON); 2407 lint_assert(before_conversion(rn)->tn_op == COLON);
2405 return true; 2408 return true;
2406} 2409}
2407 2410
2408static void 2411static void
2409typeok_colon_pointer(const mod_t *mp, const type_t *ltp, const type_t *rtp) 2412typeok_colon_pointer(const mod_t *mp, const type_t *ltp, const type_t *rtp)
2410{ 2413{
2411 type_t *lstp = ltp->t_subt; 2414 type_t *lstp = ltp->t_subt;
2412 type_t *rstp = rtp->t_subt; 2415 type_t *rstp = rtp->t_subt;
2413 tspec_t lst = lstp->t_tspec; 2416 tspec_t lst = lstp->t_tspec;
2414 tspec_t rst = rstp->t_tspec; 2417 tspec_t rst = rstp->t_tspec;
2415 2418
2416 if ((lst == VOID && rst == FUNC) || (lst == FUNC && rst == VOID)) { 2419 if ((lst == VOID && rst == FUNC) || (lst == FUNC && rst == VOID)) {
2417 /* (void *)0 is handled in typeok_colon */ 2420 /* (void *)0 is handled in typeok_colon */
2418 /* TODO: C99 behaves like C90 here. */ 2421 /* TODO: C99 behaves like C90 here. */
2419 if (!allow_trad && !allow_c99) 2422 if (!allow_trad && !allow_c99)
2420 /* ANSI C forbids conversion of %s to %s, op %s */ 2423 /* ANSI C forbids conversion of %s to %s, op %s */
2421 warning(305, "function pointer", "'void *'", 2424 warning(305, "function pointer", "'void *'",
2422 mp->m_name); 2425 mp->m_name);
2423 return; 2426 return;
2424 } 2427 }
2425 2428
2426 if (pointer_types_are_compatible(lstp, rstp, true)) 2429 if (pointer_types_are_compatible(lstp, rstp, true))
2427 return; 2430 return;
2428 if (!types_compatible(lstp, rstp, true, false, NULL)) 2431 if (!types_compatible(lstp, rstp, true, false, NULL))
2429 warn_incompatible_pointers(mp, ltp, rtp); 2432 warn_incompatible_pointers(mp, ltp, rtp);
2430} 2433}
2431 2434
2432static bool 2435static bool
2433typeok_colon(const mod_t *mp, 2436typeok_colon(const mod_t *mp,
2434 const tnode_t *ln, const type_t *ltp, tspec_t lt, 2437 const tnode_t *ln, const type_t *ltp, tspec_t lt,
2435 const tnode_t *rn, const type_t *rtp, tspec_t rt) 2438 const tnode_t *rn, const type_t *rtp, tspec_t rt)
2436{ 2439{
2437 2440
2438 if (is_arithmetic(lt) && is_arithmetic(rt)) 2441 if (is_arithmetic(lt) && is_arithmetic(rt))
2439 return true; 2442 return true;
2440 if (lt == BOOL && rt == BOOL) 2443 if (lt == BOOL && rt == BOOL)
2441 return true; 2444 return true;
2442 2445
2443 if (lt == STRUCT && rt == STRUCT && ltp->t_str == rtp->t_str) 2446 if (lt == STRUCT && rt == STRUCT && ltp->t_str == rtp->t_str)
2444 return true; 2447 return true;
2445 if (lt == UNION && rt == UNION && ltp->t_str == rtp->t_str) 2448 if (lt == UNION && rt == UNION && ltp->t_str == rtp->t_str)
2446 return true; 2449 return true;
2447 2450
2448 if (lt == PTR && is_null_pointer(rn)) 2451 if (lt == PTR && is_null_pointer(rn))
2449 return true; 2452 return true;
2450 if (rt == PTR && is_null_pointer(ln)) 2453 if (rt == PTR && is_null_pointer(ln))
2451 return true; 2454 return true;
2452 2455
2453 if ((lt == PTR && is_integer(rt)) || (is_integer(lt) && rt == PTR)) { 2456 if ((lt == PTR && is_integer(rt)) || (is_integer(lt) && rt == PTR)) {
2454 const char *lx = lt == PTR ? "pointer" : "integer"; 2457 const char *lx = lt == PTR ? "pointer" : "integer";
2455 const char *rx = rt == PTR ? "pointer" : "integer"; 2458 const char *rx = rt == PTR ? "pointer" : "integer";
2456 /* illegal combination of %s '%s' and %s '%s', op '%s' */ 2459 /* illegal combination of %s '%s' and %s '%s', op '%s' */
2457 warning(123, lx, type_name(ltp), 2460 warning(123, lx, type_name(ltp),
2458 rx, type_name(rtp), mp->m_name); 2461 rx, type_name(rtp), mp->m_name);
2459 return true; 2462 return true;
2460 } 2463 }
2461 2464
2462 if (lt == VOID || rt == VOID) { 2465 if (lt == VOID || rt == VOID) {
2463 if (lt != VOID || rt != VOID) 2466 if (lt != VOID || rt != VOID)
2464 /* incompatible types '%s' and '%s' in conditional */ 2467 /* incompatible types '%s' and '%s' in conditional */
2465 warning(126, type_name(ltp), type_name(rtp)); 2468 warning(126, type_name(ltp), type_name(rtp));
2466 return true; 2469 return true;
2467 } 2470 }
2468 2471
2469 if (lt == PTR && rt == PTR) { 2472 if (lt == PTR && rt == PTR) {
2470 typeok_colon_pointer(mp, ltp, rtp); 2473 typeok_colon_pointer(mp, ltp, rtp);
2471 return true; 2474 return true;
2472 } 2475 }
2473 2476
2474 /* incompatible types '%s' and '%s' in conditional */ 2477 /* incompatible types '%s' and '%s' in conditional */
2475 error(126, type_name(ltp), type_name(rtp)); 2478 error(126, type_name(ltp), type_name(rtp));
2476 return false; 2479 return false;
2477} 2480}
2478 2481
2479/* 2482/*
2480 * Returns true if the given structure or union has a constant member 2483 * Returns true if the given structure or union has a constant member
2481 * (maybe recursively). 2484 * (maybe recursively).
2482 */ 2485 */
2483static bool 2486static bool
2484has_constant_member(const type_t *tp) 2487has_constant_member(const type_t *tp)
2485{ 2488{
2486 lint_assert(is_struct_or_union(tp->t_tspec)); 2489 lint_assert(is_struct_or_union(tp->t_tspec));
2487 2490
2488 for (sym_t *m = tp->t_str->sou_first_member; 2491 for (sym_t *m = tp->t_str->sou_first_member;
2489 m != NULL; m = m->s_next) { 2492 m != NULL; m = m->s_next) {
2490 const type_t *mtp = m->s_type; 2493 const type_t *mtp = m->s_type;
2491 if (mtp->t_const) 2494 if (mtp->t_const)
2492 return true; 2495 return true;
2493 if (is_struct_or_union(mtp->t_tspec) && 2496 if (is_struct_or_union(mtp->t_tspec) &&
2494 has_constant_member(mtp)) 2497 has_constant_member(mtp))
2495 return true; 2498 return true;
2496 } 2499 }
2497 return false; 2500 return false;
2498} 2501}
2499 2502
2500static bool 2503static bool
2501typeok_assign(op_t op, const tnode_t *ln, const type_t *ltp, tspec_t lt) 2504typeok_assign(op_t op, const tnode_t *ln, const type_t *ltp, tspec_t lt)
2502{ 2505{
2503 if (op == RETURN || op == INIT || op == FARG) 2506 if (op == RETURN || op == INIT || op == FARG)
2504 return true; 2507 return true;
2505 2508
2506 if (!ln->tn_lvalue) { 2509 if (!ln->tn_lvalue) {
2507 if (ln->tn_op == CVT && ln->tn_cast && 2510 if (ln->tn_op == CVT && ln->tn_cast &&
2508 ln->tn_left->tn_op == LOAD) { 2511 ln->tn_left->tn_op == LOAD) {
2509 /* a cast does not yield an lvalue */ 2512 /* a cast does not yield an lvalue */
2510 error(163); 2513 error(163);
2511 } 2514 }
2512 /* %soperand of '%s' must be lvalue */ 2515 /* %soperand of '%s' must be lvalue */
2513 error(114, "left ", op_name(op)); 2516 error(114, "left ", op_name(op));
2514 return false; 2517 return false;
2515 } else if (ltp->t_const || (is_struct_or_union(lt) && 2518 } else if (ltp->t_const || (is_struct_or_union(lt) &&
2516 has_constant_member(ltp))) { 2519 has_constant_member(ltp))) {
2517 if (allow_c90) 2520 if (allow_c90)
2518 /* %soperand of '%s' must be modifiable lvalue */ 2521 /* %soperand of '%s' must be modifiable lvalue */
2519 warning(115, "left ", op_name(op)); 2522 warning(115, "left ", op_name(op));
2520 } 2523 }
2521 return true; 2524 return true;