Wed Apr 12 19:09:48 2023 UTC ()
lint: suppress warnings about LDBL_MAX in cross-build mode

This fixes the cross build for sparc64 on x86_64, in which lint
complained:
	warning: floating-point constant out of range [248]
	warning: floating point overflow on operator '-' [142]
	warning: floating-point constant out of range [248]


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

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

--- src/usr.bin/xlint/lint1/tree.c 2023/04/11 19:40:04 1.511
+++ src/usr.bin/xlint/lint1/tree.c 2023/04/12 19:09:48 1.512
@@ -1,2509 +1,2525 @@ @@ -1,2509 +1,2525 @@
1/* $NetBSD: tree.c,v 1.511 2023/04/11 19:40:04 rillig Exp $ */ 1/* $NetBSD: tree.c,v 1.512 2023/04/12 19:09:48 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.511 2023/04/11 19:40:04 rillig Exp $"); 40__RCSID("$NetBSD: tree.c,v 1.512 2023/04/12 19:09:48 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 return lv < 0 ? -LDBL_MAX : LDBL_MAX; 1510 /*
 1511 * When lint is compiled on x86_64 to check for sparc64, it uses the
 1512 * type 'long double' from x86_64, which is the Intel 80-bit format.
 1513 * The constant LDBL_MAX comes from the sparc64 preprocessor though
 1514 * and uses the IEEE-754-binary128 format, with the same exponent
 1515 * range but a wider mantissa.
 1516 *
 1517 * To properly handle this situation, lint would have to implement the
 1518 * floating-point types in a platform-independent way, which is not
 1519 * worth the effort, given how few programs practically use 'long
 1520 * double'.
 1521 *
 1522 * This caveat only affects cross builds.
 1523 */
 1524 /* LINTED 248: floating-point constant out of range */
 1525 ldbl_t max = LDBL_MAX;
 1526 return lv < 0 ? -max : max;
1511} 1527}
1512 1528
1513/* 1529/*
1514 * Fold constant nodes having operands with floating point type. 1530 * Fold constant nodes having operands with floating point type.
1515 */ 1531 */
1516static tnode_t * 1532static tnode_t *
1517fold_float(tnode_t *tn) 1533fold_float(tnode_t *tn)
1518{ 1534{
1519 val_t *v; 1535 val_t *v;
1520 tspec_t t; 1536 tspec_t t;
1521 ldbl_t lv, rv = 0; 1537 ldbl_t lv, rv = 0;
1522 1538
1523 fpe = 0; 1539 fpe = 0;
1524 v = xcalloc(1, sizeof(*v)); 1540 v = xcalloc(1, sizeof(*v));
1525 v->v_tspec = t = tn->tn_type->t_tspec; 1541 v->v_tspec = t = tn->tn_type->t_tspec;
1526 1542
1527 lint_assert(is_floating(t)); 1543 lint_assert(is_floating(t));
1528 lint_assert(t == tn->tn_left->tn_type->t_tspec); 1544 lint_assert(t == tn->tn_left->tn_type->t_tspec);
1529 lint_assert(!is_binary(tn) || t == tn->tn_right->tn_type->t_tspec); 1545 lint_assert(!is_binary(tn) || t == tn->tn_right->tn_type->t_tspec);
1530 1546
1531 lv = tn->tn_left->tn_val->v_ldbl; 1547 lv = tn->tn_left->tn_val->v_ldbl;
1532 if (is_binary(tn)) 1548 if (is_binary(tn))
1533 rv = tn->tn_right->tn_val->v_ldbl; 1549 rv = tn->tn_right->tn_val->v_ldbl;
1534 1550
1535 switch (tn->tn_op) { 1551 switch (tn->tn_op) {
1536 case UPLUS: 1552 case UPLUS:
1537 v->v_ldbl = lv; 1553 v->v_ldbl = lv;
1538 break; 1554 break;
1539 case UMINUS: 1555 case UMINUS:
1540 v->v_ldbl = -lv; 1556 v->v_ldbl = -lv;
1541 break; 1557 break;
1542 case MULT: 1558 case MULT:
1543 v->v_ldbl = lv * rv; 1559 v->v_ldbl = lv * rv;
1544 break; 1560 break;
1545 case DIV: 1561 case DIV:
1546 if (rv == 0.0) { 1562 if (rv == 0.0) {
1547 /* division by 0 */ 1563 /* division by 0 */
1548 error(139); 1564 error(139);
1549 v->v_ldbl = floating_error_value(t, lv); 1565 v->v_ldbl = floating_error_value(t, lv);
1550 } else { 1566 } else {
1551 v->v_ldbl = lv / rv; 1567 v->v_ldbl = lv / rv;
1552 } 1568 }
1553 break; 1569 break;
1554 case PLUS: 1570 case PLUS:
1555 v->v_ldbl = lv + rv; 1571 v->v_ldbl = lv + rv;
1556 break; 1572 break;
1557 case MINUS: 1573 case MINUS:
1558 v->v_ldbl = lv - rv; 1574 v->v_ldbl = lv - rv;
1559 break; 1575 break;
1560 case LT: 1576 case LT:
1561 v->v_quad = lv < rv ? 1 : 0; 1577 v->v_quad = lv < rv ? 1 : 0;
1562 break; 1578 break;
1563 case LE: 1579 case LE:
1564 v->v_quad = lv <= rv ? 1 : 0; 1580 v->v_quad = lv <= rv ? 1 : 0;
1565 break; 1581 break;
1566 case GE: 1582 case GE:
1567 v->v_quad = lv >= rv ? 1 : 0; 1583 v->v_quad = lv >= rv ? 1 : 0;
1568 break; 1584 break;
1569 case GT: 1585 case GT:
1570 v->v_quad = lv > rv ? 1 : 0; 1586 v->v_quad = lv > rv ? 1 : 0;
1571 break; 1587 break;
1572 case EQ: 1588 case EQ:
1573 v->v_quad = lv == rv ? 1 : 0; 1589 v->v_quad = lv == rv ? 1 : 0;
1574 break; 1590 break;
1575 case NE: 1591 case NE:
1576 v->v_quad = lv != rv ? 1 : 0; 1592 v->v_quad = lv != rv ? 1 : 0;
1577 break; 1593 break;
1578 default: 1594 default:
1579 lint_assert(/*CONSTCOND*/false); 1595 lint_assert(/*CONSTCOND*/false);
1580 } 1596 }
1581 1597
1582 lint_assert(fpe != 0 || isnan(v->v_ldbl) == 0); 1598 lint_assert(fpe != 0 || isnan(v->v_ldbl) == 0);
1583 if (is_complex(v->v_tspec)) { 1599 if (is_complex(v->v_tspec)) {
1584 /* 1600 /*
1585 * Don't warn, as lint doesn't model the imaginary part of 1601 * Don't warn, as lint doesn't model the imaginary part of
1586 * complex numbers. 1602 * complex numbers.
1587 */ 1603 */
1588 fpe = 0; 1604 fpe = 0;
1589 } else if (fpe != 0 || isfinite(v->v_ldbl) == 0 || 1605 } else if (fpe != 0 || isfinite(v->v_ldbl) == 0 ||
1590 (t == FLOAT && 1606 (t == FLOAT &&
1591 (v->v_ldbl > FLT_MAX || v->v_ldbl < -FLT_MAX)) || 1607 (v->v_ldbl > FLT_MAX || v->v_ldbl < -FLT_MAX)) ||
1592 (t == DOUBLE && 1608 (t == DOUBLE &&
1593 (v->v_ldbl > DBL_MAX || v->v_ldbl < -DBL_MAX))) { 1609 (v->v_ldbl > DBL_MAX || v->v_ldbl < -DBL_MAX))) {
1594 /* floating point overflow on operator '%s' */ 1610 /* floating point overflow on operator '%s' */
1595 warning(142, op_name(tn->tn_op)); 1611 warning(142, op_name(tn->tn_op));
1596 v->v_ldbl = floating_error_value(t, v->v_ldbl); 1612 v->v_ldbl = floating_error_value(t, v->v_ldbl);
1597 fpe = 0; 1613 fpe = 0;
1598 } 1614 }
1599 1615
1600 return build_constant(tn->tn_type, v); 1616 return build_constant(tn->tn_type, v);
1601} 1617}
1602 1618
1603/* 1619/*
1604 * Create a tree node for a binary operator and its two operands. Also called 1620 * Create a tree node for a binary operator and its two operands. Also called
1605 * for unary operators; in that case rn is NULL. 1621 * for unary operators; in that case rn is NULL.
1606 * 1622 *
1607 * Function calls, sizeof and casts are handled elsewhere. 1623 * Function calls, sizeof and casts are handled elsewhere.
1608 */ 1624 */
1609tnode_t * 1625tnode_t *
1610build_binary(tnode_t *ln, op_t op, bool sys, tnode_t *rn) 1626build_binary(tnode_t *ln, op_t op, bool sys, tnode_t *rn)
1611{ 1627{
1612 const mod_t *mp; 1628 const mod_t *mp;
1613 tnode_t *ntn; 1629 tnode_t *ntn;
1614 type_t *rettp; 1630 type_t *rettp;
1615 1631
1616 mp = &modtab[op]; 1632 mp = &modtab[op];
1617 1633
1618 /* If there was an error in one of the operands, return. */ 1634 /* If there was an error in one of the operands, return. */
1619 if (ln == NULL || (mp->m_binary && rn == NULL)) 1635 if (ln == NULL || (mp->m_binary && rn == NULL))
1620 return NULL; 1636 return NULL;
1621 1637
1622 /* 1638 /*
1623 * Apply class conversions to the left operand, but only if its 1639 * Apply class conversions to the left operand, but only if its
1624 * value is needed or it is compared with zero. 1640 * value is needed or it is compared with zero.
1625 */ 1641 */
1626 if (mp->m_value_context || mp->m_compares_with_zero) 1642 if (mp->m_value_context || mp->m_compares_with_zero)
1627 ln = cconv(ln); 1643 ln = cconv(ln);
1628 /* 1644 /*
1629 * The right operand is almost always in a test or value context, 1645 * The right operand is almost always in a test or value context,
1630 * except if it is a struct or union member. 1646 * except if it is a struct or union member.
1631 */ 1647 */
1632 if (mp->m_binary && op != ARROW && op != POINT) 1648 if (mp->m_binary && op != ARROW && op != POINT)
1633 rn = cconv(rn); 1649 rn = cconv(rn);
1634 1650
1635 /* 1651 /*
1636 * Print some warnings for comparisons of unsigned values with 1652 * Print some warnings for comparisons of unsigned values with
1637 * constants lower than or equal to null. This must be done 1653 * constants lower than or equal to null. This must be done
1638 * before promote() because otherwise unsigned char and unsigned 1654 * before promote() because otherwise unsigned char and unsigned
1639 * short would be promoted to int. Types are also tested to be 1655 * short would be promoted to int. Types are also tested to be
1640 * CHAR, which would also become int. 1656 * CHAR, which would also become int.
1641 */ 1657 */
1642 if (mp->m_comparison) 1658 if (mp->m_comparison)
1643 check_integer_comparison(op, ln, rn); 1659 check_integer_comparison(op, ln, rn);
1644 1660
1645 if (mp->m_value_context || mp->m_compares_with_zero) 1661 if (mp->m_value_context || mp->m_compares_with_zero)
1646 ln = promote(op, false, ln); 1662 ln = promote(op, false, ln);
1647 if (mp->m_binary && op != ARROW && op != POINT && 1663 if (mp->m_binary && op != ARROW && op != POINT &&
1648 op != ASSIGN && op != RETURN && op != INIT) { 1664 op != ASSIGN && op != RETURN && op != INIT) {
1649 rn = promote(op, false, rn); 1665 rn = promote(op, false, rn);
1650 } 1666 }
1651 1667
1652 /* 1668 /*
1653 * If the result of the operation is different for signed or 1669 * If the result of the operation is different for signed or
1654 * unsigned operands and one of the operands is signed only in 1670 * unsigned operands and one of the operands is signed only in
1655 * ANSI C, print a warning. 1671 * ANSI C, print a warning.
1656 */ 1672 */
1657 if (mp->m_warn_if_left_unsigned_in_c90 && 1673 if (mp->m_warn_if_left_unsigned_in_c90 &&
1658 ln->tn_op == CON && ln->tn_val->v_unsigned_since_c90) { 1674 ln->tn_op == CON && ln->tn_val->v_unsigned_since_c90) {
1659 /* ANSI C treats constant as unsigned, op '%s' */ 1675 /* ANSI C treats constant as unsigned, op '%s' */
1660 warning(218, mp->m_name); 1676 warning(218, mp->m_name);
1661 ln->tn_val->v_unsigned_since_c90 = false; 1677 ln->tn_val->v_unsigned_since_c90 = false;
1662 } 1678 }
1663 if (mp->m_warn_if_right_unsigned_in_c90 && 1679 if (mp->m_warn_if_right_unsigned_in_c90 &&
1664 rn->tn_op == CON && rn->tn_val->v_unsigned_since_c90) { 1680 rn->tn_op == CON && rn->tn_val->v_unsigned_since_c90) {
1665 /* ANSI C treats constant as unsigned, op '%s' */ 1681 /* ANSI C treats constant as unsigned, op '%s' */
1666 warning(218, mp->m_name); 1682 warning(218, mp->m_name);
1667 rn->tn_val->v_unsigned_since_c90 = false; 1683 rn->tn_val->v_unsigned_since_c90 = false;
1668 } 1684 }
1669 1685
1670 /* Make sure both operands are of the same type */ 1686 /* Make sure both operands are of the same type */
1671 if (mp->m_balance_operands || (!allow_c90 && (op == SHL || op == SHR))) 1687 if (mp->m_balance_operands || (!allow_c90 && (op == SHL || op == SHR)))
1672 balance(op, &ln, &rn); 1688 balance(op, &ln, &rn);
1673 1689
1674 /* 1690 /*
1675 * Check types for compatibility with the operation and mutual 1691 * Check types for compatibility with the operation and mutual
1676 * compatibility. Return if there are serious problems. 1692 * compatibility. Return if there are serious problems.
1677 */ 1693 */
1678 if (!typeok(op, 0, ln, rn)) 1694 if (!typeok(op, 0, ln, rn))
1679 return NULL; 1695 return NULL;
1680 1696
1681 /* And now create the node. */ 1697 /* And now create the node. */
1682 switch (op) { 1698 switch (op) {
1683 case POINT: 1699 case POINT:
1684 case ARROW: 1700 case ARROW:
1685 ntn = build_struct_access(op, sys, ln, rn); 1701 ntn = build_struct_access(op, sys, ln, rn);
1686 break; 1702 break;
1687 case INCAFT: 1703 case INCAFT:
1688 case DECAFT: 1704 case DECAFT:
1689 case INCBEF: 1705 case INCBEF:
1690 case DECBEF: 1706 case DECBEF:
1691 ntn = build_prepost_incdec(op, sys, ln); 1707 ntn = build_prepost_incdec(op, sys, ln);
1692 break; 1708 break;
1693 case ADDR: 1709 case ADDR:
1694 ntn = build_address(sys, ln, false); 1710 ntn = build_address(sys, ln, false);
1695 break; 1711 break;
1696 case INDIR: 1712 case INDIR:
1697 ntn = new_tnode(INDIR, sys, ln->tn_type->t_subt, ln, NULL); 1713 ntn = new_tnode(INDIR, sys, ln->tn_type->t_subt, ln, NULL);
1698 break; 1714 break;
1699 case PLUS: 1715 case PLUS:
1700 case MINUS: 1716 case MINUS:
1701 ntn = build_plus_minus(op, sys, ln, rn); 1717 ntn = build_plus_minus(op, sys, ln, rn);
1702 break; 1718 break;
1703 case SHL: 1719 case SHL:
1704 case SHR: 1720 case SHR:
1705 ntn = build_bit_shift(op, sys, ln, rn); 1721 ntn = build_bit_shift(op, sys, ln, rn);
1706 break; 1722 break;
1707 case COLON: 1723 case COLON:
1708 ntn = build_colon(sys, ln, rn); 1724 ntn = build_colon(sys, ln, rn);
1709 break; 1725 break;
1710 case ASSIGN: 1726 case ASSIGN:
1711 case MULASS: 1727 case MULASS:
1712 case DIVASS: 1728 case DIVASS:
1713 case MODASS: 1729 case MODASS:
1714 case ADDASS: 1730 case ADDASS:
1715 case SUBASS: 1731 case SUBASS:
1716 case SHLASS: 1732 case SHLASS:
1717 case SHRASS: 1733 case SHRASS:
1718 case ANDASS: 1734 case ANDASS:
1719 case XORASS: 1735 case XORASS:
1720 case ORASS: 1736 case ORASS:
1721 case RETURN: 1737 case RETURN:
1722 case INIT: 1738 case INIT:
1723 ntn = build_assignment(op, sys, ln, rn); 1739 ntn = build_assignment(op, sys, ln, rn);
1724 break; 1740 break;
1725 case COMMA: 1741 case COMMA:
1726 case QUEST: 1742 case QUEST:
1727 ntn = new_tnode(op, sys, rn->tn_type, ln, rn); 1743 ntn = new_tnode(op, sys, rn->tn_type, ln, rn);
1728 break; 1744 break;
1729 case REAL: 1745 case REAL:
1730 case IMAG: 1746 case IMAG:
1731 ntn = build_real_imag(op, sys, ln); 1747 ntn = build_real_imag(op, sys, ln);
1732 break; 1748 break;
1733 default: 1749 default:
1734 rettp = mp->m_returns_bool 1750 rettp = mp->m_returns_bool
1735 ? gettyp(Tflag ? BOOL : INT) : ln->tn_type; 1751 ? gettyp(Tflag ? BOOL : INT) : ln->tn_type;
1736 lint_assert(mp->m_binary == (rn != NULL)); 1752 lint_assert(mp->m_binary == (rn != NULL));
1737 ntn = new_tnode(op, sys, rettp, ln, rn); 1753 ntn = new_tnode(op, sys, rettp, ln, rn);
1738 break; 1754 break;
1739 } 1755 }
1740 1756
1741 /* Return if an error occurred. */ 1757 /* Return if an error occurred. */
1742 if (ntn == NULL) 1758 if (ntn == NULL)
1743 return NULL; 1759 return NULL;
1744 1760
1745 /* Print a warning if precedence confusion is possible */ 1761 /* Print a warning if precedence confusion is possible */
1746 if (mp->m_possible_precedence_confusion) 1762 if (mp->m_possible_precedence_confusion)
1747 check_precedence_confusion(ntn); 1763 check_precedence_confusion(ntn);
1748 1764
1749 /* 1765 /*
1750 * Print a warning if one of the operands is in a context where 1766 * Print a warning if one of the operands is in a context where
1751 * it is compared with zero and if this operand is a constant. 1767 * it is compared with zero and if this operand is a constant.
1752 */ 1768 */
1753 if (hflag && !constcond_flag && 1769 if (hflag && !constcond_flag &&
1754 mp->m_compares_with_zero && 1770 mp->m_compares_with_zero &&
1755 (ln->tn_op == CON || 1771 (ln->tn_op == CON ||
1756 ((mp->m_binary && op != QUEST) && rn->tn_op == CON)) && 1772 ((mp->m_binary && op != QUEST) && rn->tn_op == CON)) &&
1757 /* XXX: rn->tn_system_dependent should be checked as well */ 1773 /* XXX: rn->tn_system_dependent should be checked as well */
1758 !ln->tn_system_dependent) { 1774 !ln->tn_system_dependent) {
1759 /* constant in conditional context */ 1775 /* constant in conditional context */
1760 warning(161); 1776 warning(161);
1761 } 1777 }
1762 1778
1763 /* Fold if the operator requires it */ 1779 /* Fold if the operator requires it */
1764 if (mp->m_fold_constant_operands) { 1780 if (mp->m_fold_constant_operands) {
1765 if (ln->tn_op == CON && (!mp->m_binary || rn->tn_op == CON)) { 1781 if (ln->tn_op == CON && (!mp->m_binary || rn->tn_op == CON)) {
1766 if (mp->m_compares_with_zero) { 1782 if (mp->m_compares_with_zero) {
1767 ntn = fold_bool(ntn); 1783 ntn = fold_bool(ntn);
1768 } else if (is_floating(ntn->tn_type->t_tspec)) { 1784 } else if (is_floating(ntn->tn_type->t_tspec)) {
1769 ntn = fold_float(ntn); 1785 ntn = fold_float(ntn);
1770 } else { 1786 } else {
1771 ntn = fold(ntn); 1787 ntn = fold(ntn);
1772 } 1788 }
1773 } else if (op == QUEST && ln->tn_op == CON) { 1789 } else if (op == QUEST && ln->tn_op == CON) {
1774 ntn = ln->tn_val->v_quad != 0 1790 ntn = ln->tn_val->v_quad != 0
1775 ? rn->tn_left : rn->tn_right; 1791 ? rn->tn_left : rn->tn_right;
1776 } 1792 }
1777 } 1793 }
1778 1794
1779 return ntn; 1795 return ntn;
1780} 1796}
1781 1797
1782tnode_t * 1798tnode_t *
1783build_unary(op_t op, bool sys, tnode_t *tn) 1799build_unary(op_t op, bool sys, tnode_t *tn)
1784{ 1800{
1785 return build_binary(tn, op, sys, NULL); 1801 return build_binary(tn, op, sys, NULL);
1786} 1802}
1787 1803
1788/* 1804/*
1789 * Return whether all struct/union members with the same name have the same 1805 * Return whether all struct/union members with the same name have the same
1790 * type and offset. 1806 * type and offset.
1791 */ 1807 */
1792static bool 1808static bool
1793all_members_compatible(const sym_t *msym) 1809all_members_compatible(const sym_t *msym)
1794{ 1810{
1795 for (const sym_t *csym = msym; 1811 for (const sym_t *csym = msym;
1796 csym != NULL; csym = csym->s_symtab_next) { 1812 csym != NULL; csym = csym->s_symtab_next) {
1797 if (!is_member(csym)) 1813 if (!is_member(csym))
1798 continue; 1814 continue;
1799 if (strcmp(msym->s_name, csym->s_name) != 0) 1815 if (strcmp(msym->s_name, csym->s_name) != 0)
1800 continue; 1816 continue;
1801 1817
1802 for (const sym_t *sym = csym->s_symtab_next; 1818 for (const sym_t *sym = csym->s_symtab_next;
1803 sym != NULL; sym = sym->s_symtab_next) { 1819 sym != NULL; sym = sym->s_symtab_next) {
1804 1820
1805 if (!is_member(sym)) 1821 if (!is_member(sym))
1806 continue; 1822 continue;
1807 if (strcmp(csym->s_name, sym->s_name) != 0) 1823 if (strcmp(csym->s_name, sym->s_name) != 0)
1808 continue; 1824 continue;
1809 if (csym->u.s_member.sm_offset_in_bits != 1825 if (csym->u.s_member.sm_offset_in_bits !=
1810 sym->u.s_member.sm_offset_in_bits) 1826 sym->u.s_member.sm_offset_in_bits)
1811 return false; 1827 return false;
1812 1828
1813 bool w = false; 1829 bool w = false;
1814 if (!types_compatible(csym->s_type, sym->s_type, 1830 if (!types_compatible(csym->s_type, sym->s_type,
1815 false, false, &w) && !w) 1831 false, false, &w) && !w)
1816 return false; 1832 return false;
1817 if (csym->s_bitfield != sym->s_bitfield) 1833 if (csym->s_bitfield != sym->s_bitfield)
1818 return false; 1834 return false;
1819 if (csym->s_bitfield) { 1835 if (csym->s_bitfield) {
1820 type_t *tp1 = csym->s_type; 1836 type_t *tp1 = csym->s_type;
1821 type_t *tp2 = sym->s_type; 1837 type_t *tp2 = sym->s_type;
1822 if (tp1->t_flen != tp2->t_flen) 1838 if (tp1->t_flen != tp2->t_flen)
1823 return false; 1839 return false;
1824 if (tp1->t_foffs != tp2->t_foffs) 1840 if (tp1->t_foffs != tp2->t_foffs)
1825 return false; 1841 return false;
1826 } 1842 }
1827 } 1843 }
1828 } 1844 }
1829 return true; 1845 return true;
1830} 1846}
1831 1847
1832/* 1848/*
1833 * Returns a symbol which has the same name as the msym argument and is a 1849 * Returns a symbol which has the same name as the msym argument and is a
1834 * member of the struct or union specified by the tn argument. 1850 * member of the struct or union specified by the tn argument.
1835 */ 1851 */
1836static sym_t * 1852static sym_t *
1837struct_or_union_member(tnode_t *tn, op_t op, sym_t *msym) 1853struct_or_union_member(tnode_t *tn, op_t op, sym_t *msym)
1838{ 1854{
1839 struct_or_union *str; 1855 struct_or_union *str;
1840 type_t *tp; 1856 type_t *tp;
1841 tspec_t t; 1857 tspec_t t;
1842 1858
1843 /* 1859 /*
1844 * Remove the member if it was unknown until now, which means 1860 * Remove the member if it was unknown until now, which means
1845 * that no defined struct or union has a member with the same name. 1861 * that no defined struct or union has a member with the same name.
1846 */ 1862 */
1847 if (msym->s_scl == NOSCL) { 1863 if (msym->s_scl == NOSCL) {
1848 /* type '%s' does not have member '%s' */ 1864 /* type '%s' does not have member '%s' */
1849 error(101, type_name(tn->tn_type), msym->s_name); 1865 error(101, type_name(tn->tn_type), msym->s_name);
1850 rmsym(msym); 1866 rmsym(msym);
1851 msym->s_kind = FMEMBER; 1867 msym->s_kind = FMEMBER;
1852 msym->s_scl = STRUCT_MEMBER; 1868 msym->s_scl = STRUCT_MEMBER;
1853 1869
1854 struct_or_union *sou = expr_zero_alloc(sizeof(*sou)); 1870 struct_or_union *sou = expr_zero_alloc(sizeof(*sou));
1855 sou->sou_tag = expr_zero_alloc(sizeof(*sou->sou_tag)); 1871 sou->sou_tag = expr_zero_alloc(sizeof(*sou->sou_tag));
1856 sou->sou_tag->s_name = unnamed; 1872 sou->sou_tag->s_name = unnamed;
1857 1873
1858 msym->u.s_member.sm_sou_type = sou; 1874 msym->u.s_member.sm_sou_type = sou;
1859 /* 1875 /*
1860 * The member sm_offset_in_bits is not needed here since this 1876 * The member sm_offset_in_bits is not needed here since this
1861 * symbol can only be used for error reporting. 1877 * symbol can only be used for error reporting.
1862 */ 1878 */
1863 return msym; 1879 return msym;
1864 } 1880 }
1865 1881
1866 /* Set str to the tag of which msym is expected to be a member. */ 1882 /* Set str to the tag of which msym is expected to be a member. */
1867 str = NULL; 1883 str = NULL;
1868 t = (tp = tn->tn_type)->t_tspec; 1884 t = (tp = tn->tn_type)->t_tspec;
1869 if (op == POINT) { 1885 if (op == POINT) {
1870 if (is_struct_or_union(t)) 1886 if (is_struct_or_union(t))
1871 str = tp->t_str; 1887 str = tp->t_str;
1872 } else if (op == ARROW && t == PTR) { 1888 } else if (op == ARROW && t == PTR) {
1873 t = (tp = tp->t_subt)->t_tspec; 1889 t = (tp = tp->t_subt)->t_tspec;
1874 if (is_struct_or_union(t)) 1890 if (is_struct_or_union(t))
1875 str = tp->t_str; 1891 str = tp->t_str;
1876 } 1892 }
1877 1893
1878 /* 1894 /*
1879 * If this struct/union has a member with the name of msym, return it. 1895 * If this struct/union has a member with the name of msym, return it.
1880 */ 1896 */
1881 if (str != NULL) { 1897 if (str != NULL) {
1882 for (sym_t *sym = msym; 1898 for (sym_t *sym = msym;
1883 sym != NULL; sym = sym->s_symtab_next) { 1899 sym != NULL; sym = sym->s_symtab_next) {
1884 if (is_member(sym) && 1900 if (is_member(sym) &&
1885 sym->u.s_member.sm_sou_type == str && 1901 sym->u.s_member.sm_sou_type == str &&
1886 strcmp(sym->s_name, msym->s_name) == 0) 1902 strcmp(sym->s_name, msym->s_name) == 0)
1887 return sym; 1903 return sym;
1888 } 1904 }
1889 } 1905 }
1890 1906
1891 bool eq = all_members_compatible(msym); 1907 bool eq = all_members_compatible(msym);
1892 1908
1893 /* 1909 /*
1894 * Now handle the case in which the left operand refers really 1910 * Now handle the case in which the left operand refers really
1895 * to a struct/union, but the right operand is not member of it. 1911 * to a struct/union, but the right operand is not member of it.
1896 */ 1912 */
1897 if (str != NULL) { 1913 if (str != NULL) {
1898 if (eq && !allow_c90) { 1914 if (eq && !allow_c90) {
1899 /* illegal use of member '%s' */ 1915 /* illegal use of member '%s' */
1900 warning(102, msym->s_name); 1916 warning(102, msym->s_name);
1901 } else { 1917 } else {
1902 /* illegal use of member '%s' */ 1918 /* illegal use of member '%s' */
1903 error(102, msym->s_name); 1919 error(102, msym->s_name);
1904 } 1920 }
1905 return msym; 1921 return msym;
1906 } 1922 }
1907 1923
1908 /* 1924 /*
1909 * Now the left operand of ARROW does not point to a struct/union 1925 * Now the left operand of ARROW does not point to a struct/union
1910 * or the left operand of POINT is no struct/union. 1926 * or the left operand of POINT is no struct/union.
1911 */ 1927 */
1912 if (eq) { 1928 if (eq) {
1913 if (op == POINT) { 1929 if (op == POINT) {
1914 if (!allow_c90) { 1930 if (!allow_c90) {
1915 /* left operand of '.' must be struct ... */ 1931 /* left operand of '.' must be struct ... */
1916 warning(103, type_name(tn->tn_type)); 1932 warning(103, type_name(tn->tn_type));
1917 } else { 1933 } else {
1918 /* left operand of '.' must be struct ... */ 1934 /* left operand of '.' must be struct ... */
1919 error(103, type_name(tn->tn_type)); 1935 error(103, type_name(tn->tn_type));
1920 } 1936 }
1921 } else { 1937 } else {
1922 if (!allow_c90 && tn->tn_type->t_tspec == PTR) { 1938 if (!allow_c90 && tn->tn_type->t_tspec == PTR) {
1923 /* left operand of '->' must be pointer ... */ 1939 /* left operand of '->' must be pointer ... */
1924 warning(104, type_name(tn->tn_type)); 1940 warning(104, type_name(tn->tn_type));
1925 } else { 1941 } else {
1926 /* left operand of '->' must be pointer ... */ 1942 /* left operand of '->' must be pointer ... */
1927 error(104, type_name(tn->tn_type)); 1943 error(104, type_name(tn->tn_type));
1928 } 1944 }
1929 } 1945 }
1930 } else { 1946 } else {
1931 if (!allow_c90) { 1947 if (!allow_c90) {
1932 /* non-unique member requires struct/union %s */ 1948 /* non-unique member requires struct/union %s */
1933 error(105, op == POINT ? "object" : "pointer"); 1949 error(105, op == POINT ? "object" : "pointer");
1934 } else { 1950 } else {
1935 /* unacceptable operand of '%s' */ 1951 /* unacceptable operand of '%s' */
1936 error(111, op_name(op)); 1952 error(111, op_name(op));
1937 } 1953 }
1938 } 1954 }
1939 1955
1940 return msym; 1956 return msym;
1941} 1957}
1942 1958
1943tnode_t * 1959tnode_t *
1944build_member_access(tnode_t *ln, op_t op, bool sys, sbuf_t *member) 1960build_member_access(tnode_t *ln, op_t op, bool sys, sbuf_t *member)
1945{ 1961{
1946 sym_t *msym; 1962 sym_t *msym;
1947 1963
1948 if (ln == NULL) 1964 if (ln == NULL)
1949 return NULL; 1965 return NULL;
1950 1966
1951 if (op == ARROW) { 1967 if (op == ARROW) {
1952 /* must do this before struct_or_union_member is called */ 1968 /* must do this before struct_or_union_member is called */
1953 ln = cconv(ln); 1969 ln = cconv(ln);
1954 } 1970 }
1955 msym = struct_or_union_member(ln, op, getsym(member)); 1971 msym = struct_or_union_member(ln, op, getsym(member));
1956 return build_binary(ln, op, sys, build_name(msym, false)); 1972 return build_binary(ln, op, sys, build_name(msym, false));
1957} 1973}
1958 1974
1959/* 1975/*
1960 * Perform class conversions. 1976 * Perform class conversions.
1961 * 1977 *
1962 * Arrays of type T are converted into pointers to type T. 1978 * Arrays of type T are converted into pointers to type T.
1963 * Functions are converted to pointers to functions. 1979 * Functions are converted to pointers to functions.
1964 * Lvalues are converted to rvalues. 1980 * Lvalues are converted to rvalues.
1965 * 1981 *
1966 * C99 6.3 "Conversions" 1982 * C99 6.3 "Conversions"
1967 * C99 6.3.2 "Other operands" 1983 * C99 6.3.2 "Other operands"
1968 * C99 6.3.2.1 "Lvalues, arrays, and function designators" 1984 * C99 6.3.2.1 "Lvalues, arrays, and function designators"
1969 */ 1985 */
1970tnode_t * 1986tnode_t *
1971cconv(tnode_t *tn) 1987cconv(tnode_t *tn)
1972{ 1988{
1973 /* 1989 /*
1974 * Array-lvalue (array of type T) is converted into rvalue 1990 * Array-lvalue (array of type T) is converted into rvalue
1975 * (pointer to type T) 1991 * (pointer to type T)
1976 */ 1992 */
1977 if (tn->tn_type->t_tspec == ARRAY) { 1993 if (tn->tn_type->t_tspec == ARRAY) {
1978 if (!tn->tn_lvalue) { 1994 if (!tn->tn_lvalue) {
1979 /* XXX print correct operator */ 1995 /* XXX print correct operator */
1980 /* %soperand of '%s' must be lvalue */ 1996 /* %soperand of '%s' must be lvalue */
1981 gnuism(114, "", op_name(ADDR)); 1997 gnuism(114, "", op_name(ADDR));
1982 } 1998 }
1983 tn = new_tnode(ADDR, tn->tn_sys, 1999 tn = new_tnode(ADDR, tn->tn_sys,
1984 expr_derive_type(tn->tn_type->t_subt, PTR), tn, NULL); 2000 expr_derive_type(tn->tn_type->t_subt, PTR), tn, NULL);
1985 } 2001 }
1986 2002
1987 /* 2003 /*
1988 * Expression of type function (function with return value of type T) 2004 * Expression of type function (function with return value of type T)
1989 * in rvalue-expression (pointer to function with return value 2005 * in rvalue-expression (pointer to function with return value
1990 * of type T) 2006 * of type T)
1991 */ 2007 */
1992 if (tn->tn_type->t_tspec == FUNC) 2008 if (tn->tn_type->t_tspec == FUNC)
1993 tn = build_address(tn->tn_sys, tn, true); 2009 tn = build_address(tn->tn_sys, tn, true);
1994 2010
1995 /* lvalue to rvalue */ 2011 /* lvalue to rvalue */
1996 if (tn->tn_lvalue) { 2012 if (tn->tn_lvalue) {
1997 type_t *tp = expr_dup_type(tn->tn_type); 2013 type_t *tp = expr_dup_type(tn->tn_type);
1998 /* C99 6.3.2.1p2 sentence 2 says to remove the qualifiers. */ 2014 /* C99 6.3.2.1p2 sentence 2 says to remove the qualifiers. */
1999 tp->t_const = tp->t_volatile = false; 2015 tp->t_const = tp->t_volatile = false;
2000 tn = new_tnode(LOAD, tn->tn_sys, tp, tn, NULL); 2016 tn = new_tnode(LOAD, tn->tn_sys, tp, tn, NULL);
2001 } 2017 }
2002 2018
2003 return tn; 2019 return tn;
2004} 2020}
2005 2021
2006const tnode_t * 2022const tnode_t *
2007before_conversion(const tnode_t *tn) 2023before_conversion(const tnode_t *tn)
2008{ 2024{
2009 while (tn->tn_op == CVT && !tn->tn_cast) 2025 while (tn->tn_op == CVT && !tn->tn_cast)
2010 tn = tn->tn_left; 2026 tn = tn->tn_left;
2011 return tn; 2027 return tn;
2012} 2028}
2013 2029
2014/* 2030/*
2015 * Most errors required by ANSI C are reported in struct_or_union_member(). 2031 * Most errors required by ANSI C are reported in struct_or_union_member().
2016 * Here we only check for totally wrong things. 2032 * Here we only check for totally wrong things.
2017 */ 2033 */
2018static bool 2034static bool
2019typeok_point(const tnode_t *ln, const type_t *ltp, tspec_t lt) 2035typeok_point(const tnode_t *ln, const type_t *ltp, tspec_t lt)
2020{ 2036{
2021 if (is_struct_or_union(lt)) 2037 if (is_struct_or_union(lt))
2022 return true; 2038 return true;
2023 2039
2024 if (lt == FUNC || lt == VOID || ltp->t_bitfield) 2040 if (lt == FUNC || lt == VOID || ltp->t_bitfield)
2025 goto wrong; 2041 goto wrong;
2026 2042
2027 /* 2043 /*
2028 * Some C dialects from before C90 tolerated any lvalue on the 2044 * Some C dialects from before C90 tolerated any lvalue on the
2029 * left-hand side of the '.' operator, allowing things like 2045 * left-hand side of the '.' operator, allowing things like
2030 * char st[100]; st.st_mtime, assuming that the member 'st_mtime' 2046 * char st[100]; st.st_mtime, assuming that the member 'st_mtime'
2031 * only occurred in a single struct; see typeok_arrow. 2047 * only occurred in a single struct; see typeok_arrow.
2032 */ 2048 */
2033 if (ln->tn_lvalue) 2049 if (ln->tn_lvalue)
2034 return true; 2050 return true;
2035 2051
2036wrong: 2052wrong:
2037 /* With allow_c90 we already got an error */ 2053 /* With allow_c90 we already got an error */
2038 if (!allow_c90) 2054 if (!allow_c90)
2039 /* unacceptable operand of '%s' */ 2055 /* unacceptable operand of '%s' */
2040 error(111, op_name(POINT)); 2056 error(111, op_name(POINT));
2041 2057
2042 return false; 2058 return false;
2043} 2059}
2044 2060
2045static bool 2061static bool
2046typeok_arrow(tspec_t lt) 2062typeok_arrow(tspec_t lt)
2047{ 2063{
2048 /* 2064 /*
2049 * C1978 Appendix A 14.1 says: <quote>In fact, any lvalue is allowed 2065 * C1978 Appendix A 14.1 says: <quote>In fact, any lvalue is allowed
2050 * before '.', and that lvalue is then assumed to have the form of 2066 * before '.', and that lvalue is then assumed to have the form of
2051 * the structure of which the name of the right is a member. [...] 2067 * the structure of which the name of the right is a member. [...]
2052 * Such constructions are non-portable.</quote> 2068 * Such constructions are non-portable.</quote>
2053 */ 2069 */
2054 if (lt == PTR || (!allow_c90 && is_integer(lt))) 2070 if (lt == PTR || (!allow_c90 && is_integer(lt)))
2055 return true; 2071 return true;
2056 2072
2057 /* With allow_c90 we already got an error */ 2073 /* With allow_c90 we already got an error */
2058 if (!allow_c90) 2074 if (!allow_c90)
2059 /* unacceptable operand of '%s' */ 2075 /* unacceptable operand of '%s' */
2060 error(111, op_name(ARROW)); 2076 error(111, op_name(ARROW));
2061 return false; 2077 return false;
2062} 2078}
2063 2079
2064static bool 2080static bool
2065typeok_incdec(op_t op, const tnode_t *tn, const type_t *tp) 2081typeok_incdec(op_t op, const tnode_t *tn, const type_t *tp)
2066{ 2082{
2067 /* operand has scalar type (checked in typeok) */ 2083 /* operand has scalar type (checked in typeok) */
2068 if (!tn->tn_lvalue) { 2084 if (!tn->tn_lvalue) {
2069 if (tn->tn_op == CVT && tn->tn_cast && 2085 if (tn->tn_op == CVT && tn->tn_cast &&
2070 tn->tn_left->tn_op == LOAD) { 2086 tn->tn_left->tn_op == LOAD) {
2071 /* a cast does not yield an lvalue */ 2087 /* a cast does not yield an lvalue */
2072 error(163); 2088 error(163);
2073 } 2089 }
2074 /* %soperand of '%s' must be lvalue */ 2090 /* %soperand of '%s' must be lvalue */
2075 error(114, "", op_name(op)); 2091 error(114, "", op_name(op));
2076 return false; 2092 return false;
2077 } 2093 }
2078 if (tp->t_const && allow_c90) { 2094 if (tp->t_const && allow_c90) {
2079 /* %soperand of '%s' must be modifiable lvalue */ 2095 /* %soperand of '%s' must be modifiable lvalue */
2080 warning(115, "", op_name(op)); 2096 warning(115, "", op_name(op));
2081 } 2097 }
2082 return true; 2098 return true;
2083} 2099}
2084 2100
2085static bool 2101static bool
2086typeok_address(const mod_t *mp, 2102typeok_address(const mod_t *mp,
2087 const tnode_t *tn, const type_t *tp, tspec_t t) 2103 const tnode_t *tn, const type_t *tp, tspec_t t)
2088{ 2104{
2089 if (t == ARRAY || t == FUNC) { 2105 if (t == ARRAY || t == FUNC) {
2090 /* ok, a warning comes later (in build_address()) */ 2106 /* ok, a warning comes later (in build_address()) */
2091 } else if (!tn->tn_lvalue) { 2107 } else if (!tn->tn_lvalue) {
2092 if (tn->tn_op == CVT && tn->tn_cast && 2108 if (tn->tn_op == CVT && tn->tn_cast &&
2093 tn->tn_left->tn_op == LOAD) { 2109 tn->tn_left->tn_op == LOAD) {
2094 /* a cast does not yield an lvalue */ 2110 /* a cast does not yield an lvalue */
2095 error(163); 2111 error(163);
2096 } 2112 }
2097 /* %soperand of '%s' must be lvalue */ 2113 /* %soperand of '%s' must be lvalue */
2098 error(114, "", mp->m_name); 2114 error(114, "", mp->m_name);
2099 return false; 2115 return false;
2100 } else if (is_scalar(t)) { 2116 } else if (is_scalar(t)) {
2101 if (tp->t_bitfield) { 2117 if (tp->t_bitfield) {
2102 /* cannot take address of bit-field */ 2118 /* cannot take address of bit-field */
2103 error(112); 2119 error(112);
2104 return false; 2120 return false;
2105 } 2121 }
2106 } else if (t != STRUCT && t != UNION) { 2122 } else if (t != STRUCT && t != UNION) {
2107 /* unacceptable operand of '%s' */ 2123 /* unacceptable operand of '%s' */
2108 error(111, mp->m_name); 2124 error(111, mp->m_name);
2109 return false; 2125 return false;
2110 } 2126 }
2111 if (tn->tn_op == NAME && tn->tn_sym->s_register) { 2127 if (tn->tn_op == NAME && tn->tn_sym->s_register) {
2112 /* cannot take address of register '%s' */ 2128 /* cannot take address of register '%s' */
2113 error(113, tn->tn_sym->s_name); 2129 error(113, tn->tn_sym->s_name);
2114 return false; 2130 return false;
2115 } 2131 }
2116 return true; 2132 return true;
2117} 2133}
2118 2134
2119static bool 2135static bool
2120typeok_indir(const type_t *tp, tspec_t t) 2136typeok_indir(const type_t *tp, tspec_t t)
2121{ 2137{
2122 2138
2123 if (t != PTR) { 2139 if (t != PTR) {
2124 /* cannot dereference non-pointer type '%s' */ 2140 /* cannot dereference non-pointer type '%s' */
2125 error(96, type_name(tp)); 2141 error(96, type_name(tp));
2126 return false; 2142 return false;
2127 } 2143 }
2128 return true; 2144 return true;
2129} 2145}
2130 2146
2131static void 2147static void
2132warn_incompatible_types(op_t op, 2148warn_incompatible_types(op_t op,
2133 const type_t *ltp, tspec_t lt, 2149 const type_t *ltp, tspec_t lt,
2134 const type_t *rtp, tspec_t rt) 2150 const type_t *rtp, tspec_t rt)
2135{ 2151{
2136 const mod_t *mp = &modtab[op]; 2152 const mod_t *mp = &modtab[op];
2137 2153
2138 if (lt == VOID || (mp->m_binary && rt == VOID)) { 2154 if (lt == VOID || (mp->m_binary && rt == VOID)) {
2139 /* void type illegal in expression */ 2155 /* void type illegal in expression */
2140 error(109); 2156 error(109);
2141 } else if (op == ASSIGN) { 2157 } else if (op == ASSIGN) {
2142 /* cannot assign to '%s' from '%s' */ 2158 /* cannot assign to '%s' from '%s' */
2143 error(171, type_name(ltp), type_name(rtp)); 2159 error(171, type_name(ltp), type_name(rtp));
2144 } else if (mp->m_binary) { 2160 } else if (mp->m_binary) {
2145 /* operands of '%s' have incompatible types '%s' and '%s' */ 2161 /* operands of '%s' have incompatible types '%s' and '%s' */
2146 error(107, mp->m_name, tspec_name(lt), tspec_name(rt)); 2162 error(107, mp->m_name, tspec_name(lt), tspec_name(rt));
2147 } else { 2163 } else {
2148 lint_assert(rt == NOTSPEC); 2164 lint_assert(rt == NOTSPEC);
2149 /* operand of '%s' has invalid type '%s' */ 2165 /* operand of '%s' has invalid type '%s' */
2150 error(108, mp->m_name, type_name(ltp)); 2166 error(108, mp->m_name, type_name(ltp));
2151 } 2167 }
2152} 2168}
2153 2169
2154static bool 2170static bool
2155typeok_plus(op_t op, 2171typeok_plus(op_t op,
2156 const type_t *ltp, tspec_t lt, 2172 const type_t *ltp, tspec_t lt,
2157 const type_t *rtp, tspec_t rt) 2173 const type_t *rtp, tspec_t rt)
2158{ 2174{
2159 /* operands have scalar types (checked in typeok) */ 2175 /* operands have scalar types (checked in typeok) */
2160 if ((lt == PTR && !is_integer(rt)) || (rt == PTR && !is_integer(lt))) { 2176 if ((lt == PTR && !is_integer(rt)) || (rt == PTR && !is_integer(lt))) {
2161 warn_incompatible_types(op, ltp, lt, rtp, rt); 2177 warn_incompatible_types(op, ltp, lt, rtp, rt);
2162 return false; 2178 return false;
2163 } 2179 }
2164 return true; 2180 return true;
2165} 2181}
2166 2182
2167static bool 2183static bool
2168typeok_minus(op_t op, 2184typeok_minus(op_t op,
2169 const type_t *ltp, tspec_t lt, 2185 const type_t *ltp, tspec_t lt,
2170 const type_t *rtp, tspec_t rt) 2186 const type_t *rtp, tspec_t rt)
2171{ 2187{
2172 /* operands have scalar types (checked in typeok) */ 2188 /* operands have scalar types (checked in typeok) */
2173 if ((lt == PTR && rt != PTR && !is_integer(rt)) || 2189 if ((lt == PTR && rt != PTR && !is_integer(rt)) ||
2174 (lt != PTR && rt == PTR)) { 2190 (lt != PTR && rt == PTR)) {
2175 warn_incompatible_types(op, ltp, lt, rtp, rt); 2191 warn_incompatible_types(op, ltp, lt, rtp, rt);
2176 return false; 2192 return false;
2177 } 2193 }
2178 if (lt == PTR && rt == PTR && 2194 if (lt == PTR && rt == PTR &&
2179 !types_compatible(ltp->t_subt, rtp->t_subt, true, false, NULL)) { 2195 !types_compatible(ltp->t_subt, rtp->t_subt, true, false, NULL)) {
2180 /* illegal pointer subtraction */ 2196 /* illegal pointer subtraction */
2181 error(116); 2197 error(116);
2182 } 2198 }
2183 return true; 2199 return true;
2184} 2200}
2185 2201
2186static void 2202static void
2187typeok_shr(const mod_t *mp, 2203typeok_shr(const mod_t *mp,
2188 const tnode_t *ln, tspec_t lt, 2204 const tnode_t *ln, tspec_t lt,
2189 const tnode_t *rn, tspec_t rt) 2205 const tnode_t *rn, tspec_t rt)
2190{ 2206{
2191 tspec_t olt, ort; 2207 tspec_t olt, ort;
2192 2208
2193 olt = before_conversion(ln)->tn_type->t_tspec; 2209 olt = before_conversion(ln)->tn_type->t_tspec;
2194 ort = before_conversion(rn)->tn_type->t_tspec; 2210 ort = before_conversion(rn)->tn_type->t_tspec;
2195 2211
2196 /* operands have integer types (checked in typeok) */ 2212 /* operands have integer types (checked in typeok) */
2197 if (pflag && !is_uinteger(olt)) { 2213 if (pflag && !is_uinteger(olt)) {
2198 integer_constraints lc = ic_expr(ln); 2214 integer_constraints lc = ic_expr(ln);
2199 if (!ic_maybe_signed(ln->tn_type, &lc)) 2215 if (!ic_maybe_signed(ln->tn_type, &lc))
2200 return; 2216 return;
2201 2217
2202 /* 2218 /*
2203 * The left operand is signed. This means that 2219 * The left operand is signed. This means that
2204 * the operation is (possibly) nonportable. 2220 * the operation is (possibly) nonportable.
2205 */ 2221 */
2206 if (ln->tn_op != CON) { 2222 if (ln->tn_op != CON) {
2207 /* bitwise '%s' on signed value possibly nonportable */ 2223 /* bitwise '%s' on signed value possibly nonportable */
2208 warning(117, mp->m_name); 2224 warning(117, mp->m_name);
2209 } else if (ln->tn_val->v_quad < 0) { 2225 } else if (ln->tn_val->v_quad < 0) {
2210 /* bitwise '%s' on signed value nonportable */ 2226 /* bitwise '%s' on signed value nonportable */
2211 warning(120, mp->m_name); 2227 warning(120, mp->m_name);
2212 } 2228 }
2213 } else if (allow_trad && allow_c90 && 2229 } else if (allow_trad && allow_c90 &&
2214 !is_uinteger(olt) && is_uinteger(ort)) { 2230 !is_uinteger(olt) && is_uinteger(ort)) {
2215 /* The left operand would become unsigned in traditional C. */ 2231 /* The left operand would become unsigned in traditional C. */
2216 if (hflag && (ln->tn_op != CON || ln->tn_val->v_quad < 0)) { 2232 if (hflag && (ln->tn_op != CON || ln->tn_val->v_quad < 0)) {
2217 /* semantics of '%s' change in ANSI C; use ... */ 2233 /* semantics of '%s' change in ANSI C; use ... */
2218 warning(118, mp->m_name); 2234 warning(118, mp->m_name);
2219 } 2235 }
2220 } else if (allow_trad && allow_c90 && 2236 } else if (allow_trad && allow_c90 &&
2221 !is_uinteger(olt) && !is_uinteger(ort) && 2237 !is_uinteger(olt) && !is_uinteger(ort) &&
2222 portable_size_in_bits(lt) < portable_size_in_bits(rt)) { 2238 portable_size_in_bits(lt) < portable_size_in_bits(rt)) {
2223 /* 2239 /*
2224 * In traditional C the left operand would be extended 2240 * In traditional C the left operand would be extended
2225 * (possibly sign-extended) and then shifted. 2241 * (possibly sign-extended) and then shifted.
2226 */ 2242 */
2227 if (hflag && (ln->tn_op != CON || ln->tn_val->v_quad < 0)) { 2243 if (hflag && (ln->tn_op != CON || ln->tn_val->v_quad < 0)) {
2228 /* semantics of '%s' change in ANSI C; use ... */ 2244 /* semantics of '%s' change in ANSI C; use ... */
2229 warning(118, mp->m_name); 2245 warning(118, mp->m_name);
2230 } 2246 }
2231 } 2247 }
2232} 2248}
2233 2249
2234static void 2250static void
2235typeok_shl(const mod_t *mp, tspec_t lt, tspec_t rt) 2251typeok_shl(const mod_t *mp, tspec_t lt, tspec_t rt)
2236{ 2252{
2237 /* 2253 /*
2238 * C90 does not perform balancing for shift operations, 2254 * C90 does not perform balancing for shift operations,
2239 * but traditional C does. If the width of the right operand 2255 * but traditional C does. If the width of the right operand
2240 * is greater than the width of the left operand, then in 2256 * is greater than the width of the left operand, then in
2241 * traditional C the left operand would be extended to the 2257 * traditional C the left operand would be extended to the
2242 * width of the right operand. For SHL this may result in 2258 * width of the right operand. For SHL this may result in
2243 * different results. 2259 * different results.
2244 */ 2260 */
2245 if (portable_size_in_bits(lt) < portable_size_in_bits(rt)) { 2261 if (portable_size_in_bits(lt) < portable_size_in_bits(rt)) {
2246 /* 2262 /*
2247 * XXX If both operands are constant, make sure 2263 * XXX If both operands are constant, make sure
2248 * that there is really a difference between 2264 * that there is really a difference between
2249 * ANSI C and traditional C. 2265 * ANSI C and traditional C.
2250 */ 2266 */
2251 if (hflag && !allow_c99) 2267 if (hflag && !allow_c99)
2252 /* semantics of '%s' change in ANSI C; use ... */ 2268 /* semantics of '%s' change in ANSI C; use ... */
2253 warning(118, mp->m_name); 2269 warning(118, mp->m_name);
2254 } 2270 }
2255} 2271}
2256 2272
2257static void 2273static void
2258typeok_shift(const type_t *ltp, tspec_t lt, const tnode_t *rn, tspec_t rt) 2274typeok_shift(const type_t *ltp, tspec_t lt, const tnode_t *rn, tspec_t rt)
2259{ 2275{
2260 if (rn->tn_op != CON) 2276 if (rn->tn_op != CON)
2261 return; 2277 return;
2262 2278
2263 if (!is_uinteger(rt) && rn->tn_val->v_quad < 0) { 2279 if (!is_uinteger(rt) && rn->tn_val->v_quad < 0) {
2264 /* negative shift */ 2280 /* negative shift */
2265 warning(121); 2281 warning(121);
2266 } else if ((uint64_t)rn->tn_val->v_quad == 2282 } else if ((uint64_t)rn->tn_val->v_quad ==
2267 (uint64_t)size_in_bits(lt)) { 2283 (uint64_t)size_in_bits(lt)) {
2268 /* shift amount %u equals bit-size of '%s' */ 2284 /* shift amount %u equals bit-size of '%s' */
2269 warning(267, (unsigned)rn->tn_val->v_quad, type_name(ltp)); 2285 warning(267, (unsigned)rn->tn_val->v_quad, type_name(ltp));
2270 } else if ((uint64_t)rn->tn_val->v_quad > (uint64_t)size_in_bits(lt)) { 2286 } else if ((uint64_t)rn->tn_val->v_quad > (uint64_t)size_in_bits(lt)) {
2271 /* shift amount %llu is greater than bit-size %llu of '%s' */ 2287 /* shift amount %llu is greater than bit-size %llu of '%s' */
2272 warning(122, (unsigned long long)rn->tn_val->v_quad, 2288 warning(122, (unsigned long long)rn->tn_val->v_quad,
2273 (unsigned long long)size_in_bits(lt), 2289 (unsigned long long)size_in_bits(lt),
2274 tspec_name(lt)); 2290 tspec_name(lt));
2275 } 2291 }
2276} 2292}
2277 2293
2278static bool 2294static bool
2279is_typeok_eq(const tnode_t *ln, tspec_t lt, const tnode_t *rn, tspec_t rt) 2295is_typeok_eq(const tnode_t *ln, tspec_t lt, const tnode_t *rn, tspec_t rt)
2280{ 2296{
2281 if (lt == PTR && is_null_pointer(rn)) 2297 if (lt == PTR && is_null_pointer(rn))
2282 return true; 2298 return true;
2283 if (rt == PTR && is_null_pointer(ln)) 2299 if (rt == PTR && is_null_pointer(ln))
2284 return true; 2300 return true;
2285 return false; 2301 return false;
2286} 2302}
2287 2303
2288/* 2304/*
2289 * Called if incompatible pointer types are detected. 2305 * Called if incompatible pointer types are detected.
2290 * Print an appropriate warning. 2306 * Print an appropriate warning.
2291 */ 2307 */
2292static void 2308static void
2293warn_incompatible_pointers(const mod_t *mp, 2309warn_incompatible_pointers(const mod_t *mp,
2294 const type_t *ltp, const type_t *rtp) 2310 const type_t *ltp, const type_t *rtp)
2295{ 2311{
2296 lint_assert(ltp->t_tspec == PTR); 2312 lint_assert(ltp->t_tspec == PTR);
2297 lint_assert(rtp->t_tspec == PTR); 2313 lint_assert(rtp->t_tspec == PTR);
2298 2314
2299 tspec_t lt = ltp->t_subt->t_tspec; 2315 tspec_t lt = ltp->t_subt->t_tspec;
2300 tspec_t rt = rtp->t_subt->t_tspec; 2316 tspec_t rt = rtp->t_subt->t_tspec;
2301 2317
2302 if (is_struct_or_union(lt) && is_struct_or_union(rt)) { 2318 if (is_struct_or_union(lt) && is_struct_or_union(rt)) {
2303 if (mp == NULL) { 2319 if (mp == NULL) {
2304 /* illegal structure pointer combination */ 2320 /* illegal structure pointer combination */
2305 warning(244); 2321 warning(244);
2306 } else { 2322 } else {
2307 /* incompatible structure pointers: '%s' '%s' '%s' */ 2323 /* incompatible structure pointers: '%s' '%s' '%s' */
2308 warning(245, type_name(ltp), mp->m_name, type_name(rtp)); 2324 warning(245, type_name(ltp), mp->m_name, type_name(rtp));
2309 } 2325 }
2310 } else { 2326 } else {
2311 if (mp == NULL) { 2327 if (mp == NULL) {
2312 /* illegal combination of '%s' and '%s' */ 2328 /* illegal combination of '%s' and '%s' */
2313 warning(184, type_name(ltp), type_name(rtp)); 2329 warning(184, type_name(ltp), type_name(rtp));
2314 } else { 2330 } else {
2315 /* illegal combination of '%s' and '%s', op '%s' */ 2331 /* illegal combination of '%s' and '%s', op '%s' */
2316 warning(124, 2332 warning(124,
2317 type_name(ltp), type_name(rtp), mp->m_name); 2333 type_name(ltp), type_name(rtp), mp->m_name);
2318 } 2334 }
2319 } 2335 }
2320} 2336}
2321 2337
2322static void 2338static void
2323check_pointer_comparison(op_t op, const tnode_t *ln, const tnode_t *rn) 2339check_pointer_comparison(op_t op, const tnode_t *ln, const tnode_t *rn)
2324{ 2340{
2325 type_t *ltp = ln->tn_type, *rtp = rn->tn_type; 2341 type_t *ltp = ln->tn_type, *rtp = rn->tn_type;
2326 tspec_t lst = ltp->t_subt->t_tspec, rst = rtp->t_subt->t_tspec; 2342 tspec_t lst = ltp->t_subt->t_tspec, rst = rtp->t_subt->t_tspec;
2327 2343
2328 if (lst == VOID || rst == VOID) { 2344 if (lst == VOID || rst == VOID) {
2329 /* TODO: C99 behaves like C90 here. */ 2345 /* TODO: C99 behaves like C90 here. */
2330 if ((!allow_trad && !allow_c99) && 2346 if ((!allow_trad && !allow_c99) &&
2331 (lst == FUNC || rst == FUNC)) { 2347 (lst == FUNC || rst == FUNC)) {
2332 /* (void *)0 is already handled in typeok() */ 2348 /* (void *)0 is already handled in typeok() */
2333 const char *lsts, *rsts; 2349 const char *lsts, *rsts;
2334 *(lst == FUNC ? &lsts : &rsts) = "function pointer"; 2350 *(lst == FUNC ? &lsts : &rsts) = "function pointer";
2335 *(lst == VOID ? &lsts : &rsts) = "'void *'"; 2351 *(lst == VOID ? &lsts : &rsts) = "'void *'";
2336 /* ANSI C forbids comparison of %s with %s */ 2352 /* ANSI C forbids comparison of %s with %s */
2337 warning(274, lsts, rsts); 2353 warning(274, lsts, rsts);
2338 } 2354 }
2339 return; 2355 return;
2340 } 2356 }
2341 2357
2342 if (!types_compatible(ltp->t_subt, rtp->t_subt, true, false, NULL)) { 2358 if (!types_compatible(ltp->t_subt, rtp->t_subt, true, false, NULL)) {
2343 warn_incompatible_pointers(&modtab[op], ltp, rtp); 2359 warn_incompatible_pointers(&modtab[op], ltp, rtp);
2344 return; 2360 return;
2345 } 2361 }
2346 2362
2347 if (lst == FUNC && rst == FUNC) { 2363 if (lst == FUNC && rst == FUNC) {
2348 /* TODO: C99 behaves like C90 here, see C99 6.5.8p2. */ 2364 /* TODO: C99 behaves like C90 here, see C99 6.5.8p2. */
2349 if ((!allow_trad && !allow_c99) && op != EQ && op != NE) 2365 if ((!allow_trad && !allow_c99) && op != EQ && op != NE)
2350 /* ANSI C forbids ordered comparisons of ... */ 2366 /* ANSI C forbids ordered comparisons of ... */
2351 warning(125); 2367 warning(125);
2352 } 2368 }
2353} 2369}
2354 2370
2355static bool 2371static bool
2356typeok_compare(op_t op, 2372typeok_compare(op_t op,
2357 const tnode_t *ln, const type_t *ltp, tspec_t lt, 2373 const tnode_t *ln, const type_t *ltp, tspec_t lt,
2358 const tnode_t *rn, const type_t *rtp, tspec_t rt) 2374 const tnode_t *rn, const type_t *rtp, tspec_t rt)
2359{ 2375{
2360 if (lt == PTR && rt == PTR) { 2376 if (lt == PTR && rt == PTR) {
2361 check_pointer_comparison(op, ln, rn); 2377 check_pointer_comparison(op, ln, rn);
2362 return true; 2378 return true;
2363 } 2379 }
2364 2380
2365 if (lt != PTR && rt != PTR) 2381 if (lt != PTR && rt != PTR)
2366 return true; 2382 return true;
2367 2383
2368 if (!is_integer(lt) && !is_integer(rt)) { 2384 if (!is_integer(lt) && !is_integer(rt)) {
2369 warn_incompatible_types(op, ltp, lt, rtp, rt); 2385 warn_incompatible_types(op, ltp, lt, rtp, rt);
2370 return false; 2386 return false;
2371 } 2387 }
2372 2388
2373 const char *lx = lt == PTR ? "pointer" : "integer"; 2389 const char *lx = lt == PTR ? "pointer" : "integer";
2374 const char *rx = rt == PTR ? "pointer" : "integer"; 2390 const char *rx = rt == PTR ? "pointer" : "integer";
2375 /* illegal combination of %s '%s' and %s '%s', op '%s' */ 2391 /* illegal combination of %s '%s' and %s '%s', op '%s' */
2376 warning(123, lx, type_name(ltp), rx, type_name(rtp), op_name(op)); 2392 warning(123, lx, type_name(ltp), rx, type_name(rtp), op_name(op));
2377 return true; 2393 return true;
2378} 2394}
2379 2395
2380static bool 2396static bool
2381typeok_quest(tspec_t lt, const tnode_t *rn) 2397typeok_quest(tspec_t lt, const tnode_t *rn)
2382{ 2398{
2383 if (!is_scalar(lt)) { 2399 if (!is_scalar(lt)) {
2384 /* first operand must have scalar type, op ? : */ 2400 /* first operand must have scalar type, op ? : */
2385 error(170); 2401 error(170);
2386 return false; 2402 return false;
2387 } 2403 }
2388 lint_assert(before_conversion(rn)->tn_op == COLON); 2404 lint_assert(before_conversion(rn)->tn_op == COLON);
2389 return true; 2405 return true;
2390} 2406}
2391 2407
2392static void 2408static void
2393typeok_colon_pointer(const mod_t *mp, const type_t *ltp, const type_t *rtp) 2409typeok_colon_pointer(const mod_t *mp, const type_t *ltp, const type_t *rtp)
2394{ 2410{
2395 type_t *lstp = ltp->t_subt; 2411 type_t *lstp = ltp->t_subt;
2396 type_t *rstp = rtp->t_subt; 2412 type_t *rstp = rtp->t_subt;
2397 tspec_t lst = lstp->t_tspec; 2413 tspec_t lst = lstp->t_tspec;
2398 tspec_t rst = rstp->t_tspec; 2414 tspec_t rst = rstp->t_tspec;
2399 2415
2400 if ((lst == VOID && rst == FUNC) || (lst == FUNC && rst == VOID)) { 2416 if ((lst == VOID && rst == FUNC) || (lst == FUNC && rst == VOID)) {
2401 /* (void *)0 is handled in typeok_colon */ 2417 /* (void *)0 is handled in typeok_colon */
2402 /* TODO: C99 behaves like C90 here. */ 2418 /* TODO: C99 behaves like C90 here. */
2403 if (!allow_trad && !allow_c99) 2419 if (!allow_trad && !allow_c99)
2404 /* ANSI C forbids conversion of %s to %s, op %s */ 2420 /* ANSI C forbids conversion of %s to %s, op %s */
2405 warning(305, "function pointer", "'void *'", 2421 warning(305, "function pointer", "'void *'",
2406 mp->m_name); 2422 mp->m_name);
2407 return; 2423 return;
2408 } 2424 }
2409 2425
2410 if (pointer_types_are_compatible(lstp, rstp, true)) 2426 if (pointer_types_are_compatible(lstp, rstp, true))
2411 return; 2427 return;
2412 if (!types_compatible(lstp, rstp, true, false, NULL)) 2428 if (!types_compatible(lstp, rstp, true, false, NULL))
2413 warn_incompatible_pointers(mp, ltp, rtp); 2429 warn_incompatible_pointers(mp, ltp, rtp);
2414} 2430}
2415 2431
2416static bool 2432static bool
2417typeok_colon(const mod_t *mp, 2433typeok_colon(const mod_t *mp,
2418 const tnode_t *ln, const type_t *ltp, tspec_t lt, 2434 const tnode_t *ln, const type_t *ltp, tspec_t lt,
2419 const tnode_t *rn, const type_t *rtp, tspec_t rt) 2435 const tnode_t *rn, const type_t *rtp, tspec_t rt)
2420{ 2436{
2421 2437
2422 if (is_arithmetic(lt) && is_arithmetic(rt)) 2438 if (is_arithmetic(lt) && is_arithmetic(rt))
2423 return true; 2439 return true;
2424 if (lt == BOOL && rt == BOOL) 2440 if (lt == BOOL && rt == BOOL)
2425 return true; 2441 return true;
2426 2442
2427 if (lt == STRUCT && rt == STRUCT && ltp->t_str == rtp->t_str) 2443 if (lt == STRUCT && rt == STRUCT && ltp->t_str == rtp->t_str)
2428 return true; 2444 return true;
2429 if (lt == UNION && rt == UNION && ltp->t_str == rtp->t_str) 2445 if (lt == UNION && rt == UNION && ltp->t_str == rtp->t_str)
2430 return true; 2446 return true;
2431 2447
2432 if (lt == PTR && is_null_pointer(rn)) 2448 if (lt == PTR && is_null_pointer(rn))
2433 return true; 2449 return true;
2434 if (rt == PTR && is_null_pointer(ln)) 2450 if (rt == PTR && is_null_pointer(ln))
2435 return true; 2451 return true;
2436 2452
2437 if ((lt == PTR && is_integer(rt)) || (is_integer(lt) && rt == PTR)) { 2453 if ((lt == PTR && is_integer(rt)) || (is_integer(lt) && rt == PTR)) {
2438 const char *lx = lt == PTR ? "pointer" : "integer"; 2454 const char *lx = lt == PTR ? "pointer" : "integer";
2439 const char *rx = rt == PTR ? "pointer" : "integer"; 2455 const char *rx = rt == PTR ? "pointer" : "integer";
2440 /* illegal combination of %s '%s' and %s '%s', op '%s' */ 2456 /* illegal combination of %s '%s' and %s '%s', op '%s' */
2441 warning(123, lx, type_name(ltp), 2457 warning(123, lx, type_name(ltp),
2442 rx, type_name(rtp), mp->m_name); 2458 rx, type_name(rtp), mp->m_name);
2443 return true; 2459 return true;
2444 } 2460 }
2445 2461
2446 if (lt == VOID || rt == VOID) { 2462 if (lt == VOID || rt == VOID) {
2447 if (lt != VOID || rt != VOID) 2463 if (lt != VOID || rt != VOID)
2448 /* incompatible types '%s' and '%s' in conditional */ 2464 /* incompatible types '%s' and '%s' in conditional */
2449 warning(126, type_name(ltp), type_name(rtp)); 2465 warning(126, type_name(ltp), type_name(rtp));
2450 return true; 2466 return true;
2451 } 2467 }
2452 2468
2453 if (lt == PTR && rt == PTR) { 2469 if (lt == PTR && rt == PTR) {
2454 typeok_colon_pointer(mp, ltp, rtp); 2470 typeok_colon_pointer(mp, ltp, rtp);
2455 return true; 2471 return true;
2456 } 2472 }
2457 2473
2458 /* incompatible types '%s' and '%s' in conditional */ 2474 /* incompatible types '%s' and '%s' in conditional */
2459 error(126, type_name(ltp), type_name(rtp)); 2475 error(126, type_name(ltp), type_name(rtp));
2460 return false; 2476 return false;
2461} 2477}
2462 2478
2463/* 2479/*
2464 * Returns true if the given structure or union has a constant member 2480 * Returns true if the given structure or union has a constant member
2465 * (maybe recursively). 2481 * (maybe recursively).
2466 */ 2482 */
2467static bool 2483static bool
2468has_constant_member(const type_t *tp) 2484has_constant_member(const type_t *tp)
2469{ 2485{
2470 lint_assert(is_struct_or_union(tp->t_tspec)); 2486 lint_assert(is_struct_or_union(tp->t_tspec));
2471 2487
2472 for (sym_t *m = tp->t_str->sou_first_member; 2488 for (sym_t *m = tp->t_str->sou_first_member;
2473 m != NULL; m = m->s_next) { 2489 m != NULL; m = m->s_next) {
2474 const type_t *mtp = m->s_type; 2490 const type_t *mtp = m->s_type;
2475 if (mtp->t_const) 2491 if (mtp->t_const)
2476 return true; 2492 return true;
2477 if (is_struct_or_union(mtp->t_tspec) && 2493 if (is_struct_or_union(mtp->t_tspec) &&
2478 has_constant_member(mtp)) 2494 has_constant_member(mtp))
2479 return true; 2495 return true;
2480 } 2496 }
2481 return false; 2497 return false;
2482} 2498}
2483 2499
2484static bool 2500static bool
2485typeok_assign(op_t op, const tnode_t *ln, const type_t *ltp, tspec_t lt) 2501typeok_assign(op_t op, const tnode_t *ln, const type_t *ltp, tspec_t lt)
2486{ 2502{
2487 if (op == RETURN || op == INIT || op == FARG) 2503 if (op == RETURN || op == INIT || op == FARG)
2488 return true; 2504 return true;
2489 2505
2490 if (!ln->tn_lvalue) { 2506 if (!ln->tn_lvalue) {
2491 if (ln->tn_op == CVT && ln->tn_cast && 2507 if (ln->tn_op == CVT && ln->tn_cast &&
2492 ln->tn_left->tn_op == LOAD) { 2508 ln->tn_left->tn_op == LOAD) {
2493 /* a cast does not yield an lvalue */ 2509 /* a cast does not yield an lvalue */
2494 error(163); 2510 error(163);
2495 } 2511 }
2496 /* %soperand of '%s' must be lvalue */ 2512 /* %soperand of '%s' must be lvalue */
2497 error(114, "left ", op_name(op)); 2513 error(114, "left ", op_name(op));
2498 return false; 2514 return false;
2499 } else if (ltp->t_const || (is_struct_or_union(lt) && 2515 } else if (ltp->t_const || (is_struct_or_union(lt) &&
2500 has_constant_member(ltp))) { 2516 has_constant_member(ltp))) {
2501 if (allow_c90) 2517 if (allow_c90)
2502 /* %soperand of '%s' must be modifiable lvalue */ 2518 /* %soperand of '%s' must be modifiable lvalue */
2503 warning(115, "left ", op_name(op)); 2519 warning(115, "left ", op_name(op));
2504 } 2520 }
2505 return true; 2521 return true;
2506} 2522}
2507 2523
2508/* Check the types using the information from modtab[]. */ 2524/* Check the types using the information from modtab[]. */
2509static bool 2525static bool