Tue Apr 11 19:02:19 2023 UTC ()
lint: condense code

No functional change.


(rillig)
diff -r1.64 -r1.65 src/usr.bin/xlint/lint1/mem1.c
diff -r1.508 -r1.509 src/usr.bin/xlint/lint1/tree.c

cvs diff -r1.64 -r1.65 src/usr.bin/xlint/lint1/mem1.c (switch to unified diff)

--- src/usr.bin/xlint/lint1/mem1.c 2023/01/13 19:41:50 1.64
+++ src/usr.bin/xlint/lint1/mem1.c 2023/04/11 19:02:19 1.65
@@ -1,317 +1,315 @@ @@ -1,317 +1,315 @@
1/* $NetBSD: mem1.c,v 1.64 2023/01/13 19:41:50 rillig Exp $ */ 1/* $NetBSD: mem1.c,v 1.65 2023/04/11 19:02:19 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1994, 1995 Jochen Pohl 4 * Copyright (c) 1994, 1995 Jochen Pohl
5 * All Rights Reserved. 5 * All Rights Reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement: 16 * must display the following acknowledgement:
17 * This product includes software developed by Jochen Pohl for 17 * This product includes software developed by Jochen Pohl for
18 * The NetBSD Project. 18 * The NetBSD Project.
19 * 4. The name of the author may not be used to endorse or promote products 19 * 4. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission. 20 * derived from this software without specific prior written permission.
21 * 21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34#if HAVE_NBTOOL_CONFIG_H 34#if HAVE_NBTOOL_CONFIG_H
35#include "nbtool_config.h" 35#include "nbtool_config.h"
36#endif 36#endif
37 37
38#include <sys/cdefs.h> 38#include <sys/cdefs.h>
39#if defined(__RCSID) 39#if defined(__RCSID)
40__RCSID("$NetBSD: mem1.c,v 1.64 2023/01/13 19:41:50 rillig Exp $"); 40__RCSID("$NetBSD: mem1.c,v 1.65 2023/04/11 19:02:19 rillig Exp $");
41#endif 41#endif
42 42
43#include <sys/param.h> 43#include <sys/param.h>
44#include <stdlib.h> 44#include <stdlib.h>
45#include <string.h> 45#include <string.h>
46 46
47#include "lint1.h" 47#include "lint1.h"
48 48
49/* 49/*
50 * Filenames allocated by record_filename are shared and have unlimited 50 * Filenames allocated by record_filename are shared and have unlimited
51 * lifetime. 51 * lifetime.
52 */ 52 */
53struct filename { 53struct filename {
54 const char *fn_name; 54 const char *fn_name;
55 size_t fn_len; 55 size_t fn_len;
56 int fn_id; 56 int fn_id;
57 struct filename *fn_next; 57 struct filename *fn_next;
58}; 58};
59 59
60static struct filename *filenames; /* null-terminated array */ 60static struct filename *filenames; /* null-terminated array */
61static int next_filename_id; 61static int next_filename_id;
62 62
63/* Find the given filename, or return NULL. */ 63/* Find the given filename, or return NULL. */
64static const struct filename * 64static const struct filename *
65search_filename(const char *s, size_t len) 65search_filename(const char *s, size_t len)
66{ 66{
67 const struct filename *fn; 67 const struct filename *fn;
68 68
69 for (fn = filenames; fn != NULL; fn = fn->fn_next) { 69 for (fn = filenames; fn != NULL; fn = fn->fn_next) {
70 if (fn->fn_len == len && memcmp(fn->fn_name, s, len) == 0) 70 if (fn->fn_len == len && memcmp(fn->fn_name, s, len) == 0)
71 break; 71 break;
72 } 72 }
73 return fn; 73 return fn;
74} 74}
75 75
76struct filename_replacement { 76struct filename_replacement {
77 const char *orig; 77 const char *orig;
78 size_t orig_len; 78 size_t orig_len;
79 const char *repl; 79 const char *repl;
80 const struct filename_replacement *next; 80 const struct filename_replacement *next;
81}; 81};
82 82
83static struct filename_replacement *filename_replacements; 83static struct filename_replacement *filename_replacements;
84 84
85void 85void
86add_directory_replacement(char *arg) 86add_directory_replacement(char *arg)
87{ 87{
88 struct filename_replacement *r = xmalloc(sizeof(*r)); 88 struct filename_replacement *r = xmalloc(sizeof(*r));
89 89
90 char *sep = strchr(arg, '='); 90 char *sep = strchr(arg, '=');
91 if (sep == NULL) 91 if (sep == NULL)
92 err(1, "Bad replacement directory spec `%s'", arg); 92 err(1, "Bad replacement directory spec `%s'", arg);
93 *sep = '\0'; 93 *sep = '\0';
94 94
95 r->orig = arg; 95 r->orig = arg;
96 r->orig_len = sep - arg; 96 r->orig_len = sep - arg;
97 r->repl = sep + 1; 97 r->repl = sep + 1;
98 r->next = filename_replacements; 98 r->next = filename_replacements;
99 filename_replacements = r; 99 filename_replacements = r;
100} 100}
101 101
102const char * 102const char *
103transform_filename(const char *name, size_t len) 103transform_filename(const char *name, size_t len)
104{ 104{
105 static char buf[MAXPATHLEN]; 105 static char buf[MAXPATHLEN];
106 const struct filename_replacement *r; 106 const struct filename_replacement *r;
107 107
108 for (r = filename_replacements; r != NULL; r = r->next) 108 for (r = filename_replacements; r != NULL; r = r->next)
109 if (r->orig_len < len && 109 if (r->orig_len < len &&
110 memcmp(name, r->orig, r->orig_len) == 0) 110 memcmp(name, r->orig, r->orig_len) == 0)
111 break; 111 break;
112 if (r == NULL) 112 if (r == NULL)
113 return name; 113 return name;
114 (void)snprintf(buf, sizeof(buf), "%s%s", r->repl, name + r->orig_len); 114 (void)snprintf(buf, sizeof(buf), "%s%s", r->repl, name + r->orig_len);
115 return buf; 115 return buf;
116} 116}
117 117
118/* 118/*
119 * Return a copy of the filename s with unlimited lifetime. 119 * Return a copy of the filename s with unlimited lifetime.
120 * If the filename is new, write it to the output file. 120 * If the filename is new, write it to the output file.
121 */ 121 */
122const char * 122const char *
123record_filename(const char *s, size_t slen) 123record_filename(const char *s, size_t slen)
124{ 124{
125 const struct filename *existing_fn; 
126 struct filename *fn; 
127 char *name; 
128 125
129 if ((existing_fn = search_filename(s, slen)) != NULL) 126 const struct filename *existing_fn = search_filename(s, slen);
 127 if (existing_fn != NULL)
130 return existing_fn->fn_name; 128 return existing_fn->fn_name;
131 129
132 name = xmalloc(slen + 1); 130 char *name = xmalloc(slen + 1);
133 (void)memcpy(name, s, slen); 131 (void)memcpy(name, s, slen);
134 name[slen] = '\0'; 132 name[slen] = '\0';
135 133
136 fn = xmalloc(sizeof(*fn)); 134 struct filename *fn = xmalloc(sizeof(*fn));
137 fn->fn_name = name; 135 fn->fn_name = name;
138 fn->fn_len = slen; 136 fn->fn_len = slen;
139 fn->fn_id = next_filename_id++; 137 fn->fn_id = next_filename_id++;
140 fn->fn_next = filenames; 138 fn->fn_next = filenames;
141 filenames = fn; 139 filenames = fn;
142 140
143 /* Write the ID of this filename to the output file. */ 141 /* Write the ID of this filename to the output file. */
144 outclr(); 142 outclr();
145 outint(fn->fn_id); 143 outint(fn->fn_id);
146 outchar('s'); 144 outchar('s');
147 outstrg(transform_filename(fn->fn_name, fn->fn_len)); 145 outstrg(transform_filename(fn->fn_name, fn->fn_len));
148 146
149 return fn->fn_name; 147 return fn->fn_name;
150} 148}
151 149
152/* Get the ID of a filename. */ 150/* Get the ID of a filename. */
153int 151int
154get_filename_id(const char *s) 152get_filename_id(const char *s)
155{ 153{
156 const struct filename *fn; 154 const struct filename *fn;
157 155
158 if (s == NULL || (fn = search_filename(s, strlen(s))) == NULL) 156 if (s == NULL || (fn = search_filename(s, strlen(s))) == NULL)
159 return -1; 157 return -1;
160 return fn->fn_id; 158 return fn->fn_id;
161} 159}
162 160
163/* Array of memory pools, indexed by mem_block_level. */ 
164typedef struct memory_pools { 161typedef struct memory_pools {
165 struct memory_pool *pools; 162 struct memory_pool *pools;
166 size_t cap; 163 size_t cap;
167} memory_pools; 164} memory_pools;
168 165
 166/* Array of memory pools, indexed by mem_block_level. */
169static memory_pools mpools; 167static memory_pools mpools;
170 168
171/* The pool for the current expression is independent of any block level. */ 169/* The pool for the current expression is independent of any block level. */
172static memory_pool expr_pool; 170static memory_pool expr_pool;
173 171
174static void 172static void
175mpool_add(memory_pool *pool, void *item) 173mpool_add(memory_pool *pool, void *item)
176{ 174{
177 175
178 if (pool->len >= pool->cap) { 176 if (pool->len >= pool->cap) {
179 pool->cap = 2 * pool->len + 16; 177 pool->cap = 2 * pool->len + 16;
180 pool->items = xrealloc(pool->items, 178 pool->items = xrealloc(pool->items,
181 sizeof(*pool->items) * pool->cap); 179 sizeof(*pool->items) * pool->cap);
182 } 180 }
183 pool->items[pool->len++] = item; 181 pool->items[pool->len++] = item;
184} 182}
185 183
186static void 184static void
187mpool_free(memory_pool *pool) 185mpool_free(memory_pool *pool)
188{ 186{
189 187
190 for (; pool->len > 0; pool->len--) 188 for (; pool->len > 0; pool->len--)
191 free(pool->items[pool->len - 1]); 189 free(pool->items[pool->len - 1]);
192} 190}
193 191
194static void * 192static void *
195mpool_zero_alloc(memory_pool *pool, size_t size) 193mpool_zero_alloc(memory_pool *pool, size_t size)
196{ 194{
197 195
198 void *mem = xmalloc(size); 196 void *mem = xmalloc(size);
199 memset(mem, 0, size); 197 memset(mem, 0, size);
200 mpool_add(pool, mem); 198 mpool_add(pool, mem);
201 return mem; 199 return mem;
202} 200}
203 201
204static memory_pool * 202static memory_pool *
205mpool_at(size_t level) 203mpool_at(size_t level)
206{ 204{
207 205
208 if (level >= mpools.cap) { 206 if (level >= mpools.cap) {
209 size_t prev_cap = mpools.cap; 207 size_t prev_cap = mpools.cap;
210 mpools.cap = level + 16; 208 mpools.cap = level + 16;
211 mpools.pools = xrealloc(mpools.pools, 209 mpools.pools = xrealloc(mpools.pools,
212 sizeof(*mpools.pools) * mpools.cap); 210 sizeof(*mpools.pools) * mpools.cap);
213 for (size_t i = prev_cap; i < mpools.cap; i++) 211 for (size_t i = prev_cap; i < mpools.cap; i++)
214 mpools.pools[i] = (memory_pool){ NULL, 0, 0 }; 212 mpools.pools[i] = (memory_pool){ NULL, 0, 0 };
215 } 213 }
216 return mpools.pools + level; 214 return mpools.pools + level;
217} 215}
218 216
219 217
220/* Allocate memory associated with level l, initialized with zero. */ 218/* Allocate memory associated with level l, initialized with zero. */
221void * 219void *
222level_zero_alloc(size_t l, size_t s) 220level_zero_alloc(size_t l, size_t s)
223{ 221{
224 222
225 return mpool_zero_alloc(mpool_at(l), s); 223 return mpool_zero_alloc(mpool_at(l), s);
226} 224}
227 225
228/* Allocate memory that is freed at the end of the current block. */ 226/* Allocate memory that is freed at the end of the current block. */
229void * 227void *
230block_zero_alloc(size_t s) 228block_zero_alloc(size_t s)
231{ 229{
232 230
233 return level_zero_alloc(mem_block_level, s); 231 return level_zero_alloc(mem_block_level, s);
234} 232}
235 233
236void 234void
237level_free_all(size_t level) 235level_free_all(size_t level)
238{ 236{
239 237
240 mpool_free(mpool_at(level)); 238 mpool_free(mpool_at(level));
241} 239}
242 240
243/* Allocate memory that is freed at the end of the current expression. */ 241/* Allocate memory that is freed at the end of the current expression. */
244void * 242void *
245expr_zero_alloc(size_t s) 243expr_zero_alloc(size_t s)
246{ 244{
247 245
248 return mpool_zero_alloc(&expr_pool, s); 246 return mpool_zero_alloc(&expr_pool, s);
249} 247}
250 248
251static bool 249static bool
252str_endswith(const char *haystack, const char *needle) 250str_endswith(const char *haystack, const char *needle)
253{ 251{
254 size_t hlen = strlen(haystack); 252 size_t hlen = strlen(haystack);
255 size_t nlen = strlen(needle); 253 size_t nlen = strlen(needle);
256 254
257 return nlen <= hlen && 255 return nlen <= hlen &&
258 memcmp(haystack + hlen - nlen, needle, nlen) == 0; 256 memcmp(haystack + hlen - nlen, needle, nlen) == 0;
259} 257}
260 258
261/* 259/*
262 * Return a freshly allocated tree node that is freed at the end of the 260 * Return a freshly allocated tree node that is freed at the end of the
263 * current expression. 261 * current expression.
264 * 262 *
265 * The node records whether it comes from a system file, which makes strict 263 * The node records whether it comes from a system file, which makes strict
266 * bool mode less restrictive. 264 * bool mode less restrictive.
267 */ 265 */
268tnode_t * 266tnode_t *
269expr_alloc_tnode(void) 267expr_alloc_tnode(void)
270{ 268{
271 tnode_t *tn = expr_zero_alloc(sizeof(*tn)); 269 tnode_t *tn = expr_zero_alloc(sizeof(*tn));
272 /* 270 /*
273 * files named *.c that are different from the main translation unit 271 * files named *.c that are different from the main translation unit
274 * typically contain generated code that cannot be influenced, such 272 * typically contain generated code that cannot be influenced, such
275 * as a flex lexer or a yacc parser. 273 * as a flex lexer or a yacc parser.
276 */ 274 */
277 tn->tn_sys = in_system_header || 275 tn->tn_sys = in_system_header ||
278 (curr_pos.p_file != csrc_pos.p_file && 276 (curr_pos.p_file != csrc_pos.p_file &&
279 str_endswith(curr_pos.p_file, ".c")); 277 str_endswith(curr_pos.p_file, ".c"));
280 return tn; 278 return tn;
281} 279}
282 280
283/* Free all memory which is allocated by the current expression. */ 281/* Free all memory which is allocated by the current expression. */
284void 282void
285expr_free_all(void) 283expr_free_all(void)
286{ 284{
287 285
288 mpool_free(&expr_pool); 286 mpool_free(&expr_pool);
289} 287}
290 288
291/* 289/*
292 * Save the memory which is used by the current expression. This memory 290 * Save the memory which is used by the current expression. This memory
293 * is not freed by the next expr_free_all() call. The returned value can be 291 * is not freed by the next expr_free_all() call. The returned value can be
294 * used to restore the memory. 292 * used to restore the memory.
295 */ 293 */
296memory_pool 294memory_pool
297expr_save_memory(void) 295expr_save_memory(void)
298{ 296{
299 297
300 memory_pool saved_pool = expr_pool; 298 memory_pool saved_pool = expr_pool;
301 expr_pool = (memory_pool){ NULL, 0, 0 }; 299 expr_pool = (memory_pool){ NULL, 0, 0 };
302 return saved_pool; 300 return saved_pool;
303} 301}
304 302
305/* 303/*
306 * Free all memory used for the current expression and restore the memory used 304 * Free all memory used for the current expression and restore the memory used
307 * by a previous expression and saved by expr_save_memory(). The next call to 305 * by a previous expression and saved by expr_save_memory(). The next call to
308 * expr_free_all() frees the restored memory. 306 * expr_free_all() frees the restored memory.
309 */ 307 */
310void 308void
311expr_restore_memory(memory_pool saved_pool) 309expr_restore_memory(memory_pool saved_pool)
312{ 310{
313 311
314 expr_free_all(); 312 expr_free_all();
315 free(expr_pool.items); 313 free(expr_pool.items);
316 expr_pool = saved_pool; 314 expr_pool = saved_pool;
317} 315}

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

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