Thu Jul 15 17:03:50 2021 UTC ()
lint: replace call to ttos with type_name

Since tyname.c 1.20 from 2021-01-02, type_name is as simple to use as
ttos and more expressive.  It can also be called multiple times without
invalidating the returned strings.

Used only in debug mode.


(rillig)
diff -r1.45 -r1.46 src/usr.bin/xlint/lint1/emit1.c
diff -r1.117 -r1.118 src/usr.bin/xlint/lint1/externs1.h
diff -r1.314 -r1.315 src/usr.bin/xlint/lint1/tree.c

cvs diff -r1.45 -r1.46 src/usr.bin/xlint/lint1/emit1.c (switch to unified diff)

--- src/usr.bin/xlint/lint1/emit1.c 2021/07/05 19:39:12 1.45
+++ src/usr.bin/xlint/lint1/emit1.c 2021/07/15 17:03:50 1.46
@@ -1,612 +1,583 @@ @@ -1,612 +1,583 @@
1/* $NetBSD: emit1.c,v 1.45 2021/07/05 19:39:12 rillig Exp $ */ 1/* $NetBSD: emit1.c,v 1.46 2021/07/15 17:03:50 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. 4 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
5 * Copyright (c) 1994, 1995 Jochen Pohl 5 * Copyright (c) 1994, 1995 Jochen Pohl
6 * All Rights Reserved. 6 * All Rights Reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement: 17 * must display the following acknowledgement:
18 * This product includes software developed by Jochen Pohl for 18 * This product includes software developed by Jochen Pohl for
19 * The NetBSD Project. 19 * The NetBSD Project.
20 * 4. The name of the author may not be used to endorse or promote products 20 * 4. The name of the author may not be used to endorse or promote products
21 * derived from this software without specific prior written permission. 21 * derived from this software without specific prior written permission.
22 * 22 *
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */ 33 */
34 34
35#if HAVE_NBTOOL_CONFIG_H 35#if HAVE_NBTOOL_CONFIG_H
36#include "nbtool_config.h" 36#include "nbtool_config.h"
37#endif 37#endif
38 38
39#include <sys/cdefs.h> 39#include <sys/cdefs.h>
40#if defined(__RCSID) && !defined(lint) 40#if defined(__RCSID) && !defined(lint)
41__RCSID("$NetBSD: emit1.c,v 1.45 2021/07/05 19:39:12 rillig Exp $"); 41__RCSID("$NetBSD: emit1.c,v 1.46 2021/07/15 17:03:50 rillig Exp $");
42#endif 42#endif
43 43
44#include "lint1.h" 44#include "lint1.h"
45 45
46static void outtt(sym_t *, sym_t *); 46static void outtt(sym_t *, sym_t *);
47static void outfstrg(strg_t *); 47static void outfstrg(strg_t *);
48 48
49/* 49/*
50 * Write type into the output buffer. 50 * Write type into the output buffer.
51 * The type is written as a sequence of substrings, each of which describes a 51 * The type is written as a sequence of substrings, each of which describes a
52 * node of type type_t 52 * node of type type_t
53 * a node is encoded as follows: 53 * a node is encoded as follows:
54 * _Bool B 54 * _Bool B
55 * _Complex float s X 55 * _Complex float s X
56 * _Complex double X 56 * _Complex double X
57 * _Complex long double l X 57 * _Complex long double l X
58 * char C 58 * char C
59 * signed char s C 59 * signed char s C
60 * unsigned char u C 60 * unsigned char u C
61 * short S 61 * short S
62 * unsigned short u S 62 * unsigned short u S
63 * int I 63 * int I
64 * unsigned int u I 64 * unsigned int u I
65 * long L 65 * long L
66 * unsigned long u L 66 * unsigned long u L
67 * long long Q 67 * long long Q
68 * unsigned long long u Q 68 * unsigned long long u Q
69 * float s D 69 * float s D
70 * double D 70 * double D
71 * long double l D 71 * long double l D
72 * void V 72 * void V
73 * * P 73 * * P
74 * [n] A n 74 * [n] A n
75 * () F 75 * () F
76 * (void) F 0 76 * (void) F 0
77 * (n parameters) F n arg1 arg2 ... argn 77 * (n parameters) F n arg1 arg2 ... argn
78 * (n parameters, ...) F n arg1 arg2 ... argn-1 E 78 * (n parameters, ...) F n arg1 arg2 ... argn-1 E
79 * enum tag e T tag_or_typename 79 * enum tag e T tag_or_typename
80 * struct tag s T tag_or_typename 80 * struct tag s T tag_or_typename
81 * union tag u T tag_or_typename 81 * union tag u T tag_or_typename
82 * 82 *
83 * tag_or_typename 0 (obsolete) no tag or type name 83 * tag_or_typename 0 (obsolete) no tag or type name
84 * 1 n tag tagged type 84 * 1 n tag tagged type
85 * 2 n typename only type name 85 * 2 n typename only type name
86 * 3 line.file.uniq anonymous types 86 * 3 line.file.uniq anonymous types
87 * 87 *
88 * spaces are only for better readability 88 * spaces are only for better readability
89 * additionally it is possible to prepend the characters 'c' (for const) 89 * additionally it is possible to prepend the characters 'c' (for const)
90 * and 'v' (for volatile) 90 * and 'v' (for volatile)
91 */ 91 */
92void 92void
93outtype(const type_t *tp) 93outtype(const type_t *tp)
94{ 94{
95 int t, s, na; 95 int t, s, na;
96 sym_t *arg; 96 sym_t *arg;
97 tspec_t ts; 97 tspec_t ts;
98 98
99 while (tp != NULL) { 99 while (tp != NULL) {
100 if ((ts = tp->t_tspec) == INT && tp->t_is_enum) 100 if ((ts = tp->t_tspec) == INT && tp->t_is_enum)
101 ts = ENUM; 101 ts = ENUM;
102 switch (ts) { 102 switch (ts) {
103 case BOOL: t = 'B'; s = '\0'; break; 103 case BOOL: t = 'B'; s = '\0'; break;
104 case CHAR: t = 'C'; s = '\0'; break; 104 case CHAR: t = 'C'; s = '\0'; break;
105 case SCHAR: t = 'C'; s = 's'; break; 105 case SCHAR: t = 'C'; s = 's'; break;
106 case UCHAR: t = 'C'; s = 'u'; break; 106 case UCHAR: t = 'C'; s = 'u'; break;
107 case SHORT: t = 'S'; s = '\0'; break; 107 case SHORT: t = 'S'; s = '\0'; break;
108 case USHORT: t = 'S'; s = 'u'; break; 108 case USHORT: t = 'S'; s = 'u'; break;
109 case INT: t = 'I'; s = '\0'; break; 109 case INT: t = 'I'; s = '\0'; break;
110 case UINT: t = 'I'; s = 'u'; break; 110 case UINT: t = 'I'; s = 'u'; break;
111 case LONG: t = 'L'; s = '\0'; break; 111 case LONG: t = 'L'; s = '\0'; break;
112 case ULONG: t = 'L'; s = 'u'; break; 112 case ULONG: t = 'L'; s = 'u'; break;
113 case QUAD: t = 'Q'; s = '\0'; break; 113 case QUAD: t = 'Q'; s = '\0'; break;
114 case UQUAD: t = 'Q'; s = 'u'; break; 114 case UQUAD: t = 'Q'; s = 'u'; break;
115 case FLOAT: t = 'D'; s = 's'; break; 115 case FLOAT: t = 'D'; s = 's'; break;
116 case DOUBLE: t = 'D'; s = '\0'; break; 116 case DOUBLE: t = 'D'; s = '\0'; break;
117 case LDOUBLE: t = 'D'; s = 'l'; break; 117 case LDOUBLE: t = 'D'; s = 'l'; break;
118 case VOID: t = 'V'; s = '\0'; break; 118 case VOID: t = 'V'; s = '\0'; break;
119 case PTR: t = 'P'; s = '\0'; break; 119 case PTR: t = 'P'; s = '\0'; break;
120 case ARRAY: t = 'A'; s = '\0'; break; 120 case ARRAY: t = 'A'; s = '\0'; break;
121 case FUNC: t = 'F'; s = '\0'; break; 121 case FUNC: t = 'F'; s = '\0'; break;
122 case ENUM: t = 'T'; s = 'e'; break; 122 case ENUM: t = 'T'; s = 'e'; break;
123 case STRUCT: t = 'T'; s = 's'; break; 123 case STRUCT: t = 'T'; s = 's'; break;
124 case UNION: t = 'T'; s = 'u'; break; 124 case UNION: t = 'T'; s = 'u'; break;
125 case FCOMPLEX: t = 'X'; s = 's'; break; 125 case FCOMPLEX: t = 'X'; s = 's'; break;
126 case DCOMPLEX: t = 'X'; s = '\0'; break; 126 case DCOMPLEX: t = 'X'; s = '\0'; break;
127 case LCOMPLEX: t = 'X'; s = 'l'; break; 127 case LCOMPLEX: t = 'X'; s = 'l'; break;
128 default: 128 default:
129 lint_assert(/*CONSTCOND*/false); 129 lint_assert(/*CONSTCOND*/false);
130 } 130 }
131 if (tp->t_const) 131 if (tp->t_const)
132 outchar('c'); 132 outchar('c');
133 if (tp->t_volatile) 133 if (tp->t_volatile)
134 outchar('v'); 134 outchar('v');
135 if (s != '\0') 135 if (s != '\0')
136 outchar(s); 136 outchar(s);
137 outchar(t); 137 outchar(t);
138 if (ts == ARRAY) { 138 if (ts == ARRAY) {
139 outint(tp->t_dim); 139 outint(tp->t_dim);
140 } else if (ts == ENUM) { 140 } else if (ts == ENUM) {
141 outtt(tp->t_enum->en_tag, tp->t_enum->en_first_typedef); 141 outtt(tp->t_enum->en_tag, tp->t_enum->en_first_typedef);
142 } else if (ts == STRUCT || ts == UNION) { 142 } else if (ts == STRUCT || ts == UNION) {
143 outtt(tp->t_str->sou_tag, tp->t_str->sou_first_typedef); 143 outtt(tp->t_str->sou_tag, tp->t_str->sou_first_typedef);
144 } else if (ts == FUNC && tp->t_proto) { 144 } else if (ts == FUNC && tp->t_proto) {
145 na = 0; 145 na = 0;
146 for (arg = tp->t_args; arg != NULL; arg = arg->s_next) 146 for (arg = tp->t_args; arg != NULL; arg = arg->s_next)
147 na++; 147 na++;
148 if (tp->t_vararg) 148 if (tp->t_vararg)
149 na++; 149 na++;
150 outint(na); 150 outint(na);
151 for (arg = tp->t_args; arg != NULL; arg = arg->s_next) 151 for (arg = tp->t_args; arg != NULL; arg = arg->s_next)
152 outtype(arg->s_type); 152 outtype(arg->s_type);
153 if (tp->t_vararg) 153 if (tp->t_vararg)
154 outchar('E'); 154 outchar('E');
155 } 155 }
156 tp = tp->t_subt; 156 tp = tp->t_subt;
157 } 157 }
158} 158}
159 159
160/* 160/*
161 * type to string 
162 * used for debugging output 
163 * 
164 * it uses its own output buffer for conversion 
165 */ 
166const char * 
167ttos(const type_t *tp) 
168{ 
169 static ob_t tob; 
170 ob_t tmp; 
171 
172 if (tob.o_buf == NULL) { 
173 tob.o_len = 64; 
174 tob.o_buf = tob.o_next = xmalloc(tob.o_len); 
175 tob.o_end = tob.o_buf + tob.o_len; 
176 } 
177 
178 tmp = ob; 
179 ob = tob; 
180 ob.o_next = ob.o_buf; 
181 outtype(tp); 
182 outchar('\0'); 
183 tob = ob; 
184 ob = tmp; 
185 
186 return tob.o_buf; 
187} 
188 
189/* 
190 * write the name of a tag or typename 161 * write the name of a tag or typename
191 * 162 *
192 * if the tag is named, the name of the tag is written, 163 * if the tag is named, the name of the tag is written,
193 * otherwise, if a typename exists which refers to this tag, 164 * otherwise, if a typename exists which refers to this tag,
194 * this typename is written 165 * this typename is written
195 */ 166 */
196static void 167static void
197outtt(sym_t *tag, sym_t *tdef) 168outtt(sym_t *tag, sym_t *tdef)
198{ 169{
199 170
200 /* 0 is no longer used. */ 171 /* 0 is no longer used. */
201 172
202 if (tag->s_name != unnamed) { 173 if (tag->s_name != unnamed) {
203 outint(1); 174 outint(1);
204 outname(tag->s_name); 175 outname(tag->s_name);
205 } else if (tdef != NULL) { 176 } else if (tdef != NULL) {
206 outint(2); 177 outint(2);
207 outname(tdef->s_name); 178 outname(tdef->s_name);
208 } else { 179 } else {
209 outint(3); 180 outint(3);
210 outint(tag->s_def_pos.p_line); 181 outint(tag->s_def_pos.p_line);
211 outchar('.'); 182 outchar('.');
212 outint(get_filename_id(tag->s_def_pos.p_file)); 183 outint(get_filename_id(tag->s_def_pos.p_file));
213 outchar('.'); 184 outchar('.');
214 outint(tag->s_def_pos.p_uniq); 185 outint(tag->s_def_pos.p_uniq);
215 } 186 }
216} 187}
217 188
218/* 189/*
219 * write information about a globally declared/defined symbol 190 * write information about a globally declared/defined symbol
220 * with storage class extern 191 * with storage class extern
221 * 192 *
222 * information about function definitions are written in outfdef(), 193 * information about function definitions are written in outfdef(),
223 * not here 194 * not here
224 */ 195 */
225void 196void
226outsym(const sym_t *sym, scl_t sc, def_t def) 197outsym(const sym_t *sym, scl_t sc, def_t def)
227{ 198{
228 199
229 /* 200 /*
230 * Static function declarations must also be written to the output 201 * Static function declarations must also be written to the output
231 * file. Compatibility of function declarations (for both static 202 * file. Compatibility of function declarations (for both static
232 * and extern functions) must be checked in lint2. Lint1 can't do 203 * and extern functions) must be checked in lint2. Lint1 can't do
233 * this, especially not if functions are declared at block level 204 * this, especially not if functions are declared at block level
234 * before their first declaration at level 0. 205 * before their first declaration at level 0.
235 */ 206 */
236 if (sc != EXTERN && !(sc == STATIC && sym->s_type->t_tspec == FUNC)) 207 if (sc != EXTERN && !(sc == STATIC && sym->s_type->t_tspec == FUNC))
237 return; 208 return;
238 209
239 /* reset buffer */ 210 /* reset buffer */
240 outclr(); 211 outclr();
241 212
242 /* 213 /*
243 * line number of .c source, 'd' for declaration, Id of current 214 * line number of .c source, 'd' for declaration, Id of current
244 * source (.c or .h), and line in current source. 215 * source (.c or .h), and line in current source.
245 */ 216 */
246 outint(csrc_pos.p_line); 217 outint(csrc_pos.p_line);
247 outchar('d'); 218 outchar('d');
248 outint(get_filename_id(sym->s_def_pos.p_file)); 219 outint(get_filename_id(sym->s_def_pos.p_file));
249 outchar('.'); 220 outchar('.');
250 outint(sym->s_def_pos.p_line); 221 outint(sym->s_def_pos.p_line);
251 222
252 /* flags */ 223 /* flags */
253 224
254 switch (def) { 225 switch (def) {
255 case DEF: 226 case DEF:
256 /* defined */ 227 /* defined */
257 outchar('d'); 228 outchar('d');
258 break; 229 break;
259 case TDEF: 230 case TDEF:
260 /* tentative defined */ 231 /* tentative defined */
261 outchar('t'); 232 outchar('t');
262 break; 233 break;
263 case DECL: 234 case DECL:
264 /* declared */ 235 /* declared */
265 outchar('e'); 236 outchar('e');
266 break; 237 break;
267 default: 238 default:
268 lint_assert(/*CONSTCOND*/false); 239 lint_assert(/*CONSTCOND*/false);
269 } 240 }
270 if (llibflg && def != DECL) { 241 if (llibflg && def != DECL) {
271 /* 242 /*
272 * mark it as used so we get no warnings from lint2 about 243 * mark it as used so we get no warnings from lint2 about
273 * unused symbols in libraries. 244 * unused symbols in libraries.
274 */ 245 */
275 outchar('u'); 246 outchar('u');
276 } 247 }
277 248
278 if (sc == STATIC) 249 if (sc == STATIC)
279 outchar('s'); 250 outchar('s');
280 251
281 /* name of the symbol */ 252 /* name of the symbol */
282 outname(sym->s_name); 253 outname(sym->s_name);
283 254
284 /* renamed name of symbol, if necessary */ 255 /* renamed name of symbol, if necessary */
285 if (sym->s_rename != NULL) { 256 if (sym->s_rename != NULL) {
286 outchar('r'); 257 outchar('r');
287 outname(sym->s_rename); 258 outname(sym->s_rename);
288 } 259 }
289 260
290 /* type of the symbol */ 261 /* type of the symbol */
291 outtype(sym->s_type); 262 outtype(sym->s_type);
292} 263}
293 264
294/* 265/*
295 * write information about function definition 266 * write information about function definition
296 * 267 *
297 * this is also done for static functions so we are able to check if 268 * this is also done for static functions so we are able to check if
298 * they are called with proper argument types 269 * they are called with proper argument types
299 */ 270 */
300void 271void
301outfdef(const sym_t *fsym, const pos_t *posp, bool rval, bool osdef, 272outfdef(const sym_t *fsym, const pos_t *posp, bool rval, bool osdef,
302 const sym_t *args) 273 const sym_t *args)
303{ 274{
304 int narg; 275 int narg;
305 const sym_t *arg; 276 const sym_t *arg;
306 277
307 /* reset the buffer */ 278 /* reset the buffer */
308 outclr(); 279 outclr();
309 280
310 /* 281 /*
311 * line number of .c source, 'd' for declaration, Id of current 282 * line number of .c source, 'd' for declaration, Id of current
312 * source (.c or .h), and line in current source 283 * source (.c or .h), and line in current source
313 * 284 *
314 * we are already at the end of the function. If we are in the 285 * we are already at the end of the function. If we are in the
315 * .c source, posp->p_line is correct, otherwise csrc_pos.p_line 286 * .c source, posp->p_line is correct, otherwise csrc_pos.p_line
316 * (for functions defined in header files). 287 * (for functions defined in header files).
317 */ 288 */
318 if (posp->p_file == csrc_pos.p_file) { 289 if (posp->p_file == csrc_pos.p_file) {
319 outint(posp->p_line); 290 outint(posp->p_line);
320 } else { 291 } else {
321 outint(csrc_pos.p_line); 292 outint(csrc_pos.p_line);
322 } 293 }
323 outchar('d'); 294 outchar('d');
324 outint(get_filename_id(posp->p_file)); 295 outint(get_filename_id(posp->p_file));
325 outchar('.'); 296 outchar('.');
326 outint(posp->p_line); 297 outint(posp->p_line);
327 298
328 /* flags */ 299 /* flags */
329 300
330 /* both SCANFLIKE and PRINTFLIKE imply VARARGS */ 301 /* both SCANFLIKE and PRINTFLIKE imply VARARGS */
331 if (printflike_argnum != -1) { 302 if (printflike_argnum != -1) {
332 nvararg = printflike_argnum; 303 nvararg = printflike_argnum;
333 } else if (scanflike_argnum != -1) { 304 } else if (scanflike_argnum != -1) {
334 nvararg = scanflike_argnum; 305 nvararg = scanflike_argnum;
335 } 306 }
336 307
337 if (nvararg != -1) { 308 if (nvararg != -1) {
338 outchar('v'); 309 outchar('v');
339 outint(nvararg); 310 outint(nvararg);
340 } 311 }
341 if (scanflike_argnum != -1) { 312 if (scanflike_argnum != -1) {
342 outchar('S'); 313 outchar('S');
343 outint(scanflike_argnum); 314 outint(scanflike_argnum);
344 } 315 }
345 if (printflike_argnum != -1) { 316 if (printflike_argnum != -1) {
346 outchar('P'); 317 outchar('P');
347 outint(printflike_argnum); 318 outint(printflike_argnum);
348 } 319 }
349 nvararg = printflike_argnum = scanflike_argnum = -1; 320 nvararg = printflike_argnum = scanflike_argnum = -1;
350 321
351 outchar('d'); 322 outchar('d');
352 323
353 if (rval) 324 if (rval)
354 /* has return value */ 325 /* has return value */
355 outchar('r'); 326 outchar('r');
356 327
357 if (llibflg) 328 if (llibflg)
358 /* 329 /*
359 * mark it as used so lint2 does not complain about 330 * mark it as used so lint2 does not complain about
360 * unused symbols in libraries 331 * unused symbols in libraries
361 */ 332 */
362 outchar('u'); 333 outchar('u');
363 334
364 if (osdef) 335 if (osdef)
365 /* old style function definition */ 336 /* old style function definition */
366 outchar('o'); 337 outchar('o');
367 338
368 if (fsym->s_inline) 339 if (fsym->s_inline)
369 outchar('i'); 340 outchar('i');
370 341
371 if (fsym->s_scl == STATIC) 342 if (fsym->s_scl == STATIC)
372 outchar('s'); 343 outchar('s');
373 344
374 /* name of function */ 345 /* name of function */
375 outname(fsym->s_name); 346 outname(fsym->s_name);
376 347
377 /* renamed name of function, if necessary */ 348 /* renamed name of function, if necessary */
378 if (fsym->s_rename != NULL) { 349 if (fsym->s_rename != NULL) {
379 outchar('r'); 350 outchar('r');
380 outname(fsym->s_rename); 351 outname(fsym->s_rename);
381 } 352 }
382 353
383 /* argument types and return value */ 354 /* argument types and return value */
384 if (osdef) { 355 if (osdef) {
385 narg = 0; 356 narg = 0;
386 for (arg = args; arg != NULL; arg = arg->s_next) 357 for (arg = args; arg != NULL; arg = arg->s_next)
387 narg++; 358 narg++;
388 outchar('f'); 359 outchar('f');
389 outint(narg); 360 outint(narg);
390 for (arg = args; arg != NULL; arg = arg->s_next) 361 for (arg = args; arg != NULL; arg = arg->s_next)
391 outtype(arg->s_type); 362 outtype(arg->s_type);
392 outtype(fsym->s_type->t_subt); 363 outtype(fsym->s_type->t_subt);
393 } else { 364 } else {
394 outtype(fsym->s_type); 365 outtype(fsym->s_type);
395 } 366 }
396} 367}
397 368
398/* 369/*
399 * write out all information necessary for lint2 to check function 370 * write out all information necessary for lint2 to check function
400 * calls 371 * calls
401 * 372 *
402 * rvused is set if the return value is used (assigned to a variable) 373 * rvused is set if the return value is used (assigned to a variable)
403 * rvdisc is set if the return value is not used and not ignored 374 * rvdisc is set if the return value is not used and not ignored
404 * (casted to void) 375 * (casted to void)
405 */ 376 */
406void 377void
407outcall(const tnode_t *tn, bool rvused, bool rvdisc) 378outcall(const tnode_t *tn, bool rvused, bool rvdisc)
408{ 379{
409 tnode_t *args, *arg; 380 tnode_t *args, *arg;
410 int narg, n, i; 381 int narg, n, i;
411 int64_t q; 382 int64_t q;
412 tspec_t t; 383 tspec_t t;
413 384
414 /* reset buffer */ 385 /* reset buffer */
415 outclr(); 386 outclr();
416 387
417 /* 388 /*
418 * line number of .c source, 'c' for function call, Id of current 389 * line number of .c source, 'c' for function call, Id of current
419 * source (.c or .h), and line in current source 390 * source (.c or .h), and line in current source
420 */ 391 */
421 outint(csrc_pos.p_line); 392 outint(csrc_pos.p_line);
422 outchar('c'); 393 outchar('c');
423 outint(get_filename_id(curr_pos.p_file)); 394 outint(get_filename_id(curr_pos.p_file));
424 outchar('.'); 395 outchar('.');
425 outint(curr_pos.p_line); 396 outint(curr_pos.p_line);
426 397
427 /* 398 /*
428 * flags; 'u' and 'i' must be last to make sure a letter 399 * flags; 'u' and 'i' must be last to make sure a letter
429 * is between the numeric argument of a flag and the name of 400 * is between the numeric argument of a flag and the name of
430 * the function 401 * the function
431 */ 402 */
432 narg = 0; 403 narg = 0;
433 args = tn->tn_right; 404 args = tn->tn_right;
434 for (arg = args; arg != NULL; arg = arg->tn_right) 405 for (arg = args; arg != NULL; arg = arg->tn_right)
435 narg++; 406 narg++;
436 /* information about arguments */ 407 /* information about arguments */
437 for (n = 1; n <= narg; n++) { 408 for (n = 1; n <= narg; n++) {
438 /* the last argument is the top one in the tree */ 409 /* the last argument is the top one in the tree */
439 for (i = narg, arg = args; i > n; i--, arg = arg->tn_right) 410 for (i = narg, arg = args; i > n; i--, arg = arg->tn_right)
440 continue; 411 continue;
441 arg = arg->tn_left; 412 arg = arg->tn_left;
442 if (arg->tn_op == CON) { 413 if (arg->tn_op == CON) {
443 if (is_integer(t = arg->tn_type->t_tspec)) { 414 if (is_integer(t = arg->tn_type->t_tspec)) {
444 /* 415 /*
445 * XXX it would probably be better to 416 * XXX it would probably be better to
446 * explicitly test the sign 417 * explicitly test the sign
447 */ 418 */
448 if ((q = arg->tn_val->v_quad) == 0) { 419 if ((q = arg->tn_val->v_quad) == 0) {
449 /* zero constant */ 420 /* zero constant */
450 outchar('z'); 421 outchar('z');
451 } else if (msb(q, t, 0) == 0) { 422 } else if (msb(q, t, 0) == 0) {
452 /* positive if casted to signed */ 423 /* positive if casted to signed */
453 outchar('p'); 424 outchar('p');
454 } else { 425 } else {
455 /* negative if casted to signed */ 426 /* negative if casted to signed */
456 outchar('n'); 427 outchar('n');
457 } 428 }
458 outint(n); 429 outint(n);
459 } 430 }
460 } else if (arg->tn_op == ADDR && 431 } else if (arg->tn_op == ADDR &&
461 arg->tn_left->tn_op == STRING && 432 arg->tn_left->tn_op == STRING &&
462 arg->tn_left->tn_string->st_tspec == CHAR) { 433 arg->tn_left->tn_string->st_tspec == CHAR) {
463 /* constant string, write all format specifiers */ 434 /* constant string, write all format specifiers */
464 outchar('s'); 435 outchar('s');
465 outint(n); 436 outint(n);
466 outfstrg(arg->tn_left->tn_string); 437 outfstrg(arg->tn_left->tn_string);
467 } 438 }
468 439
469 } 440 }
470 /* return value discarded/used/ignored */ 441 /* return value discarded/used/ignored */
471 outchar(rvdisc ? 'd' : (rvused ? 'u' : 'i')); 442 outchar(rvdisc ? 'd' : (rvused ? 'u' : 'i'));
472 443
473 /* name of the called function */ 444 /* name of the called function */
474 outname(tn->tn_left->tn_left->tn_sym->s_name); 445 outname(tn->tn_left->tn_left->tn_sym->s_name);
475 446
476 /* types of arguments */ 447 /* types of arguments */
477 outchar('f'); 448 outchar('f');
478 outint(narg); 449 outint(narg);
479 for (n = 1; n <= narg; n++) { 450 for (n = 1; n <= narg; n++) {
480 /* the last argument is the top one in the tree */ 451 /* the last argument is the top one in the tree */
481 for (i = narg, arg = args; i > n; i--, arg = arg->tn_right) 452 for (i = narg, arg = args; i > n; i--, arg = arg->tn_right)
482 continue; 453 continue;
483 outtype(arg->tn_left->tn_type); 454 outtype(arg->tn_left->tn_type);
484 } 455 }
485 /* expected type of return value */ 456 /* expected type of return value */
486 outtype(tn->tn_type); 457 outtype(tn->tn_type);
487} 458}
488 459
489/* 460/*
490 * extracts potential format specifiers for printf() and scanf() and 461 * extracts potential format specifiers for printf() and scanf() and
491 * writes them, enclosed in "" and quoted if necessary, to the output buffer 462 * writes them, enclosed in "" and quoted if necessary, to the output buffer
492 */ 463 */
493static void 464static void
494outfstrg(strg_t *strg) 465outfstrg(strg_t *strg)
495{ 466{
496 unsigned char c, oc; 467 unsigned char c, oc;
497 bool first; 468 bool first;
498 u_char *cp; 469 u_char *cp;
499 470
500 lint_assert(strg->st_tspec == CHAR); 471 lint_assert(strg->st_tspec == CHAR);
501 472
502 cp = strg->st_cp; 473 cp = strg->st_cp;
503 474
504 outchar('"'); 475 outchar('"');
505 476
506 c = *cp++; 477 c = *cp++;
507 478
508 while (c != '\0') { 479 while (c != '\0') {
509 480
510 if (c != '%') { 481 if (c != '%') {
511 c = *cp++; 482 c = *cp++;
512 continue; 483 continue;
513 } 484 }
514 485
515 outqchar('%'); 486 outqchar('%');
516 c = *cp++; 487 c = *cp++;
517 488
518 /* flags for printf and scanf and *-fieldwidth for printf */ 489 /* flags for printf and scanf and *-fieldwidth for printf */
519 while (c != '\0' && (c == '-' || c == '+' || c == ' ' || 490 while (c != '\0' && (c == '-' || c == '+' || c == ' ' ||
520 c == '#' || c == '0' || c == '*')) { 491 c == '#' || c == '0' || c == '*')) {
521 outqchar(c); 492 outqchar(c);
522 c = *cp++; 493 c = *cp++;
523 } 494 }
524 495
525 /* numeric field width */ 496 /* numeric field width */
526 while (c != '\0' && ch_isdigit((char)c)) { 497 while (c != '\0' && ch_isdigit((char)c)) {
527 outqchar(c); 498 outqchar(c);
528 c = *cp++; 499 c = *cp++;
529 } 500 }
530 501
531 /* precision for printf */ 502 /* precision for printf */
532 if (c == '.') { 503 if (c == '.') {
533 outqchar(c); 504 outqchar(c);
534 if ((c = *cp++) == '*') { 505 if ((c = *cp++) == '*') {
535 outqchar(c); 506 outqchar(c);
536 c = *cp++; 507 c = *cp++;
537 } else { 508 } else {
538 while (c != '\0' && ch_isdigit((char)c)) { 509 while (c != '\0' && ch_isdigit((char)c)) {
539 outqchar(c); 510 outqchar(c);
540 c = *cp++; 511 c = *cp++;
541 } 512 }
542 } 513 }
543 } 514 }
544 515
545 /* h, l, L and q flags fpr printf and scanf */ 516 /* h, l, L and q flags fpr printf and scanf */
546 if (c == 'h' || c == 'l' || c == 'L' || c == 'q') { 517 if (c == 'h' || c == 'l' || c == 'L' || c == 'q') {
547 outqchar(c); 518 outqchar(c);
548 c = *cp++; 519 c = *cp++;
549 } 520 }
550 521
551 /* 522 /*
552 * The last character. It is always written so we can detect 523 * The last character. It is always written so we can detect
553 * invalid format specifiers. 524 * invalid format specifiers.
554 */ 525 */
555 if (c != '\0') { 526 if (c != '\0') {
556 outqchar(c); 527 outqchar(c);
557 oc = c; 528 oc = c;
558 c = *cp++; 529 c = *cp++;
559 /* 530 /*
560 * handle [ for scanf. [-] means that a minus sign 531 * handle [ for scanf. [-] means that a minus sign
561 * was found at an undefined position. 532 * was found at an undefined position.
562 */ 533 */
563 if (oc == '[') { 534 if (oc == '[') {
564 if (c == '^') 535 if (c == '^')
565 c = *cp++; 536 c = *cp++;
566 if (c == ']') 537 if (c == ']')
567 c = *cp++; 538 c = *cp++;
568 first = true; 539 first = true;
569 while (c != '\0' && c != ']') { 540 while (c != '\0' && c != ']') {
570 if (c == '-') { 541 if (c == '-') {
571 if (!first && *cp != ']') 542 if (!first && *cp != ']')
572 outqchar(c); 543 outqchar(c);
573 } 544 }
574 first = false; 545 first = false;
575 c = *cp++; 546 c = *cp++;
576 } 547 }
577 if (c == ']') { 548 if (c == ']') {
578 outqchar(c); 549 outqchar(c);
579 c = *cp++; 550 c = *cp++;
580 } 551 }
581 } 552 }
582 } 553 }
583 554
584 } 555 }
585 556
586 outchar('"'); 557 outchar('"');
587} 558}
588 559
589/* 560/*
590 * writes a record if sym was used 561 * writes a record if sym was used
591 */ 562 */
592void 563void
593outusg(const sym_t *sym) 564outusg(const sym_t *sym)
594{ 565{
595 /* reset buffer */ 566 /* reset buffer */
596 outclr(); 567 outclr();
597 568
598 /* 569 /*
599 * line number of .c source, 'u' for used, Id of current 570 * line number of .c source, 'u' for used, Id of current
600 * source (.c or .h), and line in current source 571 * source (.c or .h), and line in current source
601 */ 572 */
602 outint(csrc_pos.p_line); 573 outint(csrc_pos.p_line);
603 outchar('u'); 574 outchar('u');
604 outint(get_filename_id(curr_pos.p_file)); 575 outint(get_filename_id(curr_pos.p_file));
605 outchar('.'); 576 outchar('.');
606 outint(curr_pos.p_line); 577 outint(curr_pos.p_line);
607 578
608 /* necessary to delimit both numbers */ 579 /* necessary to delimit both numbers */
609 outchar('x'); 580 outchar('x');
610 581
611 outname(sym->s_name); 582 outname(sym->s_name);
612} 583}

cvs diff -r1.117 -r1.118 src/usr.bin/xlint/lint1/externs1.h (switch to unified diff)

--- src/usr.bin/xlint/lint1/externs1.h 2021/07/14 17:07:24 1.117
+++ src/usr.bin/xlint/lint1/externs1.h 2021/07/15 17:03:50 1.118
@@ -1,367 +1,366 @@ @@ -1,367 +1,366 @@
1/* $NetBSD: externs1.h,v 1.117 2021/07/14 17:07:24 rillig Exp $ */ 1/* $NetBSD: externs1.h,v 1.118 2021/07/15 17:03:50 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/* 34/*
35 * main.c 35 * main.c
36 */ 36 */
37extern int aflag; 37extern int aflag;
38extern bool bflag; 38extern bool bflag;
39extern bool cflag; 39extern bool cflag;
40extern bool c11flag; 40extern bool c11flag;
41extern bool dflag; 41extern bool dflag;
42extern bool eflag; 42extern bool eflag;
43extern bool Fflag; 43extern bool Fflag;
44extern bool gflag; 44extern bool gflag;
45extern bool hflag; 45extern bool hflag;
46extern bool rflag; 46extern bool rflag;
47extern bool sflag; 47extern bool sflag;
48extern bool tflag; 48extern bool tflag;
49extern bool uflag; 49extern bool uflag;
50extern bool vflag; 50extern bool vflag;
51extern bool yflag; 51extern bool yflag;
52extern bool wflag; 52extern bool wflag;
53extern bool zflag; 53extern bool zflag;
54extern bool Sflag; 54extern bool Sflag;
55extern bool Pflag; 55extern bool Pflag;
56 56
57extern void norecover(void); 57extern void norecover(void);
58 58
59/* 59/*
60 * cgram.y 60 * cgram.y
61 */ 61 */
62extern int block_level; 62extern int block_level;
63extern int mem_block_level; 63extern int mem_block_level;
64extern int yydebug; 64extern int yydebug;
65 65
66extern int yyerror(const char *); 66extern int yyerror(const char *);
67extern int yyparse(void); 67extern int yyparse(void);
68 68
69/* 69/*
70 * scan.l 70 * scan.l
71 */ 71 */
72extern bool attron; 72extern bool attron;
73extern pos_t curr_pos; 73extern pos_t curr_pos;
74extern pos_t csrc_pos; 74extern pos_t csrc_pos;
75extern bool in_system_header; 75extern bool in_system_header;
76extern symt_t symtyp; 76extern symt_t symtyp;
77extern FILE *yyin; 77extern FILE *yyin;
78 78
79extern void initscan(void); 79extern void initscan(void);
80extern int msb(int64_t, tspec_t, int); 80extern int msb(int64_t, tspec_t, int);
81extern int64_t convert_integer(int64_t, tspec_t, int); 81extern int64_t convert_integer(int64_t, tspec_t, int);
82extern void clear_warn_flags(void); 82extern void clear_warn_flags(void);
83extern sym_t *getsym(sbuf_t *); 83extern sym_t *getsym(sbuf_t *);
84extern void cleanup(void); 84extern void cleanup(void);
85extern sym_t *pushdown(const sym_t *); 85extern sym_t *pushdown(const sym_t *);
86extern sym_t *mktempsym(type_t *); 86extern sym_t *mktempsym(type_t *);
87extern void rmsym(sym_t *); 87extern void rmsym(sym_t *);
88extern void rmsyms(sym_t *); 88extern void rmsyms(sym_t *);
89extern void inssym(int, sym_t *); 89extern void inssym(int, sym_t *);
90extern void freeyyv(void *, int); 90extern void freeyyv(void *, int);
91extern int yylex(void); 91extern int yylex(void);
92 92
93/* 93/*
94 * mem1.c 94 * mem1.c
95 */ 95 */
96extern const char *record_filename(const char *, size_t); 96extern const char *record_filename(const char *, size_t);
97extern int get_filename_id(const char *); 97extern int get_filename_id(const char *);
98extern void add_directory_replacement(char *); 98extern void add_directory_replacement(char *);
99extern const char *transform_filename(const char *, size_t); 99extern const char *transform_filename(const char *, size_t);
100 100
101extern void initmem(void); 101extern void initmem(void);
102 102
103extern void *getblk(size_t); 103extern void *getblk(size_t);
104extern void *getlblk(size_t, size_t); 104extern void *getlblk(size_t, size_t);
105extern void freeblk(void); 105extern void freeblk(void);
106extern void freelblk(int); 106extern void freelblk(int);
107 107
108extern void *expr_zalloc(size_t); 108extern void *expr_zalloc(size_t);
109extern tnode_t *expr_zalloc_tnode(void); 109extern tnode_t *expr_zalloc_tnode(void);
110extern void expr_free_all(void); 110extern void expr_free_all(void);
111extern struct memory_block *expr_save_memory(void); 111extern struct memory_block *expr_save_memory(void);
112extern void expr_restore_memory(struct memory_block *); 112extern void expr_restore_memory(struct memory_block *);
113 113
114/* 114/*
115 * err.c 115 * err.c
116 */ 116 */
117extern int nerr; 117extern int nerr;
118extern int sytxerr; 118extern int sytxerr;
119extern const char *const msgs[]; 119extern const char *const msgs[];
120 120
121extern void msglist(void); 121extern void msglist(void);
122extern void error_at(int, const pos_t *, ...); 122extern void error_at(int, const pos_t *, ...);
123extern void warning_at(int, const pos_t *, ...); 123extern void warning_at(int, const pos_t *, ...);
124extern void message_at(int, const pos_t *, ...); 124extern void message_at(int, const pos_t *, ...);
125extern void error(int, ...); 125extern void error(int, ...);
126extern void warning(int, ...); 126extern void warning(int, ...);
127extern void message(int, ...); 127extern void message(int, ...);
128extern void gnuism(int, ...); 128extern void gnuism(int, ...);
129extern void c99ism(int, ...); 129extern void c99ism(int, ...);
130extern void c11ism(int, ...); 130extern void c11ism(int, ...);
131extern void internal_error(const char *, int, const char *, ...) 131extern void internal_error(const char *, int, const char *, ...)
132 __attribute__((__noreturn__,__format__(__printf__, 3, 4))); 132 __attribute__((__noreturn__,__format__(__printf__, 3, 4)));
133extern void assert_failed(const char *, int, const char *, const char *) 133extern void assert_failed(const char *, int, const char *, const char *)
134 __attribute__((__noreturn__)); 134 __attribute__((__noreturn__));
135extern void update_location(const char *, int, bool, bool); 135extern void update_location(const char *, int, bool, bool);
136 136
137/* 137/*
138 * decl.c 138 * decl.c
139 */ 139 */
140extern dinfo_t *dcs; 140extern dinfo_t *dcs;
141extern const char *unnamed; 141extern const char *unnamed;
142extern int enumval; 142extern int enumval;
143 143
144extern void initdecl(void); 144extern void initdecl(void);
145extern type_t *gettyp(tspec_t); 145extern type_t *gettyp(tspec_t);
146extern type_t *dup_type(const type_t *); 146extern type_t *dup_type(const type_t *);
147extern type_t *expr_dup_type(const type_t *); 147extern type_t *expr_dup_type(const type_t *);
148extern bool is_incomplete(const type_t *); 148extern bool is_incomplete(const type_t *);
149extern void setcomplete(type_t *, bool); 149extern void setcomplete(type_t *, bool);
150extern void add_storage_class(scl_t); 150extern void add_storage_class(scl_t);
151extern void add_type(type_t *); 151extern void add_type(type_t *);
152extern void add_qualifier(tqual_t); 152extern void add_qualifier(tqual_t);
153extern void addpacked(void); 153extern void addpacked(void);
154extern void add_attr_used(void); 154extern void add_attr_used(void);
155extern void begin_declaration_level(scl_t); 155extern void begin_declaration_level(scl_t);
156extern void end_declaration_level(void); 156extern void end_declaration_level(void);
157extern void setasm(void); 157extern void setasm(void);
158extern void begin_type(void); 158extern void begin_type(void);
159extern void end_type(void); 159extern void end_type(void);
160extern int length(const type_t *, const char *); 160extern int length(const type_t *, const char *);
161extern int alignment_in_bits(const type_t *); 161extern int alignment_in_bits(const type_t *);
162extern sym_t *lnklst(sym_t *, sym_t *); 162extern sym_t *lnklst(sym_t *, sym_t *);
163extern void check_type(sym_t *); 163extern void check_type(sym_t *);
164extern sym_t *declarator_1_struct_union(sym_t *); 164extern sym_t *declarator_1_struct_union(sym_t *);
165extern sym_t *bitfield(sym_t *, int); 165extern sym_t *bitfield(sym_t *, int);
166extern qual_ptr *merge_qualified_pointer(qual_ptr *, qual_ptr *); 166extern qual_ptr *merge_qualified_pointer(qual_ptr *, qual_ptr *);
167extern sym_t *add_pointer(sym_t *, qual_ptr *); 167extern sym_t *add_pointer(sym_t *, qual_ptr *);
168extern sym_t *add_array(sym_t *, bool, int); 168extern sym_t *add_array(sym_t *, bool, int);
169extern sym_t *add_function(sym_t *, sym_t *); 169extern sym_t *add_function(sym_t *, sym_t *);
170extern void check_function_definition(sym_t *, bool); 170extern void check_function_definition(sym_t *, bool);
171extern sym_t *declarator_name(sym_t *); 171extern sym_t *declarator_name(sym_t *);
172extern sym_t *old_style_function_name(sym_t *); 172extern sym_t *old_style_function_name(sym_t *);
173extern type_t *mktag(sym_t *, tspec_t, bool, bool); 173extern type_t *mktag(sym_t *, tspec_t, bool, bool);
174extern const char *storage_class_name(scl_t); 174extern const char *storage_class_name(scl_t);
175extern type_t *complete_tag_struct_or_union(type_t *, sym_t *); 175extern type_t *complete_tag_struct_or_union(type_t *, sym_t *);
176extern type_t *complete_tag_enum(type_t *, sym_t *); 176extern type_t *complete_tag_enum(type_t *, sym_t *);
177extern sym_t *enumeration_constant(sym_t *, int, bool); 177extern sym_t *enumeration_constant(sym_t *, int, bool);
178extern void declare(sym_t *, bool, sbuf_t *); 178extern void declare(sym_t *, bool, sbuf_t *);
179extern void copy_usage_info(sym_t *, sym_t *); 179extern void copy_usage_info(sym_t *, sym_t *);
180extern bool check_redeclaration(sym_t *, bool *); 180extern bool check_redeclaration(sym_t *, bool *);
181extern bool eqptrtype(const type_t *, const type_t *, bool); 181extern bool eqptrtype(const type_t *, const type_t *, bool);
182extern bool eqtype(const type_t *, const type_t *, bool, bool, bool *); 182extern bool eqtype(const type_t *, const type_t *, bool, bool, bool *);
183extern void complete_type(sym_t *, sym_t *); 183extern void complete_type(sym_t *, sym_t *);
184extern sym_t *declare_argument(sym_t *, bool); 184extern sym_t *declare_argument(sym_t *, bool);
185extern void check_func_lint_directives(void); 185extern void check_func_lint_directives(void);
186extern void check_func_old_style_arguments(void); 186extern void check_func_old_style_arguments(void);
187 187
188extern void declare_local(sym_t *, bool); 188extern void declare_local(sym_t *, bool);
189extern sym_t *abstract_name(void); 189extern sym_t *abstract_name(void);
190extern void global_clean_up(void); 190extern void global_clean_up(void);
191extern sym_t *declare_1_abstract(sym_t *); 191extern sym_t *declare_1_abstract(sym_t *);
192extern void check_size(sym_t *); 192extern void check_size(sym_t *);
193extern void mark_as_set(sym_t *); 193extern void mark_as_set(sym_t *);
194extern void mark_as_used(sym_t *, bool, bool); 194extern void mark_as_used(sym_t *, bool, bool);
195extern void check_usage(dinfo_t *); 195extern void check_usage(dinfo_t *);
196extern void check_usage_sym(bool, sym_t *); 196extern void check_usage_sym(bool, sym_t *);
197extern void check_global_symbols(void); 197extern void check_global_symbols(void);
198extern void print_previous_declaration(int, const sym_t *); 198extern void print_previous_declaration(int, const sym_t *);
199extern int to_int_constant(tnode_t *, bool); 199extern int to_int_constant(tnode_t *, bool);
200 200
201/* 201/*
202 * tree.c 202 * tree.c
203 */ 203 */
204extern const tnode_t *before_conversion(const tnode_t *); 204extern const tnode_t *before_conversion(const tnode_t *);
205extern type_t *derive_type(type_t *, tspec_t); 205extern type_t *derive_type(type_t *, tspec_t);
206extern type_t *expr_derive_type(type_t *, tspec_t); 206extern type_t *expr_derive_type(type_t *, tspec_t);
207extern tnode_t *expr_new_constant(type_t *, val_t *); 207extern tnode_t *expr_new_constant(type_t *, val_t *);
208extern tnode_t *new_name_node(sym_t *, int); 208extern tnode_t *new_name_node(sym_t *, int);
209extern tnode_t *new_string_node(strg_t *); 209extern tnode_t *new_string_node(strg_t *);
210extern sym_t *struct_or_union_member(tnode_t *, op_t, sym_t *); 210extern sym_t *struct_or_union_member(tnode_t *, op_t, sym_t *);
211extern tnode_t *build_generic_selection(const tnode_t *, 211extern tnode_t *build_generic_selection(const tnode_t *,
212 struct generic_association *); 212 struct generic_association *);
213 213
214extern tnode_t *build(op_t, tnode_t *, tnode_t *); 214extern tnode_t *build(op_t, tnode_t *, tnode_t *);
215extern tnode_t *build_member_access(tnode_t *, op_t, sbuf_t *); 215extern tnode_t *build_member_access(tnode_t *, op_t, sbuf_t *);
216extern tnode_t *cconv(tnode_t *); 216extern tnode_t *cconv(tnode_t *);
217extern bool is_typeok_bool_operand(const tnode_t *); 217extern bool is_typeok_bool_operand(const tnode_t *);
218extern bool typeok(op_t, int, const tnode_t *, const tnode_t *); 218extern bool typeok(op_t, int, const tnode_t *, const tnode_t *);
219extern tnode_t *promote(op_t, bool, tnode_t *); 219extern tnode_t *promote(op_t, bool, tnode_t *);
220extern tnode_t *convert(op_t, int, type_t *, tnode_t *); 220extern tnode_t *convert(op_t, int, type_t *, tnode_t *);
221extern void convert_constant(op_t, int, const type_t *, val_t *, val_t *); 221extern void convert_constant(op_t, int, const type_t *, val_t *, val_t *);
222extern tnode_t *build_sizeof(const type_t *); 222extern tnode_t *build_sizeof(const type_t *);
223extern tnode_t *build_offsetof(const type_t *, const sym_t *); 223extern tnode_t *build_offsetof(const type_t *, const sym_t *);
224extern tnode_t *build_alignof(const type_t *); 224extern tnode_t *build_alignof(const type_t *);
225extern tnode_t *cast(tnode_t *, type_t *); 225extern tnode_t *cast(tnode_t *, type_t *);
226extern tnode_t *new_function_argument_node(tnode_t *, tnode_t *); 226extern tnode_t *new_function_argument_node(tnode_t *, tnode_t *);
227extern tnode_t *new_function_call_node(tnode_t *, tnode_t *); 227extern tnode_t *new_function_call_node(tnode_t *, tnode_t *);
228extern val_t *constant(tnode_t *, bool); 228extern val_t *constant(tnode_t *, bool);
229extern void expr(tnode_t *, bool, bool, bool, bool); 229extern void expr(tnode_t *, bool, bool, bool, bool);
230extern void check_expr_misc(const tnode_t *, bool, bool, bool, 230extern void check_expr_misc(const tnode_t *, bool, bool, bool,
231 bool, bool, bool); 231 bool, bool, bool);
232extern bool constant_addr(const tnode_t *, const sym_t **, ptrdiff_t *); 232extern bool constant_addr(const tnode_t *, const sym_t **, ptrdiff_t *);
233extern strg_t *cat_strings(strg_t *, strg_t *); 233extern strg_t *cat_strings(strg_t *, strg_t *);
234extern int64_t type_size_in_bits(const type_t *); 234extern int64_t type_size_in_bits(const type_t *);
235#ifdef DEBUG 235#ifdef DEBUG
236extern void debug_node(const tnode_t *, int); 236extern void debug_node(const tnode_t *, int);
237#else 237#else
238#define debug_node(tn, indent) do { } while (false) 238#define debug_node(tn, indent) do { } while (false)
239#endif 239#endif
240 240
241/* 241/*
242 * func.c 242 * func.c
243 */ 243 */
244extern sym_t *funcsym; 244extern sym_t *funcsym;
245extern bool reached; 245extern bool reached;
246extern bool warn_about_unreachable; 246extern bool warn_about_unreachable;
247extern bool seen_fallthrough; 247extern bool seen_fallthrough;
248extern int nargusg; 248extern int nargusg;
249extern pos_t argsused_pos; 249extern pos_t argsused_pos;
250extern int nvararg; 250extern int nvararg;
251extern pos_t vapos; 251extern pos_t vapos;
252extern int printflike_argnum; 252extern int printflike_argnum;
253extern pos_t printflike_pos; 253extern pos_t printflike_pos;
254extern int scanflike_argnum; 254extern int scanflike_argnum;
255extern pos_t scanflike_pos; 255extern pos_t scanflike_pos;
256extern bool constcond_flag; 256extern bool constcond_flag;
257extern bool llibflg; 257extern bool llibflg;
258extern int lwarn; 258extern int lwarn;
259extern bool bitfieldtype_ok; 259extern bool bitfieldtype_ok;
260extern bool plibflg; 260extern bool plibflg;
261extern bool quadflg; 261extern bool quadflg;
262 262
263extern void begin_control_statement(control_statement_kind); 263extern void begin_control_statement(control_statement_kind);
264extern void end_control_statement(control_statement_kind); 264extern void end_control_statement(control_statement_kind);
265extern void check_statement_reachable(void); 265extern void check_statement_reachable(void);
266extern void funcdef(sym_t *); 266extern void funcdef(sym_t *);
267extern void funcend(void); 267extern void funcend(void);
268extern void named_label(sym_t *); 268extern void named_label(sym_t *);
269extern void case_label(tnode_t *); 269extern void case_label(tnode_t *);
270extern void default_label(void); 270extern void default_label(void);
271extern void if1(tnode_t *); 271extern void if1(tnode_t *);
272extern void if2(void); 272extern void if2(void);
273extern void if3(bool); 273extern void if3(bool);
274extern void switch1(tnode_t *); 274extern void switch1(tnode_t *);
275extern void switch2(void); 275extern void switch2(void);
276extern void while1(tnode_t *); 276extern void while1(tnode_t *);
277extern void while2(void); 277extern void while2(void);
278extern void do1(void); 278extern void do1(void);
279extern void do2(tnode_t *); 279extern void do2(tnode_t *);
280extern void for1(tnode_t *, tnode_t *, tnode_t *); 280extern void for1(tnode_t *, tnode_t *, tnode_t *);
281extern void for2(void); 281extern void for2(void);
282extern void do_goto(sym_t *); 282extern void do_goto(sym_t *);
283extern void do_continue(void); 283extern void do_continue(void);
284extern void do_break(void); 284extern void do_break(void);
285extern void do_return(tnode_t *); 285extern void do_return(tnode_t *);
286extern void global_clean_up_decl(bool); 286extern void global_clean_up_decl(bool);
287extern void argsused(int); 287extern void argsused(int);
288extern void constcond(int); 288extern void constcond(int);
289extern void fallthru(int); 289extern void fallthru(int);
290extern void not_reached(int); 290extern void not_reached(int);
291extern void lintlib(int); 291extern void lintlib(int);
292extern void linted(int); 292extern void linted(int);
293extern void varargs(int); 293extern void varargs(int);
294extern void printflike(int); 294extern void printflike(int);
295extern void scanflike(int); 295extern void scanflike(int);
296extern void protolib(int); 296extern void protolib(int);
297extern void longlong(int); 297extern void longlong(int);
298extern void bitfieldtype(int); 298extern void bitfieldtype(int);
299 299
300/* 300/*
301 * init.c 301 * init.c
302 */ 302 */
303extern void begin_initialization(sym_t *); 303extern void begin_initialization(sym_t *);
304extern void end_initialization(void); 304extern void end_initialization(void);
305extern sym_t **current_initsym(void); 305extern sym_t **current_initsym(void);
306 306
307extern void init_rbrace(void); 307extern void init_rbrace(void);
308extern void init_lbrace(void); 308extern void init_lbrace(void);
309extern void init_expr(tnode_t *); 309extern void init_expr(tnode_t *);
310extern void add_designator_member(sbuf_t *); 310extern void add_designator_member(sbuf_t *);
311extern void add_designator_subscript(range_t); 311extern void add_designator_subscript(range_t);
312 312
313/* 313/*
314 * emit.c 314 * emit.c
315 */ 315 */
316extern void outtype(const type_t *); 316extern void outtype(const type_t *);
317extern const char *ttos(const type_t *); 
318extern void outsym(const sym_t *, scl_t, def_t); 317extern void outsym(const sym_t *, scl_t, def_t);
319extern void outfdef(const sym_t *, const pos_t *, bool, bool, 318extern void outfdef(const sym_t *, const pos_t *, bool, bool,
320 const sym_t *); 319 const sym_t *);
321extern void outcall(const tnode_t *, bool, bool); 320extern void outcall(const tnode_t *, bool, bool);
322extern void outusg(const sym_t *); 321extern void outusg(const sym_t *);
323 322
324/* 323/*
325 * lex.c 324 * lex.c
326 */ 325 */
327extern int lex_name(const char *, size_t); 326extern int lex_name(const char *, size_t);
328extern int lex_integer_constant(const char *, size_t, int); 327extern int lex_integer_constant(const char *, size_t, int);
329extern int lex_floating_constant(const char *, size_t); 328extern int lex_floating_constant(const char *, size_t);
330extern int lex_operator(int, op_t); 329extern int lex_operator(int, op_t);
331extern int lex_string(void); 330extern int lex_string(void);
332extern int lex_wide_string(void); 331extern int lex_wide_string(void);
333extern int lex_character_constant(void); 332extern int lex_character_constant(void);
334extern int lex_wide_character_constant(void); 333extern int lex_wide_character_constant(void);
335extern void lex_directive(const char *); 334extern void lex_directive(const char *);
336extern void lex_next_line(void); 335extern void lex_next_line(void);
337extern void lex_comment(void); 336extern void lex_comment(void);
338extern void lex_slash_slash_comment(void); 337extern void lex_slash_slash_comment(void);
339extern void lex_unknown_character(int); 338extern void lex_unknown_character(int);
340extern int lex_input(void); 339extern int lex_input(void);
341 340
342/* 341/*
343 * print.c 342 * print.c
344 */ 343 */
345const char *scl_name(scl_t); 344const char *scl_name(scl_t);
346 345
347/* 346/*
348 * ckbool.c 347 * ckbool.c
349 */ 348 */
350extern bool typeok_scalar_strict_bool(op_t, const mod_t *, int, 349extern bool typeok_scalar_strict_bool(op_t, const mod_t *, int,
351 const tnode_t *, const tnode_t *); 350 const tnode_t *, const tnode_t *);
352extern bool fallback_symbol_strict_bool(sym_t *); 351extern bool fallback_symbol_strict_bool(sym_t *);
353 352
354/* 353/*
355 * ckctype.c 354 * ckctype.c
356 */ 355 */
357extern void check_ctype_function_call(const tnode_t *, const tnode_t *); 356extern void check_ctype_function_call(const tnode_t *, const tnode_t *);
358extern void check_ctype_macro_invocation(const tnode_t *, const tnode_t *); 357extern void check_ctype_macro_invocation(const tnode_t *, const tnode_t *);
359 358
360/* 359/*
361 * ckgetopt.c 360 * ckgetopt.c
362 */ 361 */
363extern void check_getopt_begin_while(const tnode_t *); 362extern void check_getopt_begin_while(const tnode_t *);
364extern void check_getopt_begin_switch(void); 363extern void check_getopt_begin_switch(void);
365extern void check_getopt_case_label(int64_t); 364extern void check_getopt_case_label(int64_t);
366extern void check_getopt_end_switch(void); 365extern void check_getopt_end_switch(void);
367extern void check_getopt_end_while(void); 366extern void check_getopt_end_while(void);

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

--- src/usr.bin/xlint/lint1/tree.c 2021/07/14 17:07:24 1.314
+++ src/usr.bin/xlint/lint1/tree.c 2021/07/15 17:03:50 1.315
@@ -1,1039 +1,1039 @@ @@ -1,1039 +1,1039 @@
1/* $NetBSD: tree.c,v 1.314 2021/07/14 17:07:24 rillig Exp $ */ 1/* $NetBSD: tree.c,v 1.315 2021/07/15 17:03:50 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) && !defined(lint) 39#if defined(__RCSID) && !defined(lint)
40__RCSID("$NetBSD: tree.c,v 1.314 2021/07/14 17:07:24 rillig Exp $"); 40__RCSID("$NetBSD: tree.c,v 1.315 2021/07/15 17:03:50 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#include "cgram.h" 51#include "cgram.h"
52 52
53static tnode_t *expr_new_integer_constant(tspec_t, int64_t); 53static tnode_t *expr_new_integer_constant(tspec_t, int64_t);
54static void check_pointer_comparison(op_t, 54static void check_pointer_comparison(op_t,
55 const tnode_t *, const tnode_t *); 55 const tnode_t *, const tnode_t *);
56static bool check_assign_types_compatible(op_t, int, 56static bool check_assign_types_compatible(op_t, int,
57 const tnode_t *, const tnode_t *); 57 const tnode_t *, const tnode_t *);
58static void check_bad_enum_operation(op_t, 58static void check_bad_enum_operation(op_t,
59 const tnode_t *, const tnode_t *); 59 const tnode_t *, const tnode_t *);
60static void check_enum_type_mismatch(op_t, int, 60static void check_enum_type_mismatch(op_t, int,
61 const tnode_t *, const tnode_t *); 61 const tnode_t *, const tnode_t *);
62static void check_enum_int_mismatch(op_t, int, 62static void check_enum_int_mismatch(op_t, int,
63 const tnode_t *, const tnode_t *); 63 const tnode_t *, const tnode_t *);
64static tnode_t *new_tnode(op_t, type_t *, tnode_t *, tnode_t *); 64static tnode_t *new_tnode(op_t, type_t *, tnode_t *, tnode_t *);
65static void balance(op_t, tnode_t **, tnode_t **); 65static void balance(op_t, tnode_t **, tnode_t **);
66static void warn_incompatible_types(op_t, const type_t *, tspec_t, 66static void warn_incompatible_types(op_t, const type_t *, tspec_t,
67 const type_t *, tspec_t); 67 const type_t *, tspec_t);
68static void warn_incompatible_pointers(const mod_t *, 68static void warn_incompatible_pointers(const mod_t *,
69 const type_t *, const type_t *); 69 const type_t *, const type_t *);
70static bool has_constant_member(const type_t *); 70static bool has_constant_member(const type_t *);
71static void check_prototype_conversion(int, tspec_t, tspec_t, type_t *, 71static void check_prototype_conversion(int, tspec_t, tspec_t, type_t *,
72 tnode_t *); 72 tnode_t *);
73static void check_integer_conversion(op_t, int, tspec_t, tspec_t, type_t *, 73static void check_integer_conversion(op_t, int, tspec_t, tspec_t, type_t *,
74 tnode_t *); 74 tnode_t *);
75static void check_pointer_integer_conversion(op_t, tspec_t, type_t *, 75static void check_pointer_integer_conversion(op_t, tspec_t, type_t *,
76 tnode_t *); 76 tnode_t *);
77static void check_pointer_conversion(tnode_t *, type_t *); 77static void check_pointer_conversion(tnode_t *, type_t *);
78static tnode_t *build_struct_access(op_t, tnode_t *, tnode_t *); 78static tnode_t *build_struct_access(op_t, tnode_t *, tnode_t *);
79static tnode_t *build_prepost_incdec(op_t, tnode_t *); 79static tnode_t *build_prepost_incdec(op_t, tnode_t *);
80static tnode_t *build_real_imag(op_t, tnode_t *); 80static tnode_t *build_real_imag(op_t, tnode_t *);
81static tnode_t *build_address(tnode_t *, bool); 81static tnode_t *build_address(tnode_t *, bool);
82static tnode_t *build_plus_minus(op_t, tnode_t *, tnode_t *); 82static tnode_t *build_plus_minus(op_t, tnode_t *, tnode_t *);
83static tnode_t *build_bit_shift(op_t, tnode_t *, tnode_t *); 83static tnode_t *build_bit_shift(op_t, tnode_t *, tnode_t *);
84static tnode_t *build_colon(tnode_t *, tnode_t *); 84static tnode_t *build_colon(tnode_t *, tnode_t *);
85static tnode_t *build_assignment(op_t, tnode_t *, tnode_t *); 85static tnode_t *build_assignment(op_t, tnode_t *, tnode_t *);
86static tnode_t *plength(type_t *); 86static tnode_t *plength(type_t *);
87static tnode_t *fold(tnode_t *); 87static tnode_t *fold(tnode_t *);
88static tnode_t *fold_test(tnode_t *); 88static tnode_t *fold_test(tnode_t *);
89static tnode_t *fold_float(tnode_t *); 89static tnode_t *fold_float(tnode_t *);
90static tnode_t *check_function_arguments(type_t *, tnode_t *); 90static tnode_t *check_function_arguments(type_t *, tnode_t *);
91static tnode_t *check_prototype_argument(int, type_t *, tnode_t *); 91static tnode_t *check_prototype_argument(int, type_t *, tnode_t *);
92static void check_null_effect(const tnode_t *); 92static void check_null_effect(const tnode_t *);
93static void display_expression(const tnode_t *, int); 93static void display_expression(const tnode_t *, int);
94static void check_array_index(tnode_t *, bool); 94static void check_array_index(tnode_t *, bool);
95static void check_integer_comparison(op_t, tnode_t *, tnode_t *); 95static void check_integer_comparison(op_t, tnode_t *, tnode_t *);
96static void check_precedence_confusion(tnode_t *); 96static void check_precedence_confusion(tnode_t *);
97 97
98extern sig_atomic_t fpe; 98extern sig_atomic_t fpe;
99 99
100static const char * 100static const char *
101op_name(op_t op) 101op_name(op_t op)
102{ 102{
103 return modtab[op].m_name; 103 return modtab[op].m_name;
104} 104}
105 105
106#ifdef DEBUG 106#ifdef DEBUG
107void 107void
108debug_node(const tnode_t *tn, int indent) 108debug_node(const tnode_t *tn, int indent)
109{ 109{
110 op_t op; 110 op_t op;
111 111
112 if (tn == NULL) { 112 if (tn == NULL) {
113 printf("%*s" "null\n", indent, ""); 113 printf("%*s" "null\n", indent, "");
114 return; 114 return;
115 } 115 }
116 116
117 op = tn->tn_op; 117 op = tn->tn_op;
118 printf("%*s%s with type '%s'%s%s", 118 printf("%*s%s with type '%s'%s%s",
119 2 * indent, "", 119 2 * indent, "",
120 op == CVT && !tn->tn_cast ? "convert" : op_name(op), 120 op == CVT && !tn->tn_cast ? "convert" : op_name(op),
121 type_name(tn->tn_type), tn->tn_lvalue ? ", lvalue" : "", 121 type_name(tn->tn_type), tn->tn_lvalue ? ", lvalue" : "",
122 tn->tn_parenthesized ? ", parenthesized" : ""); 122 tn->tn_parenthesized ? ", parenthesized" : "");
123 123
124 if (op == NAME) 124 if (op == NAME)
125 printf(" %s\n", tn->tn_sym->s_name); 125 printf(" %s\n", tn->tn_sym->s_name);
126 else if (op == CON && is_floating(tn->tn_type->t_tspec)) 126 else if (op == CON && is_floating(tn->tn_type->t_tspec))
127 printf(", value %Lg", tn->tn_val->v_ldbl); 127 printf(", value %Lg", tn->tn_val->v_ldbl);
128 else if (op == CON && is_uinteger(tn->tn_type->t_tspec)) 128 else if (op == CON && is_uinteger(tn->tn_type->t_tspec))
129 printf(", value %llu\n", (unsigned long long)tn->tn_val->v_quad); 129 printf(", value %llu\n", (unsigned long long)tn->tn_val->v_quad);
130 else if (op == CON && is_integer(tn->tn_type->t_tspec)) 130 else if (op == CON && is_integer(tn->tn_type->t_tspec))
131 printf(", value %lld\n", (long long)tn->tn_val->v_quad); 131 printf(", value %lld\n", (long long)tn->tn_val->v_quad);
132 else if (op == CON) 132 else if (op == CON)
133 printf(", unknown value\n"); 133 printf(", unknown value\n");
134 else if (op == STRING) 134 else if (op == STRING)
135 printf(", length %zu\n", tn->tn_string->st_len); 135 printf(", length %zu\n", tn->tn_string->st_len);
136 else { 136 else {
137 printf("\n"); 137 printf("\n");
138 138
139 debug_node(tn->tn_left, indent + 1); 139 debug_node(tn->tn_left, indent + 1);
140 if (modtab[op].m_binary || tn->tn_right != NULL) 140 if (modtab[op].m_binary || tn->tn_right != NULL)
141 debug_node(tn->tn_right, indent + 1); 141 debug_node(tn->tn_right, indent + 1);
142 } 142 }
143} 143}
144#endif 144#endif
145 145
146/* Build 'pointer to tp', 'array of tp' or 'function returning tp'. */ 146/* Build 'pointer to tp', 'array of tp' or 'function returning tp'. */
147type_t * 147type_t *
148derive_type(type_t *tp, tspec_t t) 148derive_type(type_t *tp, tspec_t t)
149{ 149{
150 type_t *tp2; 150 type_t *tp2;
151 151
152 tp2 = getblk(sizeof(*tp2)); 152 tp2 = getblk(sizeof(*tp2));
153 tp2->t_tspec = t; 153 tp2->t_tspec = t;
154 tp2->t_subt = tp; 154 tp2->t_subt = tp;
155 return tp2; 155 return tp2;
156} 156}
157 157
158/* 158/*
159 * Build 'pointer to tp', 'array of tp' or 'function returning tp'. The 159 * Build 'pointer to tp', 'array of tp' or 'function returning tp'. The
160 * memory is freed at the end of the current expression. 160 * memory is freed at the end of the current expression.
161 */ 161 */
162type_t * 162type_t *
163expr_derive_type(type_t *tp, tspec_t t) 163expr_derive_type(type_t *tp, tspec_t t)
164{ 164{
165 type_t *tp2; 165 type_t *tp2;
166 166
167 tp2 = expr_zalloc(sizeof(*tp2)); 167 tp2 = expr_zalloc(sizeof(*tp2));
168 tp2->t_tspec = t; 168 tp2->t_tspec = t;
169 tp2->t_subt = tp; 169 tp2->t_subt = tp;
170 return tp2; 170 return tp2;
171} 171}
172 172
173/* 173/*
174 * Create a node for a constant. 174 * Create a node for a constant.
175 */ 175 */
176tnode_t * 176tnode_t *
177expr_new_constant(type_t *tp, val_t *v) 177expr_new_constant(type_t *tp, val_t *v)
178{ 178{
179 tnode_t *n; 179 tnode_t *n;
180 180
181 n = expr_zalloc_tnode(); 181 n = expr_zalloc_tnode();
182 n->tn_op = CON; 182 n->tn_op = CON;
183 n->tn_type = tp; 183 n->tn_type = tp;
184 n->tn_val = expr_zalloc(sizeof(*n->tn_val)); 184 n->tn_val = expr_zalloc(sizeof(*n->tn_val));
185 n->tn_val->v_tspec = tp->t_tspec; 185 n->tn_val->v_tspec = tp->t_tspec;
186 n->tn_val->v_unsigned_since_c90 = v->v_unsigned_since_c90; 186 n->tn_val->v_unsigned_since_c90 = v->v_unsigned_since_c90;
187 n->tn_val->v_u = v->v_u; 187 n->tn_val->v_u = v->v_u;
188 free(v); 188 free(v);
189 return n; 189 return n;
190} 190}
191 191
192static tnode_t * 192static tnode_t *
193expr_new_integer_constant(tspec_t t, int64_t q) 193expr_new_integer_constant(tspec_t t, int64_t q)
194{ 194{
195 tnode_t *n; 195 tnode_t *n;
196 196
197 n = expr_zalloc_tnode(); 197 n = expr_zalloc_tnode();
198 n->tn_op = CON; 198 n->tn_op = CON;
199 n->tn_type = gettyp(t); 199 n->tn_type = gettyp(t);
200 n->tn_val = expr_zalloc(sizeof(*n->tn_val)); 200 n->tn_val = expr_zalloc(sizeof(*n->tn_val));
201 n->tn_val->v_tspec = t; 201 n->tn_val->v_tspec = t;
202 n->tn_val->v_quad = q; 202 n->tn_val->v_quad = q;
203 return n; 203 return n;
204} 204}
205 205
206static void 206static void
207fallback_symbol(sym_t *sym) 207fallback_symbol(sym_t *sym)
208{ 208{
209 209
210 if (fallback_symbol_strict_bool(sym)) 210 if (fallback_symbol_strict_bool(sym))
211 return; 211 return;
212 212
213 if (block_level > 0 && (strcmp(sym->s_name, "__FUNCTION__") == 0 || 213 if (block_level > 0 && (strcmp(sym->s_name, "__FUNCTION__") == 0 ||
214 strcmp(sym->s_name, "__PRETTY_FUNCTION__") == 0)) { 214 strcmp(sym->s_name, "__PRETTY_FUNCTION__") == 0)) {
215 /* __FUNCTION__/__PRETTY_FUNCTION__ is a GCC extension */ 215 /* __FUNCTION__/__PRETTY_FUNCTION__ is a GCC extension */
216 gnuism(316); 216 gnuism(316);
217 sym->s_type = derive_type(gettyp(CHAR), PTR); 217 sym->s_type = derive_type(gettyp(CHAR), PTR);
218 sym->s_type->t_const = true; 218 sym->s_type->t_const = true;
219 return; 219 return;
220 } 220 }
221 221
222 if (block_level > 0 && strcmp(sym->s_name, "__func__") == 0) { 222 if (block_level > 0 && strcmp(sym->s_name, "__func__") == 0) {
223 if (!Sflag) 223 if (!Sflag)
224 /* __func__ is a C9X feature */ 224 /* __func__ is a C9X feature */
225 warning(317); 225 warning(317);
226 sym->s_type = derive_type(gettyp(CHAR), PTR); 226 sym->s_type = derive_type(gettyp(CHAR), PTR);
227 sym->s_type->t_const = true; 227 sym->s_type->t_const = true;
228 return; 228 return;
229 } 229 }
230 230
231 /* '%s' undefined */ 231 /* '%s' undefined */
232 error(99, sym->s_name); 232 error(99, sym->s_name);
233} 233}
234 234
235/* https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html */ 235/* https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html */
236static bool 236static bool
237is_gcc_builtin(const char *name) 237is_gcc_builtin(const char *name)
238{ 238{
239 return strncmp(name, "__atomic_", 9) == 0 || 239 return strncmp(name, "__atomic_", 9) == 0 ||
240 strncmp(name, "__builtin_", 10) == 0; 240 strncmp(name, "__builtin_", 10) == 0;
241} 241}
242 242
243/* 243/*
244 * Create a node for a name (symbol table entry). 244 * Create a node for a name (symbol table entry).
245 * follow_token is the token which follows the name. 245 * follow_token is the token which follows the name.
246 */ 246 */
247tnode_t * 247tnode_t *
248new_name_node(sym_t *sym, int follow_token) 248new_name_node(sym_t *sym, int follow_token)
249{ 249{
250 tnode_t *n; 250 tnode_t *n;
251 251
252 if (sym->s_scl == NOSCL) { 252 if (sym->s_scl == NOSCL) {
253 sym->s_scl = EXTERN; 253 sym->s_scl = EXTERN;
254 sym->s_def = DECL; 254 sym->s_def = DECL;
255 if (follow_token == T_LPAREN) { 255 if (follow_token == T_LPAREN) {
256 if (gflag && is_gcc_builtin(sym->s_name)) { 256 if (gflag && is_gcc_builtin(sym->s_name)) {
257 /* 257 /*
258 * Do not warn about these, just assume that 258 * Do not warn about these, just assume that
259 * they are regular functions compatible with 259 * they are regular functions compatible with
260 * non-prototype calling conventions. 260 * non-prototype calling conventions.
261 */ 261 */
262 } else if (Sflag) { 262 } else if (Sflag) {
263 /* function '%s' implicitly declared to ... */ 263 /* function '%s' implicitly declared to ... */
264 warning(215, sym->s_name); 264 warning(215, sym->s_name);
265 } else if (sflag) { 265 } else if (sflag) {
266 /* function '%s' implicitly declared to ... */ 266 /* function '%s' implicitly declared to ... */
267 warning(215, sym->s_name); 267 warning(215, sym->s_name);
268 } 268 }
269 /* 269 /*
270 * XXX if tflag is set the symbol should be 270 * XXX if tflag is set the symbol should be
271 * exported to level 0 271 * exported to level 0
272 */ 272 */
273 sym->s_type = derive_type(sym->s_type, FUNC); 273 sym->s_type = derive_type(sym->s_type, FUNC);
274 } else { 274 } else {
275 fallback_symbol(sym); 275 fallback_symbol(sym);
276 } 276 }
277 } 277 }
278 278
279 lint_assert(sym->s_kind == FVFT || sym->s_kind == FMEMBER); 279 lint_assert(sym->s_kind == FVFT || sym->s_kind == FMEMBER);
280 280
281 n = expr_zalloc_tnode(); 281 n = expr_zalloc_tnode();
282 n->tn_type = sym->s_type; 282 n->tn_type = sym->s_type;
283 if (sym->s_scl != CTCONST) { 283 if (sym->s_scl != CTCONST) {
284 n->tn_op = NAME; 284 n->tn_op = NAME;
285 n->tn_sym = sym; 285 n->tn_sym = sym;
286 if (sym->s_kind == FVFT && sym->s_type->t_tspec != FUNC) 286 if (sym->s_kind == FVFT && sym->s_type->t_tspec != FUNC)
287 n->tn_lvalue = true; 287 n->tn_lvalue = true;
288 } else { 288 } else {
289 n->tn_op = CON; 289 n->tn_op = CON;
290 n->tn_val = expr_zalloc(sizeof(*n->tn_val)); 290 n->tn_val = expr_zalloc(sizeof(*n->tn_val));
291 *n->tn_val = sym->s_value; 291 *n->tn_val = sym->s_value;
292 } 292 }
293 293
294 return n; 294 return n;
295} 295}
296 296
297tnode_t * 297tnode_t *
298new_string_node(strg_t *strg) 298new_string_node(strg_t *strg)
299{ 299{
300 size_t len; 300 size_t len;
301 tnode_t *n; 301 tnode_t *n;
302 302
303 len = strg->st_len; 303 len = strg->st_len;
304 304
305 n = expr_zalloc_tnode(); 305 n = expr_zalloc_tnode();
306 306
307 n->tn_op = STRING; 307 n->tn_op = STRING;
308 n->tn_type = expr_derive_type(gettyp(strg->st_tspec), ARRAY); 308 n->tn_type = expr_derive_type(gettyp(strg->st_tspec), ARRAY);
309 n->tn_type->t_dim = len + 1; 309 n->tn_type->t_dim = len + 1;
310 n->tn_lvalue = true; 310 n->tn_lvalue = true;
311 311
312 n->tn_string = expr_zalloc(sizeof(*n->tn_string)); 312 n->tn_string = expr_zalloc(sizeof(*n->tn_string));
313 n->tn_string->st_tspec = strg->st_tspec; 313 n->tn_string->st_tspec = strg->st_tspec;
314 n->tn_string->st_len = len; 314 n->tn_string->st_len = len;
315 315
316 if (strg->st_tspec == CHAR) { 316 if (strg->st_tspec == CHAR) {
317 n->tn_string->st_cp = expr_zalloc(len + 1); 317 n->tn_string->st_cp = expr_zalloc(len + 1);
318 (void)memcpy(n->tn_string->st_cp, strg->st_cp, len + 1); 318 (void)memcpy(n->tn_string->st_cp, strg->st_cp, len + 1);
319 free(strg->st_cp); 319 free(strg->st_cp);
320 } else { 320 } else {
321 size_t size = (len + 1) * sizeof(*n->tn_string->st_wcp); 321 size_t size = (len + 1) * sizeof(*n->tn_string->st_wcp);
322 n->tn_string->st_wcp = expr_zalloc(size); 322 n->tn_string->st_wcp = expr_zalloc(size);
323 (void)memcpy(n->tn_string->st_wcp, strg->st_wcp, size); 323 (void)memcpy(n->tn_string->st_wcp, strg->st_wcp, size);
324 free(strg->st_wcp); 324 free(strg->st_wcp);
325 } 325 }
326 free(strg); 326 free(strg);
327 327
328 return n; 328 return n;
329} 329}
330 330
331/* 331/*
332 * Returns a symbol which has the same name as the msym argument and is a 332 * Returns a symbol which has the same name as the msym argument and is a
333 * member of the struct or union specified by the tn argument. 333 * member of the struct or union specified by the tn argument.
334 */ 334 */
335sym_t * 335sym_t *
336struct_or_union_member(tnode_t *tn, op_t op, sym_t *msym) 336struct_or_union_member(tnode_t *tn, op_t op, sym_t *msym)
337{ 337{
338 struct_or_union *str; 338 struct_or_union *str;
339 type_t *tp; 339 type_t *tp;
340 sym_t *sym, *csym; 340 sym_t *sym, *csym;
341 bool eq; 341 bool eq;
342 tspec_t t; 342 tspec_t t;
343 343
344 /* 344 /*
345 * Remove the member if it was unknown until now, which means 345 * Remove the member if it was unknown until now, which means
346 * that no defined struct or union has a member with the same name. 346 * that no defined struct or union has a member with the same name.
347 */ 347 */
348 if (msym->s_scl == NOSCL) { 348 if (msym->s_scl == NOSCL) {
349 /* type '%s' does not have member '%s' */ 349 /* type '%s' does not have member '%s' */
350 error(101, type_name(tn->tn_type), msym->s_name); 350 error(101, type_name(tn->tn_type), msym->s_name);
351 rmsym(msym); 351 rmsym(msym);
352 msym->s_kind = FMEMBER; 352 msym->s_kind = FMEMBER;
353 msym->s_scl = MOS; 353 msym->s_scl = MOS;
354 msym->s_styp = expr_zalloc(sizeof(*msym->s_styp)); 354 msym->s_styp = expr_zalloc(sizeof(*msym->s_styp));
355 msym->s_styp->sou_tag = expr_zalloc( 355 msym->s_styp->sou_tag = expr_zalloc(
356 sizeof(*msym->s_styp->sou_tag)); 356 sizeof(*msym->s_styp->sou_tag));
357 msym->s_styp->sou_tag->s_name = unnamed; 357 msym->s_styp->sou_tag->s_name = unnamed;
358 msym->s_value.v_tspec = INT; 358 msym->s_value.v_tspec = INT;
359 return msym; 359 return msym;
360 } 360 }
361 361
362 /* Set str to the tag of which msym is expected to be a member. */ 362 /* Set str to the tag of which msym is expected to be a member. */
363 str = NULL; 363 str = NULL;
364 t = (tp = tn->tn_type)->t_tspec; 364 t = (tp = tn->tn_type)->t_tspec;
365 if (op == POINT) { 365 if (op == POINT) {
366 if (t == STRUCT || t == UNION) 366 if (t == STRUCT || t == UNION)
367 str = tp->t_str; 367 str = tp->t_str;
368 } else if (op == ARROW && t == PTR) { 368 } else if (op == ARROW && t == PTR) {
369 t = (tp = tp->t_subt)->t_tspec; 369 t = (tp = tp->t_subt)->t_tspec;
370 if (t == STRUCT || t == UNION) 370 if (t == STRUCT || t == UNION)
371 str = tp->t_str; 371 str = tp->t_str;
372 } 372 }
373 373
374 /* 374 /*
375 * If this struct/union has a member with the name of msym, return it. 375 * If this struct/union has a member with the name of msym, return it.
376 */ 376 */
377 if (str != NULL) { 377 if (str != NULL) {
378 for (sym = msym; sym != NULL; sym = sym->s_link) { 378 for (sym = msym; sym != NULL; sym = sym->s_link) {
379 if (sym->s_scl != MOS && sym->s_scl != MOU) 379 if (sym->s_scl != MOS && sym->s_scl != MOU)
380 continue; 380 continue;
381 if (sym->s_styp != str) 381 if (sym->s_styp != str)
382 continue; 382 continue;
383 if (strcmp(sym->s_name, msym->s_name) != 0) 383 if (strcmp(sym->s_name, msym->s_name) != 0)
384 continue; 384 continue;
385 return sym; 385 return sym;
386 } 386 }
387 } 387 }
388 388
389 /* 389 /*
390 * Set eq to false if there are struct/union members with the same 390 * Set eq to false if there are struct/union members with the same
391 * name and different types and/or offsets. 391 * name and different types and/or offsets.
392 */ 392 */
393 eq = true; 393 eq = true;
394 for (csym = msym; csym != NULL; csym = csym->s_link) { 394 for (csym = msym; csym != NULL; csym = csym->s_link) {
395 if (csym->s_scl != MOS && csym->s_scl != MOU) 395 if (csym->s_scl != MOS && csym->s_scl != MOU)
396 continue; 396 continue;
397 if (strcmp(msym->s_name, csym->s_name) != 0) 397 if (strcmp(msym->s_name, csym->s_name) != 0)
398 continue; 398 continue;
399 for (sym = csym->s_link ; sym != NULL; sym = sym->s_link) { 399 for (sym = csym->s_link ; sym != NULL; sym = sym->s_link) {
400 bool w; 400 bool w;
401 401
402 if (sym->s_scl != MOS && sym->s_scl != MOU) 402 if (sym->s_scl != MOS && sym->s_scl != MOU)
403 continue; 403 continue;
404 if (strcmp(csym->s_name, sym->s_name) != 0) 404 if (strcmp(csym->s_name, sym->s_name) != 0)
405 continue; 405 continue;
406 if (csym->s_value.v_quad != sym->s_value.v_quad) { 406 if (csym->s_value.v_quad != sym->s_value.v_quad) {
407 eq = false; 407 eq = false;
408 break; 408 break;
409 } 409 }
410 w = false; 410 w = false;
411 eq = eqtype(csym->s_type, sym->s_type, 411 eq = eqtype(csym->s_type, sym->s_type,
412 false, false, &w) && !w; 412 false, false, &w) && !w;
413 if (!eq) 413 if (!eq)
414 break; 414 break;
415 if (csym->s_bitfield != sym->s_bitfield) { 415 if (csym->s_bitfield != sym->s_bitfield) {
416 eq = false; 416 eq = false;
417 break; 417 break;
418 } 418 }
419 if (csym->s_bitfield) { 419 if (csym->s_bitfield) {
420 type_t *tp1, *tp2; 420 type_t *tp1, *tp2;
421 421
422 tp1 = csym->s_type; 422 tp1 = csym->s_type;
423 tp2 = sym->s_type; 423 tp2 = sym->s_type;
424 if (tp1->t_flen != tp2->t_flen) { 424 if (tp1->t_flen != tp2->t_flen) {
425 eq = false; 425 eq = false;
426 break; 426 break;
427 } 427 }
428 if (tp1->t_foffs != tp2->t_foffs) { 428 if (tp1->t_foffs != tp2->t_foffs) {
429 eq = false; 429 eq = false;
430 break; 430 break;
431 } 431 }
432 } 432 }
433 } 433 }
434 if (!eq) 434 if (!eq)
435 break; 435 break;
436 } 436 }
437 437
438 /* 438 /*
439 * Now handle the case in which the left operand refers really 439 * Now handle the case in which the left operand refers really
440 * to a struct/union, but the right operand is not member of it. 440 * to a struct/union, but the right operand is not member of it.
441 */ 441 */
442 if (str != NULL) { 442 if (str != NULL) {
443 if (eq && tflag) { 443 if (eq && tflag) {
444 /* illegal member use: %s */ 444 /* illegal member use: %s */
445 warning(102, msym->s_name); 445 warning(102, msym->s_name);
446 } else { 446 } else {
447 /* illegal member use: %s */ 447 /* illegal member use: %s */
448 error(102, msym->s_name); 448 error(102, msym->s_name);
449 } 449 }
450 return msym; 450 return msym;
451 } 451 }
452 452
453 /* 453 /*
454 * Now the left operand of ARROW does not point to a struct/union 454 * Now the left operand of ARROW does not point to a struct/union
455 * or the left operand of POINT is no struct/union. 455 * or the left operand of POINT is no struct/union.
456 */ 456 */
457 if (eq) { 457 if (eq) {
458 if (op == POINT) { 458 if (op == POINT) {
459 if (tflag) { 459 if (tflag) {
460 /* left operand of '.' must be struct ... */ 460 /* left operand of '.' must be struct ... */
461 warning(103, type_name(tn->tn_type)); 461 warning(103, type_name(tn->tn_type));
462 } else { 462 } else {
463 /* left operand of '.' must be struct ... */ 463 /* left operand of '.' must be struct ... */
464 error(103, type_name(tn->tn_type)); 464 error(103, type_name(tn->tn_type));
465 } 465 }
466 } else { 466 } else {
467 if (tflag && tn->tn_type->t_tspec == PTR) { 467 if (tflag && tn->tn_type->t_tspec == PTR) {
468 /* left operand of '->' must be pointer ... */ 468 /* left operand of '->' must be pointer ... */
469 warning(104, type_name(tn->tn_type)); 469 warning(104, type_name(tn->tn_type));
470 } else { 470 } else {
471 /* left operand of '->' must be pointer ... */ 471 /* left operand of '->' must be pointer ... */
472 error(104, type_name(tn->tn_type)); 472 error(104, type_name(tn->tn_type));
473 } 473 }
474 } 474 }
475 } else { 475 } else {
476 if (tflag) { 476 if (tflag) {
477 /* non-unique member requires struct/union %s */ 477 /* non-unique member requires struct/union %s */
478 error(105, op == POINT ? "object" : "pointer"); 478 error(105, op == POINT ? "object" : "pointer");
479 } else { 479 } else {
480 /* unacceptable operand of '%s' */ 480 /* unacceptable operand of '%s' */
481 error(111, op_name(op)); 481 error(111, op_name(op));
482 } 482 }
483 } 483 }
484 484
485 return msym; 485 return msym;
486} 486}
487 487
488tnode_t * 488tnode_t *
489build_generic_selection(const tnode_t *expr, 489build_generic_selection(const tnode_t *expr,
490 struct generic_association *sel) 490 struct generic_association *sel)
491{ 491{
492 tnode_t *default_result = NULL; 492 tnode_t *default_result = NULL;
493 493
494 for (; sel != NULL; sel = sel->ga_prev) 494 for (; sel != NULL; sel = sel->ga_prev)
495 if (expr != NULL && 495 if (expr != NULL &&
496 eqtype(sel->ga_arg, expr->tn_type, false, false, NULL)) 496 eqtype(sel->ga_arg, expr->tn_type, false, false, NULL))
497 return sel->ga_result; 497 return sel->ga_result;
498 else if (sel->ga_arg == NULL) 498 else if (sel->ga_arg == NULL)
499 default_result = sel->ga_result; 499 default_result = sel->ga_result;
500 return default_result; 500 return default_result;
501} 501}
502 502
503/* 503/*
504 * Create a tree node. Called for most operands except function calls, 504 * Create a tree node. Called for most operands except function calls,
505 * sizeof and casts. 505 * sizeof and casts.
506 * 506 *
507 * op operator 507 * op operator
508 * ln left operand 508 * ln left operand
509 * rn if not NULL, right operand 509 * rn if not NULL, right operand
510 */ 510 */
511tnode_t * 511tnode_t *
512build(op_t op, tnode_t *ln, tnode_t *rn) 512build(op_t op, tnode_t *ln, tnode_t *rn)
513{ 513{
514 const mod_t *mp; 514 const mod_t *mp;
515 tnode_t *ntn; 515 tnode_t *ntn;
516 type_t *rettp; 516 type_t *rettp;
517 517
518 mp = &modtab[op]; 518 mp = &modtab[op];
519 519
520 /* If there was an error in one of the operands, return. */ 520 /* If there was an error in one of the operands, return. */
521 if (ln == NULL || (mp->m_binary && rn == NULL)) 521 if (ln == NULL || (mp->m_binary && rn == NULL))
522 return NULL; 522 return NULL;
523 523
524 /* 524 /*
525 * Apply class conversions to the left operand, but only if its 525 * Apply class conversions to the left operand, but only if its
526 * value is needed or it is compared with null. 526 * value is needed or it is compared with null.
527 */ 527 */
528 if (mp->m_left_value_context || mp->m_left_test_context) 528 if (mp->m_left_value_context || mp->m_left_test_context)
529 ln = cconv(ln); 529 ln = cconv(ln);
530 /* 530 /*
531 * The right operand is almost always in a test or value context, 531 * The right operand is almost always in a test or value context,
532 * except if it is a struct or union member. 532 * except if it is a struct or union member.
533 */ 533 */
534 if (mp->m_binary && op != ARROW && op != POINT) 534 if (mp->m_binary && op != ARROW && op != POINT)
535 rn = cconv(rn); 535 rn = cconv(rn);
536 536
537 /* 537 /*
538 * Print some warnings for comparisons of unsigned values with 538 * Print some warnings for comparisons of unsigned values with
539 * constants lower than or equal to null. This must be done 539 * constants lower than or equal to null. This must be done
540 * before promote() because otherwise unsigned char and unsigned 540 * before promote() because otherwise unsigned char and unsigned
541 * short would be promoted to int. Also types are tested to be 541 * short would be promoted to int. Also types are tested to be
542 * CHAR, which would also become int. 542 * CHAR, which would also become int.
543 */ 543 */
544 if (mp->m_comparison) 544 if (mp->m_comparison)
545 check_integer_comparison(op, ln, rn); 545 check_integer_comparison(op, ln, rn);
546 546
547 /* 547 /*
548 * Promote the left operand if it is in a test or value context 548 * Promote the left operand if it is in a test or value context
549 */ 549 */
550 if (mp->m_left_value_context || mp->m_left_test_context) 550 if (mp->m_left_value_context || mp->m_left_test_context)
551 ln = promote(op, false, ln); 551 ln = promote(op, false, ln);
552 /* 552 /*
553 * Promote the right operand, but only if it is no struct or 553 * Promote the right operand, but only if it is no struct or
554 * union member, or if it is not to be assigned to the left operand 554 * union member, or if it is not to be assigned to the left operand
555 */ 555 */
556 if (mp->m_binary && op != ARROW && op != POINT && 556 if (mp->m_binary && op != ARROW && op != POINT &&
557 op != ASSIGN && op != RETURN) { 557 op != ASSIGN && op != RETURN) {
558 rn = promote(op, false, rn); 558 rn = promote(op, false, rn);
559 } 559 }
560 560
561 /* 561 /*
562 * If the result of the operation is different for signed or 562 * If the result of the operation is different for signed or
563 * unsigned operands and one of the operands is signed only in 563 * unsigned operands and one of the operands is signed only in
564 * ANSI C, print a warning. 564 * ANSI C, print a warning.
565 */ 565 */
566 if (mp->m_warn_if_left_unsigned_in_c90 && 566 if (mp->m_warn_if_left_unsigned_in_c90 &&
567 ln->tn_op == CON && ln->tn_val->v_unsigned_since_c90) { 567 ln->tn_op == CON && ln->tn_val->v_unsigned_since_c90) {
568 /* ANSI C treats constant as unsigned, op %s */ 568 /* ANSI C treats constant as unsigned, op %s */
569 warning(218, mp->m_name); 569 warning(218, mp->m_name);
570 ln->tn_val->v_unsigned_since_c90 = false; 570 ln->tn_val->v_unsigned_since_c90 = false;
571 } 571 }
572 if (mp->m_warn_if_right_unsigned_in_c90 && 572 if (mp->m_warn_if_right_unsigned_in_c90 &&
573 rn->tn_op == CON && rn->tn_val->v_unsigned_since_c90) { 573 rn->tn_op == CON && rn->tn_val->v_unsigned_since_c90) {
574 /* ANSI C treats constant as unsigned, op %s */ 574 /* ANSI C treats constant as unsigned, op %s */
575 warning(218, mp->m_name); 575 warning(218, mp->m_name);
576 rn->tn_val->v_unsigned_since_c90 = false; 576 rn->tn_val->v_unsigned_since_c90 = false;
577 } 577 }
578 578
579 /* Make sure both operands are of the same type */ 579 /* Make sure both operands are of the same type */
580 if (mp->m_balance_operands || (tflag && (op == SHL || op == SHR))) 580 if (mp->m_balance_operands || (tflag && (op == SHL || op == SHR)))
581 balance(op, &ln, &rn); 581 balance(op, &ln, &rn);
582 582
583 /* 583 /*
584 * Check types for compatibility with the operation and mutual 584 * Check types for compatibility with the operation and mutual
585 * compatibility. Return if there are serious problems. 585 * compatibility. Return if there are serious problems.
586 */ 586 */
587 if (!typeok(op, 0, ln, rn)) 587 if (!typeok(op, 0, ln, rn))
588 return NULL; 588 return NULL;
589 589
590 /* And now create the node. */ 590 /* And now create the node. */
591 switch (op) { 591 switch (op) {
592 case POINT: 592 case POINT:
593 case ARROW: 593 case ARROW:
594 ntn = build_struct_access(op, ln, rn); 594 ntn = build_struct_access(op, ln, rn);
595 break; 595 break;
596 case INCAFT: 596 case INCAFT:
597 case DECAFT: 597 case DECAFT:
598 case INCBEF: 598 case INCBEF:
599 case DECBEF: 599 case DECBEF:
600 ntn = build_prepost_incdec(op, ln); 600 ntn = build_prepost_incdec(op, ln);
601 break; 601 break;
602 case ADDR: 602 case ADDR:
603 ntn = build_address(ln, false); 603 ntn = build_address(ln, false);
604 break; 604 break;
605 case INDIR: 605 case INDIR:
606 ntn = new_tnode(INDIR, ln->tn_type->t_subt, ln, NULL); 606 ntn = new_tnode(INDIR, ln->tn_type->t_subt, ln, NULL);
607 break; 607 break;
608 case PLUS: 608 case PLUS:
609 case MINUS: 609 case MINUS:
610 ntn = build_plus_minus(op, ln, rn); 610 ntn = build_plus_minus(op, ln, rn);
611 break; 611 break;
612 case SHL: 612 case SHL:
613 case SHR: 613 case SHR:
614 ntn = build_bit_shift(op, ln, rn); 614 ntn = build_bit_shift(op, ln, rn);
615 break; 615 break;
616 case COLON: 616 case COLON:
617 ntn = build_colon(ln, rn); 617 ntn = build_colon(ln, rn);
618 break; 618 break;
619 case ASSIGN: 619 case ASSIGN:
620 case MULASS: 620 case MULASS:
621 case DIVASS: 621 case DIVASS:
622 case MODASS: 622 case MODASS:
623 case ADDASS: 623 case ADDASS:
624 case SUBASS: 624 case SUBASS:
625 case SHLASS: 625 case SHLASS:
626 case SHRASS: 626 case SHRASS:
627 case ANDASS: 627 case ANDASS:
628 case XORASS: 628 case XORASS:
629 case ORASS: 629 case ORASS:
630 case RETURN: 630 case RETURN:
631 ntn = build_assignment(op, ln, rn); 631 ntn = build_assignment(op, ln, rn);
632 break; 632 break;
633 case COMMA: 633 case COMMA:
634 case QUEST: 634 case QUEST:
635 ntn = new_tnode(op, rn->tn_type, ln, rn); 635 ntn = new_tnode(op, rn->tn_type, ln, rn);
636 break; 636 break;
637 case REAL: 637 case REAL:
638 case IMAG: 638 case IMAG:
639 ntn = build_real_imag(op, ln); 639 ntn = build_real_imag(op, ln);
640 break; 640 break;
641 default: 641 default:
642 rettp = mp->m_returns_bool 642 rettp = mp->m_returns_bool
643 ? gettyp(Tflag ? BOOL : INT) : ln->tn_type; 643 ? gettyp(Tflag ? BOOL : INT) : ln->tn_type;
644 lint_assert(mp->m_binary || rn == NULL); 644 lint_assert(mp->m_binary || rn == NULL);
645 ntn = new_tnode(op, rettp, ln, rn); 645 ntn = new_tnode(op, rettp, ln, rn);
646 break; 646 break;
647 } 647 }
648 648
649 /* Return if an error occurred. */ 649 /* Return if an error occurred. */
650 if (ntn == NULL) 650 if (ntn == NULL)
651 return NULL; 651 return NULL;
652 652
653 /* Print a warning if precedence confusion is possible */ 653 /* Print a warning if precedence confusion is possible */
654 if (mp->m_possible_precedence_confusion) 654 if (mp->m_possible_precedence_confusion)
655 check_precedence_confusion(ntn); 655 check_precedence_confusion(ntn);
656 656
657 /* 657 /*
658 * Print a warning if one of the operands is in a context where 658 * Print a warning if one of the operands is in a context where
659 * it is compared with null and if this operand is a constant. 659 * it is compared with null and if this operand is a constant.
660 */ 660 */
661 if (mp->m_left_test_context) { 661 if (mp->m_left_test_context) {
662 if (ln->tn_op == CON || 662 if (ln->tn_op == CON ||
663 ((mp->m_binary && op != QUEST) && rn->tn_op == CON)) { 663 ((mp->m_binary && op != QUEST) && rn->tn_op == CON)) {
664 if (hflag && !constcond_flag && 664 if (hflag && !constcond_flag &&
665 !ln->tn_system_dependent) 665 !ln->tn_system_dependent)
666 /* constant in conditional context */ 666 /* constant in conditional context */
667 warning(161); 667 warning(161);
668 } 668 }
669 } 669 }
670 670
671 /* Fold if the operator requires it */ 671 /* Fold if the operator requires it */
672 if (mp->m_fold_constant_operands) { 672 if (mp->m_fold_constant_operands) {
673 if (ln->tn_op == CON && (!mp->m_binary || rn->tn_op == CON)) { 673 if (ln->tn_op == CON && (!mp->m_binary || rn->tn_op == CON)) {
674 if (mp->m_left_test_context) { 674 if (mp->m_left_test_context) {
675 ntn = fold_test(ntn); 675 ntn = fold_test(ntn);
676 } else if (is_floating(ntn->tn_type->t_tspec)) { 676 } else if (is_floating(ntn->tn_type->t_tspec)) {
677 ntn = fold_float(ntn); 677 ntn = fold_float(ntn);
678 } else { 678 } else {
679 ntn = fold(ntn); 679 ntn = fold(ntn);
680 } 680 }
681 } else if (op == QUEST && ln->tn_op == CON) { 681 } else if (op == QUEST && ln->tn_op == CON) {
682 ntn = ln->tn_val->v_quad != 0 682 ntn = ln->tn_val->v_quad != 0
683 ? rn->tn_left : rn->tn_right; 683 ? rn->tn_left : rn->tn_right;
684 } 684 }
685 } 685 }
686 686
687 return ntn; 687 return ntn;
688} 688}
689 689
690tnode_t * 690tnode_t *
691build_member_access(tnode_t *ln, op_t op, sbuf_t *member) 691build_member_access(tnode_t *ln, op_t op, sbuf_t *member)
692{ 692{
693 sym_t *msym; 693 sym_t *msym;
694 694
695 if (ln == NULL) 695 if (ln == NULL)
696 return NULL; 696 return NULL;
697 697
698 if (op == ARROW) { 698 if (op == ARROW) {
699 /* must do this before struct_or_union_member is called */ 699 /* must do this before struct_or_union_member is called */
700 ln = cconv(ln); 700 ln = cconv(ln);
701 } 701 }
702 msym = struct_or_union_member(ln, op, getsym(member)); 702 msym = struct_or_union_member(ln, op, getsym(member));
703 return build(op, ln, new_name_node(msym, 0)); 703 return build(op, ln, new_name_node(msym, 0));
704} 704}
705 705
706/* 706/*
707 * Perform class conversions. 707 * Perform class conversions.
708 * 708 *
709 * Arrays of type T are converted into pointers to type T. 709 * Arrays of type T are converted into pointers to type T.
710 * Functions are converted to pointers to functions. 710 * Functions are converted to pointers to functions.
711 * Lvalues are converted to rvalues. 711 * Lvalues are converted to rvalues.
712 * 712 *
713 * C99 6.3 "Conversions" 713 * C99 6.3 "Conversions"
714 * C99 6.3.2 "Other operands" 714 * C99 6.3.2 "Other operands"
715 * C99 6.3.2.1 "Lvalues, arrays, and function designators" 715 * C99 6.3.2.1 "Lvalues, arrays, and function designators"
716 */ 716 */
717tnode_t * 717tnode_t *
718cconv(tnode_t *tn) 718cconv(tnode_t *tn)
719{ 719{
720 type_t *tp; 720 type_t *tp;
721 721
722 /* 722 /*
723 * Array-lvalue (array of type T) is converted into rvalue 723 * Array-lvalue (array of type T) is converted into rvalue
724 * (pointer to type T) 724 * (pointer to type T)
725 */ 725 */
726 if (tn->tn_type->t_tspec == ARRAY) { 726 if (tn->tn_type->t_tspec == ARRAY) {
727 if (!tn->tn_lvalue) { 727 if (!tn->tn_lvalue) {
728 /* XXX print correct operator */ 728 /* XXX print correct operator */
729 /* %soperand of '%s' must be lvalue */ 729 /* %soperand of '%s' must be lvalue */
730 gnuism(114, "", op_name(ADDR)); 730 gnuism(114, "", op_name(ADDR));
731 } 731 }
732 tn = new_tnode(ADDR, 732 tn = new_tnode(ADDR,
733 expr_derive_type(tn->tn_type->t_subt, PTR), tn, NULL); 733 expr_derive_type(tn->tn_type->t_subt, PTR), tn, NULL);
734 } 734 }
735 735
736 /* 736 /*
737 * Expression of type function (function with return value of type T) 737 * Expression of type function (function with return value of type T)
738 * in rvalue-expression (pointer to function with return value 738 * in rvalue-expression (pointer to function with return value
739 * of type T) 739 * of type T)
740 */ 740 */
741 if (tn->tn_type->t_tspec == FUNC) 741 if (tn->tn_type->t_tspec == FUNC)
742 tn = build_address(tn, true); 742 tn = build_address(tn, true);
743 743
744 /* lvalue to rvalue */ 744 /* lvalue to rvalue */
745 if (tn->tn_lvalue) { 745 if (tn->tn_lvalue) {
746 tp = expr_dup_type(tn->tn_type); 746 tp = expr_dup_type(tn->tn_type);
747 /* C99 6.3.2.1p2 sentence 2 says to remove the qualifiers. */ 747 /* C99 6.3.2.1p2 sentence 2 says to remove the qualifiers. */
748 tp->t_const = tp->t_volatile = false; 748 tp->t_const = tp->t_volatile = false;
749 tn = new_tnode(LOAD, tp, tn, NULL); 749 tn = new_tnode(LOAD, tp, tn, NULL);
750 } 750 }
751 751
752 return tn; 752 return tn;
753} 753}
754 754
755const tnode_t * 755const tnode_t *
756before_conversion(const tnode_t *tn) 756before_conversion(const tnode_t *tn)
757{ 757{
758 while (tn->tn_op == CVT && !tn->tn_cast) 758 while (tn->tn_op == CVT && !tn->tn_cast)
759 tn = tn->tn_left; 759 tn = tn->tn_left;
760 return tn; 760 return tn;
761} 761}
762 762
763static bool 763static bool
764is_null_pointer(const tnode_t *tn) 764is_null_pointer(const tnode_t *tn)
765{ 765{
766 tspec_t t = tn->tn_type->t_tspec; 766 tspec_t t = tn->tn_type->t_tspec;
767 767
768 return ((t == PTR && tn->tn_type->t_subt->t_tspec == VOID) || 768 return ((t == PTR && tn->tn_type->t_subt->t_tspec == VOID) ||
769 is_integer(t)) 769 is_integer(t))
770 && (tn->tn_op == CON && tn->tn_val->v_quad == 0); 770 && (tn->tn_op == CON && tn->tn_val->v_quad == 0);
771} 771}
772 772
773static bool 773static bool
774typeok_incdec(op_t op, const tnode_t *tn, const type_t *tp) 774typeok_incdec(op_t op, const tnode_t *tn, const type_t *tp)
775{ 775{
776 /* operand has scalar type (checked in typeok) */ 776 /* operand has scalar type (checked in typeok) */
777 if (!tn->tn_lvalue) { 777 if (!tn->tn_lvalue) {
778 if (tn->tn_op == CVT && tn->tn_cast && 778 if (tn->tn_op == CVT && tn->tn_cast &&
779 tn->tn_left->tn_op == LOAD) { 779 tn->tn_left->tn_op == LOAD) {
780 /* a cast does not yield an lvalue */ 780 /* a cast does not yield an lvalue */
781 error(163); 781 error(163);
782 } 782 }
783 /* %soperand of '%s' must be lvalue */ 783 /* %soperand of '%s' must be lvalue */
784 error(114, "", op_name(op)); 784 error(114, "", op_name(op));
785 return false; 785 return false;
786 } else if (tp->t_const) { 786 } else if (tp->t_const) {
787 if (!tflag) 787 if (!tflag)
788 /* %soperand of '%s' must be modifiable lvalue */ 788 /* %soperand of '%s' must be modifiable lvalue */
789 warning(115, "", op_name(op)); 789 warning(115, "", op_name(op));
790 } 790 }
791 return true; 791 return true;
792} 792}
793 793
794static bool 794static bool
795typeok_address(const mod_t *mp, 795typeok_address(const mod_t *mp,
796 const tnode_t *tn, const type_t *tp, tspec_t t) 796 const tnode_t *tn, const type_t *tp, tspec_t t)
797{ 797{
798 if (t == ARRAY || t == FUNC) { 798 if (t == ARRAY || t == FUNC) {
799 /* ok, a warning comes later (in build_address()) */ 799 /* ok, a warning comes later (in build_address()) */
800 } else if (!tn->tn_lvalue) { 800 } else if (!tn->tn_lvalue) {
801 if (tn->tn_op == CVT && tn->tn_cast && 801 if (tn->tn_op == CVT && tn->tn_cast &&
802 tn->tn_left->tn_op == LOAD) { 802 tn->tn_left->tn_op == LOAD) {
803 /* a cast does not yield an lvalue */ 803 /* a cast does not yield an lvalue */
804 error(163); 804 error(163);
805 } 805 }
806 /* %soperand of '%s' must be lvalue */ 806 /* %soperand of '%s' must be lvalue */
807 error(114, "", mp->m_name); 807 error(114, "", mp->m_name);
808 return false; 808 return false;
809 } else if (is_scalar(t)) { 809 } else if (is_scalar(t)) {
810 if (tp->t_bitfield) { 810 if (tp->t_bitfield) {
811 /* cannot take address of bit-field */ 811 /* cannot take address of bit-field */
812 error(112); 812 error(112);
813 return false; 813 return false;
814 } 814 }
815 } else if (t != STRUCT && t != UNION) { 815 } else if (t != STRUCT && t != UNION) {
816 /* unacceptable operand of '%s' */ 816 /* unacceptable operand of '%s' */
817 error(111, mp->m_name); 817 error(111, mp->m_name);
818 return false; 818 return false;
819 } 819 }
820 if (tn->tn_op == NAME && tn->tn_sym->s_reg) { 820 if (tn->tn_op == NAME && tn->tn_sym->s_reg) {
821 /* cannot take address of register %s */ 821 /* cannot take address of register %s */
822 error(113, tn->tn_sym->s_name); 822 error(113, tn->tn_sym->s_name);
823 return false; 823 return false;
824 } 824 }
825 return true; 825 return true;
826} 826}
827 827
828static bool 828static bool
829typeok_star(tspec_t t) 829typeok_star(tspec_t t)
830{ 830{
831 /* until now there were no type checks for this operator */ 831 /* until now there were no type checks for this operator */
832 if (t != PTR) { 832 if (t != PTR) {
833 /* cannot dereference non-pointer type */ 833 /* cannot dereference non-pointer type */
834 error(96); 834 error(96);
835 return false; 835 return false;
836 } 836 }
837 return true; 837 return true;
838} 838}
839 839
840static bool 840static bool
841typeok_plus(op_t op, 841typeok_plus(op_t op,
842 const type_t *ltp, tspec_t lt, 842 const type_t *ltp, tspec_t lt,
843 const type_t *rtp, tspec_t rt) 843 const type_t *rtp, tspec_t rt)
844{ 844{
845 /* operands have scalar types (checked above) */ 845 /* operands have scalar types (checked above) */
846 if ((lt == PTR && !is_integer(rt)) || (rt == PTR && !is_integer(lt))) { 846 if ((lt == PTR && !is_integer(rt)) || (rt == PTR && !is_integer(lt))) {
847 warn_incompatible_types(op, ltp, lt, rtp, rt); 847 warn_incompatible_types(op, ltp, lt, rtp, rt);
848 return false; 848 return false;
849 } 849 }
850 return true; 850 return true;
851} 851}
852 852
853static bool 853static bool
854typeok_minus(op_t op, 854typeok_minus(op_t op,
855 const type_t *ltp, tspec_t lt, 855 const type_t *ltp, tspec_t lt,
856 const type_t *rtp, tspec_t rt) 856 const type_t *rtp, tspec_t rt)
857{ 857{
858 /* operands have scalar types (checked above) */ 858 /* operands have scalar types (checked above) */
859 if (lt == PTR && (!is_integer(rt) && rt != PTR)) { 859 if (lt == PTR && (!is_integer(rt) && rt != PTR)) {
860 warn_incompatible_types(op, ltp, lt, rtp, rt); 860 warn_incompatible_types(op, ltp, lt, rtp, rt);
861 return false; 861 return false;
862 } else if (rt == PTR && lt != PTR) { 862 } else if (rt == PTR && lt != PTR) {
863 warn_incompatible_types(op, ltp, lt, rtp, rt); 863 warn_incompatible_types(op, ltp, lt, rtp, rt);
864 return false; 864 return false;
865 } 865 }
866 if (lt == PTR && rt == PTR) { 866 if (lt == PTR && rt == PTR) {
867 if (!eqtype(ltp->t_subt, rtp->t_subt, true, false, NULL)) { 867 if (!eqtype(ltp->t_subt, rtp->t_subt, true, false, NULL)) {
868 /* illegal pointer subtraction */ 868 /* illegal pointer subtraction */
869 error(116); 869 error(116);
870 } 870 }
871 } 871 }
872 return true; 872 return true;
873} 873}
874 874
875static void 875static void
876typeok_shr(const mod_t *mp, 876typeok_shr(const mod_t *mp,
877 const tnode_t *ln, tspec_t lt, 877 const tnode_t *ln, tspec_t lt,
878 const tnode_t *rn, tspec_t rt) 878 const tnode_t *rn, tspec_t rt)
879{ 879{
880 tspec_t olt, ort; 880 tspec_t olt, ort;
881 881
882 olt = before_conversion(ln)->tn_type->t_tspec; 882 olt = before_conversion(ln)->tn_type->t_tspec;
883 ort = before_conversion(rn)->tn_type->t_tspec; 883 ort = before_conversion(rn)->tn_type->t_tspec;
884 884
885 /* operands have integer types (checked above) */ 885 /* operands have integer types (checked above) */
886 if (pflag && !is_uinteger(lt)) { 886 if (pflag && !is_uinteger(lt)) {
887 /* 887 /*
888 * The left operand is signed. This means that 888 * The left operand is signed. This means that
889 * the operation is (possibly) nonportable. 889 * the operation is (possibly) nonportable.
890 */ 890 */
891 if (ln->tn_op != CON) { 891 if (ln->tn_op != CON) {
892 /* bitwise '%s' on signed value possibly nonportable */ 892 /* bitwise '%s' on signed value possibly nonportable */
893 warning(117, mp->m_name); 893 warning(117, mp->m_name);
894 } else if (ln->tn_val->v_quad < 0) { 894 } else if (ln->tn_val->v_quad < 0) {
895 /* bitwise '%s' on signed value nonportable */ 895 /* bitwise '%s' on signed value nonportable */
896 warning(120, mp->m_name); 896 warning(120, mp->m_name);
897 } 897 }
898 } else if (!tflag && !sflag && !is_uinteger(olt) && is_uinteger(ort)) { 898 } else if (!tflag && !sflag && !is_uinteger(olt) && is_uinteger(ort)) {
899 /* 899 /*
900 * The left operand would become unsigned in 900 * The left operand would become unsigned in
901 * traditional C. 901 * traditional C.
902 */ 902 */
903 if (hflag && !Sflag && 903 if (hflag && !Sflag &&
904 (ln->tn_op != CON || ln->tn_val->v_quad < 0)) { 904 (ln->tn_op != CON || ln->tn_val->v_quad < 0)) {
905 /* semantics of '%s' change in ANSI C; use ... */ 905 /* semantics of '%s' change in ANSI C; use ... */
906 warning(118, mp->m_name); 906 warning(118, mp->m_name);
907 } 907 }
908 } else if (!tflag && !sflag && !is_uinteger(olt) && !is_uinteger(ort) && 908 } else if (!tflag && !sflag && !is_uinteger(olt) && !is_uinteger(ort) &&
909 portable_size_in_bits(lt) < portable_size_in_bits(rt)) { 909 portable_size_in_bits(lt) < portable_size_in_bits(rt)) {
910 /* 910 /*
911 * In traditional C the left operand would be extended, 911 * In traditional C the left operand would be extended,
912 * possibly with 1, and then shifted. 912 * possibly with 1, and then shifted.
913 */ 913 */
914 if (hflag && !Sflag && 914 if (hflag && !Sflag &&
915 (ln->tn_op != CON || ln->tn_val->v_quad < 0)) { 915 (ln->tn_op != CON || ln->tn_val->v_quad < 0)) {
916 /* semantics of '%s' change in ANSI C; use ... */ 916 /* semantics of '%s' change in ANSI C; use ... */
917 warning(118, mp->m_name); 917 warning(118, mp->m_name);
918 } 918 }
919 } 919 }
920} 920}
921 921
922static void 922static void
923typeok_shl(const mod_t *mp, tspec_t lt, tspec_t rt) 923typeok_shl(const mod_t *mp, tspec_t lt, tspec_t rt)
924{ 924{
925 /* 925 /*
926 * C90 does not perform balancing for shift operations, 926 * C90 does not perform balancing for shift operations,
927 * but traditional C does. If the width of the right operand 927 * but traditional C does. If the width of the right operand
928 * is greater than the width of the left operand, then in 928 * is greater than the width of the left operand, then in
929 * traditional C the left operand would be extended to the 929 * traditional C the left operand would be extended to the
930 * width of the right operand. For SHL this may result in 930 * width of the right operand. For SHL this may result in
931 * different results. 931 * different results.
932 */ 932 */
933 if (portable_size_in_bits(lt) < portable_size_in_bits(rt)) { 933 if (portable_size_in_bits(lt) < portable_size_in_bits(rt)) {
934 /* 934 /*
935 * XXX If both operands are constant, make sure 935 * XXX If both operands are constant, make sure
936 * that there is really a difference between 936 * that there is really a difference between
937 * ANSI C and traditional C. 937 * ANSI C and traditional C.
938 */ 938 */
939 if (hflag && !Sflag) 939 if (hflag && !Sflag)
940 /* semantics of '%s' change in ANSI C; use ... */ 940 /* semantics of '%s' change in ANSI C; use ... */
941 warning(118, mp->m_name); 941 warning(118, mp->m_name);
942 } 942 }
943} 943}
944 944
945static void 945static void
946typeok_shift(tspec_t lt, const tnode_t *rn, tspec_t rt) 946typeok_shift(tspec_t lt, const tnode_t *rn, tspec_t rt)
947{ 947{
948 if (rn->tn_op != CON) 948 if (rn->tn_op != CON)
949 return; 949 return;
950 950
951 if (!is_uinteger(rt) && rn->tn_val->v_quad < 0) { 951 if (!is_uinteger(rt) && rn->tn_val->v_quad < 0) {
952 /* negative shift */ 952 /* negative shift */
953 warning(121); 953 warning(121);
954 } else if ((uint64_t)rn->tn_val->v_quad == 954 } else if ((uint64_t)rn->tn_val->v_quad ==
955 (uint64_t)size_in_bits(lt)) { 955 (uint64_t)size_in_bits(lt)) {
956 /* shift equal to size of object */ 956 /* shift equal to size of object */
957 warning(267); 957 warning(267);
958 } else if ((uint64_t)rn->tn_val->v_quad > (uint64_t)size_in_bits(lt)) { 958 } else if ((uint64_t)rn->tn_val->v_quad > (uint64_t)size_in_bits(lt)) {
959 /* shift amount %llu is greater than bit-size %llu of '%s' */ 959 /* shift amount %llu is greater than bit-size %llu of '%s' */
960 warning(122, (unsigned long long)rn->tn_val->v_quad, 960 warning(122, (unsigned long long)rn->tn_val->v_quad,
961 (unsigned long long)size_in_bits(lt), 961 (unsigned long long)size_in_bits(lt),
962 tspec_name(lt)); 962 tspec_name(lt));
963 } 963 }
964} 964}
965 965
966static bool 966static bool
967is_typeok_eq(const tnode_t *ln, tspec_t lt, const tnode_t *rn, tspec_t rt) 967is_typeok_eq(const tnode_t *ln, tspec_t lt, const tnode_t *rn, tspec_t rt)
968{ 968{
969 if (lt == PTR && is_null_pointer(rn)) 969 if (lt == PTR && is_null_pointer(rn))
970 return true; 970 return true;
971 if (rt == PTR && is_null_pointer(ln)) 971 if (rt == PTR && is_null_pointer(ln))
972 return true; 972 return true;
973 return false; 973 return false;
974} 974}
975 975
976static bool 976static bool
977typeok_ordered_comparison(op_t op, 977typeok_ordered_comparison(op_t op,
978 const tnode_t *ln, const type_t *ltp, tspec_t lt, 978 const tnode_t *ln, const type_t *ltp, tspec_t lt,
979 const tnode_t *rn, const type_t *rtp, tspec_t rt) 979 const tnode_t *rn, const type_t *rtp, tspec_t rt)
980{ 980{
981 if (lt == PTR && rt == PTR) { 981 if (lt == PTR && rt == PTR) {
982 check_pointer_comparison(op, ln, rn); 982 check_pointer_comparison(op, ln, rn);
983 return true; 983 return true;
984 } 984 }
985 985
986 if (lt != PTR && rt != PTR) 986 if (lt != PTR && rt != PTR)
987 return true; 987 return true;
988 988
989 if (!is_integer(lt) && !is_integer(rt)) { 989 if (!is_integer(lt) && !is_integer(rt)) {
990 warn_incompatible_types(op, ltp, lt, rtp, rt); 990 warn_incompatible_types(op, ltp, lt, rtp, rt);
991 return false; 991 return false;
992 } 992 }
993 993
994 const char *lx = lt == PTR ? "pointer" : "integer"; 994 const char *lx = lt == PTR ? "pointer" : "integer";
995 const char *rx = rt == PTR ? "pointer" : "integer"; 995 const char *rx = rt == PTR ? "pointer" : "integer";
996 /* illegal combination of %s (%s) and %s (%s), op %s */ 996 /* illegal combination of %s (%s) and %s (%s), op %s */
997 warning(123, lx, type_name(ltp), rx, type_name(rtp), op_name(op)); 997 warning(123, lx, type_name(ltp), rx, type_name(rtp), op_name(op));
998 return true; 998 return true;
999} 999}
1000 1000
1001static bool 1001static bool
1002typeok_quest(tspec_t lt, const tnode_t **rn) 1002typeok_quest(tspec_t lt, const tnode_t **rn)
1003{ 1003{
1004 if (!is_scalar(lt)) { 1004 if (!is_scalar(lt)) {
1005 /* first operand must have scalar type, op ? : */ 1005 /* first operand must have scalar type, op ? : */
1006 error(170); 1006 error(170);
1007 return false; 1007 return false;
1008 } 1008 }
1009 while ((*rn)->tn_op == CVT) 1009 while ((*rn)->tn_op == CVT)
1010 *rn = (*rn)->tn_left; 1010 *rn = (*rn)->tn_left;
1011 lint_assert((*rn)->tn_op == COLON); 1011 lint_assert((*rn)->tn_op == COLON);
1012 return true; 1012 return true;
1013} 1013}
1014 1014
1015static void 1015static void
1016typeok_colon_pointer(const mod_t *mp, const type_t *ltp, const type_t *rtp) 1016typeok_colon_pointer(const mod_t *mp, const type_t *ltp, const type_t *rtp)
1017{ 1017{
1018 type_t *lstp = ltp->t_subt; 1018 type_t *lstp = ltp->t_subt;
1019 type_t *rstp = rtp->t_subt; 1019 type_t *rstp = rtp->t_subt;
1020 tspec_t lst = lstp->t_tspec; 1020 tspec_t lst = lstp->t_tspec;
1021 tspec_t rst = rstp->t_tspec; 1021 tspec_t rst = rstp->t_tspec;
1022 1022
1023 if ((lst == VOID && rst == FUNC) || (lst == FUNC && rst == VOID)) { 1023 if ((lst == VOID && rst == FUNC) || (lst == FUNC && rst == VOID)) {
1024 /* (void *)0 handled above */ 1024 /* (void *)0 handled above */
1025 if (sflag) 1025 if (sflag)
1026 /* ANSI C forbids conv. of %s to %s, op %s */ 1026 /* ANSI C forbids conv. of %s to %s, op %s */
1027 warning(305, "function pointer", "'void *'", 1027 warning(305, "function pointer", "'void *'",
1028 mp->m_name); 1028 mp->m_name);
1029 return; 1029 return;
1030 } 1030 }
1031 1031
1032 if (eqptrtype(lstp, rstp, true)) 1032 if (eqptrtype(lstp, rstp, true))
1033 return; 1033 return;
1034 if (!eqtype(lstp, rstp, true, false, NULL)) 1034 if (!eqtype(lstp, rstp, true, false, NULL))
1035 warn_incompatible_pointers(mp, ltp, rtp); 1035 warn_incompatible_pointers(mp, ltp, rtp);
1036} 1036}
1037 1037
1038static bool 1038static bool
1039typeok_colon(const mod_t *mp, 1039typeok_colon(const mod_t *mp,
@@ -2819,1500 +2819,1500 @@ build_colon(tnode_t *ln, tnode_t *rn) @@ -2819,1500 +2819,1500 @@ build_colon(tnode_t *ln, tnode_t *rn)
2819 return ntn; 2819 return ntn;
2820} 2820}
2821 2821
2822/* 2822/*
2823 * Create a node for an assignment operator (both = and op= ). 2823 * Create a node for an assignment operator (both = and op= ).
2824 */ 2824 */
2825static tnode_t * 2825static tnode_t *
2826build_assignment(op_t op, tnode_t *ln, tnode_t *rn) 2826build_assignment(op_t op, tnode_t *ln, tnode_t *rn)
2827{ 2827{
2828 tspec_t lt, rt; 2828 tspec_t lt, rt;
2829 tnode_t *ntn, *ctn; 2829 tnode_t *ntn, *ctn;
2830 2830
2831 lint_assert(ln != NULL); 2831 lint_assert(ln != NULL);
2832 lint_assert(rn != NULL); 2832 lint_assert(rn != NULL);
2833 2833
2834 lt = ln->tn_type->t_tspec; 2834 lt = ln->tn_type->t_tspec;
2835 rt = rn->tn_type->t_tspec; 2835 rt = rn->tn_type->t_tspec;
2836 2836
2837 if ((op == ADDASS || op == SUBASS) && lt == PTR) { 2837 if ((op == ADDASS || op == SUBASS) && lt == PTR) {
2838 lint_assert(is_integer(rt)); 2838 lint_assert(is_integer(rt));
2839 ctn = plength(ln->tn_type); 2839 ctn = plength(ln->tn_type);
2840 if (rn->tn_type->t_tspec != ctn->tn_type->t_tspec) 2840 if (rn->tn_type->t_tspec != ctn->tn_type->t_tspec)
2841 rn = convert(NOOP, 0, ctn->tn_type, rn); 2841 rn = convert(NOOP, 0, ctn->tn_type, rn);
2842 rn = new_tnode(MULT, rn->tn_type, rn, ctn); 2842 rn = new_tnode(MULT, rn->tn_type, rn, ctn);
2843 if (rn->tn_left->tn_op == CON) 2843 if (rn->tn_left->tn_op == CON)
2844 rn = fold(rn); 2844 rn = fold(rn);
2845 } 2845 }
2846 2846
2847 if ((op == ASSIGN || op == RETURN) && (lt == STRUCT || rt == STRUCT)) { 2847 if ((op == ASSIGN || op == RETURN) && (lt == STRUCT || rt == STRUCT)) {
2848 lint_assert(lt == rt); 2848 lint_assert(lt == rt);
2849 lint_assert(ln->tn_type->t_str == rn->tn_type->t_str); 2849 lint_assert(ln->tn_type->t_str == rn->tn_type->t_str);
2850 if (is_incomplete(ln->tn_type)) { 2850 if (is_incomplete(ln->tn_type)) {
2851 if (op == RETURN) { 2851 if (op == RETURN) {
2852 /* cannot return incomplete type */ 2852 /* cannot return incomplete type */
2853 error(212); 2853 error(212);
2854 } else { 2854 } else {
2855 /* unknown operand size, op %s */ 2855 /* unknown operand size, op %s */
2856 error(138, op_name(op)); 2856 error(138, op_name(op));
2857 } 2857 }
2858 return NULL; 2858 return NULL;
2859 } 2859 }
2860 } 2860 }
2861 2861
2862 if (op == SHLASS) { 2862 if (op == SHLASS) {
2863 if (portable_size_in_bits(lt) < portable_size_in_bits(rt)) { 2863 if (portable_size_in_bits(lt) < portable_size_in_bits(rt)) {
2864 if (hflag) 2864 if (hflag)
2865 /* semantics of '%s' change in ANSI C; ... */ 2865 /* semantics of '%s' change in ANSI C; ... */
2866 warning(118, "<<="); 2866 warning(118, "<<=");
2867 } 2867 }
2868 } else if (op != SHRASS) { 2868 } else if (op != SHRASS) {
2869 if (op == ASSIGN || lt != PTR) { 2869 if (op == ASSIGN || lt != PTR) {
2870 if (lt != rt || 2870 if (lt != rt ||
2871 (ln->tn_type->t_bitfield && rn->tn_op == CON)) { 2871 (ln->tn_type->t_bitfield && rn->tn_op == CON)) {
2872 rn = convert(op, 0, ln->tn_type, rn); 2872 rn = convert(op, 0, ln->tn_type, rn);
2873 rt = lt; 2873 rt = lt;
2874 } 2874 }
2875 } 2875 }
2876 } 2876 }
2877 2877
2878 ntn = new_tnode(op, ln->tn_type, ln, rn); 2878 ntn = new_tnode(op, ln->tn_type, ln, rn);
2879 2879
2880 return ntn; 2880 return ntn;
2881} 2881}
2882 2882
2883/* 2883/*
2884 * Get length of type tp->t_subt. 2884 * Get length of type tp->t_subt.
2885 */ 2885 */
2886static tnode_t * 2886static tnode_t *
2887plength(type_t *tp) 2887plength(type_t *tp)
2888{ 2888{
2889 int elem, elsz; 2889 int elem, elsz;
2890 2890
2891 lint_assert(tp->t_tspec == PTR); 2891 lint_assert(tp->t_tspec == PTR);
2892 tp = tp->t_subt; 2892 tp = tp->t_subt;
2893 2893
2894 elem = 1; 2894 elem = 1;
2895 elsz = 0; 2895 elsz = 0;
2896 2896
2897 while (tp->t_tspec == ARRAY) { 2897 while (tp->t_tspec == ARRAY) {
2898 elem *= tp->t_dim; 2898 elem *= tp->t_dim;
2899 tp = tp->t_subt; 2899 tp = tp->t_subt;
2900 } 2900 }
2901 2901
2902 switch (tp->t_tspec) { 2902 switch (tp->t_tspec) {
2903 case FUNC: 2903 case FUNC:
2904 /* pointer to function is not allowed here */ 2904 /* pointer to function is not allowed here */
2905 error(110); 2905 error(110);
2906 break; 2906 break;
2907 case VOID: 2907 case VOID:
2908 /* cannot do pointer arithmetic on operand of unknown size */ 2908 /* cannot do pointer arithmetic on operand of unknown size */
2909 gnuism(136); 2909 gnuism(136);
2910 break; 2910 break;
2911 case STRUCT: 2911 case STRUCT:
2912 case UNION: 2912 case UNION:
2913 if ((elsz = tp->t_str->sou_size_in_bits) == 0) 2913 if ((elsz = tp->t_str->sou_size_in_bits) == 0)
2914 /* cannot do pointer arithmetic on operand of ... */ 2914 /* cannot do pointer arithmetic on operand of ... */
2915 error(136); 2915 error(136);
2916 break; 2916 break;
2917 case ENUM: 2917 case ENUM:
2918 if (is_incomplete(tp)) { 2918 if (is_incomplete(tp)) {
2919 /* cannot do pointer arithmetic on operand of ... */ 2919 /* cannot do pointer arithmetic on operand of ... */
2920 warning(136); 2920 warning(136);
2921 } 2921 }
2922 /* FALLTHROUGH */ 2922 /* FALLTHROUGH */
2923 default: 2923 default:
2924 if ((elsz = size_in_bits(tp->t_tspec)) == 0) { 2924 if ((elsz = size_in_bits(tp->t_tspec)) == 0) {
2925 /* cannot do pointer arithmetic on operand of ... */ 2925 /* cannot do pointer arithmetic on operand of ... */
2926 error(136); 2926 error(136);
2927 } else { 2927 } else {
2928 lint_assert(elsz != -1); 2928 lint_assert(elsz != -1);
2929 } 2929 }
2930 break; 2930 break;
2931 } 2931 }
2932 2932
2933 if (elem == 0 && elsz != 0) { 2933 if (elem == 0 && elsz != 0) {
2934 /* cannot do pointer arithmetic on operand of unknown size */ 2934 /* cannot do pointer arithmetic on operand of unknown size */
2935 error(136); 2935 error(136);
2936 } 2936 }
2937 2937
2938 if (elsz == 0) 2938 if (elsz == 0)
2939 elsz = CHAR_SIZE; 2939 elsz = CHAR_SIZE;
2940 2940
2941 return expr_new_integer_constant(PTRDIFF_TSPEC, 2941 return expr_new_integer_constant(PTRDIFF_TSPEC,
2942 (int64_t)(elem * elsz / CHAR_SIZE)); 2942 (int64_t)(elem * elsz / CHAR_SIZE));
2943} 2943}
2944 2944
2945/* 2945/*
2946 * XXX 2946 * XXX
2947 * Note: There appear to be a number of bugs in detecting overflow in 2947 * Note: There appear to be a number of bugs in detecting overflow in
2948 * this function. An audit and a set of proper regression tests are needed. 2948 * this function. An audit and a set of proper regression tests are needed.
2949 * --Perry Metzger, Nov. 16, 2001 2949 * --Perry Metzger, Nov. 16, 2001
2950 */ 2950 */
2951/* 2951/*
2952 * Do only as much as necessary to compute constant expressions. 2952 * Do only as much as necessary to compute constant expressions.
2953 * Called only if the operator allows folding and all operands are constants. 2953 * Called only if the operator allows folding and all operands are constants.
2954 */ 2954 */
2955static tnode_t * 2955static tnode_t *
2956fold(tnode_t *tn) 2956fold(tnode_t *tn)
2957{ 2957{
2958 val_t *v; 2958 val_t *v;
2959 tspec_t t; 2959 tspec_t t;
2960 bool utyp, ovfl; 2960 bool utyp, ovfl;
2961 int64_t sl, sr = 0, q = 0, mask; 2961 int64_t sl, sr = 0, q = 0, mask;
2962 uint64_t ul, ur = 0; 2962 uint64_t ul, ur = 0;
2963 tnode_t *cn; 2963 tnode_t *cn;
2964 2964
2965 v = xcalloc(1, sizeof(*v)); 2965 v = xcalloc(1, sizeof(*v));
2966 v->v_tspec = t = tn->tn_type->t_tspec; 2966 v->v_tspec = t = tn->tn_type->t_tspec;
2967 2967
2968 utyp = t == PTR || is_uinteger(t); 2968 utyp = t == PTR || is_uinteger(t);
2969 ul = sl = tn->tn_left->tn_val->v_quad; 2969 ul = sl = tn->tn_left->tn_val->v_quad;
2970 if (modtab[tn->tn_op].m_binary) 2970 if (modtab[tn->tn_op].m_binary)
2971 ur = sr = tn->tn_right->tn_val->v_quad; 2971 ur = sr = tn->tn_right->tn_val->v_quad;
2972 2972
2973 mask = value_bits(size_in_bits(t)); 2973 mask = value_bits(size_in_bits(t));
2974 ovfl = false; 2974 ovfl = false;
2975 2975
2976 switch (tn->tn_op) { 2976 switch (tn->tn_op) {
2977 case UPLUS: 2977 case UPLUS:
2978 q = sl; 2978 q = sl;
2979 break; 2979 break;
2980 case UMINUS: 2980 case UMINUS:
2981 q = -sl; 2981 q = -sl;
2982 if (sl != 0 && msb(q, t, -1) == msb(sl, t, -1)) 2982 if (sl != 0 && msb(q, t, -1) == msb(sl, t, -1))
2983 ovfl = true; 2983 ovfl = true;
2984 break; 2984 break;
2985 case COMPL: 2985 case COMPL:
2986 q = ~sl; 2986 q = ~sl;
2987 break; 2987 break;
2988 case MULT: 2988 case MULT:
2989 if (utyp) { 2989 if (utyp) {
2990 q = ul * ur; 2990 q = ul * ur;
2991 if (q != (q & mask)) 2991 if (q != (q & mask))
2992 ovfl = true; 2992 ovfl = true;
2993 else if ((ul != 0) && ((q / ul) != ur)) 2993 else if ((ul != 0) && ((q / ul) != ur))
2994 ovfl = true; 2994 ovfl = true;
2995 } else { 2995 } else {
2996 q = sl * sr; 2996 q = sl * sr;
2997 if (msb(q, t, -1) != (msb(sl, t, -1) ^ msb(sr, t, -1))) 2997 if (msb(q, t, -1) != (msb(sl, t, -1) ^ msb(sr, t, -1)))
2998 ovfl = true; 2998 ovfl = true;
2999 } 2999 }
3000 break; 3000 break;
3001 case DIV: 3001 case DIV:
3002 if (sr == 0) { 3002 if (sr == 0) {
3003 /* division by 0 */ 3003 /* division by 0 */
3004 error(139); 3004 error(139);
3005 q = utyp ? UQUAD_MAX : QUAD_MAX; 3005 q = utyp ? UQUAD_MAX : QUAD_MAX;
3006 } else { 3006 } else {
3007 q = utyp ? (int64_t)(ul / ur) : sl / sr; 3007 q = utyp ? (int64_t)(ul / ur) : sl / sr;
3008 } 3008 }
3009 break; 3009 break;
3010 case MOD: 3010 case MOD:
3011 if (sr == 0) { 3011 if (sr == 0) {
3012 /* modulus by 0 */ 3012 /* modulus by 0 */
3013 error(140); 3013 error(140);
3014 q = 0; 3014 q = 0;
3015 } else { 3015 } else {
3016 q = utyp ? (int64_t)(ul % ur) : sl % sr; 3016 q = utyp ? (int64_t)(ul % ur) : sl % sr;
3017 } 3017 }
3018 break; 3018 break;
3019 case PLUS: 3019 case PLUS:
3020 q = utyp ? (int64_t)(ul + ur) : sl + sr; 3020 q = utyp ? (int64_t)(ul + ur) : sl + sr;
3021 if (msb(sl, t, -1) != 0 && msb(sr, t, -1) != 0) { 3021 if (msb(sl, t, -1) != 0 && msb(sr, t, -1) != 0) {
3022 if (msb(q, t, -1) == 0) 3022 if (msb(q, t, -1) == 0)
3023 ovfl = true; 3023 ovfl = true;
3024 } else if (msb(sl, t, -1) == 0 && msb(sr, t, -1) == 0) { 3024 } else if (msb(sl, t, -1) == 0 && msb(sr, t, -1) == 0) {
3025 if (msb(q, t, -1) != 0) 3025 if (msb(q, t, -1) != 0)
3026 ovfl = true; 3026 ovfl = true;
3027 } 3027 }
3028 break; 3028 break;
3029 case MINUS: 3029 case MINUS:
3030 q = utyp ? (int64_t)(ul - ur) : sl - sr; 3030 q = utyp ? (int64_t)(ul - ur) : sl - sr;
3031 if (msb(sl, t, -1) != 0 && msb(sr, t, -1) == 0) { 3031 if (msb(sl, t, -1) != 0 && msb(sr, t, -1) == 0) {
3032 if (msb(q, t, -1) == 0) 3032 if (msb(q, t, -1) == 0)
3033 ovfl = true; 3033 ovfl = true;
3034 } else if (msb(sl, t, -1) == 0 && msb(sr, t, -1) != 0) { 3034 } else if (msb(sl, t, -1) == 0 && msb(sr, t, -1) != 0) {
3035 if (msb(q, t, -1) != 0) 3035 if (msb(q, t, -1) != 0)
3036 ovfl = true; 3036 ovfl = true;
3037 } 3037 }
3038 break; 3038 break;
3039 case SHL: 3039 case SHL:
3040 q = utyp ? (int64_t)(ul << sr) : sl << sr; 3040 q = utyp ? (int64_t)(ul << sr) : sl << sr;
3041 break; 3041 break;
3042 case SHR: 3042 case SHR:
3043 /* 3043 /*
3044 * The sign must be explicitly extended because 3044 * The sign must be explicitly extended because
3045 * shifts of signed values are implementation dependent. 3045 * shifts of signed values are implementation dependent.
3046 */ 3046 */
3047 q = ul >> sr; 3047 q = ul >> sr;
3048 q = convert_integer(q, t, size_in_bits(t) - (int)sr); 3048 q = convert_integer(q, t, size_in_bits(t) - (int)sr);
3049 break; 3049 break;
3050 case LT: 3050 case LT:
3051 q = (utyp ? ul < ur : sl < sr) ? 1 : 0; 3051 q = (utyp ? ul < ur : sl < sr) ? 1 : 0;
3052 break; 3052 break;
3053 case LE: 3053 case LE:
3054 q = (utyp ? ul <= ur : sl <= sr) ? 1 : 0; 3054 q = (utyp ? ul <= ur : sl <= sr) ? 1 : 0;
3055 break; 3055 break;
3056 case GE: 3056 case GE:
3057 q = (utyp ? ul >= ur : sl >= sr) ? 1 : 0; 3057 q = (utyp ? ul >= ur : sl >= sr) ? 1 : 0;
3058 break; 3058 break;
3059 case GT: 3059 case GT:
3060 q = (utyp ? ul > ur : sl > sr) ? 1 : 0; 3060 q = (utyp ? ul > ur : sl > sr) ? 1 : 0;
3061 break; 3061 break;
3062 case EQ: 3062 case EQ:
3063 q = (utyp ? ul == ur : sl == sr) ? 1 : 0; 3063 q = (utyp ? ul == ur : sl == sr) ? 1 : 0;
3064 break; 3064 break;
3065 case NE: 3065 case NE:
3066 q = (utyp ? ul != ur : sl != sr) ? 1 : 0; 3066 q = (utyp ? ul != ur : sl != sr) ? 1 : 0;
3067 break; 3067 break;
3068 case BITAND: 3068 case BITAND:
3069 q = utyp ? (int64_t)(ul & ur) : sl & sr; 3069 q = utyp ? (int64_t)(ul & ur) : sl & sr;
3070 break; 3070 break;
3071 case BITXOR: 3071 case BITXOR:
3072 q = utyp ? (int64_t)(ul ^ ur) : sl ^ sr; 3072 q = utyp ? (int64_t)(ul ^ ur) : sl ^ sr;
3073 break; 3073 break;
3074 case BITOR: 3074 case BITOR:
3075 q = utyp ? (int64_t)(ul | ur) : sl | sr; 3075 q = utyp ? (int64_t)(ul | ur) : sl | sr;
3076 break; 3076 break;
3077 default: 3077 default:
3078 lint_assert(/*CONSTCOND*/false); 3078 lint_assert(/*CONSTCOND*/false);
3079 } 3079 }
3080 3080
3081 /* XXX does not work for quads. */ 3081 /* XXX does not work for quads. */
3082 if (ovfl || ((uint64_t)(q | mask) != ~(uint64_t)0 && 3082 if (ovfl || ((uint64_t)(q | mask) != ~(uint64_t)0 &&
3083 (q & ~mask) != 0)) { 3083 (q & ~mask) != 0)) {
3084 if (hflag) 3084 if (hflag)
3085 /* integer overflow detected, op %s */ 3085 /* integer overflow detected, op %s */
3086 warning(141, op_name(tn->tn_op)); 3086 warning(141, op_name(tn->tn_op));
3087 } 3087 }
3088 3088
3089 v->v_quad = convert_integer(q, t, -1); 3089 v->v_quad = convert_integer(q, t, -1);
3090 3090
3091 cn = expr_new_constant(tn->tn_type, v); 3091 cn = expr_new_constant(tn->tn_type, v);
3092 if (tn->tn_left->tn_system_dependent) 3092 if (tn->tn_left->tn_system_dependent)
3093 cn->tn_system_dependent = true; 3093 cn->tn_system_dependent = true;
3094 if (modtab[tn->tn_op].m_binary && tn->tn_right->tn_system_dependent) 3094 if (modtab[tn->tn_op].m_binary && tn->tn_right->tn_system_dependent)
3095 cn->tn_system_dependent = true; 3095 cn->tn_system_dependent = true;
3096 3096
3097 return cn; 3097 return cn;
3098} 3098}
3099 3099
3100/* 3100/*
3101 * Fold constant nodes, as much as is needed for comparing the value with 0 3101 * Fold constant nodes, as much as is needed for comparing the value with 0
3102 * (test context, for controlling expressions). 3102 * (test context, for controlling expressions).
3103 */ 3103 */
3104static tnode_t * 3104static tnode_t *
3105fold_test(tnode_t *tn) 3105fold_test(tnode_t *tn)
3106{ 3106{
3107 bool l, r; 3107 bool l, r;
3108 val_t *v; 3108 val_t *v;
3109 3109
3110 v = xcalloc(1, sizeof(*v)); 3110 v = xcalloc(1, sizeof(*v));
3111 v->v_tspec = tn->tn_type->t_tspec; 3111 v->v_tspec = tn->tn_type->t_tspec;
3112 lint_assert(v->v_tspec == INT || (Tflag && v->v_tspec == BOOL)); 3112 lint_assert(v->v_tspec == INT || (Tflag && v->v_tspec == BOOL));
3113 3113
3114 l = constant_is_nonzero(tn->tn_left); 3114 l = constant_is_nonzero(tn->tn_left);
3115 r = modtab[tn->tn_op].m_binary && constant_is_nonzero(tn->tn_right); 3115 r = modtab[tn->tn_op].m_binary && constant_is_nonzero(tn->tn_right);
3116 3116
3117 switch (tn->tn_op) { 3117 switch (tn->tn_op) {
3118 case NOT: 3118 case NOT:
3119 if (hflag && !constcond_flag) 3119 if (hflag && !constcond_flag)
3120 /* constant argument to '!' */ 3120 /* constant argument to '!' */
3121 warning(239); 3121 warning(239);
3122 v->v_quad = !l ? 1 : 0; 3122 v->v_quad = !l ? 1 : 0;
3123 break; 3123 break;
3124 case LOGAND: 3124 case LOGAND:
3125 v->v_quad = l && r ? 1 : 0; 3125 v->v_quad = l && r ? 1 : 0;
3126 break; 3126 break;
3127 case LOGOR: 3127 case LOGOR:
3128 v->v_quad = l || r ? 1 : 0; 3128 v->v_quad = l || r ? 1 : 0;
3129 break; 3129 break;
3130 default: 3130 default:
3131 lint_assert(/*CONSTCOND*/false); 3131 lint_assert(/*CONSTCOND*/false);
3132 } 3132 }
3133 3133
3134 return expr_new_constant(tn->tn_type, v); 3134 return expr_new_constant(tn->tn_type, v);
3135} 3135}
3136 3136
3137/* 3137/*
3138 * Fold constant nodes having operands with floating point type. 3138 * Fold constant nodes having operands with floating point type.
3139 */ 3139 */
3140static tnode_t * 3140static tnode_t *
3141fold_float(tnode_t *tn) 3141fold_float(tnode_t *tn)
3142{ 3142{
3143 val_t *v; 3143 val_t *v;
3144 tspec_t t; 3144 tspec_t t;
3145 ldbl_t l, r = 0; 3145 ldbl_t l, r = 0;
3146 3146
3147 fpe = 0; 3147 fpe = 0;
3148 v = xcalloc(1, sizeof(*v)); 3148 v = xcalloc(1, sizeof(*v));
3149 v->v_tspec = t = tn->tn_type->t_tspec; 3149 v->v_tspec = t = tn->tn_type->t_tspec;
3150 3150
3151 lint_assert(is_floating(t)); 3151 lint_assert(is_floating(t));
3152 lint_assert(t == tn->tn_left->tn_type->t_tspec); 3152 lint_assert(t == tn->tn_left->tn_type->t_tspec);
3153 lint_assert(!modtab[tn->tn_op].m_binary || 3153 lint_assert(!modtab[tn->tn_op].m_binary ||
3154 t == tn->tn_right->tn_type->t_tspec); 3154 t == tn->tn_right->tn_type->t_tspec);
3155 3155
3156 l = tn->tn_left->tn_val->v_ldbl; 3156 l = tn->tn_left->tn_val->v_ldbl;
3157 if (modtab[tn->tn_op].m_binary) 3157 if (modtab[tn->tn_op].m_binary)
3158 r = tn->tn_right->tn_val->v_ldbl; 3158 r = tn->tn_right->tn_val->v_ldbl;
3159 3159
3160 switch (tn->tn_op) { 3160 switch (tn->tn_op) {
3161 case UPLUS: 3161 case UPLUS:
3162 v->v_ldbl = l; 3162 v->v_ldbl = l;
3163 break; 3163 break;
3164 case UMINUS: 3164 case UMINUS:
3165 v->v_ldbl = -l; 3165 v->v_ldbl = -l;
3166 break; 3166 break;
3167 case MULT: 3167 case MULT:
3168 v->v_ldbl = l * r; 3168 v->v_ldbl = l * r;
3169 break; 3169 break;
3170 case DIV: 3170 case DIV:
3171 if (r == 0.0) { 3171 if (r == 0.0) {
3172 /* division by 0 */ 3172 /* division by 0 */
3173 error(139); 3173 error(139);
3174 if (t == FLOAT) { 3174 if (t == FLOAT) {
3175 v->v_ldbl = l < 0 ? -FLT_MAX : FLT_MAX; 3175 v->v_ldbl = l < 0 ? -FLT_MAX : FLT_MAX;
3176 } else if (t == DOUBLE) { 3176 } else if (t == DOUBLE) {
3177 v->v_ldbl = l < 0 ? -DBL_MAX : DBL_MAX; 3177 v->v_ldbl = l < 0 ? -DBL_MAX : DBL_MAX;
3178 } else { 3178 } else {
3179 v->v_ldbl = l < 0 ? -LDBL_MAX : LDBL_MAX; 3179 v->v_ldbl = l < 0 ? -LDBL_MAX : LDBL_MAX;
3180 } 3180 }
3181 } else { 3181 } else {
3182 v->v_ldbl = l / r; 3182 v->v_ldbl = l / r;
3183 } 3183 }
3184 break; 3184 break;
3185 case PLUS: 3185 case PLUS:
3186 v->v_ldbl = l + r; 3186 v->v_ldbl = l + r;
3187 break; 3187 break;
3188 case MINUS: 3188 case MINUS:
3189 v->v_ldbl = l - r; 3189 v->v_ldbl = l - r;
3190 break; 3190 break;
3191 case LT: 3191 case LT:
3192 v->v_quad = l < r ? 1 : 0; 3192 v->v_quad = l < r ? 1 : 0;
3193 break; 3193 break;
3194 case LE: 3194 case LE:
3195 v->v_quad = l <= r ? 1 : 0; 3195 v->v_quad = l <= r ? 1 : 0;
3196 break; 3196 break;
3197 case GE: 3197 case GE:
3198 v->v_quad = l >= r ? 1 : 0; 3198 v->v_quad = l >= r ? 1 : 0;
3199 break; 3199 break;
3200 case GT: 3200 case GT:
3201 v->v_quad = l > r ? 1 : 0; 3201 v->v_quad = l > r ? 1 : 0;
3202 break; 3202 break;
3203 case EQ: 3203 case EQ:
3204 v->v_quad = l == r ? 1 : 0; 3204 v->v_quad = l == r ? 1 : 0;
3205 break; 3205 break;
3206 case NE: 3206 case NE:
3207 v->v_quad = l != r ? 1 : 0; 3207 v->v_quad = l != r ? 1 : 0;
3208 break; 3208 break;
3209 default: 3209 default:
3210 lint_assert(/*CONSTCOND*/false); 3210 lint_assert(/*CONSTCOND*/false);
3211 } 3211 }
3212 3212
3213 lint_assert(fpe != 0 || isnan((double)v->v_ldbl) == 0); 3213 lint_assert(fpe != 0 || isnan((double)v->v_ldbl) == 0);
3214 if (fpe != 0 || finite((double)v->v_ldbl) == 0 || 3214 if (fpe != 0 || finite((double)v->v_ldbl) == 0 ||
3215 (t == FLOAT && 3215 (t == FLOAT &&
3216 (v->v_ldbl > FLT_MAX || v->v_ldbl < -FLT_MAX)) || 3216 (v->v_ldbl > FLT_MAX || v->v_ldbl < -FLT_MAX)) ||
3217 (t == DOUBLE && 3217 (t == DOUBLE &&
3218 (v->v_ldbl > DBL_MAX || v->v_ldbl < -DBL_MAX))) { 3218 (v->v_ldbl > DBL_MAX || v->v_ldbl < -DBL_MAX))) {
3219 /* floating point overflow detected, op %s */ 3219 /* floating point overflow detected, op %s */
3220 warning(142, op_name(tn->tn_op)); 3220 warning(142, op_name(tn->tn_op));
3221 if (t == FLOAT) { 3221 if (t == FLOAT) {
3222 v->v_ldbl = v->v_ldbl < 0 ? -FLT_MAX : FLT_MAX; 3222 v->v_ldbl = v->v_ldbl < 0 ? -FLT_MAX : FLT_MAX;
3223 } else if (t == DOUBLE) { 3223 } else if (t == DOUBLE) {
3224 v->v_ldbl = v->v_ldbl < 0 ? -DBL_MAX : DBL_MAX; 3224 v->v_ldbl = v->v_ldbl < 0 ? -DBL_MAX : DBL_MAX;
3225 } else { 3225 } else {
3226 v->v_ldbl = v->v_ldbl < 0 ? -LDBL_MAX: LDBL_MAX; 3226 v->v_ldbl = v->v_ldbl < 0 ? -LDBL_MAX: LDBL_MAX;
3227 } 3227 }
3228 fpe = 0; 3228 fpe = 0;
3229 } 3229 }
3230 3230
3231 return expr_new_constant(tn->tn_type, v); 3231 return expr_new_constant(tn->tn_type, v);
3232} 3232}
3233 3233
3234 3234
3235/* 3235/*
3236 * Create a constant node for sizeof. 3236 * Create a constant node for sizeof.
3237 */ 3237 */
3238tnode_t * 3238tnode_t *
3239build_sizeof(const type_t *tp) 3239build_sizeof(const type_t *tp)
3240{ 3240{
3241 int64_t size_in_bytes = type_size_in_bits(tp) / CHAR_SIZE; 3241 int64_t size_in_bytes = type_size_in_bits(tp) / CHAR_SIZE;
3242 tnode_t *tn = expr_new_integer_constant(SIZEOF_TSPEC, size_in_bytes); 3242 tnode_t *tn = expr_new_integer_constant(SIZEOF_TSPEC, size_in_bytes);
3243 tn->tn_system_dependent = true; 3243 tn->tn_system_dependent = true;
3244 return tn; 3244 return tn;
3245} 3245}
3246 3246
3247/* 3247/*
3248 * Create a constant node for offsetof. 3248 * Create a constant node for offsetof.
3249 */ 3249 */
3250tnode_t * 3250tnode_t *
3251build_offsetof(const type_t *tp, const sym_t *sym) 3251build_offsetof(const type_t *tp, const sym_t *sym)
3252{ 3252{
3253 tspec_t t = tp->t_tspec; 3253 tspec_t t = tp->t_tspec;
3254 if (t != STRUCT && t != UNION) 3254 if (t != STRUCT && t != UNION)
3255 /* unacceptable operand of '%s' */ 3255 /* unacceptable operand of '%s' */
3256 error(111, "offsetof"); 3256 error(111, "offsetof");
3257 3257
3258 // XXX: wrong size, no checking for sym fixme 3258 // XXX: wrong size, no checking for sym fixme
3259 int64_t offset_in_bytes = type_size_in_bits(tp) / CHAR_SIZE; 3259 int64_t offset_in_bytes = type_size_in_bits(tp) / CHAR_SIZE;
3260 tnode_t *tn = expr_new_integer_constant(SIZEOF_TSPEC, offset_in_bytes); 3260 tnode_t *tn = expr_new_integer_constant(SIZEOF_TSPEC, offset_in_bytes);
3261 tn->tn_system_dependent = true; 3261 tn->tn_system_dependent = true;
3262 return tn; 3262 return tn;
3263} 3263}
3264 3264
3265int64_t 3265int64_t
3266type_size_in_bits(const type_t *tp) 3266type_size_in_bits(const type_t *tp)
3267{ 3267{
3268 int elem, elsz; 3268 int elem, elsz;
3269 bool flex; 3269 bool flex;
3270 3270
3271 elem = 1; 3271 elem = 1;
3272 flex = false; 3272 flex = false;
3273 while (tp->t_tspec == ARRAY) { 3273 while (tp->t_tspec == ARRAY) {
3274 flex = true; /* allow c99 flex arrays [] [0] */ 3274 flex = true; /* allow c99 flex arrays [] [0] */
3275 elem *= tp->t_dim; 3275 elem *= tp->t_dim;
3276 tp = tp->t_subt; 3276 tp = tp->t_subt;
3277 } 3277 }
3278 if (elem == 0) { 3278 if (elem == 0) {
3279 if (!flex) { 3279 if (!flex) {
3280 /* cannot take size/alignment of incomplete type */ 3280 /* cannot take size/alignment of incomplete type */
3281 error(143); 3281 error(143);
3282 elem = 1; 3282 elem = 1;
3283 } 3283 }
3284 } 3284 }
3285 switch (tp->t_tspec) { 3285 switch (tp->t_tspec) {
3286 case FUNC: 3286 case FUNC:
3287 /* cannot take size/alignment of function */ 3287 /* cannot take size/alignment of function */
3288 error(144); 3288 error(144);
3289 elsz = 1; 3289 elsz = 1;
3290 break; 3290 break;
3291 case STRUCT: 3291 case STRUCT:
3292 case UNION: 3292 case UNION:
3293 if (is_incomplete(tp)) { 3293 if (is_incomplete(tp)) {
3294 /* cannot take size/alignment of incomplete type */ 3294 /* cannot take size/alignment of incomplete type */
3295 error(143); 3295 error(143);
3296 elsz = 1; 3296 elsz = 1;
3297 } else { 3297 } else {
3298 elsz = tp->t_str->sou_size_in_bits; 3298 elsz = tp->t_str->sou_size_in_bits;
3299 } 3299 }
3300 break; 3300 break;
3301 case ENUM: 3301 case ENUM:
3302 if (is_incomplete(tp)) { 3302 if (is_incomplete(tp)) {
3303 /* cannot take size/alignment of incomplete type */ 3303 /* cannot take size/alignment of incomplete type */
3304 warning(143); 3304 warning(143);
3305 } 3305 }
3306 /* FALLTHROUGH */ 3306 /* FALLTHROUGH */
3307 default: 3307 default:
3308 if (tp->t_bitfield) { 3308 if (tp->t_bitfield) {
3309 /* cannot take size/alignment of bit-field */ 3309 /* cannot take size/alignment of bit-field */
3310 error(145); 3310 error(145);
3311 } 3311 }
3312 if (tp->t_tspec == VOID) { 3312 if (tp->t_tspec == VOID) {
3313 /* cannot take size/alignment of void */ 3313 /* cannot take size/alignment of void */
3314 error(146); 3314 error(146);
3315 elsz = 1; 3315 elsz = 1;
3316 } else { 3316 } else {
3317 elsz = size_in_bits(tp->t_tspec); 3317 elsz = size_in_bits(tp->t_tspec);
3318 lint_assert(elsz > 0); 3318 lint_assert(elsz > 0);
3319 } 3319 }
3320 break; 3320 break;
3321 } 3321 }
3322 3322
3323 return (int64_t)elem * elsz; 3323 return (int64_t)elem * elsz;
3324} 3324}
3325 3325
3326tnode_t * 3326tnode_t *
3327build_alignof(const type_t *tp) 3327build_alignof(const type_t *tp)
3328{ 3328{
3329 switch (tp->t_tspec) { 3329 switch (tp->t_tspec) {
3330 case ARRAY: 3330 case ARRAY:
3331 break; 3331 break;
3332 3332
3333 case FUNC: 3333 case FUNC:
3334 /* cannot take size/alignment of function */ 3334 /* cannot take size/alignment of function */
3335 error(144); 3335 error(144);
3336 return 0; 3336 return 0;
3337 3337
3338 case STRUCT: 3338 case STRUCT:
3339 case UNION: 3339 case UNION:
3340 if (is_incomplete(tp)) { 3340 if (is_incomplete(tp)) {
3341 /* cannot take size/alignment of incomplete type */ 3341 /* cannot take size/alignment of incomplete type */
3342 error(143); 3342 error(143);
3343 return 0; 3343 return 0;
3344 } 3344 }
3345 break; 3345 break;
3346 case ENUM: 3346 case ENUM:
3347 break; 3347 break;
3348 default: 3348 default:
3349 if (tp->t_bitfield) { 3349 if (tp->t_bitfield) {
3350 /* cannot take size/alignment of bit-field */ 3350 /* cannot take size/alignment of bit-field */
3351 error(145); 3351 error(145);
3352 return 0; 3352 return 0;
3353 } 3353 }
3354 if (tp->t_tspec == VOID) { 3354 if (tp->t_tspec == VOID) {
3355 /* cannot take size/alignment of void */ 3355 /* cannot take size/alignment of void */
3356 error(146); 3356 error(146);
3357 return 0; 3357 return 0;
3358 } 3358 }
3359 break; 3359 break;
3360 } 3360 }
3361 3361
3362 return expr_new_integer_constant(SIZEOF_TSPEC, 3362 return expr_new_integer_constant(SIZEOF_TSPEC,
3363 (int64_t)alignment_in_bits(tp) / CHAR_SIZE); 3363 (int64_t)alignment_in_bits(tp) / CHAR_SIZE);
3364} 3364}
3365 3365
3366/* 3366/*
3367 * Type casts. 3367 * Type casts.
3368 */ 3368 */
3369tnode_t * 3369tnode_t *
3370cast(tnode_t *tn, type_t *tp) 3370cast(tnode_t *tn, type_t *tp)
3371{ 3371{
3372 tspec_t nt, ot; 3372 tspec_t nt, ot;
3373 3373
3374 if (tn == NULL) 3374 if (tn == NULL)
3375 return NULL; 3375 return NULL;
3376 3376
3377 /* 3377 /*
3378 * XXX: checking for tp == NULL is only a quick fix for PR 22119. 3378 * XXX: checking for tp == NULL is only a quick fix for PR 22119.
3379 * The proper fix needs to be investigated properly. 3379 * The proper fix needs to be investigated properly.
3380 * See d_pr_22119.c for how to get here. 3380 * See d_pr_22119.c for how to get here.
3381 */ 3381 */
3382 if (tp == NULL) 3382 if (tp == NULL)
3383 return NULL; 3383 return NULL;
3384 3384
3385 tn = cconv(tn); 3385 tn = cconv(tn);
3386 3386
3387 nt = tp->t_tspec; 3387 nt = tp->t_tspec;
3388 ot = tn->tn_type->t_tspec; 3388 ot = tn->tn_type->t_tspec;
3389 3389
3390 if (nt == VOID) { 3390 if (nt == VOID) {
3391 /* 3391 /*
3392 * XXX ANSI C requires scalar types or void (Plauger & Brodie). 3392 * XXX ANSI C requires scalar types or void (Plauger & Brodie).
3393 * But this seems really questionable. 3393 * But this seems really questionable.
3394 */ 3394 */
3395 } else if (nt == UNION) { 3395 } else if (nt == UNION) {
3396 sym_t *m; 3396 sym_t *m;
3397 struct_or_union *str = tp->t_str; 3397 struct_or_union *str = tp->t_str;
3398 if (!Sflag) { 3398 if (!Sflag) {
3399 /* union cast is a C9X feature */ 3399 /* union cast is a C9X feature */
3400 error(328); 3400 error(328);
3401 return NULL; 3401 return NULL;
3402 } 3402 }
3403 for (m = str->sou_first_member; m != NULL; m = m->s_next) { 3403 for (m = str->sou_first_member; m != NULL; m = m->s_next) {
3404 if (sametype(m->s_type, tn->tn_type)) { 3404 if (sametype(m->s_type, tn->tn_type)) {
3405 tn = expr_zalloc_tnode(); 3405 tn = expr_zalloc_tnode();
3406 tn->tn_op = CVT; 3406 tn->tn_op = CVT;
3407 tn->tn_type = tp; 3407 tn->tn_type = tp;
3408 tn->tn_cast = true; 3408 tn->tn_cast = true;
3409 tn->tn_right = NULL; 3409 tn->tn_right = NULL;
3410 return tn; 3410 return tn;
3411 } 3411 }
3412 } 3412 }
3413 /* type '%s' is not a member of '%s' */ 3413 /* type '%s' is not a member of '%s' */
3414 error(329, type_name(tn->tn_type), type_name(tp)); 3414 error(329, type_name(tn->tn_type), type_name(tp));
3415 return NULL; 3415 return NULL;
3416 } else if (nt == STRUCT || nt == ARRAY || nt == FUNC) { 3416 } else if (nt == STRUCT || nt == ARRAY || nt == FUNC) {
3417 if (!Sflag || nt == ARRAY || nt == FUNC) { 3417 if (!Sflag || nt == ARRAY || nt == FUNC) {
3418 /* invalid cast expression */ 3418 /* invalid cast expression */
3419 error(147); 3419 error(147);
3420 return NULL; 3420 return NULL;
3421 } 3421 }
3422 } else if (ot == STRUCT || ot == UNION) { 3422 } else if (ot == STRUCT || ot == UNION) {
3423 /* invalid cast expression */ 3423 /* invalid cast expression */
3424 error(147); 3424 error(147);
3425 return NULL; 3425 return NULL;
3426 } else if (ot == VOID) { 3426 } else if (ot == VOID) {
3427 /* improper cast of void expression */ 3427 /* improper cast of void expression */
3428 error(148); 3428 error(148);
3429 return NULL; 3429 return NULL;
3430 } else if (is_integer(nt) && is_scalar(ot)) { 3430 } else if (is_integer(nt) && is_scalar(ot)) {
3431 /* ok */ 3431 /* ok */
3432 } else if (is_floating(nt) && is_arithmetic(ot)) { 3432 } else if (is_floating(nt) && is_arithmetic(ot)) {
3433 /* ok */ 3433 /* ok */
3434 } else if (nt == PTR && is_integer(ot)) { 3434 } else if (nt == PTR && is_integer(ot)) {
3435 /* ok */ 3435 /* ok */
3436 } else if (nt == PTR && ot == PTR) { 3436 } else if (nt == PTR && ot == PTR) {
3437 if (!tp->t_subt->t_const && tn->tn_type->t_subt->t_const) { 3437 if (!tp->t_subt->t_const && tn->tn_type->t_subt->t_const) {
3438 if (hflag) 3438 if (hflag)
3439 /* cast discards 'const' from type '%s' */ 3439 /* cast discards 'const' from type '%s' */
3440 warning(275, type_name(tn->tn_type)); 3440 warning(275, type_name(tn->tn_type));
3441 } 3441 }
3442 } else { 3442 } else {
3443 /* invalid cast expression */ 3443 /* invalid cast expression */
3444 error(147); 3444 error(147);
3445 return NULL; 3445 return NULL;
3446 } 3446 }
3447 3447
3448 tn = convert(CVT, 0, tp, tn); 3448 tn = convert(CVT, 0, tp, tn);
3449 tn->tn_cast = true; 3449 tn->tn_cast = true;
3450 3450
3451 return tn; 3451 return tn;
3452} 3452}
3453 3453
3454/* 3454/*
3455 * Create the node for a function argument. 3455 * Create the node for a function argument.
3456 * All necessary conversions and type checks are done in 3456 * All necessary conversions and type checks are done in
3457 * new_function_call_node because new_function_argument_node has no 3457 * new_function_call_node because new_function_argument_node has no
3458 * information about expected argument types. 3458 * information about expected argument types.
3459 */ 3459 */
3460tnode_t * 3460tnode_t *
3461new_function_argument_node(tnode_t *args, tnode_t *arg) 3461new_function_argument_node(tnode_t *args, tnode_t *arg)
3462{ 3462{
3463 tnode_t *ntn; 3463 tnode_t *ntn;
3464 3464
3465 /* 3465 /*
3466 * If there was a serious error in the expression for the argument, 3466 * If there was a serious error in the expression for the argument,
3467 * create a dummy argument so the positions of the remaining arguments 3467 * create a dummy argument so the positions of the remaining arguments
3468 * will not change. 3468 * will not change.
3469 */ 3469 */
3470 if (arg == NULL) 3470 if (arg == NULL)
3471 arg = expr_new_integer_constant(INT, 0); 3471 arg = expr_new_integer_constant(INT, 0);
3472 3472
3473 ntn = new_tnode(PUSH, arg->tn_type, arg, args); 3473 ntn = new_tnode(PUSH, arg->tn_type, arg, args);
3474 3474
3475 return ntn; 3475 return ntn;
3476} 3476}
3477 3477
3478/* 3478/*
3479 * Create the node for a function call. Also check types of 3479 * Create the node for a function call. Also check types of
3480 * function arguments and insert conversions, if necessary. 3480 * function arguments and insert conversions, if necessary.
3481 */ 3481 */
3482tnode_t * 3482tnode_t *
3483new_function_call_node(tnode_t *func, tnode_t *args) 3483new_function_call_node(tnode_t *func, tnode_t *args)
3484{ 3484{
3485 tnode_t *ntn; 3485 tnode_t *ntn;
3486 op_t fcop; 3486 op_t fcop;
3487 3487
3488 if (func == NULL) 3488 if (func == NULL)
3489 return NULL; 3489 return NULL;
3490 3490
3491 if (func->tn_op == NAME && func->tn_type->t_tspec == FUNC) { 3491 if (func->tn_op == NAME && func->tn_type->t_tspec == FUNC) {
3492 fcop = CALL; 3492 fcop = CALL;
3493 } else { 3493 } else {
3494 fcop = ICALL; 3494 fcop = ICALL;
3495 } 3495 }
3496 3496
3497 check_ctype_function_call(func, args); 3497 check_ctype_function_call(func, args);
3498 3498
3499 /* 3499 /*
3500 * after cconv() func will always be a pointer to a function 3500 * after cconv() func will always be a pointer to a function
3501 * if it is a valid function designator. 3501 * if it is a valid function designator.
3502 */ 3502 */
3503 func = cconv(func); 3503 func = cconv(func);
3504 3504
3505 if (func->tn_type->t_tspec != PTR || 3505 if (func->tn_type->t_tspec != PTR ||
3506 func->tn_type->t_subt->t_tspec != FUNC) { 3506 func->tn_type->t_subt->t_tspec != FUNC) {
3507 /* illegal function (type %s) */ 3507 /* illegal function (type %s) */
3508 error(149, type_name(func->tn_type)); 3508 error(149, type_name(func->tn_type));
3509 return NULL; 3509 return NULL;
3510 } 3510 }
3511 3511
3512 args = check_function_arguments(func->tn_type->t_subt, args); 3512 args = check_function_arguments(func->tn_type->t_subt, args);
3513 3513
3514 ntn = new_tnode(fcop, func->tn_type->t_subt->t_subt, func, args); 3514 ntn = new_tnode(fcop, func->tn_type->t_subt->t_subt, func, args);
3515 3515
3516 return ntn; 3516 return ntn;
3517} 3517}
3518 3518
3519/* 3519/*
3520 * Check types of all function arguments and insert conversions, 3520 * Check types of all function arguments and insert conversions,
3521 * if necessary. 3521 * if necessary.
3522 */ 3522 */
3523static tnode_t * 3523static tnode_t *
3524check_function_arguments(type_t *ftp, tnode_t *args) 3524check_function_arguments(type_t *ftp, tnode_t *args)
3525{ 3525{
3526 tnode_t *arg; 3526 tnode_t *arg;
3527 sym_t *asym; 3527 sym_t *asym;
3528 tspec_t at; 3528 tspec_t at;
3529 int narg, npar, n, i; 3529 int narg, npar, n, i;
3530 3530
3531 /* get # of args in the prototype */ 3531 /* get # of args in the prototype */
3532 npar = 0; 3532 npar = 0;
3533 for (asym = ftp->t_args; asym != NULL; asym = asym->s_next) 3533 for (asym = ftp->t_args; asym != NULL; asym = asym->s_next)
3534 npar++; 3534 npar++;
3535 3535
3536 /* get # of args in function call */ 3536 /* get # of args in function call */
3537 narg = 0; 3537 narg = 0;
3538 for (arg = args; arg != NULL; arg = arg->tn_right) 3538 for (arg = args; arg != NULL; arg = arg->tn_right)
3539 narg++; 3539 narg++;
3540 3540
3541 asym = ftp->t_args; 3541 asym = ftp->t_args;
3542 if (ftp->t_proto && npar != narg && !(ftp->t_vararg && npar < narg)) { 3542 if (ftp->t_proto && npar != narg && !(ftp->t_vararg && npar < narg)) {
3543 /* argument mismatch: %d arg%s passed, %d expected */ 3543 /* argument mismatch: %d arg%s passed, %d expected */
3544 error(150, narg, narg > 1 ? "s" : "", npar); 3544 error(150, narg, narg > 1 ? "s" : "", npar);
3545 asym = NULL; 3545 asym = NULL;
3546 } 3546 }
3547 3547
3548 for (n = 1; n <= narg; n++) { 3548 for (n = 1; n <= narg; n++) {
3549 3549
3550 /* 3550 /*
3551 * The rightmost argument is at the top of the argument 3551 * The rightmost argument is at the top of the argument
3552 * subtree. 3552 * subtree.
3553 */ 3553 */
3554 for (i = narg, arg = args; i > n; i--, arg = arg->tn_right) 3554 for (i = narg, arg = args; i > n; i--, arg = arg->tn_right)
3555 continue; 3555 continue;
3556 3556
3557 /* some things which are always not allowed */ 3557 /* some things which are always not allowed */
3558 if ((at = arg->tn_left->tn_type->t_tspec) == VOID) { 3558 if ((at = arg->tn_left->tn_type->t_tspec) == VOID) {
3559 /* void expressions may not be arguments, arg #%d */ 3559 /* void expressions may not be arguments, arg #%d */
3560 error(151, n); 3560 error(151, n);
3561 return NULL; 3561 return NULL;
3562 } else if ((at == STRUCT || at == UNION) && 3562 } else if ((at == STRUCT || at == UNION) &&
3563 is_incomplete(arg->tn_left->tn_type)) { 3563 is_incomplete(arg->tn_left->tn_type)) {
3564 /* argument cannot have unknown size, arg #%d */ 3564 /* argument cannot have unknown size, arg #%d */
3565 error(152, n); 3565 error(152, n);
3566 return NULL; 3566 return NULL;
3567 } else if (is_integer(at) && 3567 } else if (is_integer(at) &&
3568 arg->tn_left->tn_type->t_is_enum && 3568 arg->tn_left->tn_type->t_is_enum &&
3569 is_incomplete(arg->tn_left->tn_type)) { 3569 is_incomplete(arg->tn_left->tn_type)) {
3570 /* argument cannot have unknown size, arg #%d */ 3570 /* argument cannot have unknown size, arg #%d */
3571 warning(152, n); 3571 warning(152, n);
3572 } 3572 }
3573 3573
3574 /* class conversions (arg in value context) */ 3574 /* class conversions (arg in value context) */
3575 arg->tn_left = cconv(arg->tn_left); 3575 arg->tn_left = cconv(arg->tn_left);
3576 3576
3577 if (asym != NULL) { 3577 if (asym != NULL) {
3578 arg->tn_left = check_prototype_argument( 3578 arg->tn_left = check_prototype_argument(
3579 n, asym->s_type, arg->tn_left); 3579 n, asym->s_type, arg->tn_left);
3580 } else { 3580 } else {
3581 arg->tn_left = promote(NOOP, true, arg->tn_left); 3581 arg->tn_left = promote(NOOP, true, arg->tn_left);
3582 } 3582 }
3583 arg->tn_type = arg->tn_left->tn_type; 3583 arg->tn_type = arg->tn_left->tn_type;
3584 3584
3585 if (asym != NULL) 3585 if (asym != NULL)
3586 asym = asym->s_next; 3586 asym = asym->s_next;
3587 } 3587 }
3588 3588
3589 return args; 3589 return args;
3590} 3590}
3591 3591
3592/* 3592/*
3593 * Compare the type of an argument with the corresponding type of a 3593 * Compare the type of an argument with the corresponding type of a
3594 * prototype parameter. If it is a valid combination, but both types 3594 * prototype parameter. If it is a valid combination, but both types
3595 * are not the same, insert a conversion to convert the argument into 3595 * are not the same, insert a conversion to convert the argument into
3596 * the type of the parameter. 3596 * the type of the parameter.
3597 */ 3597 */
3598static tnode_t * 3598static tnode_t *
3599check_prototype_argument( 3599check_prototype_argument(
3600 int n, /* pos of arg */ 3600 int n, /* pos of arg */
3601 type_t *tp, /* expected type (from prototype) */ 3601 type_t *tp, /* expected type (from prototype) */
3602 tnode_t *tn) /* argument */ 3602 tnode_t *tn) /* argument */
3603{ 3603{
3604 tnode_t *ln; 3604 tnode_t *ln;
3605 bool dowarn; 3605 bool dowarn;
3606 3606
3607 ln = xcalloc(1, sizeof(*ln)); 3607 ln = xcalloc(1, sizeof(*ln));
3608 ln->tn_type = expr_dup_type(tp); 3608 ln->tn_type = expr_dup_type(tp);
3609 ln->tn_type->t_const = false; 3609 ln->tn_type->t_const = false;
3610 ln->tn_lvalue = true; 3610 ln->tn_lvalue = true;
3611 if (typeok(FARG, n, ln, tn)) { 3611 if (typeok(FARG, n, ln, tn)) {
3612 if (!eqtype(tp, tn->tn_type, 3612 if (!eqtype(tp, tn->tn_type,
3613 true, false, (dowarn = false, &dowarn)) || dowarn) 3613 true, false, (dowarn = false, &dowarn)) || dowarn)
3614 tn = convert(FARG, n, tp, tn); 3614 tn = convert(FARG, n, tp, tn);
3615 } 3615 }
3616 free(ln); 3616 free(ln);
3617 return tn; 3617 return tn;
3618} 3618}
3619 3619
3620/* 3620/*
3621 * Return the value of an integral constant expression. 3621 * Return the value of an integral constant expression.
3622 * If the expression is not constant or its type is not an integer 3622 * If the expression is not constant or its type is not an integer
3623 * type, an error message is printed. 3623 * type, an error message is printed.
3624 */ 3624 */
3625val_t * 3625val_t *
3626constant(tnode_t *tn, bool required) 3626constant(tnode_t *tn, bool required)
3627{ 3627{
3628 val_t *v; 3628 val_t *v;
3629 3629
3630 if (tn != NULL) 3630 if (tn != NULL)
3631 tn = cconv(tn); 3631 tn = cconv(tn);
3632 if (tn != NULL) 3632 if (tn != NULL)
3633 tn = promote(NOOP, false, tn); 3633 tn = promote(NOOP, false, tn);
3634 3634
3635 v = xcalloc(1, sizeof(*v)); 3635 v = xcalloc(1, sizeof(*v));
3636 3636
3637 if (tn == NULL) { 3637 if (tn == NULL) {
3638 lint_assert(nerr != 0); 3638 lint_assert(nerr != 0);
3639 if (dflag) 3639 if (dflag)
3640 printf("constant node is null; returning 1 instead\n"); 3640 printf("constant node is null; returning 1 instead\n");
3641 v->v_tspec = INT; 3641 v->v_tspec = INT;
3642 v->v_quad = 1; 3642 v->v_quad = 1;
3643 return v; 3643 return v;
3644 } 3644 }
3645 3645
3646 v->v_tspec = tn->tn_type->t_tspec; 3646 v->v_tspec = tn->tn_type->t_tspec;
3647 3647
3648 if (tn->tn_op == CON) { 3648 if (tn->tn_op == CON) {
3649 lint_assert(tn->tn_type->t_tspec == tn->tn_val->v_tspec); 3649 lint_assert(tn->tn_type->t_tspec == tn->tn_val->v_tspec);
3650 if (is_integer(tn->tn_val->v_tspec)) { 3650 if (is_integer(tn->tn_val->v_tspec)) {
3651 v->v_unsigned_since_c90 = 3651 v->v_unsigned_since_c90 =
3652 tn->tn_val->v_unsigned_since_c90; 3652 tn->tn_val->v_unsigned_since_c90;
3653 v->v_quad = tn->tn_val->v_quad; 3653 v->v_quad = tn->tn_val->v_quad;
3654 return v; 3654 return v;
3655 } 3655 }
3656 v->v_quad = tn->tn_val->v_ldbl; 3656 v->v_quad = tn->tn_val->v_ldbl;
3657 } else { 3657 } else {
3658 v->v_quad = 1; 3658 v->v_quad = 1;
3659 } 3659 }
3660 3660
3661 if (required) 3661 if (required)
3662 /* integral constant expression expected */ 3662 /* integral constant expression expected */
3663 error(55); 3663 error(55);
3664 else 3664 else
3665 /* variable array dimension is a C99/GCC extension */ 3665 /* variable array dimension is a C99/GCC extension */
3666 c99ism(318); 3666 c99ism(318);
3667 3667
3668 if (!is_integer(v->v_tspec)) 3668 if (!is_integer(v->v_tspec))
3669 v->v_tspec = INT; 3669 v->v_tspec = INT;
3670 3670
3671 return v; 3671 return v;
3672} 3672}
3673 3673
3674static bool 3674static bool
3675is_constcond_false(const tnode_t *tn, tspec_t t) 3675is_constcond_false(const tnode_t *tn, tspec_t t)
3676{ 3676{
3677 return (t == BOOL || t == INT) && 3677 return (t == BOOL || t == INT) &&
3678 tn->tn_op == CON && tn->tn_val->v_quad == 0; 3678 tn->tn_op == CON && tn->tn_val->v_quad == 0;
3679} 3679}
3680 3680
3681/* 3681/*
3682 * Perform some tests on expressions which can't be done in build() and 3682 * Perform some tests on expressions which can't be done in build() and
3683 * functions called by build(). These tests must be done here because 3683 * functions called by build(). These tests must be done here because
3684 * we need some information about the context in which the operations 3684 * we need some information about the context in which the operations
3685 * are performed. 3685 * are performed.
3686 * After all tests are performed and dofreeblk is true, expr() frees the 3686 * After all tests are performed and dofreeblk is true, expr() frees the
3687 * memory which is used for the expression. 3687 * memory which is used for the expression.
3688 */ 3688 */
3689void 3689void
3690expr(tnode_t *tn, bool vctx, bool tctx, bool dofreeblk, bool is_do_while) 3690expr(tnode_t *tn, bool vctx, bool tctx, bool dofreeblk, bool is_do_while)
3691{ 3691{
3692 3692
3693 if (tn == NULL) { /* in case of errors */ 3693 if (tn == NULL) { /* in case of errors */
3694 expr_free_all(); 3694 expr_free_all();
3695 return; 3695 return;
3696 } 3696 }
3697 3697
3698 /* expr() is also called in global initializations */ 3698 /* expr() is also called in global initializations */
3699 if (dcs->d_ctx != EXTERN && !is_do_while) 3699 if (dcs->d_ctx != EXTERN && !is_do_while)
3700 check_statement_reachable(); 3700 check_statement_reachable();
3701 3701
3702 check_expr_misc(tn, vctx, tctx, !tctx, false, false, false); 3702 check_expr_misc(tn, vctx, tctx, !tctx, false, false, false);
3703 if (tn->tn_op == ASSIGN) { 3703 if (tn->tn_op == ASSIGN) {
3704 if (hflag && tctx) 3704 if (hflag && tctx)
3705 /* assignment in conditional context */ 3705 /* assignment in conditional context */
3706 warning(159); 3706 warning(159);
3707 } else if (tn->tn_op == CON) { 3707 } else if (tn->tn_op == CON) {
3708 if (hflag && tctx && !constcond_flag && 3708 if (hflag && tctx && !constcond_flag &&
3709 !tn->tn_system_dependent && 3709 !tn->tn_system_dependent &&
3710 !(is_do_while && 3710 !(is_do_while &&
3711 is_constcond_false(tn, tn->tn_type->t_tspec))) 3711 is_constcond_false(tn, tn->tn_type->t_tspec)))
3712 /* constant in conditional context */ 3712 /* constant in conditional context */
3713 warning(161); 3713 warning(161);
3714 } 3714 }
3715 if (!modtab[tn->tn_op].m_has_side_effect) { 3715 if (!modtab[tn->tn_op].m_has_side_effect) {
3716 /* 3716 /*
3717 * for left operands of COMMA this warning is already 3717 * for left operands of COMMA this warning is already
3718 * printed 3718 * printed
3719 */ 3719 */
3720 if (tn->tn_op != COMMA && !vctx && !tctx) 3720 if (tn->tn_op != COMMA && !vctx && !tctx)
3721 check_null_effect(tn); 3721 check_null_effect(tn);
3722 } 3722 }
3723 if (dflag) 3723 if (dflag)
3724 display_expression(tn, 0); 3724 display_expression(tn, 0);
3725 3725
3726 /* free the tree memory */ 3726 /* free the tree memory */
3727 if (dofreeblk) 3727 if (dofreeblk)
3728 expr_free_all(); 3728 expr_free_all();
3729} 3729}
3730 3730
3731static bool 3731static bool
3732has_side_effect(const tnode_t *tn) // NOLINT(misc-no-recursion) 3732has_side_effect(const tnode_t *tn) // NOLINT(misc-no-recursion)
3733{ 3733{
3734 op_t op = tn->tn_op; 3734 op_t op = tn->tn_op;
3735 3735
3736 if (modtab[op].m_has_side_effect) 3736 if (modtab[op].m_has_side_effect)
3737 return true; 3737 return true;
3738 3738
3739 if (op == CVT && tn->tn_type->t_tspec == VOID) 3739 if (op == CVT && tn->tn_type->t_tspec == VOID)
3740 return has_side_effect(tn->tn_left); 3740 return has_side_effect(tn->tn_left);
3741 3741
3742 /* XXX: Why not has_side_effect(tn->tn_left) as well? */ 3742 /* XXX: Why not has_side_effect(tn->tn_left) as well? */
3743 if (op == LOGAND || op == LOGOR) 3743 if (op == LOGAND || op == LOGOR)
3744 return has_side_effect(tn->tn_right); 3744 return has_side_effect(tn->tn_right);
3745 3745
3746 /* XXX: Why not has_side_effect(tn->tn_left) as well? */ 3746 /* XXX: Why not has_side_effect(tn->tn_left) as well? */
3747 if (op == QUEST) 3747 if (op == QUEST)
3748 return has_side_effect(tn->tn_right); 3748 return has_side_effect(tn->tn_right);
3749 3749
3750 if (op == COLON || op == COMMA) { 3750 if (op == COLON || op == COMMA) {
3751 return has_side_effect(tn->tn_left) || 3751 return has_side_effect(tn->tn_left) ||
3752 has_side_effect(tn->tn_right); 3752 has_side_effect(tn->tn_right);
3753 } 3753 }
3754 3754
3755 return false; 3755 return false;
3756} 3756}
3757 3757
3758static void 3758static void
3759check_null_effect(const tnode_t *tn) 3759check_null_effect(const tnode_t *tn)
3760{ 3760{
3761 3761
3762 if (hflag && !has_side_effect(tn)) { 3762 if (hflag && !has_side_effect(tn)) {
3763 /* expression has null effect */ 3763 /* expression has null effect */
3764 warning(129); 3764 warning(129);
3765 } 3765 }
3766} 3766}
3767 3767
3768/* 3768/*
3769 * Dump an expression to stdout 3769 * Dump an expression to stdout
3770 * only used for debugging 3770 * only used for debugging
3771 */ 3771 */
3772static void 3772static void
3773display_expression(const tnode_t *tn, int offs) 3773display_expression(const tnode_t *tn, int offs)
3774{ 3774{
3775 uint64_t uq; 3775 uint64_t uq;
3776 3776
3777 if (tn == NULL) { 3777 if (tn == NULL) {
3778 (void)printf("%*s%s\n", offs, "", "NULL"); 3778 (void)printf("%*s%s\n", offs, "", "NULL");
3779 return; 3779 return;
3780 } 3780 }
3781 (void)printf("%*sop %s ", offs, "", op_name(tn->tn_op)); 3781 (void)printf("%*sop %s ", offs, "", op_name(tn->tn_op));
3782 3782
3783 if (tn->tn_op == NAME) { 3783 if (tn->tn_op == NAME) {
3784 (void)printf("%s: %s ", 3784 (void)printf("%s: %s ",
3785 tn->tn_sym->s_name, 3785 tn->tn_sym->s_name,
3786 storage_class_name(tn->tn_sym->s_scl)); 3786 storage_class_name(tn->tn_sym->s_scl));
3787 } else if (tn->tn_op == CON && is_floating(tn->tn_type->t_tspec)) { 3787 } else if (tn->tn_op == CON && is_floating(tn->tn_type->t_tspec)) {
3788 (void)printf("%#g ", (double)tn->tn_val->v_ldbl); 3788 (void)printf("%#g ", (double)tn->tn_val->v_ldbl);
3789 } else if (tn->tn_op == CON && is_integer(tn->tn_type->t_tspec)) { 3789 } else if (tn->tn_op == CON && is_integer(tn->tn_type->t_tspec)) {
3790 uq = tn->tn_val->v_quad; 3790 uq = tn->tn_val->v_quad;
3791 (void)printf("0x %08lx %08lx ", 3791 (void)printf("0x %08lx %08lx ",
3792 (long)(uq >> 32) & 0xffffffffl, 3792 (long)(uq >> 32) & 0xffffffffl,
3793 (long)uq & 0xffffffffl); 3793 (long)uq & 0xffffffffl);
3794 } else if (tn->tn_op == CON && tn->tn_type->t_tspec == BOOL) { 3794 } else if (tn->tn_op == CON && tn->tn_type->t_tspec == BOOL) {
3795 (void)printf("%s ", 3795 (void)printf("%s ",
3796 tn->tn_val->v_quad != 0 ? "true" : "false"); 3796 tn->tn_val->v_quad != 0 ? "true" : "false");
3797 } else if (tn->tn_op == CON) { 3797 } else if (tn->tn_op == CON) {
3798 lint_assert(tn->tn_type->t_tspec == PTR); 3798 lint_assert(tn->tn_type->t_tspec == PTR);
3799 (void)printf("0x%0*lx ", (int)(sizeof(void *) * CHAR_BIT / 4), 3799 (void)printf("0x%0*lx ", (int)(sizeof(void *) * CHAR_BIT / 4),
3800 (u_long)tn->tn_val->v_quad); 3800 (u_long)tn->tn_val->v_quad);
3801 } else if (tn->tn_op == STRING) { 3801 } else if (tn->tn_op == STRING) {
3802 if (tn->tn_string->st_tspec == CHAR) { 3802 if (tn->tn_string->st_tspec == CHAR) {
3803 (void)printf("\"%s\"", tn->tn_string->st_cp); 3803 (void)printf("\"%s\"", tn->tn_string->st_cp);
3804 } else { 3804 } else {
3805 char *s; 3805 char *s;
3806 size_t n; 3806 size_t n;
3807 n = MB_CUR_MAX * (tn->tn_string->st_len + 1); 3807 n = MB_CUR_MAX * (tn->tn_string->st_len + 1);
3808 s = xmalloc(n); 3808 s = xmalloc(n);
3809 (void)wcstombs(s, tn->tn_string->st_wcp, n); 3809 (void)wcstombs(s, tn->tn_string->st_wcp, n);
3810 (void)printf("L\"%s\"", s); 3810 (void)printf("L\"%s\"", s);
3811 free(s); 3811 free(s);
3812 } 3812 }
3813 (void)printf(" "); 3813 (void)printf(" ");
3814 } else if (tn->tn_op == FSEL) { 3814 } else if (tn->tn_op == FSEL) {
3815 (void)printf("o=%d, l=%d ", tn->tn_type->t_foffs, 3815 (void)printf("o=%d, l=%d ", tn->tn_type->t_foffs,
3816 tn->tn_type->t_flen); 3816 tn->tn_type->t_flen);
3817 } 3817 }
3818 (void)printf("%s\n", ttos(tn->tn_type)); 3818 (void)printf("%s\n", type_name(tn->tn_type));
3819 if (tn->tn_op == NAME || tn->tn_op == CON || tn->tn_op == STRING) 3819 if (tn->tn_op == NAME || tn->tn_op == CON || tn->tn_op == STRING)
3820 return; 3820 return;
3821 display_expression(tn->tn_left, offs + 2); 3821 display_expression(tn->tn_left, offs + 2);
3822 if (modtab[tn->tn_op].m_binary || 3822 if (modtab[tn->tn_op].m_binary ||
3823 (tn->tn_op == PUSH && tn->tn_right != NULL)) { 3823 (tn->tn_op == PUSH && tn->tn_right != NULL)) {
3824 display_expression(tn->tn_right, offs + 2); 3824 display_expression(tn->tn_right, offs + 2);
3825 } 3825 }
3826} 3826}
3827 3827
3828/* 3828/*
3829 * Called by expr() to recursively perform some tests. 3829 * Called by expr() to recursively perform some tests.
3830 */ 3830 */
3831/* ARGSUSED */ 3831/* ARGSUSED */
3832void 3832void
3833check_expr_misc(const tnode_t *tn, bool vctx, bool tctx, 3833check_expr_misc(const tnode_t *tn, bool vctx, bool tctx,
3834 bool eqwarn, bool fcall, bool rvdisc, bool szof) 3834 bool eqwarn, bool fcall, bool rvdisc, bool szof)
3835{ 3835{
3836 tnode_t *ln, *rn; 3836 tnode_t *ln, *rn;
3837 const mod_t *mp; 3837 const mod_t *mp;
3838 op_t op; 3838 op_t op;
3839 scl_t sc; 3839 scl_t sc;
3840 dinfo_t *di; 3840 dinfo_t *di;
3841 3841
3842 if (tn == NULL) 3842 if (tn == NULL)
3843 return; 3843 return;
3844 3844
3845 ln = tn->tn_left; 3845 ln = tn->tn_left;
3846 rn = tn->tn_right; 3846 rn = tn->tn_right;
3847 mp = &modtab[op = tn->tn_op]; 3847 mp = &modtab[op = tn->tn_op];
3848 3848
3849 switch (op) { 3849 switch (op) {
3850 case ADDR: 3850 case ADDR:
3851 /* XXX: Taking warn_about_unreachable into account here feels wrong. */ 3851 /* XXX: Taking warn_about_unreachable into account here feels wrong. */
3852 if (ln->tn_op == NAME && (reached || !warn_about_unreachable)) { 3852 if (ln->tn_op == NAME && (reached || !warn_about_unreachable)) {
3853 if (!szof) 3853 if (!szof)
3854 mark_as_set(ln->tn_sym); 3854 mark_as_set(ln->tn_sym);
3855 mark_as_used(ln->tn_sym, fcall, szof); 3855 mark_as_used(ln->tn_sym, fcall, szof);
3856 } 3856 }
3857 if (ln->tn_op == INDIR && ln->tn_left->tn_op == PLUS) 3857 if (ln->tn_op == INDIR && ln->tn_left->tn_op == PLUS)
3858 /* check the range of array indices */ 3858 /* check the range of array indices */
3859 check_array_index(ln->tn_left, true); 3859 check_array_index(ln->tn_left, true);
3860 break; 3860 break;
3861 case LOAD: 3861 case LOAD:
3862 if (ln->tn_op == INDIR && ln->tn_left->tn_op == PLUS) 3862 if (ln->tn_op == INDIR && ln->tn_left->tn_op == PLUS)
3863 /* check the range of array indices */ 3863 /* check the range of array indices */
3864 check_array_index(ln->tn_left, false); 3864 check_array_index(ln->tn_left, false);
3865 /* FALLTHROUGH */ 3865 /* FALLTHROUGH */
3866 case PUSH: 3866 case PUSH:
3867 case INCBEF: 3867 case INCBEF:
3868 case DECBEF: 3868 case DECBEF:
3869 case INCAFT: 3869 case INCAFT:
3870 case DECAFT: 3870 case DECAFT:
3871 case ADDASS: 3871 case ADDASS:
3872 case SUBASS: 3872 case SUBASS:
3873 case MULASS: 3873 case MULASS:
3874 case DIVASS: 3874 case DIVASS:
3875 case MODASS: 3875 case MODASS:
3876 case ANDASS: 3876 case ANDASS:
3877 case ORASS: 3877 case ORASS:
3878 case XORASS: 3878 case XORASS:
3879 case SHLASS: 3879 case SHLASS:
3880 case SHRASS: 3880 case SHRASS:
3881 case REAL: 3881 case REAL:
3882 case IMAG: 3882 case IMAG:
3883 /* XXX: Taking warn_about_unreachable into account here feels wrong. */ 3883 /* XXX: Taking warn_about_unreachable into account here feels wrong. */
3884 if (ln->tn_op == NAME && (reached || !warn_about_unreachable)) { 3884 if (ln->tn_op == NAME && (reached || !warn_about_unreachable)) {
3885 sc = ln->tn_sym->s_scl; 3885 sc = ln->tn_sym->s_scl;
3886 /* 3886 /*
3887 * Look if there was a asm statement in one of the 3887 * Look if there was a asm statement in one of the
3888 * compound statements we are in. If not, we don't 3888 * compound statements we are in. If not, we don't
3889 * print a warning. 3889 * print a warning.
3890 */ 3890 */
3891 for (di = dcs; di != NULL; di = di->d_next) { 3891 for (di = dcs; di != NULL; di = di->d_next) {
3892 if (di->d_asm) 3892 if (di->d_asm)
3893 break; 3893 break;
3894 } 3894 }
3895 if (sc != EXTERN && sc != STATIC && 3895 if (sc != EXTERN && sc != STATIC &&
3896 !ln->tn_sym->s_set && !szof && di == NULL) { 3896 !ln->tn_sym->s_set && !szof && di == NULL) {
3897 /* %s may be used before set */ 3897 /* %s may be used before set */
3898 warning(158, ln->tn_sym->s_name); 3898 warning(158, ln->tn_sym->s_name);
3899 mark_as_set(ln->tn_sym); 3899 mark_as_set(ln->tn_sym);
3900 } 3900 }
3901 mark_as_used(ln->tn_sym, false, false); 3901 mark_as_used(ln->tn_sym, false, false);
3902 } 3902 }
3903 break; 3903 break;
3904 case ASSIGN: 3904 case ASSIGN:
3905 /* XXX: Taking warn_about_unreachable into account here feels wrong. */ 3905 /* XXX: Taking warn_about_unreachable into account here feels wrong. */
3906 if (ln->tn_op == NAME && !szof && (reached || !warn_about_unreachable)) { 3906 if (ln->tn_op == NAME && !szof && (reached || !warn_about_unreachable)) {
3907 mark_as_set(ln->tn_sym); 3907 mark_as_set(ln->tn_sym);
3908 if (ln->tn_sym->s_scl == EXTERN) 3908 if (ln->tn_sym->s_scl == EXTERN)
3909 outusg(ln->tn_sym); 3909 outusg(ln->tn_sym);
3910 } 3910 }
3911 if (ln->tn_op == INDIR && ln->tn_left->tn_op == PLUS) 3911 if (ln->tn_op == INDIR && ln->tn_left->tn_op == PLUS)
3912 /* check the range of array indices */ 3912 /* check the range of array indices */
3913 check_array_index(ln->tn_left, false); 3913 check_array_index(ln->tn_left, false);
3914 break; 3914 break;
3915 case CALL: 3915 case CALL:
3916 lint_assert(ln->tn_op == ADDR); 3916 lint_assert(ln->tn_op == ADDR);
3917 lint_assert(ln->tn_left->tn_op == NAME); 3917 lint_assert(ln->tn_left->tn_op == NAME);
3918 if (!szof) 3918 if (!szof)
3919 outcall(tn, vctx || tctx, rvdisc); 3919 outcall(tn, vctx || tctx, rvdisc);
3920 break; 3920 break;
3921 case EQ: 3921 case EQ:
3922 if (hflag && eqwarn) 3922 if (hflag && eqwarn)
3923 /* operator '==' found where '=' was expected */ 3923 /* operator '==' found where '=' was expected */
3924 warning(160); 3924 warning(160);
3925 break; 3925 break;
3926 case CON: 3926 case CON:
3927 case NAME: 3927 case NAME:
3928 case STRING: 3928 case STRING:
3929 return; 3929 return;
3930 /* LINTED206: (enumeration values not handled in switch) */ 3930 /* LINTED206: (enumeration values not handled in switch) */
3931 case BITOR: 3931 case BITOR:
3932 case BITXOR: 3932 case BITXOR:
3933 case NE: 3933 case NE:
3934 case GE: 3934 case GE:
3935 case GT: 3935 case GT:
3936 case LE: 3936 case LE:
3937 case LT: 3937 case LT:
3938 case SHR: 3938 case SHR:
3939 case SHL: 3939 case SHL:
3940 case MINUS: 3940 case MINUS:
3941 case PLUS: 3941 case PLUS:
3942 case MOD: 3942 case MOD:
3943 case DIV: 3943 case DIV:
3944 case MULT: 3944 case MULT:
3945 case INDIR: 3945 case INDIR:
3946 case UMINUS: 3946 case UMINUS:
3947 case UPLUS: 3947 case UPLUS:
3948 case DEC: 3948 case DEC:
3949 case INC: 3949 case INC:
3950 case COMPL: 3950 case COMPL:
3951 case NOT: 3951 case NOT:
3952 case POINT: 3952 case POINT:
3953 case ARROW: 3953 case ARROW:
3954 case NOOP: 3954 case NOOP:
3955 case BITAND: 3955 case BITAND:
3956 case FARG: 3956 case FARG:
3957 case CASE: 3957 case CASE:
3958 case INIT: 3958 case INIT:
3959 case RETURN: 3959 case RETURN:
3960 case ICALL: 3960 case ICALL:
3961 case CVT: 3961 case CVT:
3962 case COMMA: 3962 case COMMA:
3963 case FSEL: 3963 case FSEL:
3964 case COLON: 3964 case COLON:
3965 case QUEST: 3965 case QUEST:
3966 case LOGOR: 3966 case LOGOR:
3967 case LOGAND: 3967 case LOGAND:
3968 break; 3968 break;
3969 } 3969 }
3970 3970
3971 bool cvctx = mp->m_left_value_context; 3971 bool cvctx = mp->m_left_value_context;
3972 bool ctctx = mp->m_left_test_context; 3972 bool ctctx = mp->m_left_test_context;
3973 bool eq = mp->m_warn_if_operand_eq && 3973 bool eq = mp->m_warn_if_operand_eq &&
3974 !ln->tn_parenthesized && 3974 !ln->tn_parenthesized &&
3975 rn != NULL && !rn->tn_parenthesized; 3975 rn != NULL && !rn->tn_parenthesized;
3976 3976
3977 /* 3977 /*
3978 * values of operands of ':' are not used if the type of at least 3978 * values of operands of ':' are not used if the type of at least
3979 * one of the operands (for gcc compatibility) is void 3979 * one of the operands (for gcc compatibility) is void
3980 * XXX test/value context of QUEST should probably be used as 3980 * XXX test/value context of QUEST should probably be used as
3981 * context for both operands of COLON 3981 * context for both operands of COLON
3982 */ 3982 */
3983 if (op == COLON && tn->tn_type->t_tspec == VOID) 3983 if (op == COLON && tn->tn_type->t_tspec == VOID)
3984 cvctx = ctctx = false; 3984 cvctx = ctctx = false;
3985 bool discard = op == CVT && tn->tn_type->t_tspec == VOID; 3985 bool discard = op == CVT && tn->tn_type->t_tspec == VOID;
3986 check_expr_misc(ln, cvctx, ctctx, eq, op == CALL, discard, szof); 3986 check_expr_misc(ln, cvctx, ctctx, eq, op == CALL, discard, szof);
3987 3987
3988 switch (op) { 3988 switch (op) {
3989 case PUSH: 3989 case PUSH:
3990 if (rn != NULL) 3990 if (rn != NULL)
3991 check_expr_misc(rn, false, false, eq, false, false, 3991 check_expr_misc(rn, false, false, eq, false, false,
3992 szof); 3992 szof);
3993 break; 3993 break;
3994 case LOGAND: 3994 case LOGAND:
3995 case LOGOR: 3995 case LOGOR:
3996 check_expr_misc(rn, false, true, eq, false, false, szof); 3996 check_expr_misc(rn, false, true, eq, false, false, szof);
3997 break; 3997 break;
3998 case COLON: 3998 case COLON:
3999 check_expr_misc(rn, cvctx, ctctx, eq, false, false, szof); 3999 check_expr_misc(rn, cvctx, ctctx, eq, false, false, szof);
4000 break; 4000 break;
4001 case COMMA: 4001 case COMMA:
4002 check_expr_misc(rn, vctx, tctx, eq, false, false, szof); 4002 check_expr_misc(rn, vctx, tctx, eq, false, false, szof);
4003 break; 4003 break;
4004 default: 4004 default:
4005 if (mp->m_binary) 4005 if (mp->m_binary)
4006 check_expr_misc(rn, true, false, eq, false, false, 4006 check_expr_misc(rn, true, false, eq, false, false,
4007 szof); 4007 szof);
4008 break; 4008 break;
4009 } 4009 }
4010 4010
4011} 4011}
4012 4012
4013/* 4013/*
4014 * Checks the range of array indices, if possible. 4014 * Checks the range of array indices, if possible.
4015 * amper is set if only the address of the element is used. This 4015 * amper is set if only the address of the element is used. This
4016 * means that the index is allowed to refer to the first element 4016 * means that the index is allowed to refer to the first element
4017 * after the array. 4017 * after the array.
4018 */ 4018 */
4019static void 4019static void
4020check_array_index(tnode_t *tn, bool amper) 4020check_array_index(tnode_t *tn, bool amper)
4021{ 4021{
4022 int dim; 4022 int dim;
4023 tnode_t *ln, *rn; 4023 tnode_t *ln, *rn;
4024 int elsz; 4024 int elsz;
4025 int64_t con; 4025 int64_t con;
4026 4026
4027 ln = tn->tn_left; 4027 ln = tn->tn_left;
4028 rn = tn->tn_right; 4028 rn = tn->tn_right;
4029 4029
4030 /* We can only check constant indices. */ 4030 /* We can only check constant indices. */
4031 if (rn->tn_op != CON) 4031 if (rn->tn_op != CON)
4032 return; 4032 return;
4033 4033
4034 /* Return if the left node does not stem from an array. */ 4034 /* Return if the left node does not stem from an array. */
4035 if (ln->tn_op != ADDR) 4035 if (ln->tn_op != ADDR)
4036 return; 4036 return;
4037 if (ln->tn_left->tn_op != STRING && ln->tn_left->tn_op != NAME) 4037 if (ln->tn_left->tn_op != STRING && ln->tn_left->tn_op != NAME)
4038 return; 4038 return;
4039 if (ln->tn_left->tn_type->t_tspec != ARRAY) 4039 if (ln->tn_left->tn_type->t_tspec != ARRAY)
4040 return; 4040 return;
4041 4041
4042 /* 4042 /*
4043 * For incomplete array types, we can print a warning only if 4043 * For incomplete array types, we can print a warning only if
4044 * the index is negative. 4044 * the index is negative.
4045 */ 4045 */
4046 if (is_incomplete(ln->tn_left->tn_type) && rn->tn_val->v_quad >= 0) 4046 if (is_incomplete(ln->tn_left->tn_type) && rn->tn_val->v_quad >= 0)
4047 return; 4047 return;
4048 4048
4049 /* Get the size of one array element */ 4049 /* Get the size of one array element */
4050 if ((elsz = length(ln->tn_type->t_subt, NULL)) == 0) 4050 if ((elsz = length(ln->tn_type->t_subt, NULL)) == 0)
4051 return; 4051 return;
4052 elsz /= CHAR_SIZE; 4052 elsz /= CHAR_SIZE;
4053 4053
4054 /* Change the unit of the index from bytes to element size. */ 4054 /* Change the unit of the index from bytes to element size. */
4055 if (is_uinteger(rn->tn_type->t_tspec)) { 4055 if (is_uinteger(rn->tn_type->t_tspec)) {
4056 con = (uint64_t)rn->tn_val->v_quad / elsz; 4056 con = (uint64_t)rn->tn_val->v_quad / elsz;
4057 } else { 4057 } else {
4058 con = rn->tn_val->v_quad / elsz; 4058 con = rn->tn_val->v_quad / elsz;
4059 } 4059 }
4060 4060
4061 dim = ln->tn_left->tn_type->t_dim + (amper ? 1 : 0); 4061 dim = ln->tn_left->tn_type->t_dim + (amper ? 1 : 0);
4062 4062
4063 if (!is_uinteger(rn->tn_type->t_tspec) && con < 0) { 4063 if (!is_uinteger(rn->tn_type->t_tspec) && con < 0) {
4064 /* array subscript cannot be negative: %ld */ 4064 /* array subscript cannot be negative: %ld */
4065 warning(167, (long)con); 4065 warning(167, (long)con);
4066 } else if (dim > 0 && (uint64_t)con >= (uint64_t)dim) { 4066 } else if (dim > 0 && (uint64_t)con >= (uint64_t)dim) {
4067 /* array subscript cannot be > %d: %ld */ 4067 /* array subscript cannot be > %d: %ld */
4068 warning(168, dim - 1, (long)con); 4068 warning(168, dim - 1, (long)con);
4069 } 4069 }
4070} 4070}
4071 4071
4072/* 4072/*
4073 * Check for ordered comparisons of unsigned values with 0. 4073 * Check for ordered comparisons of unsigned values with 0.
4074 */ 4074 */
4075static void 4075static void
4076check_integer_comparison(op_t op, tnode_t *ln, tnode_t *rn) 4076check_integer_comparison(op_t op, tnode_t *ln, tnode_t *rn)
4077{ 4077{
4078 tspec_t lt, rt; 4078 tspec_t lt, rt;
4079 4079
4080 lt = ln->tn_type->t_tspec; 4080 lt = ln->tn_type->t_tspec;
4081 rt = rn->tn_type->t_tspec; 4081 rt = rn->tn_type->t_tspec;
4082 4082
4083 if (ln->tn_op != CON && rn->tn_op != CON) 4083 if (ln->tn_op != CON && rn->tn_op != CON)
4084 return; 4084 return;
4085 4085
4086 if (!is_integer(lt) || !is_integer(rt)) 4086 if (!is_integer(lt) || !is_integer(rt))
4087 return; 4087 return;
4088 4088
4089 if ((hflag || pflag) && lt == CHAR && rn->tn_op == CON && 4089 if ((hflag || pflag) && lt == CHAR && rn->tn_op == CON &&
4090 (rn->tn_val->v_quad < 0 || 4090 (rn->tn_val->v_quad < 0 ||
4091 rn->tn_val->v_quad > (int)~(~0U << (CHAR_SIZE - 1)))) { 4091 rn->tn_val->v_quad > (int)~(~0U << (CHAR_SIZE - 1)))) {
4092 /* nonportable character comparison, op %s */ 4092 /* nonportable character comparison, op %s */
4093 warning(230, op_name(op)); 4093 warning(230, op_name(op));
4094 return; 4094 return;
4095 } 4095 }
4096 if ((hflag || pflag) && rt == CHAR && ln->tn_op == CON && 4096 if ((hflag || pflag) && rt == CHAR && ln->tn_op == CON &&
4097 (ln->tn_val->v_quad < 0 || 4097 (ln->tn_val->v_quad < 0 ||
4098 ln->tn_val->v_quad > (int)~(~0U << (CHAR_SIZE - 1)))) { 4098 ln->tn_val->v_quad > (int)~(~0U << (CHAR_SIZE - 1)))) {
4099 /* nonportable character comparison, op %s */ 4099 /* nonportable character comparison, op %s */
4100 warning(230, op_name(op)); 4100 warning(230, op_name(op));
4101 return; 4101 return;
4102 } 4102 }
4103 if (is_uinteger(lt) && !is_uinteger(rt) && 4103 if (is_uinteger(lt) && !is_uinteger(rt) &&
4104 rn->tn_op == CON && rn->tn_val->v_quad <= 0) { 4104 rn->tn_op == CON && rn->tn_val->v_quad <= 0) {
4105 if (rn->tn_val->v_quad < 0) { 4105 if (rn->tn_val->v_quad < 0) {
4106 /* comparison of %s with %s, op %s */ 4106 /* comparison of %s with %s, op %s */
4107 warning(162, type_name(ln->tn_type), 4107 warning(162, type_name(ln->tn_type),
4108 "negative constant", op_name(op)); 4108 "negative constant", op_name(op));
4109 } else if (op == LT || op == GE || (hflag && op == LE)) { 4109 } else if (op == LT || op == GE || (hflag && op == LE)) {
4110 /* comparison of %s with %s, op %s */ 4110 /* comparison of %s with %s, op %s */
4111 warning(162, type_name(ln->tn_type), "0", op_name(op)); 4111 warning(162, type_name(ln->tn_type), "0", op_name(op));
4112 } 4112 }
4113 return; 4113 return;
4114 } 4114 }
4115 if (is_uinteger(rt) && !is_uinteger(lt) && 4115 if (is_uinteger(rt) && !is_uinteger(lt) &&
4116 ln->tn_op == CON && ln->tn_val->v_quad <= 0) { 4116 ln->tn_op == CON && ln->tn_val->v_quad <= 0) {
4117 if (ln->tn_val->v_quad < 0) { 4117 if (ln->tn_val->v_quad < 0) {
4118 /* comparison of %s with %s, op %s */ 4118 /* comparison of %s with %s, op %s */
4119 warning(162, "negative constant", 4119 warning(162, "negative constant",
4120 type_name(rn->tn_type), op_name(op)); 4120 type_name(rn->tn_type), op_name(op));
4121 } else if (op == GT || op == LE || (hflag && op == GE)) { 4121 } else if (op == GT || op == LE || (hflag && op == GE)) {
4122 /* comparison of %s with %s, op %s */ 4122 /* comparison of %s with %s, op %s */
4123 warning(162, "0", type_name(rn->tn_type), op_name(op)); 4123 warning(162, "0", type_name(rn->tn_type), op_name(op));
4124 } 4124 }
4125 return; 4125 return;
4126 } 4126 }
4127} 4127}
4128 4128
4129/* 4129/*
4130 * Return whether the expression can be used for static initialization. 4130 * Return whether the expression can be used for static initialization.
4131 * 4131 *
4132 * Constant initialization expressions must be constant or an address 4132 * Constant initialization expressions must be constant or an address
4133 * of a static object with an optional offset. In the first case, 4133 * of a static object with an optional offset. In the first case,
4134 * the result is returned in *offsp. In the second case, the static 4134 * the result is returned in *offsp. In the second case, the static
4135 * object is returned in *symp and the offset in *offsp. 4135 * object is returned in *symp and the offset in *offsp.
4136 * 4136 *
4137 * The expression can consist of PLUS, MINUS, ADDR, NAME, STRING and 4137 * The expression can consist of PLUS, MINUS, ADDR, NAME, STRING and
4138 * CON. Type conversions are allowed if they do not change binary 4138 * CON. Type conversions are allowed if they do not change binary
4139 * representation (including width). 4139 * representation (including width).
4140 * 4140 *
4141 * C99 6.6 "Constant expressions" 4141 * C99 6.6 "Constant expressions"
4142 * C99 6.7.8p4 restricts initializers for static storage duration 4142 * C99 6.7.8p4 restricts initializers for static storage duration
4143 */ 4143 */
4144bool 4144bool
4145constant_addr(const tnode_t *tn, const sym_t **symp, ptrdiff_t *offsp) 4145constant_addr(const tnode_t *tn, const sym_t **symp, ptrdiff_t *offsp)
4146{ 4146{
4147 const sym_t *sym; 4147 const sym_t *sym;
4148 ptrdiff_t offs1, offs2; 4148 ptrdiff_t offs1, offs2;
4149 tspec_t t, ot; 4149 tspec_t t, ot;
4150 4150
4151 switch (tn->tn_op) { 4151 switch (tn->tn_op) {
4152 case MINUS: 4152 case MINUS:
4153 if (tn->tn_right->tn_op == CVT) 4153 if (tn->tn_right->tn_op == CVT)
4154 return constant_addr(tn->tn_right, symp, offsp); 4154 return constant_addr(tn->tn_right, symp, offsp);
4155 else if (tn->tn_right->tn_op != CON) 4155 else if (tn->tn_right->tn_op != CON)
4156 return false; 4156 return false;
4157 /* FALLTHROUGH */ 4157 /* FALLTHROUGH */
4158 case PLUS: 4158 case PLUS:
4159 offs1 = offs2 = 0; 4159 offs1 = offs2 = 0;
4160 if (tn->tn_left->tn_op == CON) { 4160 if (tn->tn_left->tn_op == CON) {
4161 offs1 = (ptrdiff_t)tn->tn_left->tn_val->v_quad; 4161 offs1 = (ptrdiff_t)tn->tn_left->tn_val->v_quad;
4162 if (!constant_addr(tn->tn_right, &sym, &offs2)) 4162 if (!constant_addr(tn->tn_right, &sym, &offs2))
4163 return false; 4163 return false;
4164 } else if (tn->tn_right->tn_op == CON) { 4164 } else if (tn->tn_right->tn_op == CON) {
4165 offs2 = (ptrdiff_t)tn->tn_right->tn_val->v_quad; 4165 offs2 = (ptrdiff_t)tn->tn_right->tn_val->v_quad;
4166 if (tn->tn_op == MINUS) 4166 if (tn->tn_op == MINUS)
4167 offs2 = -offs2; 4167 offs2 = -offs2;
4168 if (!constant_addr(tn->tn_left, &sym, &offs1)) 4168 if (!constant_addr(tn->tn_left, &sym, &offs1))
4169 return false; 4169 return false;
4170 } else { 4170 } else {
4171 return false; 4171 return false;
4172 } 4172 }
4173 *symp = sym; 4173 *symp = sym;
4174 *offsp = offs1 + offs2; 4174 *offsp = offs1 + offs2;
4175 return true; 4175 return true;
4176 case ADDR: 4176 case ADDR:
4177 if (tn->tn_left->tn_op == NAME) { 4177 if (tn->tn_left->tn_op == NAME) {
4178 *symp = tn->tn_left->tn_sym; 4178 *symp = tn->tn_left->tn_sym;
4179 *offsp = 0; 4179 *offsp = 0;
4180 return true; 4180 return true;
4181 } else { 4181 } else {
4182 /* 4182 /*
4183 * If this would be the front end of a compiler we 4183 * If this would be the front end of a compiler we
4184 * would return a label instead of 0, at least if 4184 * would return a label instead of 0, at least if
4185 * 'tn->tn_left->tn_op == STRING'. 4185 * 'tn->tn_left->tn_op == STRING'.
4186 */ 4186 */
4187 *symp = NULL; 4187 *symp = NULL;
4188 *offsp = 0; 4188 *offsp = 0;
4189 return true; 4189 return true;
4190 } 4190 }
4191 case CVT: 4191 case CVT:
4192 t = tn->tn_type->t_tspec; 4192 t = tn->tn_type->t_tspec;
4193 ot = tn->tn_left->tn_type->t_tspec; 4193 ot = tn->tn_left->tn_type->t_tspec;
4194 if ((!is_integer(t) && t != PTR) || 4194 if ((!is_integer(t) && t != PTR) ||
4195 (!is_integer(ot) && ot != PTR)) { 4195 (!is_integer(ot) && ot != PTR)) {
4196 return false; 4196 return false;
4197 } 4197 }
4198#ifdef notdef 4198#ifdef notdef
4199 /* 4199 /*
4200 * consider: 4200 * consider:
4201 * struct foo { 4201 * struct foo {
4202 * unsigned char a; 4202 * unsigned char a;
4203 * } f = { 4203 * } f = {
4204 * (u_char)(u_long)(&(((struct foo *)0)->a)) 4204 * (u_char)(u_long)(&(((struct foo *)0)->a))
4205 * }; 4205 * };
4206 * since psize(u_long) != psize(u_char) this fails. 4206 * since psize(u_long) != psize(u_char) this fails.
4207 */ 4207 */
4208 else if (psize(t) != psize(ot)) 4208 else if (psize(t) != psize(ot))
4209 return -1; 4209 return -1;
4210#endif 4210#endif
4211 return constant_addr(tn->tn_left, symp, offsp); 4211 return constant_addr(tn->tn_left, symp, offsp);
4212 default: 4212 default:
4213 return false; 4213 return false;
4214 } 4214 }
4215} 4215}
4216 4216
4217/* 4217/*
4218 * Concatenate two string constants. 4218 * Concatenate two string constants.
4219 */ 4219 */
4220strg_t * 4220strg_t *
4221cat_strings(strg_t *strg1, strg_t *strg2) 4221cat_strings(strg_t *strg1, strg_t *strg2)
4222{ 4222{
4223 size_t len1, len2, len; 4223 size_t len1, len2, len;
4224 4224
4225 if (strg1->st_tspec != strg2->st_tspec) { 4225 if (strg1->st_tspec != strg2->st_tspec) {
4226 /* cannot concatenate wide and regular string literals */ 4226 /* cannot concatenate wide and regular string literals */
4227 error(292); 4227 error(292);
4228 return strg1; 4228 return strg1;
4229 } 4229 }
4230 4230
4231 len1 = strg1->st_len; 4231 len1 = strg1->st_len;
4232 len2 = strg2->st_len + 1; /* + NUL */ 4232 len2 = strg2->st_len + 1; /* + NUL */
4233 len = len1 + len2; 4233 len = len1 + len2;
4234 4234
4235#define COPY(F) \ 4235#define COPY(F) \
4236 do { \ 4236 do { \
4237 strg1->F = xrealloc(strg1->F, len * sizeof(*strg1->F)); \ 4237 strg1->F = xrealloc(strg1->F, len * sizeof(*strg1->F)); \
4238 (void)memcpy(strg1->F + len1, strg2->F, len2 * sizeof(*strg1->F)); \ 4238 (void)memcpy(strg1->F + len1, strg2->F, len2 * sizeof(*strg1->F)); \
4239 free(strg2->F); \ 4239 free(strg2->F); \
4240 } while (false) 4240 } while (false)
4241 4241
4242 if (strg1->st_tspec == CHAR) 4242 if (strg1->st_tspec == CHAR)
4243 COPY(st_cp); 4243 COPY(st_cp);
4244 else 4244 else
4245 COPY(st_wcp); 4245 COPY(st_wcp);
4246 4246
4247 strg1->st_len = len - 1; /* - NUL */ 4247 strg1->st_len = len - 1; /* - NUL */
4248 free(strg2); 4248 free(strg2);
4249 4249
4250 return strg1; 4250 return strg1;
4251} 4251}
4252 4252
4253static bool 4253static bool
4254is_confusing_precedence(op_t op, op_t lop, bool lparen, op_t rop, bool rparen) 4254is_confusing_precedence(op_t op, op_t lop, bool lparen, op_t rop, bool rparen)
4255{ 4255{
4256 4256
4257 if (op == SHL || op == SHR) { 4257 if (op == SHL || op == SHR) {
4258 if (!lparen && (lop == PLUS || lop == MINUS)) 4258 if (!lparen && (lop == PLUS || lop == MINUS))
4259 return true; 4259 return true;
4260 if (!rparen && (rop == PLUS || rop == MINUS)) 4260 if (!rparen && (rop == PLUS || rop == MINUS))
4261 return true; 4261 return true;
4262 return false; 4262 return false;
4263 } 4263 }
4264 4264
4265 if (op == LOGOR) { 4265 if (op == LOGOR) {
4266 if (!lparen && lop == LOGAND) 4266 if (!lparen && lop == LOGAND)
4267 return true; 4267 return true;
4268 if (!rparen && rop == LOGAND) 4268 if (!rparen && rop == LOGAND)
4269 return true; 4269 return true;
4270 return false; 4270 return false;
4271 } 4271 }
4272 4272
4273 lint_assert(op == BITAND || op == BITXOR || op == BITOR); 4273 lint_assert(op == BITAND || op == BITXOR || op == BITOR);
4274 if (!lparen && lop != op) { 4274 if (!lparen && lop != op) {
4275 if (lop == PLUS || lop == MINUS) 4275 if (lop == PLUS || lop == MINUS)
4276 return true; 4276 return true;
4277 if (lop == BITAND || lop == BITXOR) 4277 if (lop == BITAND || lop == BITXOR)
4278 return true; 4278 return true;
4279 } 4279 }
4280 if (!rparen && rop != op) { 4280 if (!rparen && rop != op) {
4281 if (rop == PLUS || rop == MINUS) 4281 if (rop == PLUS || rop == MINUS)
4282 return true; 4282 return true;
4283 if (rop == BITAND || rop == BITXOR) 4283 if (rop == BITAND || rop == BITXOR)
4284 return true; 4284 return true;
4285 } 4285 }
4286 return false; 4286 return false;
4287} 4287}
4288 4288
4289/* 4289/*
4290 * Print a warning if the given node has operands which should be 4290 * Print a warning if the given node has operands which should be
4291 * parenthesized. 4291 * parenthesized.
4292 * 4292 *
4293 * XXX Does not work if an operand is a constant expression. Constant 4293 * XXX Does not work if an operand is a constant expression. Constant
4294 * expressions are already folded. 4294 * expressions are already folded.
4295 */ 4295 */
4296static void 4296static void
4297check_precedence_confusion(tnode_t *tn) 4297check_precedence_confusion(tnode_t *tn)
4298{ 4298{
4299 tnode_t *ln, *rn; 4299 tnode_t *ln, *rn;
4300 4300
4301 if (!hflag) 4301 if (!hflag)
4302 return; 4302 return;
4303 4303
4304 debug_node(tn, 0); 4304 debug_node(tn, 0);
4305 4305
4306 lint_assert(modtab[tn->tn_op].m_binary); 4306 lint_assert(modtab[tn->tn_op].m_binary);
4307 for (ln = tn->tn_left; ln->tn_op == CVT; ln = ln->tn_left) 4307 for (ln = tn->tn_left; ln->tn_op == CVT; ln = ln->tn_left)
4308 continue; 4308 continue;
4309 for (rn = tn->tn_right; rn->tn_op == CVT; rn = rn->tn_left) 4309 for (rn = tn->tn_right; rn->tn_op == CVT; rn = rn->tn_left)
4310 continue; 4310 continue;
4311 4311
4312 if (is_confusing_precedence(tn->tn_op, 4312 if (is_confusing_precedence(tn->tn_op,
4313 ln->tn_op, ln->tn_parenthesized, 4313 ln->tn_op, ln->tn_parenthesized,
4314 rn->tn_op, rn->tn_parenthesized)) { 4314 rn->tn_op, rn->tn_parenthesized)) {
4315 /* precedence confusion possible: parenthesize! */ 4315 /* precedence confusion possible: parenthesize! */
4316 warning(169); 4316 warning(169);
4317 } 4317 }
4318} 4318}