Thu Apr 1 15:06:50 2021 UTC ()
lint: remove wrong assumption from comment

The size in bits of a struct or union is not measured at all at this
point since portable_size_in_bits only takes the broad type
classification (tspec_t), not the precise type information (type_t).

No functional change.


(rillig)
diff -r1.254 -r1.255 src/usr.bin/xlint/lint1/tree.c

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

--- src/usr.bin/xlint/lint1/tree.c 2021/03/30 15:18:19 1.254
+++ src/usr.bin/xlint/lint1/tree.c 2021/04/01 15:06:49 1.255
@@ -1,1039 +1,1039 @@ @@ -1,1039 +1,1039 @@
1/* $NetBSD: tree.c,v 1.254 2021/03/30 15:18:19 rillig Exp $ */ 1/* $NetBSD: tree.c,v 1.255 2021/04/01 15:06:49 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1994, 1995 Jochen Pohl 4 * Copyright (c) 1994, 1995 Jochen Pohl
5 * All Rights Reserved. 5 * All Rights Reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement: 16 * must display the following acknowledgement:
17 * This product includes software developed by Jochen Pohl for 17 * This product includes software developed by Jochen Pohl for
18 * The NetBSD Project. 18 * The NetBSD Project.
19 * 4. The name of the author may not be used to endorse or promote products 19 * 4. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission. 20 * derived from this software without specific prior written permission.
21 * 21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34#if HAVE_NBTOOL_CONFIG_H 34#if HAVE_NBTOOL_CONFIG_H
35#include "nbtool_config.h" 35#include "nbtool_config.h"
36#endif 36#endif
37 37
38#include <sys/cdefs.h> 38#include <sys/cdefs.h>
39#if defined(__RCSID) && !defined(lint) 39#if defined(__RCSID) && !defined(lint)
40__RCSID("$NetBSD: tree.c,v 1.254 2021/03/30 15:18:19 rillig Exp $"); 40__RCSID("$NetBSD: tree.c,v 1.255 2021/04/01 15:06:49 rillig Exp $");
41#endif 41#endif
42 42
43#include <float.h> 43#include <float.h>
44#include <limits.h> 44#include <limits.h>
45#include <math.h> 45#include <math.h>
46#include <signal.h> 46#include <signal.h>
47#include <stdlib.h> 47#include <stdlib.h>
48#include <string.h> 48#include <string.h>
49 49
50#include "lint1.h" 50#include "lint1.h"
51#include "cgram.h" 51#include "cgram.h"
52 52
53static tnode_t *new_integer_constant_node(tspec_t, int64_t); 53static tnode_t *new_integer_constant_node(tspec_t, int64_t);
54static void check_pointer_comparison(op_t, 54static void check_pointer_comparison(op_t,
55 const tnode_t *, const tnode_t *); 55 const tnode_t *, const tnode_t *);
56static bool check_assign_types_compatible(op_t, int, 56static bool check_assign_types_compatible(op_t, int,
57 const tnode_t *, const tnode_t *); 57 const tnode_t *, const tnode_t *);
58static void check_bad_enum_operation(op_t, 58static void check_bad_enum_operation(op_t,
59 const tnode_t *, const tnode_t *); 59 const tnode_t *, const tnode_t *);
60static void check_enum_type_mismatch(op_t, int, 60static void check_enum_type_mismatch(op_t, int,
61 const tnode_t *, const tnode_t *); 61 const tnode_t *, const tnode_t *);
62static void check_enum_int_mismatch(op_t, int, 62static void check_enum_int_mismatch(op_t, int,
63 const tnode_t *, const tnode_t *); 63 const tnode_t *, const tnode_t *);
64static tnode_t *new_tnode(op_t, type_t *, tnode_t *, tnode_t *); 64static tnode_t *new_tnode(op_t, type_t *, tnode_t *, tnode_t *);
65static void balance(op_t, tnode_t **, tnode_t **); 65static void balance(op_t, tnode_t **, tnode_t **);
66static void warn_incompatible_types(op_t, const type_t *, tspec_t, 66static void warn_incompatible_types(op_t, const type_t *, tspec_t,
67 const type_t *, tspec_t); 67 const type_t *, tspec_t);
68static void warn_incompatible_pointers(const mod_t *, 68static void warn_incompatible_pointers(const mod_t *,
69 const type_t *, const type_t *); 69 const type_t *, const type_t *);
70static void merge_qualifiers(type_t **, type_t *, type_t *); 70static void merge_qualifiers(type_t **, type_t *, type_t *);
71static bool has_constant_member(const type_t *); 71static bool has_constant_member(const type_t *);
72static void check_prototype_conversion(int, tspec_t, tspec_t, type_t *, 72static void check_prototype_conversion(int, tspec_t, tspec_t, type_t *,
73 tnode_t *); 73 tnode_t *);
74static void check_integer_conversion(op_t, int, tspec_t, tspec_t, type_t *, 74static void check_integer_conversion(op_t, int, tspec_t, tspec_t, type_t *,
75 tnode_t *); 75 tnode_t *);
76static void check_pointer_integer_conversion(op_t, tspec_t, type_t *, 76static void check_pointer_integer_conversion(op_t, tspec_t, type_t *,
77 tnode_t *); 77 tnode_t *);
78static void check_pointer_conversion(op_t, tnode_t *, type_t *); 78static void check_pointer_conversion(op_t, tnode_t *, type_t *);
79static tnode_t *build_struct_access(op_t, tnode_t *, tnode_t *); 79static tnode_t *build_struct_access(op_t, tnode_t *, tnode_t *);
80static tnode_t *build_prepost_incdec(op_t, tnode_t *); 80static tnode_t *build_prepost_incdec(op_t, tnode_t *);
81static tnode_t *build_real_imag(op_t, tnode_t *); 81static tnode_t *build_real_imag(op_t, tnode_t *);
82static tnode_t *build_address(tnode_t *, bool); 82static tnode_t *build_address(tnode_t *, bool);
83static tnode_t *build_plus_minus(op_t, tnode_t *, tnode_t *); 83static tnode_t *build_plus_minus(op_t, tnode_t *, tnode_t *);
84static tnode_t *build_bit_shift(op_t, tnode_t *, tnode_t *); 84static tnode_t *build_bit_shift(op_t, tnode_t *, tnode_t *);
85static tnode_t *build_colon(tnode_t *, tnode_t *); 85static tnode_t *build_colon(tnode_t *, tnode_t *);
86static tnode_t *build_assignment(op_t, tnode_t *, tnode_t *); 86static tnode_t *build_assignment(op_t, tnode_t *, tnode_t *);
87static tnode_t *plength(type_t *); 87static tnode_t *plength(type_t *);
88static tnode_t *fold(tnode_t *); 88static tnode_t *fold(tnode_t *);
89static tnode_t *fold_test(tnode_t *); 89static tnode_t *fold_test(tnode_t *);
90static tnode_t *fold_float(tnode_t *); 90static tnode_t *fold_float(tnode_t *);
91static tnode_t *check_function_arguments(type_t *, tnode_t *); 91static tnode_t *check_function_arguments(type_t *, tnode_t *);
92static tnode_t *check_prototype_argument(int, type_t *, tnode_t *); 92static tnode_t *check_prototype_argument(int, type_t *, tnode_t *);
93static void check_null_effect(const tnode_t *); 93static void check_null_effect(const tnode_t *);
94static void display_expression(const tnode_t *, int); 94static void display_expression(const tnode_t *, int);
95static void check_array_index(tnode_t *, bool); 95static void check_array_index(tnode_t *, bool);
96static void check_integer_comparison(op_t, tnode_t *, tnode_t *); 96static void check_integer_comparison(op_t, tnode_t *, tnode_t *);
97static void check_precedence_confusion(tnode_t *); 97static void check_precedence_confusion(tnode_t *);
98 98
99extern sig_atomic_t fpe; 99extern sig_atomic_t fpe;
100 100
101static const char * 101static const char *
102getopname(op_t op) 102getopname(op_t op)
103{ 103{
104 return modtab[op].m_name; 104 return modtab[op].m_name;
105} 105}
106 106
107#ifdef DEBUG 107#ifdef DEBUG
108void 108void
109debug_node(const tnode_t *tn, int indent) 109debug_node(const tnode_t *tn, int indent)
110{ 110{
111 op_t op; 111 op_t op;
112 112
113 if (tn == NULL) { 113 if (tn == NULL) {
114 printf("%*s" "null\n", indent, ""); 114 printf("%*s" "null\n", indent, "");
115 return; 115 return;
116 } 116 }
117 117
118 op = tn->tn_op; 118 op = tn->tn_op;
119 printf("%*s%s with type '%s'%s%s", 119 printf("%*s%s with type '%s'%s%s",
120 2 * indent, "", 120 2 * indent, "",
121 op == CVT && !tn->tn_cast ? "convert" : getopname(op), 121 op == CVT && !tn->tn_cast ? "convert" : getopname(op),
122 type_name(tn->tn_type), tn->tn_lvalue ? ", lvalue" : "", 122 type_name(tn->tn_type), tn->tn_lvalue ? ", lvalue" : "",
123 tn->tn_parenthesized ? ", parenthesized" : ""); 123 tn->tn_parenthesized ? ", parenthesized" : "");
124 124
125 if (op == NAME) 125 if (op == NAME)
126 printf(" %s\n", tn->tn_sym->s_name); 126 printf(" %s\n", tn->tn_sym->s_name);
127 else if (op == CON && is_floating(tn->tn_type->t_tspec)) 127 else if (op == CON && is_floating(tn->tn_type->t_tspec))
128 printf(", value %Lg", tn->tn_val->v_ldbl); 128 printf(", value %Lg", tn->tn_val->v_ldbl);
129 else if (op == CON && is_uinteger(tn->tn_type->t_tspec)) 129 else if (op == CON && is_uinteger(tn->tn_type->t_tspec))
130 printf(", value %llu\n", (unsigned long long)tn->tn_val->v_quad); 130 printf(", value %llu\n", (unsigned long long)tn->tn_val->v_quad);
131 else if (op == CON && is_integer(tn->tn_type->t_tspec)) 131 else if (op == CON && is_integer(tn->tn_type->t_tspec))
132 printf(", value %lld\n", (long long)tn->tn_val->v_quad); 132 printf(", value %lld\n", (long long)tn->tn_val->v_quad);
133 else if (op == CON) 133 else if (op == CON)
134 printf(", unknown value\n"); 134 printf(", unknown value\n");
135 else if (op == STRING) 135 else if (op == STRING)
136 printf(", length %zu\n", tn->tn_string->st_len); 136 printf(", length %zu\n", tn->tn_string->st_len);
137 else { 137 else {
138 printf("\n"); 138 printf("\n");
139 139
140 debug_node(tn->tn_left, indent + 1); 140 debug_node(tn->tn_left, indent + 1);
141 if (modtab[op].m_binary || tn->tn_right != NULL) 141 if (modtab[op].m_binary || tn->tn_right != NULL)
142 debug_node(tn->tn_right, indent + 1); 142 debug_node(tn->tn_right, indent + 1);
143 } 143 }
144} 144}
145#endif 145#endif
146 146
147/* 147/*
148 * Increase degree of reference. 148 * Increase degree of reference.
149 * This is most often used to change type "T" in type "pointer to T". 149 * This is most often used to change type "T" in type "pointer to T".
150 */ 150 */
151type_t * 151type_t *
152incref(type_t *tp, tspec_t t) 152incref(type_t *tp, tspec_t t)
153{ 153{
154 type_t *tp2; 154 type_t *tp2;
155 155
156 tp2 = getblk(sizeof *tp2); 156 tp2 = getblk(sizeof *tp2);
157 tp2->t_tspec = t; 157 tp2->t_tspec = t;
158 tp2->t_subt = tp; 158 tp2->t_subt = tp;
159 return tp2; 159 return tp2;
160} 160}
161 161
162/* 162/*
163 * same for use in expressions 163 * same for use in expressions
164 */ 164 */
165type_t * 165type_t *
166tincref(type_t *tp, tspec_t t) 166tincref(type_t *tp, tspec_t t)
167{ 167{
168 type_t *tp2; 168 type_t *tp2;
169 169
170 tp2 = tgetblk(sizeof *tp2); 170 tp2 = tgetblk(sizeof *tp2);
171 tp2->t_tspec = t; 171 tp2->t_tspec = t;
172 tp2->t_subt = tp; 172 tp2->t_subt = tp;
173 return tp2; 173 return tp2;
174} 174}
175 175
176/* 176/*
177 * Create a node for a constant. 177 * Create a node for a constant.
178 */ 178 */
179tnode_t * 179tnode_t *
180new_constant_node(type_t *tp, val_t *v) 180new_constant_node(type_t *tp, val_t *v)
181{ 181{
182 tnode_t *n; 182 tnode_t *n;
183 183
184 n = getnode(); 184 n = getnode();
185 n->tn_op = CON; 185 n->tn_op = CON;
186 n->tn_type = tp; 186 n->tn_type = tp;
187 n->tn_val = tgetblk(sizeof *n->tn_val); 187 n->tn_val = tgetblk(sizeof *n->tn_val);
188 n->tn_val->v_tspec = tp->t_tspec; 188 n->tn_val->v_tspec = tp->t_tspec;
189 n->tn_val->v_ansiu = v->v_ansiu; 189 n->tn_val->v_ansiu = v->v_ansiu;
190 n->tn_val->v_u = v->v_u; 190 n->tn_val->v_u = v->v_u;
191 free(v); 191 free(v);
192 return n; 192 return n;
193} 193}
194 194
195static tnode_t * 195static tnode_t *
196new_integer_constant_node(tspec_t t, int64_t q) 196new_integer_constant_node(tspec_t t, int64_t q)
197{ 197{
198 tnode_t *n; 198 tnode_t *n;
199 199
200 n = getnode(); 200 n = getnode();
201 n->tn_op = CON; 201 n->tn_op = CON;
202 n->tn_type = gettyp(t); 202 n->tn_type = gettyp(t);
203 n->tn_val = tgetblk(sizeof *n->tn_val); 203 n->tn_val = tgetblk(sizeof *n->tn_val);
204 n->tn_val->v_tspec = t; 204 n->tn_val->v_tspec = t;
205 n->tn_val->v_quad = q; 205 n->tn_val->v_quad = q;
206 return n; 206 return n;
207} 207}
208 208
209static void 209static void
210fallback_symbol(sym_t *sym) 210fallback_symbol(sym_t *sym)
211{ 211{
212 212
213 if (Tflag && strcmp(sym->s_name, "__lint_false") == 0) { 213 if (Tflag && strcmp(sym->s_name, "__lint_false") == 0) {
214 sym->s_scl = CTCONST; /* close enough */ 214 sym->s_scl = CTCONST; /* close enough */
215 sym->s_type = gettyp(BOOL); 215 sym->s_type = gettyp(BOOL);
216 sym->s_value.v_tspec = BOOL; 216 sym->s_value.v_tspec = BOOL;
217 sym->s_value.v_ansiu = false; 217 sym->s_value.v_ansiu = false;
218 sym->s_value.v_quad = 0; 218 sym->s_value.v_quad = 0;
219 return; 219 return;
220 } 220 }
221 221
222 if (Tflag && strcmp(sym->s_name, "__lint_true") == 0) { 222 if (Tflag && strcmp(sym->s_name, "__lint_true") == 0) {
223 sym->s_scl = CTCONST; /* close enough */ 223 sym->s_scl = CTCONST; /* close enough */
224 sym->s_type = gettyp(BOOL); 224 sym->s_type = gettyp(BOOL);
225 sym->s_value.v_tspec = BOOL; 225 sym->s_value.v_tspec = BOOL;
226 sym->s_value.v_ansiu = false; 226 sym->s_value.v_ansiu = false;
227 sym->s_value.v_quad = 1; 227 sym->s_value.v_quad = 1;
228 return; 228 return;
229 } 229 }
230 230
231 if (block_level > 0 && (strcmp(sym->s_name, "__FUNCTION__") == 0 || 231 if (block_level > 0 && (strcmp(sym->s_name, "__FUNCTION__") == 0 ||
232 strcmp(sym->s_name, "__PRETTY_FUNCTION__") == 0)) { 232 strcmp(sym->s_name, "__PRETTY_FUNCTION__") == 0)) {
233 /* __FUNCTION__/__PRETTY_FUNCTION__ is a GCC extension */ 233 /* __FUNCTION__/__PRETTY_FUNCTION__ is a GCC extension */
234 gnuism(316); 234 gnuism(316);
235 sym->s_type = incref(gettyp(CHAR), PTR); 235 sym->s_type = incref(gettyp(CHAR), PTR);
236 sym->s_type->t_const = true; 236 sym->s_type->t_const = true;
237 return; 237 return;
238 } 238 }
239 239
240 if (block_level > 0 && strcmp(sym->s_name, "__func__") == 0) { 240 if (block_level > 0 && strcmp(sym->s_name, "__func__") == 0) {
241 if (!Sflag) 241 if (!Sflag)
242 /* __func__ is a C9X feature */ 242 /* __func__ is a C9X feature */
243 warning(317); 243 warning(317);
244 sym->s_type = incref(gettyp(CHAR), PTR); 244 sym->s_type = incref(gettyp(CHAR), PTR);
245 sym->s_type->t_const = true; 245 sym->s_type->t_const = true;
246 return; 246 return;
247 } 247 }
248 248
249 /* '%s' undefined */ 249 /* '%s' undefined */
250 error(99, sym->s_name); 250 error(99, sym->s_name);
251} 251}
252 252
253/* 253/*
254 * Create a node for a name (symbol table entry). 254 * Create a node for a name (symbol table entry).
255 * follow_token is the token which follows the name. 255 * follow_token is the token which follows the name.
256 */ 256 */
257tnode_t * 257tnode_t *
258new_name_node(sym_t *sym, int follow_token) 258new_name_node(sym_t *sym, int follow_token)
259{ 259{
260 tnode_t *n; 260 tnode_t *n;
261 261
262 if (sym->s_scl == NOSCL) { 262 if (sym->s_scl == NOSCL) {
263 sym->s_scl = EXTERN; 263 sym->s_scl = EXTERN;
264 sym->s_def = DECL; 264 sym->s_def = DECL;
265 if (follow_token == T_LPAREN) { 265 if (follow_token == T_LPAREN) {
266 if (sflag) { 266 if (sflag) {
267 /* function implicitly declared to ... */ 267 /* function implicitly declared to ... */
268 warning(215); 268 warning(215);
269 } 269 }
270 /* 270 /*
271 * XXX if tflag is set the symbol should be 271 * XXX if tflag is set the symbol should be
272 * exported to level 0 272 * exported to level 0
273 */ 273 */
274 sym->s_type = incref(sym->s_type, FUNC); 274 sym->s_type = incref(sym->s_type, FUNC);
275 } else { 275 } else {
276 fallback_symbol(sym); 276 fallback_symbol(sym);
277 } 277 }
278 } 278 }
279 279
280 lint_assert(sym->s_kind == FVFT || sym->s_kind == FMEMBER); 280 lint_assert(sym->s_kind == FVFT || sym->s_kind == FMEMBER);
281 281
282 n = getnode(); 282 n = getnode();
283 n->tn_type = sym->s_type; 283 n->tn_type = sym->s_type;
284 if (sym->s_scl != CTCONST) { 284 if (sym->s_scl != CTCONST) {
285 n->tn_op = NAME; 285 n->tn_op = NAME;
286 n->tn_sym = sym; 286 n->tn_sym = sym;
287 if (sym->s_kind == FVFT && sym->s_type->t_tspec != FUNC) 287 if (sym->s_kind == FVFT && sym->s_type->t_tspec != FUNC)
288 n->tn_lvalue = true; 288 n->tn_lvalue = true;
289 } else { 289 } else {
290 n->tn_op = CON; 290 n->tn_op = CON;
291 n->tn_val = tgetblk(sizeof *n->tn_val); 291 n->tn_val = tgetblk(sizeof *n->tn_val);
292 *n->tn_val = sym->s_value; 292 *n->tn_val = sym->s_value;
293 } 293 }
294 294
295 return n; 295 return n;
296} 296}
297 297
298tnode_t * 298tnode_t *
299new_string_node(strg_t *strg) 299new_string_node(strg_t *strg)
300{ 300{
301 size_t len; 301 size_t len;
302 tnode_t *n; 302 tnode_t *n;
303 303
304 len = strg->st_len; 304 len = strg->st_len;
305 305
306 n = getnode(); 306 n = getnode();
307 307
308 n->tn_op = STRING; 308 n->tn_op = STRING;
309 n->tn_type = tincref(gettyp(strg->st_tspec), ARRAY); 309 n->tn_type = tincref(gettyp(strg->st_tspec), ARRAY);
310 n->tn_type->t_dim = len + 1; 310 n->tn_type->t_dim = len + 1;
311 n->tn_lvalue = true; 311 n->tn_lvalue = true;
312 312
313 n->tn_string = tgetblk(sizeof *n->tn_string); 313 n->tn_string = tgetblk(sizeof *n->tn_string);
314 n->tn_string->st_tspec = strg->st_tspec; 314 n->tn_string->st_tspec = strg->st_tspec;
315 n->tn_string->st_len = len; 315 n->tn_string->st_len = len;
316 316
317 if (strg->st_tspec == CHAR) { 317 if (strg->st_tspec == CHAR) {
318 n->tn_string->st_cp = tgetblk(len + 1); 318 n->tn_string->st_cp = tgetblk(len + 1);
319 (void)memcpy(n->tn_string->st_cp, strg->st_cp, len + 1); 319 (void)memcpy(n->tn_string->st_cp, strg->st_cp, len + 1);
320 free(strg->st_cp); 320 free(strg->st_cp);
321 } else { 321 } else {
322 size_t size = (len + 1) * sizeof *n->tn_string->st_wcp; 322 size_t size = (len + 1) * sizeof *n->tn_string->st_wcp;
323 n->tn_string->st_wcp = tgetblk(size); 323 n->tn_string->st_wcp = tgetblk(size);
324 (void)memcpy(n->tn_string->st_wcp, strg->st_wcp, size); 324 (void)memcpy(n->tn_string->st_wcp, strg->st_wcp, size);
325 free(strg->st_wcp); 325 free(strg->st_wcp);
326 } 326 }
327 free(strg); 327 free(strg);
328 328
329 return n; 329 return n;
330} 330}
331 331
332/* 332/*
333 * Returns a symbol which has the same name as the msym argument and is a 333 * Returns a symbol which has the same name as the msym argument and is a
334 * member of the struct or union specified by the tn argument. 334 * member of the struct or union specified by the tn argument.
335 */ 335 */
336sym_t * 336sym_t *
337struct_or_union_member(tnode_t *tn, op_t op, sym_t *msym) 337struct_or_union_member(tnode_t *tn, op_t op, sym_t *msym)
338{ 338{
339 struct_or_union *str; 339 struct_or_union *str;
340 type_t *tp; 340 type_t *tp;
341 sym_t *sym, *csym; 341 sym_t *sym, *csym;
342 bool eq; 342 bool eq;
343 tspec_t t; 343 tspec_t t;
344 344
345 /* 345 /*
346 * Remove the member if it was unknown until now, which means 346 * Remove the member if it was unknown until now, which means
347 * that no defined struct or union has a member with the same name. 347 * that no defined struct or union has a member with the same name.
348 */ 348 */
349 if (msym->s_scl == NOSCL) { 349 if (msym->s_scl == NOSCL) {
350 /* type '%s' does not have member '%s' */ 350 /* type '%s' does not have member '%s' */
351 error(101, type_name(msym->s_type), msym->s_name); 351 error(101, type_name(msym->s_type), msym->s_name);
352 rmsym(msym); 352 rmsym(msym);
353 msym->s_kind = FMEMBER; 353 msym->s_kind = FMEMBER;
354 msym->s_scl = MOS; 354 msym->s_scl = MOS;
355 msym->s_styp = tgetblk(sizeof *msym->s_styp); 355 msym->s_styp = tgetblk(sizeof *msym->s_styp);
356 msym->s_styp->sou_tag = tgetblk(sizeof *msym->s_styp->sou_tag); 356 msym->s_styp->sou_tag = tgetblk(sizeof *msym->s_styp->sou_tag);
357 msym->s_styp->sou_tag->s_name = unnamed; 357 msym->s_styp->sou_tag->s_name = unnamed;
358 msym->s_value.v_tspec = INT; 358 msym->s_value.v_tspec = INT;
359 return msym; 359 return msym;
360 } 360 }
361 361
362 /* Set str to the tag of which msym is expected to be a member. */ 362 /* Set str to the tag of which msym is expected to be a member. */
363 str = NULL; 363 str = NULL;
364 t = (tp = tn->tn_type)->t_tspec; 364 t = (tp = tn->tn_type)->t_tspec;
365 if (op == POINT) { 365 if (op == POINT) {
366 if (t == STRUCT || t == UNION) 366 if (t == STRUCT || t == UNION)
367 str = tp->t_str; 367 str = tp->t_str;
368 } else if (op == ARROW && t == PTR) { 368 } else if (op == ARROW && t == PTR) {
369 t = (tp = tp->t_subt)->t_tspec; 369 t = (tp = tp->t_subt)->t_tspec;
370 if (t == STRUCT || t == UNION) 370 if (t == STRUCT || t == UNION)
371 str = tp->t_str; 371 str = tp->t_str;
372 } 372 }
373 373
374 /* 374 /*
375 * If this struct/union has a member with the name of msym, return it. 375 * If this struct/union has a member with the name of msym, return it.
376 */ 376 */
377 if (str != NULL) { 377 if (str != NULL) {
378 for (sym = msym; sym != NULL; sym = sym->s_link) { 378 for (sym = msym; sym != NULL; sym = sym->s_link) {
379 if (sym->s_scl != MOS && sym->s_scl != MOU) 379 if (sym->s_scl != MOS && sym->s_scl != MOU)
380 continue; 380 continue;
381 if (sym->s_styp != str) 381 if (sym->s_styp != str)
382 continue; 382 continue;
383 if (strcmp(sym->s_name, msym->s_name) != 0) 383 if (strcmp(sym->s_name, msym->s_name) != 0)
384 continue; 384 continue;
385 return sym; 385 return sym;
386 } 386 }
387 } 387 }
388 388
389 /* 389 /*
390 * Set eq to false if there are struct/union members with the same 390 * Set eq to false if there are struct/union members with the same
391 * name and different types and/or offsets. 391 * name and different types and/or offsets.
392 */ 392 */
393 eq = true; 393 eq = true;
394 for (csym = msym; csym != NULL; csym = csym->s_link) { 394 for (csym = msym; csym != NULL; csym = csym->s_link) {
395 if (csym->s_scl != MOS && csym->s_scl != MOU) 395 if (csym->s_scl != MOS && csym->s_scl != MOU)
396 continue; 396 continue;
397 if (strcmp(msym->s_name, csym->s_name) != 0) 397 if (strcmp(msym->s_name, csym->s_name) != 0)
398 continue; 398 continue;
399 for (sym = csym->s_link ; sym != NULL; sym = sym->s_link) { 399 for (sym = csym->s_link ; sym != NULL; sym = sym->s_link) {
400 bool w; 400 bool w;
401 401
402 if (sym->s_scl != MOS && sym->s_scl != MOU) 402 if (sym->s_scl != MOS && sym->s_scl != MOU)
403 continue; 403 continue;
404 if (strcmp(csym->s_name, sym->s_name) != 0) 404 if (strcmp(csym->s_name, sym->s_name) != 0)
405 continue; 405 continue;
406 if (csym->s_value.v_quad != sym->s_value.v_quad) { 406 if (csym->s_value.v_quad != sym->s_value.v_quad) {
407 eq = false; 407 eq = false;
408 break; 408 break;
409 } 409 }
410 w = false; 410 w = false;
411 eq = eqtype(csym->s_type, sym->s_type, 411 eq = eqtype(csym->s_type, sym->s_type,
412 false, false, &w) && !w; 412 false, false, &w) && !w;
413 if (!eq) 413 if (!eq)
414 break; 414 break;
415 if (csym->s_bitfield != sym->s_bitfield) { 415 if (csym->s_bitfield != sym->s_bitfield) {
416 eq = false; 416 eq = false;
417 break; 417 break;
418 } 418 }
419 if (csym->s_bitfield) { 419 if (csym->s_bitfield) {
420 type_t *tp1, *tp2; 420 type_t *tp1, *tp2;
421 421
422 tp1 = csym->s_type; 422 tp1 = csym->s_type;
423 tp2 = sym->s_type; 423 tp2 = sym->s_type;
424 if (tp1->t_flen != tp2->t_flen) { 424 if (tp1->t_flen != tp2->t_flen) {
425 eq = false; 425 eq = false;
426 break; 426 break;
427 } 427 }
428 if (tp1->t_foffs != tp2->t_foffs) { 428 if (tp1->t_foffs != tp2->t_foffs) {
429 eq = false; 429 eq = false;
430 break; 430 break;
431 } 431 }
432 } 432 }
433 } 433 }
434 if (!eq) 434 if (!eq)
435 break; 435 break;
436 } 436 }
437 437
438 /* 438 /*
439 * Now handle the case in which the left operand refers really 439 * Now handle the case in which the left operand refers really
440 * to a struct/union, but the right operand is not member of it. 440 * to a struct/union, but the right operand is not member of it.
441 */ 441 */
442 if (str != NULL) { 442 if (str != NULL) {
443 if (eq && tflag) { 443 if (eq && tflag) {
444 /* illegal member use: %s */ 444 /* illegal member use: %s */
445 warning(102, msym->s_name); 445 warning(102, msym->s_name);
446 } else { 446 } else {
447 /* illegal member use: %s */ 447 /* illegal member use: %s */
448 error(102, msym->s_name); 448 error(102, msym->s_name);
449 } 449 }
450 return msym; 450 return msym;
451 } 451 }
452 452
453 /* 453 /*
454 * Now the left operand of ARROW does not point to a struct/union 454 * Now the left operand of ARROW does not point to a struct/union
455 * or the left operand of POINT is no struct/union. 455 * or the left operand of POINT is no struct/union.
456 */ 456 */
457 if (eq) { 457 if (eq) {
458 if (op == POINT) { 458 if (op == POINT) {
459 if (tflag) { 459 if (tflag) {
460 /* left operand of '.' must be struct/... */ 460 /* left operand of '.' must be struct/... */
461 warning(103); 461 warning(103);
462 } else { 462 } else {
463 /* left operand of '.' must be struct/... */ 463 /* left operand of '.' must be struct/... */
464 error(103); 464 error(103);
465 } 465 }
466 } else { 466 } else {
467 if (tflag && tn->tn_type->t_tspec == PTR) { 467 if (tflag && tn->tn_type->t_tspec == PTR) {
468 /* left operand of '->' must be pointer ... */ 468 /* left operand of '->' must be pointer ... */
469 warning(104, type_name(tn->tn_type)); 469 warning(104, type_name(tn->tn_type));
470 } else { 470 } else {
471 /* left operand of '->' must be pointer ... */ 471 /* left operand of '->' must be pointer ... */
472 error(104, type_name(tn->tn_type)); 472 error(104, type_name(tn->tn_type));
473 } 473 }
474 } 474 }
475 } else { 475 } else {
476 if (tflag) { 476 if (tflag) {
477 /* non-unique member requires struct/union %s */ 477 /* non-unique member requires struct/union %s */
478 error(105, op == POINT ? "object" : "pointer"); 478 error(105, op == POINT ? "object" : "pointer");
479 } else { 479 } else {
480 /* unacceptable operand of '%s' */ 480 /* unacceptable operand of '%s' */
481 error(111, getopname(op)); 481 error(111, getopname(op));
482 } 482 }
483 } 483 }
484 484
485 return msym; 485 return msym;
486} 486}
487 487
488/* 488/*
489 * Create a tree node. Called for most operands except function calls, 489 * Create a tree node. Called for most operands except function calls,
490 * sizeof and casts. 490 * sizeof and casts.
491 * 491 *
492 * op operator 492 * op operator
493 * ln left operand 493 * ln left operand
494 * rn if not NULL, right operand 494 * rn if not NULL, right operand
495 */ 495 */
496tnode_t * 496tnode_t *
497build(op_t op, tnode_t *ln, tnode_t *rn) 497build(op_t op, tnode_t *ln, tnode_t *rn)
498{ 498{
499 const mod_t *mp; 499 const mod_t *mp;
500 tnode_t *ntn; 500 tnode_t *ntn;
501 type_t *rettp; 501 type_t *rettp;
502 502
503 mp = &modtab[op]; 503 mp = &modtab[op];
504 504
505 /* If there was an error in one of the operands, return. */ 505 /* If there was an error in one of the operands, return. */
506 if (ln == NULL || (mp->m_binary && rn == NULL)) 506 if (ln == NULL || (mp->m_binary && rn == NULL))
507 return NULL; 507 return NULL;
508 508
509 /* 509 /*
510 * Apply class conversions to the left operand, but only if its 510 * Apply class conversions to the left operand, but only if its
511 * value is needed or it is compared with null. 511 * value is needed or it is compared with null.
512 */ 512 */
513 if (mp->m_left_value_context || mp->m_left_test_context) 513 if (mp->m_left_value_context || mp->m_left_test_context)
514 ln = cconv(ln); 514 ln = cconv(ln);
515 /* 515 /*
516 * The right operand is almost always in a test or value context, 516 * The right operand is almost always in a test or value context,
517 * except if it is a struct or union member. 517 * except if it is a struct or union member.
518 */ 518 */
519 if (mp->m_binary && op != ARROW && op != POINT) 519 if (mp->m_binary && op != ARROW && op != POINT)
520 rn = cconv(rn); 520 rn = cconv(rn);
521 521
522 /* 522 /*
523 * Print some warnings for comparisons of unsigned values with 523 * Print some warnings for comparisons of unsigned values with
524 * constants lower than or equal to null. This must be done 524 * constants lower than or equal to null. This must be done
525 * before promote() because otherwise unsigned char and unsigned 525 * before promote() because otherwise unsigned char and unsigned
526 * short would be promoted to int. Also types are tested to be 526 * short would be promoted to int. Also types are tested to be
527 * CHAR, which would also become int. 527 * CHAR, which would also become int.
528 */ 528 */
529 if (mp->m_comparison) 529 if (mp->m_comparison)
530 check_integer_comparison(op, ln, rn); 530 check_integer_comparison(op, ln, rn);
531 531
532 /* 532 /*
533 * Promote the left operand if it is in a test or value context 533 * Promote the left operand if it is in a test or value context
534 */ 534 */
535 if (mp->m_left_value_context || mp->m_left_test_context) 535 if (mp->m_left_value_context || mp->m_left_test_context)
536 ln = promote(op, false, ln); 536 ln = promote(op, false, ln);
537 /* 537 /*
538 * Promote the right operand, but only if it is no struct or 538 * Promote the right operand, but only if it is no struct or
539 * union member, or if it is not to be assigned to the left operand 539 * union member, or if it is not to be assigned to the left operand
540 */ 540 */
541 if (mp->m_binary && op != ARROW && op != POINT && 541 if (mp->m_binary && op != ARROW && op != POINT &&
542 op != ASSIGN && op != RETURN) { 542 op != ASSIGN && op != RETURN) {
543 rn = promote(op, false, rn); 543 rn = promote(op, false, rn);
544 } 544 }
545 545
546 /* 546 /*
547 * If the result of the operation is different for signed or 547 * If the result of the operation is different for signed or
548 * unsigned operands and one of the operands is signed only in 548 * unsigned operands and one of the operands is signed only in
549 * ANSI C, print a warning. 549 * ANSI C, print a warning.
550 */ 550 */
551 if (mp->m_warn_if_left_unsigned_in_c90 && 551 if (mp->m_warn_if_left_unsigned_in_c90 &&
552 ln->tn_op == CON && ln->tn_val->v_ansiu) { 552 ln->tn_op == CON && ln->tn_val->v_ansiu) {
553 /* ANSI C treats constant as unsigned, op %s */ 553 /* ANSI C treats constant as unsigned, op %s */
554 warning(218, mp->m_name); 554 warning(218, mp->m_name);
555 ln->tn_val->v_ansiu = false; 555 ln->tn_val->v_ansiu = false;
556 } 556 }
557 if (mp->m_warn_if_right_unsigned_in_c90 && 557 if (mp->m_warn_if_right_unsigned_in_c90 &&
558 rn->tn_op == CON && rn->tn_val->v_ansiu) { 558 rn->tn_op == CON && rn->tn_val->v_ansiu) {
559 /* ANSI C treats constant as unsigned, op %s */ 559 /* ANSI C treats constant as unsigned, op %s */
560 warning(218, mp->m_name); 560 warning(218, mp->m_name);
561 rn->tn_val->v_ansiu = false; 561 rn->tn_val->v_ansiu = false;
562 } 562 }
563 563
564 /* Make sure both operands are of the same type */ 564 /* Make sure both operands are of the same type */
565 if (mp->m_balance_operands || (tflag && (op == SHL || op == SHR))) 565 if (mp->m_balance_operands || (tflag && (op == SHL || op == SHR)))
566 balance(op, &ln, &rn); 566 balance(op, &ln, &rn);
567 567
568 /* 568 /*
569 * Check types for compatibility with the operation and mutual 569 * Check types for compatibility with the operation and mutual
570 * compatibility. Return if there are serious problems. 570 * compatibility. Return if there are serious problems.
571 */ 571 */
572 if (!typeok(op, 0, ln, rn)) 572 if (!typeok(op, 0, ln, rn))
573 return NULL; 573 return NULL;
574 574
575 /* And now create the node. */ 575 /* And now create the node. */
576 switch (op) { 576 switch (op) {
577 case POINT: 577 case POINT:
578 case ARROW: 578 case ARROW:
579 ntn = build_struct_access(op, ln, rn); 579 ntn = build_struct_access(op, ln, rn);
580 break; 580 break;
581 case INCAFT: 581 case INCAFT:
582 case DECAFT: 582 case DECAFT:
583 case INCBEF: 583 case INCBEF:
584 case DECBEF: 584 case DECBEF:
585 ntn = build_prepost_incdec(op, ln); 585 ntn = build_prepost_incdec(op, ln);
586 break; 586 break;
587 case ADDR: 587 case ADDR:
588 ntn = build_address(ln, false); 588 ntn = build_address(ln, false);
589 break; 589 break;
590 case INDIR: 590 case INDIR:
591 ntn = new_tnode(INDIR, ln->tn_type->t_subt, ln, NULL); 591 ntn = new_tnode(INDIR, ln->tn_type->t_subt, ln, NULL);
592 break; 592 break;
593 case PLUS: 593 case PLUS:
594 case MINUS: 594 case MINUS:
595 ntn = build_plus_minus(op, ln, rn); 595 ntn = build_plus_minus(op, ln, rn);
596 break; 596 break;
597 case SHL: 597 case SHL:
598 case SHR: 598 case SHR:
599 ntn = build_bit_shift(op, ln, rn); 599 ntn = build_bit_shift(op, ln, rn);
600 break; 600 break;
601 case COLON: 601 case COLON:
602 ntn = build_colon(ln, rn); 602 ntn = build_colon(ln, rn);
603 break; 603 break;
604 case ASSIGN: 604 case ASSIGN:
605 case MULASS: 605 case MULASS:
606 case DIVASS: 606 case DIVASS:
607 case MODASS: 607 case MODASS:
608 case ADDASS: 608 case ADDASS:
609 case SUBASS: 609 case SUBASS:
610 case SHLASS: 610 case SHLASS:
611 case SHRASS: 611 case SHRASS:
612 case ANDASS: 612 case ANDASS:
613 case XORASS: 613 case XORASS:
614 case ORASS: 614 case ORASS:
615 case RETURN: 615 case RETURN:
616 ntn = build_assignment(op, ln, rn); 616 ntn = build_assignment(op, ln, rn);
617 break; 617 break;
618 case COMMA: 618 case COMMA:
619 case QUEST: 619 case QUEST:
620 ntn = new_tnode(op, rn->tn_type, ln, rn); 620 ntn = new_tnode(op, rn->tn_type, ln, rn);
621 break; 621 break;
622 case REAL: 622 case REAL:
623 case IMAG: 623 case IMAG:
624 ntn = build_real_imag(op, ln); 624 ntn = build_real_imag(op, ln);
625 break; 625 break;
626 default: 626 default:
627 rettp = mp->m_returns_bool 627 rettp = mp->m_returns_bool
628 ? gettyp(Tflag ? BOOL : INT) : ln->tn_type; 628 ? gettyp(Tflag ? BOOL : INT) : ln->tn_type;
629 lint_assert(mp->m_binary || rn == NULL); 629 lint_assert(mp->m_binary || rn == NULL);
630 ntn = new_tnode(op, rettp, ln, rn); 630 ntn = new_tnode(op, rettp, ln, rn);
631 break; 631 break;
632 } 632 }
633 633
634 /* Return if an error occurred. */ 634 /* Return if an error occurred. */
635 if (ntn == NULL) 635 if (ntn == NULL)
636 return NULL; 636 return NULL;
637 637
638 /* Print a warning if precedence confusion is possible */ 638 /* Print a warning if precedence confusion is possible */
639 if (mp->m_possible_precedence_confusion) 639 if (mp->m_possible_precedence_confusion)
640 check_precedence_confusion(ntn); 640 check_precedence_confusion(ntn);
641 641
642 /* 642 /*
643 * Print a warning if one of the operands is in a context where 643 * Print a warning if one of the operands is in a context where
644 * it is compared with null and if this operand is a constant. 644 * it is compared with null and if this operand is a constant.
645 */ 645 */
646 if (mp->m_left_test_context) { 646 if (mp->m_left_test_context) {
647 if (ln->tn_op == CON || 647 if (ln->tn_op == CON ||
648 ((mp->m_binary && op != QUEST) && rn->tn_op == CON)) { 648 ((mp->m_binary && op != QUEST) && rn->tn_op == CON)) {
649 if (hflag && !constcond_flag && 649 if (hflag && !constcond_flag &&
650 !ln->tn_system_dependent) 650 !ln->tn_system_dependent)
651 /* constant in conditional context */ 651 /* constant in conditional context */
652 warning(161); 652 warning(161);
653 } 653 }
654 } 654 }
655 655
656 /* Fold if the operator requires it */ 656 /* Fold if the operator requires it */
657 if (mp->m_fold_constant_operands) { 657 if (mp->m_fold_constant_operands) {
658 if (ln->tn_op == CON && (!mp->m_binary || rn->tn_op == CON)) { 658 if (ln->tn_op == CON && (!mp->m_binary || rn->tn_op == CON)) {
659 if (mp->m_left_test_context) { 659 if (mp->m_left_test_context) {
660 ntn = fold_test(ntn); 660 ntn = fold_test(ntn);
661 } else if (is_floating(ntn->tn_type->t_tspec)) { 661 } else if (is_floating(ntn->tn_type->t_tspec)) {
662 ntn = fold_float(ntn); 662 ntn = fold_float(ntn);
663 } else { 663 } else {
664 ntn = fold(ntn); 664 ntn = fold(ntn);
665 } 665 }
666 } else if (op == QUEST && ln->tn_op == CON) { 666 } else if (op == QUEST && ln->tn_op == CON) {
667 ntn = ln->tn_val->v_quad != 0 667 ntn = ln->tn_val->v_quad != 0
668 ? rn->tn_left : rn->tn_right; 668 ? rn->tn_left : rn->tn_right;
669 } 669 }
670 } 670 }
671 671
672 return ntn; 672 return ntn;
673} 673}
674 674
675/* 675/*
676 * Perform class conversions. 676 * Perform class conversions.
677 * 677 *
678 * Arrays of type T are converted into pointers to type T. 678 * Arrays of type T are converted into pointers to type T.
679 * Functions are converted to pointers to functions. 679 * Functions are converted to pointers to functions.
680 * Lvalues are converted to rvalues. 680 * Lvalues are converted to rvalues.
681 * 681 *
682 * C99 6.3 "Conversions" 682 * C99 6.3 "Conversions"
683 * C99 6.3.2 "Other operands" 683 * C99 6.3.2 "Other operands"
684 * C99 6.3.2.1 "Lvalues, arrays, and function designators" 684 * C99 6.3.2.1 "Lvalues, arrays, and function designators"
685 */ 685 */
686tnode_t * 686tnode_t *
687cconv(tnode_t *tn) 687cconv(tnode_t *tn)
688{ 688{
689 type_t *tp; 689 type_t *tp;
690 690
691 /* 691 /*
692 * Array-lvalue (array of type T) is converted into rvalue 692 * Array-lvalue (array of type T) is converted into rvalue
693 * (pointer to type T) 693 * (pointer to type T)
694 */ 694 */
695 if (tn->tn_type->t_tspec == ARRAY) { 695 if (tn->tn_type->t_tspec == ARRAY) {
696 if (!tn->tn_lvalue) { 696 if (!tn->tn_lvalue) {
697 /* XXX print correct operator */ 697 /* XXX print correct operator */
698 /* %soperand of '%s' must be lvalue */ 698 /* %soperand of '%s' must be lvalue */
699 gnuism(114, "", modtab[ADDR].m_name); 699 gnuism(114, "", modtab[ADDR].m_name);
700 } 700 }
701 tn = new_tnode(ADDR, tincref(tn->tn_type->t_subt, PTR), 701 tn = new_tnode(ADDR, tincref(tn->tn_type->t_subt, PTR),
702 tn, NULL); 702 tn, NULL);
703 } 703 }
704 704
705 /* 705 /*
706 * Expression of type function (function with return value of type T) 706 * Expression of type function (function with return value of type T)
707 * in rvalue-expression (pointer to function with return value 707 * in rvalue-expression (pointer to function with return value
708 * of type T) 708 * of type T)
709 */ 709 */
710 if (tn->tn_type->t_tspec == FUNC) 710 if (tn->tn_type->t_tspec == FUNC)
711 tn = build_address(tn, true); 711 tn = build_address(tn, true);
712 712
713 /* lvalue to rvalue */ 713 /* lvalue to rvalue */
714 if (tn->tn_lvalue) { 714 if (tn->tn_lvalue) {
715 tp = tduptyp(tn->tn_type); 715 tp = tduptyp(tn->tn_type);
716 tp->t_const = tp->t_volatile = false; 716 tp->t_const = tp->t_volatile = false;
717 tn = new_tnode(LOAD, tp, tn, NULL); 717 tn = new_tnode(LOAD, tp, tn, NULL);
718 } 718 }
719 719
720 return tn; 720 return tn;
721} 721}
722 722
723static const tnode_t * 723static const tnode_t *
724before_conversion(const tnode_t *tn) 724before_conversion(const tnode_t *tn)
725{ 725{
726 while (tn->tn_op == CVT && !tn->tn_cast) 726 while (tn->tn_op == CVT && !tn->tn_cast)
727 tn = tn->tn_left; 727 tn = tn->tn_left;
728 return tn; 728 return tn;
729} 729}
730 730
731static bool 731static bool
732is_null_pointer(const tnode_t *tn) 732is_null_pointer(const tnode_t *tn)
733{ 733{
734 tspec_t t = tn->tn_type->t_tspec; 734 tspec_t t = tn->tn_type->t_tspec;
735 735
736 return ((t == PTR && tn->tn_type->t_subt->t_tspec == VOID) || 736 return ((t == PTR && tn->tn_type->t_subt->t_tspec == VOID) ||
737 is_integer(t)) 737 is_integer(t))
738 && (tn->tn_op == CON && tn->tn_val->v_quad == 0); 738 && (tn->tn_op == CON && tn->tn_val->v_quad == 0);
739} 739}
740 740
741/* 741/*
742 * See if the node is valid as operand of an operator that compares its 742 * See if the node is valid as operand of an operator that compares its
743 * argument with 0. 743 * argument with 0.
744 */ 744 */
745bool 745bool
746is_typeok_bool_operand(const tnode_t *tn) 746is_typeok_bool_operand(const tnode_t *tn)
747{ 747{
748 tspec_t t; 748 tspec_t t;
749 749
750 lint_assert(Tflag); 750 lint_assert(Tflag);
751 751
752 tn = before_conversion(tn); 752 tn = before_conversion(tn);
753 t = tn->tn_type->t_tspec; 753 t = tn->tn_type->t_tspec;
754 754
755 if (t == BOOL) 755 if (t == BOOL)
756 return true; 756 return true;
757 757
758 if (tn->tn_from_system_header && is_scalar(t)) 758 if (tn->tn_from_system_header && is_scalar(t))
759 return true; 759 return true;
760 760
761 /* For enums that are used as bit sets, allow "flags & FLAG". */ 761 /* For enums that are used as bit sets, allow "flags & FLAG". */
762 if (tn->tn_op == BITAND && 762 if (tn->tn_op == BITAND &&
763 tn->tn_left->tn_op == CVT && 763 tn->tn_left->tn_op == CVT &&
764 tn->tn_left->tn_type->t_tspec == INT && !tn->tn_left->tn_cast && 764 tn->tn_left->tn_type->t_tspec == INT && !tn->tn_left->tn_cast &&
765 tn->tn_left->tn_left->tn_type->t_tspec == ENUM && 765 tn->tn_left->tn_left->tn_type->t_tspec == ENUM &&
766 /* 766 /*
767 * XXX: Somehow the type information got lost here. The type 767 * XXX: Somehow the type information got lost here. The type
768 * of the enum constant on the right-hand side should still be 768 * of the enum constant on the right-hand side should still be
769 * ENUM, but is INT. 769 * ENUM, but is INT.
770 */ 770 */
771 tn->tn_right->tn_type->t_tspec == INT) 771 tn->tn_right->tn_type->t_tspec == INT)
772 return true; 772 return true;
773 773
774 return false; 774 return false;
775} 775}
776 776
777static bool 777static bool
778typeok_incdec(const mod_t *mp, const tnode_t *tn, const type_t *tp) 778typeok_incdec(const mod_t *mp, const tnode_t *tn, const type_t *tp)
779{ 779{
780 /* operand has scalar type (checked in typeok) */ 780 /* operand has scalar type (checked in typeok) */
781 if (!tn->tn_lvalue) { 781 if (!tn->tn_lvalue) {
782 if (tn->tn_op == CVT && tn->tn_cast && 782 if (tn->tn_op == CVT && tn->tn_cast &&
783 tn->tn_left->tn_op == LOAD) { 783 tn->tn_left->tn_op == LOAD) {
784 if (tn->tn_type->t_tspec == PTR) 784 if (tn->tn_type->t_tspec == PTR)
785 return true; 785 return true;
786 /* a cast does not yield an lvalue */ 786 /* a cast does not yield an lvalue */
787 error(163); 787 error(163);
788 } 788 }
789 /* %soperand of '%s' must be lvalue */ 789 /* %soperand of '%s' must be lvalue */
790 error(114, "", mp->m_name); 790 error(114, "", mp->m_name);
791 return false; 791 return false;
792 } else if (tp->t_const) { 792 } else if (tp->t_const) {
793 if (!tflag) 793 if (!tflag)
794 /* %soperand of '%s' must be modifiable lvalue */ 794 /* %soperand of '%s' must be modifiable lvalue */
795 warning(115, "", mp->m_name); 795 warning(115, "", mp->m_name);
796 } 796 }
797 return true; 797 return true;
798} 798}
799 799
800static bool 800static bool
801typeok_address(const mod_t *mp, 801typeok_address(const mod_t *mp,
802 const tnode_t *tn, const type_t *tp, tspec_t t) 802 const tnode_t *tn, const type_t *tp, tspec_t t)
803{ 803{
804 if (t == ARRAY || t == FUNC) { 804 if (t == ARRAY || t == FUNC) {
805 /* ok, a warning comes later (in build_address()) */ 805 /* ok, a warning comes later (in build_address()) */
806 } else if (!tn->tn_lvalue) { 806 } else if (!tn->tn_lvalue) {
807 if (tn->tn_op == CVT && tn->tn_cast && 807 if (tn->tn_op == CVT && tn->tn_cast &&
808 tn->tn_left->tn_op == LOAD) { 808 tn->tn_left->tn_op == LOAD) {
809 if (tn->tn_type->t_tspec == PTR) 809 if (tn->tn_type->t_tspec == PTR)
810 return true; 810 return true;
811 /* a cast does not yield an lvalue */ 811 /* a cast does not yield an lvalue */
812 error(163); 812 error(163);
813 } 813 }
814 /* %soperand of '%s' must be lvalue */ 814 /* %soperand of '%s' must be lvalue */
815 error(114, "", mp->m_name); 815 error(114, "", mp->m_name);
816 return false; 816 return false;
817 } else if (is_scalar(t)) { 817 } else if (is_scalar(t)) {
818 if (tp->t_bitfield) { 818 if (tp->t_bitfield) {
819 /* cannot take address of bit-field */ 819 /* cannot take address of bit-field */
820 error(112); 820 error(112);
821 return false; 821 return false;
822 } 822 }
823 } else if (t != STRUCT && t != UNION) { 823 } else if (t != STRUCT && t != UNION) {
824 /* unacceptable operand of '%s' */ 824 /* unacceptable operand of '%s' */
825 error(111, mp->m_name); 825 error(111, mp->m_name);
826 return false; 826 return false;
827 } 827 }
828 if (tn->tn_op == NAME && tn->tn_sym->s_reg) { 828 if (tn->tn_op == NAME && tn->tn_sym->s_reg) {
829 /* cannot take address of register %s */ 829 /* cannot take address of register %s */
830 error(113, tn->tn_sym->s_name); 830 error(113, tn->tn_sym->s_name);
831 return false; 831 return false;
832 } 832 }
833 return true; 833 return true;
834} 834}
835 835
836static bool 836static bool
837typeok_star(tspec_t t) 837typeok_star(tspec_t t)
838{ 838{
839 /* until now there were no type checks for this operator */ 839 /* until now there were no type checks for this operator */
840 if (t != PTR) { 840 if (t != PTR) {
841 /* cannot dereference non-pointer type */ 841 /* cannot dereference non-pointer type */
842 error(96); 842 error(96);
843 return false; 843 return false;
844 } 844 }
845 return true; 845 return true;
846} 846}
847 847
848static bool 848static bool
849typeok_plus(op_t op, 849typeok_plus(op_t op,
850 const type_t *ltp, tspec_t lt, 850 const type_t *ltp, tspec_t lt,
851 const type_t *rtp, tspec_t rt) 851 const type_t *rtp, tspec_t rt)
852{ 852{
853 /* operands have scalar types (checked above) */ 853 /* operands have scalar types (checked above) */
854 if ((lt == PTR && !is_integer(rt)) || (rt == PTR && !is_integer(lt))) { 854 if ((lt == PTR && !is_integer(rt)) || (rt == PTR && !is_integer(lt))) {
855 warn_incompatible_types(op, ltp, lt, rtp, rt); 855 warn_incompatible_types(op, ltp, lt, rtp, rt);
856 return false; 856 return false;
857 } 857 }
858 return true; 858 return true;
859} 859}
860 860
861static bool 861static bool
862typeok_minus(op_t op, 862typeok_minus(op_t op,
863 const type_t *ltp, tspec_t lt, 863 const type_t *ltp, tspec_t lt,
864 const type_t *rtp, tspec_t rt) 864 const type_t *rtp, tspec_t rt)
865{ 865{
866 /* operands have scalar types (checked above) */ 866 /* operands have scalar types (checked above) */
867 if (lt == PTR && (!is_integer(rt) && rt != PTR)) { 867 if (lt == PTR && (!is_integer(rt) && rt != PTR)) {
868 warn_incompatible_types(op, ltp, lt, rtp, rt); 868 warn_incompatible_types(op, ltp, lt, rtp, rt);
869 return false; 869 return false;
870 } else if (rt == PTR && lt != PTR) { 870 } else if (rt == PTR && lt != PTR) {
871 warn_incompatible_types(op, ltp, lt, rtp, rt); 871 warn_incompatible_types(op, ltp, lt, rtp, rt);
872 return false; 872 return false;
873 } 873 }
874 if (lt == PTR && rt == PTR) { 874 if (lt == PTR && rt == PTR) {
875 if (!eqtype(ltp->t_subt, rtp->t_subt, true, false, NULL)) { 875 if (!eqtype(ltp->t_subt, rtp->t_subt, true, false, NULL)) {
876 /* illegal pointer subtraction */ 876 /* illegal pointer subtraction */
877 error(116); 877 error(116);
878 } 878 }
879 } 879 }
880 return true; 880 return true;
881} 881}
882 882
883static void 883static void
884typeok_shr(const mod_t *mp, 884typeok_shr(const mod_t *mp,
885 const tnode_t *ln, tspec_t lt, 885 const tnode_t *ln, tspec_t lt,
886 const tnode_t *rn, tspec_t rt) 886 const tnode_t *rn, tspec_t rt)
887{ 887{
888 tspec_t olt, ort; 888 tspec_t olt, ort;
889 889
890 olt = before_conversion(ln)->tn_type->t_tspec; 890 olt = before_conversion(ln)->tn_type->t_tspec;
891 ort = before_conversion(rn)->tn_type->t_tspec; 891 ort = before_conversion(rn)->tn_type->t_tspec;
892 892
893 /* operands have integer types (checked above) */ 893 /* operands have integer types (checked above) */
894 if (pflag && !is_uinteger(lt)) { 894 if (pflag && !is_uinteger(lt)) {
895 /* 895 /*
896 * The left operand is signed. This means that 896 * The left operand is signed. This means that
897 * the operation is (possibly) nonportable. 897 * the operation is (possibly) nonportable.
898 */ 898 */
899 if (ln->tn_op != CON) { 899 if (ln->tn_op != CON) {
900 /* bitwise '%s' on signed value possibly nonportable */ 900 /* bitwise '%s' on signed value possibly nonportable */
901 warning(117, mp->m_name); 901 warning(117, mp->m_name);
902 } else if (ln->tn_val->v_quad < 0) { 902 } else if (ln->tn_val->v_quad < 0) {
903 /* bitwise '%s' on signed value nonportable */ 903 /* bitwise '%s' on signed value nonportable */
904 warning(120, mp->m_name); 904 warning(120, mp->m_name);
905 } 905 }
906 } else if (!tflag && !sflag && !is_uinteger(olt) && is_uinteger(ort)) { 906 } else if (!tflag && !sflag && !is_uinteger(olt) && is_uinteger(ort)) {
907 /* 907 /*
908 * The left operand would become unsigned in 908 * The left operand would become unsigned in
909 * traditional C. 909 * traditional C.
910 */ 910 */
911 if (hflag && 911 if (hflag &&
912 (ln->tn_op != CON || ln->tn_val->v_quad < 0)) { 912 (ln->tn_op != CON || ln->tn_val->v_quad < 0)) {
913 /* semantics of '%s' change in ANSI C; use ... */ 913 /* semantics of '%s' change in ANSI C; use ... */
914 warning(118, mp->m_name); 914 warning(118, mp->m_name);
915 } 915 }
916 } else if (!tflag && !sflag && !is_uinteger(olt) && !is_uinteger(ort) && 916 } else if (!tflag && !sflag && !is_uinteger(olt) && !is_uinteger(ort) &&
917 portable_size_in_bits(lt) < portable_size_in_bits(rt)) { 917 portable_size_in_bits(lt) < portable_size_in_bits(rt)) {
918 /* 918 /*
919 * In traditional C the left operand would be extended, 919 * In traditional C the left operand would be extended,
920 * possibly with 1, and then shifted. 920 * possibly with 1, and then shifted.
921 */ 921 */
922 if (hflag && 922 if (hflag &&
923 (ln->tn_op != CON || ln->tn_val->v_quad < 0)) { 923 (ln->tn_op != CON || ln->tn_val->v_quad < 0)) {
924 /* semantics of '%s' change in ANSI C; use ... */ 924 /* semantics of '%s' change in ANSI C; use ... */
925 warning(118, mp->m_name); 925 warning(118, mp->m_name);
926 } 926 }
927 } 927 }
928} 928}
929 929
930static void 930static void
931typeok_shl(const mod_t *mp, tspec_t lt, tspec_t rt) 931typeok_shl(const mod_t *mp, tspec_t lt, tspec_t rt)
932{ 932{
933 /* 933 /*
934 * C90 does not perform balancing for shift operations, 934 * C90 does not perform balancing for shift operations,
935 * but traditional C does. If the width of the right operand 935 * but traditional C does. If the width of the right operand
936 * is greater than the width of the left operand, then in 936 * is greater than the width of the left operand, then in
937 * traditional C the left operand would be extended to the 937 * traditional C the left operand would be extended to the
938 * width of the right operand. For SHL this may result in 938 * width of the right operand. For SHL this may result in
939 * different results. 939 * different results.
940 */ 940 */
941 if (portable_size_in_bits(lt) < portable_size_in_bits(rt)) { 941 if (portable_size_in_bits(lt) < portable_size_in_bits(rt)) {
942 /* 942 /*
943 * XXX If both operands are constant, make sure 943 * XXX If both operands are constant, make sure
944 * that there is really a difference between 944 * that there is really a difference between
945 * ANSI C and traditional C. 945 * ANSI C and traditional C.
946 */ 946 */
947 if (hflag) 947 if (hflag)
948 /* semantics of '%s' change in ANSI C; use ... */ 948 /* semantics of '%s' change in ANSI C; use ... */
949 warning(118, mp->m_name); 949 warning(118, mp->m_name);
950 } 950 }
951} 951}
952 952
953static void 953static void
954typeok_shift(tspec_t lt, const tnode_t *rn, tspec_t rt) 954typeok_shift(tspec_t lt, const tnode_t *rn, tspec_t rt)
955{ 955{
956 if (rn->tn_op == CON) { 956 if (rn->tn_op == CON) {
957 if (!is_uinteger(rt) && rn->tn_val->v_quad < 0) { 957 if (!is_uinteger(rt) && rn->tn_val->v_quad < 0) {
958 /* negative shift */ 958 /* negative shift */
959 warning(121); 959 warning(121);
960 } else if ((uint64_t)rn->tn_val->v_quad == 960 } else if ((uint64_t)rn->tn_val->v_quad ==
961 (uint64_t)size_in_bits(lt)) { 961 (uint64_t)size_in_bits(lt)) {
962 /* shift equal to size of object */ 962 /* shift equal to size of object */
963 warning(267); 963 warning(267);
964 } else if ((uint64_t)rn->tn_val->v_quad > 964 } else if ((uint64_t)rn->tn_val->v_quad >
965 (uint64_t)size_in_bits(lt)) { 965 (uint64_t)size_in_bits(lt)) {
966 /* shift greater than size of object */ 966 /* shift greater than size of object */
967 warning(122); 967 warning(122);
968 } 968 }
969 } 969 }
970} 970}
971 971
972static bool 972static bool
973is_typeok_eq(const tnode_t *ln, tspec_t lt, const tnode_t *rn, tspec_t rt) 973is_typeok_eq(const tnode_t *ln, tspec_t lt, const tnode_t *rn, tspec_t rt)
974{ 974{
975 if (lt == PTR && is_null_pointer(rn)) 975 if (lt == PTR && is_null_pointer(rn))
976 return true; 976 return true;
977 if (rt == PTR && is_null_pointer(ln)) 977 if (rt == PTR && is_null_pointer(ln))
978 return true; 978 return true;
979 return false; 979 return false;
980} 980}
981 981
982static bool 982static bool
983typeok_ordered_comparison(op_t op, 983typeok_ordered_comparison(op_t op,
984 const tnode_t *ln, const type_t *ltp, tspec_t lt, 984 const tnode_t *ln, const type_t *ltp, tspec_t lt,
985 const tnode_t *rn, const type_t *rtp, tspec_t rt) 985 const tnode_t *rn, const type_t *rtp, tspec_t rt)
986{ 986{
987 if (lt == PTR && rt == PTR) { 987 if (lt == PTR && rt == PTR) {
988 check_pointer_comparison(op, ln, rn); 988 check_pointer_comparison(op, ln, rn);
989 return true; 989 return true;
990 } 990 }
991 991
992 if (lt != PTR && rt != PTR) 992 if (lt != PTR && rt != PTR)
993 return true; 993 return true;
994 994
995 if (!is_integer(lt) && !is_integer(rt)) { 995 if (!is_integer(lt) && !is_integer(rt)) {
996 warn_incompatible_types(op, ltp, lt, rtp, rt); 996 warn_incompatible_types(op, ltp, lt, rtp, rt);
997 return false; 997 return false;
998 } 998 }
999 999
1000 const char *lx = lt == PTR ? "pointer" : "integer"; 1000 const char *lx = lt == PTR ? "pointer" : "integer";
1001 const char *rx = rt == PTR ? "pointer" : "integer"; 1001 const char *rx = rt == PTR ? "pointer" : "integer";
1002 /* illegal combination of %s (%s) and %s (%s), op %s */ 1002 /* illegal combination of %s (%s) and %s (%s), op %s */
1003 warning(123, lx, type_name(ltp), rx, type_name(rtp), getopname(op)); 1003 warning(123, lx, type_name(ltp), rx, type_name(rtp), getopname(op));
1004 return true; 1004 return true;
1005} 1005}
1006 1006
1007static bool 1007static bool
1008typeok_quest(tspec_t lt, const tnode_t **rn) 1008typeok_quest(tspec_t lt, const tnode_t **rn)
1009{ 1009{
1010 if (!is_scalar(lt)) { 1010 if (!is_scalar(lt)) {
1011 /* first operand must have scalar type, op ? : */ 1011 /* first operand must have scalar type, op ? : */
1012 error(170); 1012 error(170);
1013 return false; 1013 return false;
1014 } 1014 }
1015 while ((*rn)->tn_op == CVT) 1015 while ((*rn)->tn_op == CVT)
1016 *rn = (*rn)->tn_left; 1016 *rn = (*rn)->tn_left;
1017 lint_assert((*rn)->tn_op == COLON); 1017 lint_assert((*rn)->tn_op == COLON);
1018 return true; 1018 return true;
1019} 1019}
1020 1020
1021static void 1021static void
1022typeok_colon_pointer(const mod_t *mp, const type_t *ltp, const type_t *rtp) 1022typeok_colon_pointer(const mod_t *mp, const type_t *ltp, const type_t *rtp)
1023{ 1023{
1024 type_t *lstp = ltp->t_subt; 1024 type_t *lstp = ltp->t_subt;
1025 type_t *rstp = rtp->t_subt; 1025 type_t *rstp = rtp->t_subt;
1026 tspec_t lst = lstp->t_tspec; 1026 tspec_t lst = lstp->t_tspec;
1027 tspec_t rst = rstp->t_tspec; 1027 tspec_t rst = rstp->t_tspec;
1028 1028
1029 if ((lst == VOID && rst == FUNC) || (lst == FUNC && rst == VOID)) { 1029 if ((lst == VOID && rst == FUNC) || (lst == FUNC && rst == VOID)) {
1030 /* (void *)0 handled above */ 1030 /* (void *)0 handled above */
1031 if (sflag) 1031 if (sflag)
1032 /* ANSI C forbids conv. of %s to %s, op %s */ 1032 /* ANSI C forbids conv. of %s to %s, op %s */
1033 warning(305, "function pointer", "'void *'", 1033 warning(305, "function pointer", "'void *'",
1034 mp->m_name); 1034 mp->m_name);
1035 return; 1035 return;
1036 } 1036 }
1037 1037
1038 if (eqptrtype(lstp, rstp, true)) 1038 if (eqptrtype(lstp, rstp, true))
1039 return; 1039 return;
@@ -1237,2002 +1237,1998 @@ typeok_scalar_strict_bool(op_t op, const @@ -1237,2002 +1237,1998 @@ typeok_scalar_strict_bool(op_t op, const
1237 ok = false; 1237 ok = false;
1238 } 1238 }
1239 return ok; 1239 return ok;
1240 } 1240 }
1241 1241
1242 if (!mp->m_takes_bool) { 1242 if (!mp->m_takes_bool) {
1243 bool binary = mp->m_binary; 1243 bool binary = mp->m_binary;
1244 bool lbool = ln->tn_type->t_tspec == BOOL; 1244 bool lbool = ln->tn_type->t_tspec == BOOL;
1245 bool ok = true; 1245 bool ok = true;
1246 1246
1247 if (!binary && lbool) { 1247 if (!binary && lbool) {
1248 /* operand of '%s' must not be bool */ 1248 /* operand of '%s' must not be bool */
1249 error(335, getopname(op)); 1249 error(335, getopname(op));
1250 ok = false; 1250 ok = false;
1251 } 1251 }
1252 if (binary && lbool) { 1252 if (binary && lbool) {
1253 /* left operand of '%s' must not be bool */ 1253 /* left operand of '%s' must not be bool */
1254 error(336, getopname(op)); 1254 error(336, getopname(op));
1255 ok = false; 1255 ok = false;
1256 } 1256 }
1257 if (binary && rn->tn_type->t_tspec == BOOL) { 1257 if (binary && rn->tn_type->t_tspec == BOOL) {
1258 /* right operand of '%s' must not be bool */ 1258 /* right operand of '%s' must not be bool */
1259 error(337, getopname(op)); 1259 error(337, getopname(op));
1260 ok = false; 1260 ok = false;
1261 } 1261 }
1262 return ok; 1262 return ok;
1263 } 1263 }
1264 1264
1265 return true; 1265 return true;
1266} 1266}
1267 1267
1268/* Check the types using the information from modtab[]. */ 1268/* Check the types using the information from modtab[]. */
1269static bool 1269static bool
1270typeok_scalar(op_t op, const mod_t *mp, 1270typeok_scalar(op_t op, const mod_t *mp,
1271 const type_t *ltp, tspec_t lt, 1271 const type_t *ltp, tspec_t lt,
1272 const type_t *rtp, tspec_t rt) 1272 const type_t *rtp, tspec_t rt)
1273{ 1273{
1274 if (mp->m_takes_bool && lt == BOOL && rt == BOOL) 1274 if (mp->m_takes_bool && lt == BOOL && rt == BOOL)
1275 return true; 1275 return true;
1276 if (mp->m_requires_integer) { 1276 if (mp->m_requires_integer) {
1277 if (!is_integer(lt) || (mp->m_binary && !is_integer(rt))) { 1277 if (!is_integer(lt) || (mp->m_binary && !is_integer(rt))) {
1278 warn_incompatible_types(op, ltp, lt, rtp, rt); 1278 warn_incompatible_types(op, ltp, lt, rtp, rt);
1279 return false; 1279 return false;
1280 } 1280 }
1281 } else if (mp->m_requires_integer_or_complex) { 1281 } else if (mp->m_requires_integer_or_complex) {
1282 if ((!is_integer(lt) && !is_complex(lt)) || 1282 if ((!is_integer(lt) && !is_complex(lt)) ||
1283 (mp->m_binary && (!is_integer(rt) && !is_complex(rt)))) { 1283 (mp->m_binary && (!is_integer(rt) && !is_complex(rt)))) {
1284 warn_incompatible_types(op, ltp, lt, rtp, rt); 1284 warn_incompatible_types(op, ltp, lt, rtp, rt);
1285 return false; 1285 return false;
1286 } 1286 }
1287 } else if (mp->m_requires_scalar) { 1287 } else if (mp->m_requires_scalar) {
1288 if (!is_scalar(lt) || (mp->m_binary && !is_scalar(rt))) { 1288 if (!is_scalar(lt) || (mp->m_binary && !is_scalar(rt))) {
1289 warn_incompatible_types(op, ltp, lt, rtp, rt); 1289 warn_incompatible_types(op, ltp, lt, rtp, rt);
1290 return false; 1290 return false;
1291 } 1291 }
1292 } else if (mp->m_requires_arith) { 1292 } else if (mp->m_requires_arith) {
1293 if (!is_arithmetic(lt) || 1293 if (!is_arithmetic(lt) ||
1294 (mp->m_binary && !is_arithmetic(rt))) { 1294 (mp->m_binary && !is_arithmetic(rt))) {
1295 warn_incompatible_types(op, ltp, lt, rtp, rt); 1295 warn_incompatible_types(op, ltp, lt, rtp, rt);
1296 return false; 1296 return false;
1297 } 1297 }
1298 } 1298 }
1299 return true; 1299 return true;
1300} 1300}
1301 1301
1302/* Check the types for specific operators and type combinations. */ 1302/* Check the types for specific operators and type combinations. */
1303static bool 1303static bool
1304typeok_op(op_t op, const mod_t *mp, int arg, 1304typeok_op(op_t op, const mod_t *mp, int arg,
1305 const tnode_t *ln, const type_t *ltp, tspec_t lt, 1305 const tnode_t *ln, const type_t *ltp, tspec_t lt,
1306 const tnode_t *rn, const type_t *rtp, tspec_t rt) 1306 const tnode_t *rn, const type_t *rtp, tspec_t rt)
1307{ 1307{
1308 switch (op) { 1308 switch (op) {
1309 case POINT: 1309 case POINT:
1310 /* 1310 /*
1311 * Most errors required by ANSI C are reported in 1311 * Most errors required by ANSI C are reported in
1312 * struct_or_union_member(). 1312 * struct_or_union_member().
1313 * Here we only must check for totally wrong things. 1313 * Here we only must check for totally wrong things.
1314 */ 1314 */
1315 if (lt == FUNC || lt == VOID || ltp->t_bitfield || 1315 if (lt == FUNC || lt == VOID || ltp->t_bitfield ||
1316 ((lt != STRUCT && lt != UNION) && !ln->tn_lvalue)) { 1316 ((lt != STRUCT && lt != UNION) && !ln->tn_lvalue)) {
1317 /* Without tflag we got already an error */ 1317 /* Without tflag we got already an error */
1318 if (tflag) 1318 if (tflag)
1319 /* unacceptable operand of '%s' */ 1319 /* unacceptable operand of '%s' */
1320 error(111, mp->m_name); 1320 error(111, mp->m_name);
1321 return false; 1321 return false;
1322 } 1322 }
1323 /* Now we have an object we can create a pointer to */ 1323 /* Now we have an object we can create a pointer to */
1324 break; 1324 break;
1325 case ARROW: 1325 case ARROW:
1326 if (lt != PTR && !(tflag && is_integer(lt))) { 1326 if (lt != PTR && !(tflag && is_integer(lt))) {
1327 /* Without tflag we got already an error */ 1327 /* Without tflag we got already an error */
1328 if (tflag) 1328 if (tflag)
1329 /* unacceptable operand of '%s' */ 1329 /* unacceptable operand of '%s' */
1330 error(111, mp->m_name); 1330 error(111, mp->m_name);
1331 return false; 1331 return false;
1332 } 1332 }
1333 break; 1333 break;
1334 case INCAFT: 1334 case INCAFT:
1335 case DECAFT: 1335 case DECAFT:
1336 case INCBEF: 1336 case INCBEF:
1337 case DECBEF: 1337 case DECBEF:
1338 if (!typeok_incdec(mp, ln, ltp)) 1338 if (!typeok_incdec(mp, ln, ltp))
1339 return false; 1339 return false;
1340 break; 1340 break;
1341 case ADDR: 1341 case ADDR:
1342 if (!typeok_address(mp, ln, ltp, lt)) 1342 if (!typeok_address(mp, ln, ltp, lt))
1343 return false; 1343 return false;
1344 break; 1344 break;
1345 case INDIR: 1345 case INDIR:
1346 if (!typeok_star(lt)) 1346 if (!typeok_star(lt))
1347 return false; 1347 return false;
1348 break; 1348 break;
1349 case PLUS: 1349 case PLUS:
1350 if (!typeok_plus(op, ltp, lt, rtp, rt)) 1350 if (!typeok_plus(op, ltp, lt, rtp, rt))
1351 return false; 1351 return false;
1352 break; 1352 break;
1353 case MINUS: 1353 case MINUS:
1354 if (!typeok_minus(op, ltp, lt, rtp, rt)) 1354 if (!typeok_minus(op, ltp, lt, rtp, rt))
1355 return false; 1355 return false;
1356 break; 1356 break;
1357 case SHR: 1357 case SHR:
1358 typeok_shr(mp, ln, lt, rn, rt); 1358 typeok_shr(mp, ln, lt, rn, rt);
1359 goto shift; 1359 goto shift;
1360 case SHL: 1360 case SHL:
1361 typeok_shl(mp, lt, rt); 1361 typeok_shl(mp, lt, rt);
1362 shift: 1362 shift:
1363 typeok_shift(lt, rn, rt); 1363 typeok_shift(lt, rn, rt);
1364 break; 1364 break;
1365 case EQ: 1365 case EQ:
1366 case NE: 1366 case NE:
1367 /* 1367 /*
1368 * Accept some things which are allowed with EQ and NE, 1368 * Accept some things which are allowed with EQ and NE,
1369 * but not with ordered comparisons. 1369 * but not with ordered comparisons.
1370 */ 1370 */
1371 if (is_typeok_eq(ln, lt, rn, rt)) 1371 if (is_typeok_eq(ln, lt, rn, rt))
1372 break; 1372 break;
1373 /* FALLTHROUGH */ 1373 /* FALLTHROUGH */
1374 case LT: 1374 case LT:
1375 case GT: 1375 case GT:
1376 case LE: 1376 case LE:
1377 case GE: 1377 case GE:
1378 if (!typeok_ordered_comparison(op, ln, ltp, lt, rn, rtp, rt)) 1378 if (!typeok_ordered_comparison(op, ln, ltp, lt, rn, rtp, rt))
1379 return false; 1379 return false;
1380 break; 1380 break;
1381 case QUEST: 1381 case QUEST:
1382 if (!typeok_quest(lt, &rn)) 1382 if (!typeok_quest(lt, &rn))
1383 return false; 1383 return false;
1384 break; 1384 break;
1385 case COLON: 1385 case COLON:
1386 if (!typeok_colon(mp, ln, ltp, lt, rn, rtp, rt)) 1386 if (!typeok_colon(mp, ln, ltp, lt, rn, rtp, rt))
1387 return false; 1387 return false;
1388 break; 1388 break;
1389 case ASSIGN: 1389 case ASSIGN:
1390 case INIT: 1390 case INIT:
1391 case FARG: 1391 case FARG:
1392 case RETURN: 1392 case RETURN:
1393 if (!check_assign_types_compatible(op, arg, ln, rn)) 1393 if (!check_assign_types_compatible(op, arg, ln, rn))
1394 return false; 1394 return false;
1395 goto assign; 1395 goto assign;
1396 case MULASS: 1396 case MULASS:
1397 case DIVASS: 1397 case DIVASS:
1398 case MODASS: 1398 case MODASS:
1399 goto assign; 1399 goto assign;
1400 case ADDASS: 1400 case ADDASS:
1401 case SUBASS: 1401 case SUBASS:
1402 /* operands have scalar types (checked above) */ 1402 /* operands have scalar types (checked above) */
1403 if ((lt == PTR && !is_integer(rt)) || rt == PTR) { 1403 if ((lt == PTR && !is_integer(rt)) || rt == PTR) {
1404 warn_incompatible_types(op, ltp, lt, rtp, rt); 1404 warn_incompatible_types(op, ltp, lt, rtp, rt);
1405 return false; 1405 return false;
1406 } 1406 }
1407 goto assign; 1407 goto assign;
1408 case SHLASS: 1408 case SHLASS:
1409 goto assign; 1409 goto assign;
1410 case SHRASS: 1410 case SHRASS:
1411 if (pflag && !is_uinteger(lt) && !(tflag && is_uinteger(rt))) { 1411 if (pflag && !is_uinteger(lt) && !(tflag && is_uinteger(rt))) {
1412 /* bitwise '%s' on signed value possibly nonportable */ 1412 /* bitwise '%s' on signed value possibly nonportable */
1413 warning(117, mp->m_name); 1413 warning(117, mp->m_name);
1414 } 1414 }
1415 goto assign; 1415 goto assign;
1416 case ANDASS: 1416 case ANDASS:
1417 case XORASS: 1417 case XORASS:
1418 case ORASS: 1418 case ORASS:
1419 goto assign; 1419 goto assign;
1420 assign: 1420 assign:
1421 if (!typeok_assign(mp, ln, ltp, lt)) 1421 if (!typeok_assign(mp, ln, ltp, lt))
1422 return false; 1422 return false;
1423 break; 1423 break;
1424 case COMMA: 1424 case COMMA:
1425 if (!modtab[ln->tn_op].m_has_side_effect) 1425 if (!modtab[ln->tn_op].m_has_side_effect)
1426 check_null_effect(ln); 1426 check_null_effect(ln);
1427 break; 1427 break;
1428 /* LINTED206: (enumeration values not handled in switch) */ 1428 /* LINTED206: (enumeration values not handled in switch) */
1429 case CON: 1429 case CON:
1430 case CASE: 1430 case CASE:
1431 case PUSH: 1431 case PUSH:
1432 case LOAD: 1432 case LOAD:
1433 case ICALL: 1433 case ICALL:
1434 case CVT: 1434 case CVT:
1435 case CALL: 1435 case CALL:
1436 case FSEL: 1436 case FSEL:
1437 case STRING: 1437 case STRING:
1438 case NAME: 1438 case NAME:
1439 case LOGOR: 1439 case LOGOR:
1440 case LOGAND: 1440 case LOGAND:
1441 case BITOR: 1441 case BITOR:
1442 case BITXOR: 1442 case BITXOR:
1443 case BITAND: 1443 case BITAND:
1444 case MOD: 1444 case MOD:
1445 case DIV: 1445 case DIV:
1446 case MULT: 1446 case MULT:
1447 case UMINUS: 1447 case UMINUS:
1448 case UPLUS: 1448 case UPLUS:
1449 case DEC: 1449 case DEC:
1450 case INC: 1450 case INC:
1451 case COMPL: 1451 case COMPL:
1452 case NOT: 1452 case NOT:
1453 case NOOP: 1453 case NOOP:
1454 case REAL: 1454 case REAL:
1455 case IMAG: 1455 case IMAG:
1456 break; 1456 break;
1457 } 1457 }
1458 return true; 1458 return true;
1459} 1459}
1460 1460
1461static void 1461static void
1462typeok_enum(op_t op, const mod_t *mp, int arg, 1462typeok_enum(op_t op, const mod_t *mp, int arg,
1463 const tnode_t *ln, const type_t *ltp, 1463 const tnode_t *ln, const type_t *ltp,
1464 const tnode_t *rn, const type_t *rtp) 1464 const tnode_t *rn, const type_t *rtp)
1465{ 1465{
1466 if (mp->m_bad_on_enum && 1466 if (mp->m_bad_on_enum &&
1467 (ltp->t_is_enum || (mp->m_binary && rtp->t_is_enum))) { 1467 (ltp->t_is_enum || (mp->m_binary && rtp->t_is_enum))) {
1468 check_bad_enum_operation(op, ln, rn); 1468 check_bad_enum_operation(op, ln, rn);
1469 } else if (mp->m_valid_on_enum && 1469 } else if (mp->m_valid_on_enum &&
1470 (ltp->t_is_enum && rtp != NULL && rtp->t_is_enum)) { 1470 (ltp->t_is_enum && rtp != NULL && rtp->t_is_enum)) {
1471 check_enum_type_mismatch(op, arg, ln, rn); 1471 check_enum_type_mismatch(op, arg, ln, rn);
1472 } else if (mp->m_valid_on_enum && 1472 } else if (mp->m_valid_on_enum &&
1473 (ltp->t_is_enum || (rtp != NULL && rtp->t_is_enum))) { 1473 (ltp->t_is_enum || (rtp != NULL && rtp->t_is_enum))) {
1474 check_enum_int_mismatch(op, arg, ln, rn); 1474 check_enum_int_mismatch(op, arg, ln, rn);
1475 } 1475 }
1476} 1476}
1477 1477
1478/* Perform most type checks. Return whether the types are ok. */ 1478/* Perform most type checks. Return whether the types are ok. */
1479bool 1479bool
1480typeok(op_t op, int arg, const tnode_t *ln, const tnode_t *rn) 1480typeok(op_t op, int arg, const tnode_t *ln, const tnode_t *rn)
1481{ 1481{
1482 const mod_t *mp; 1482 const mod_t *mp;
1483 tspec_t lt, rt; 1483 tspec_t lt, rt;
1484 type_t *ltp, *rtp; 1484 type_t *ltp, *rtp;
1485 1485
1486 mp = &modtab[op]; 1486 mp = &modtab[op];
1487 1487
1488 lint_assert((ltp = ln->tn_type) != NULL); 1488 lint_assert((ltp = ln->tn_type) != NULL);
1489 lt = ltp->t_tspec; 1489 lt = ltp->t_tspec;
1490 1490
1491 if (mp->m_binary) { 1491 if (mp->m_binary) {
1492 lint_assert((rtp = rn->tn_type) != NULL); 1492 lint_assert((rtp = rn->tn_type) != NULL);
1493 rt = rtp->t_tspec; 1493 rt = rtp->t_tspec;
1494 } else { 1494 } else {
1495 rtp = NULL; 1495 rtp = NULL;
1496 rt = NOTSPEC; 1496 rt = NOTSPEC;
1497 } 1497 }
1498 1498
1499 if (Tflag && !typeok_scalar_strict_bool(op, mp, arg, ln, rn)) 1499 if (Tflag && !typeok_scalar_strict_bool(op, mp, arg, ln, rn))
1500 return false; 1500 return false;
1501 if (!typeok_scalar(op, mp, ltp, lt, rtp, rt)) 1501 if (!typeok_scalar(op, mp, ltp, lt, rtp, rt))
1502 return false; 1502 return false;
1503 1503
1504 if (!typeok_op(op, mp, arg, ln, ltp, lt, rn, rtp, rt)) 1504 if (!typeok_op(op, mp, arg, ln, ltp, lt, rn, rtp, rt))
1505 return false; 1505 return false;
1506 1506
1507 typeok_enum(op, mp, arg, ln, ltp, rn, rtp); 1507 typeok_enum(op, mp, arg, ln, ltp, rn, rtp);
1508 return true; 1508 return true;
1509} 1509}
1510 1510
1511static void 1511static void
1512check_pointer_comparison(op_t op, const tnode_t *ln, const tnode_t *rn) 1512check_pointer_comparison(op_t op, const tnode_t *ln, const tnode_t *rn)
1513{ 1513{
1514 type_t *ltp, *rtp; 1514 type_t *ltp, *rtp;
1515 tspec_t lst, rst; 1515 tspec_t lst, rst;
1516 const char *lsts, *rsts; 1516 const char *lsts, *rsts;
1517 1517
1518 lst = (ltp = ln->tn_type)->t_subt->t_tspec; 1518 lst = (ltp = ln->tn_type)->t_subt->t_tspec;
1519 rst = (rtp = rn->tn_type)->t_subt->t_tspec; 1519 rst = (rtp = rn->tn_type)->t_subt->t_tspec;
1520 1520
1521 if (lst == VOID || rst == VOID) { 1521 if (lst == VOID || rst == VOID) {
1522 if (sflag && (lst == FUNC || rst == FUNC)) { 1522 if (sflag && (lst == FUNC || rst == FUNC)) {
1523 /* (void *)0 already handled in typeok() */ 1523 /* (void *)0 already handled in typeok() */
1524 *(lst == FUNC ? &lsts : &rsts) = "function pointer"; 1524 *(lst == FUNC ? &lsts : &rsts) = "function pointer";
1525 *(lst == VOID ? &lsts : &rsts) = "'void *'"; 1525 *(lst == VOID ? &lsts : &rsts) = "'void *'";
1526 /* ANSI C forbids comparison of %s with %s */ 1526 /* ANSI C forbids comparison of %s with %s */
1527 warning(274, lsts, rsts); 1527 warning(274, lsts, rsts);
1528 } 1528 }
1529 return; 1529 return;
1530 } 1530 }
1531 1531
1532 if (!eqtype(ltp->t_subt, rtp->t_subt, true, false, NULL)) { 1532 if (!eqtype(ltp->t_subt, rtp->t_subt, true, false, NULL)) {
1533 warn_incompatible_pointers(&modtab[op], ltp, rtp); 1533 warn_incompatible_pointers(&modtab[op], ltp, rtp);
1534 return; 1534 return;
1535 } 1535 }
1536 1536
1537 if (lst == FUNC && rst == FUNC) { 1537 if (lst == FUNC && rst == FUNC) {
1538 if (sflag && op != EQ && op != NE) 1538 if (sflag && op != EQ && op != NE)
1539 /* ANSI C forbids ordered comparisons of ... */ 1539 /* ANSI C forbids ordered comparisons of ... */
1540 warning(125); 1540 warning(125);
1541 } 1541 }
1542} 1542}
1543 1543
1544/* 1544/*
1545 * Checks type compatibility for ASSIGN, INIT, FARG and RETURN 1545 * Checks type compatibility for ASSIGN, INIT, FARG and RETURN
1546 * and prints warnings/errors if necessary. 1546 * and prints warnings/errors if necessary.
1547 * If the types are (almost) compatible, 1 is returned, otherwise 0. 1547 * If the types are (almost) compatible, 1 is returned, otherwise 0.
1548 */ 1548 */
1549static bool 1549static bool
1550check_assign_types_compatible(op_t op, int arg, 1550check_assign_types_compatible(op_t op, int arg,
1551 const tnode_t *ln, const tnode_t *rn) 1551 const tnode_t *ln, const tnode_t *rn)
1552{ 1552{
1553 tspec_t lt, rt, lst = NOTSPEC, rst = NOTSPEC; 1553 tspec_t lt, rt, lst = NOTSPEC, rst = NOTSPEC;
1554 type_t *ltp, *rtp, *lstp = NULL, *rstp = NULL; 1554 type_t *ltp, *rtp, *lstp = NULL, *rstp = NULL;
1555 const mod_t *mp; 1555 const mod_t *mp;
1556 const char *lts, *rts; 1556 const char *lts, *rts;
1557 1557
1558 if ((lt = (ltp = ln->tn_type)->t_tspec) == PTR) 1558 if ((lt = (ltp = ln->tn_type)->t_tspec) == PTR)
1559 lst = (lstp = ltp->t_subt)->t_tspec; 1559 lst = (lstp = ltp->t_subt)->t_tspec;
1560 if ((rt = (rtp = rn->tn_type)->t_tspec) == PTR) 1560 if ((rt = (rtp = rn->tn_type)->t_tspec) == PTR)
1561 rst = (rstp = rtp->t_subt)->t_tspec; 1561 rst = (rstp = rtp->t_subt)->t_tspec;
1562 mp = &modtab[op]; 1562 mp = &modtab[op];
1563 1563
1564 if (lt == BOOL && is_scalar(rt)) /* C99 6.3.1.2 */ 1564 if (lt == BOOL && is_scalar(rt)) /* C99 6.3.1.2 */
1565 return true; 1565 return true;
1566 1566
1567 if (is_arithmetic(lt) && (is_arithmetic(rt) || rt == BOOL)) 1567 if (is_arithmetic(lt) && (is_arithmetic(rt) || rt == BOOL))
1568 return true; 1568 return true;
1569 1569
1570 if ((lt == STRUCT || lt == UNION) && (rt == STRUCT || rt == UNION)) 1570 if ((lt == STRUCT || lt == UNION) && (rt == STRUCT || rt == UNION))
1571 /* both are struct or union */ 1571 /* both are struct or union */
1572 return ltp->t_str == rtp->t_str; 1572 return ltp->t_str == rtp->t_str;
1573 1573
1574 /* a null pointer may be assigned to any pointer */ 1574 /* a null pointer may be assigned to any pointer */
1575 if (lt == PTR && is_null_pointer(rn)) 1575 if (lt == PTR && is_null_pointer(rn))
1576 return true; 1576 return true;
1577 1577
1578 if (lt == PTR && rt == PTR && (lst == VOID || rst == VOID)) { 1578 if (lt == PTR && rt == PTR && (lst == VOID || rst == VOID)) {
1579 /* two pointers, at least one pointer to void */ 1579 /* two pointers, at least one pointer to void */
1580 if (sflag && (lst == FUNC || rst == FUNC)) { 1580 if (sflag && (lst == FUNC || rst == FUNC)) {
1581 /* comb. of ptr to func and ptr to void */ 1581 /* comb. of ptr to func and ptr to void */
1582 *(lst == FUNC ? &lts : &rts) = "function pointer"; 1582 *(lst == FUNC ? &lts : &rts) = "function pointer";
1583 *(lst == VOID ? &lts : &rts) = "'void *'"; 1583 *(lst == VOID ? &lts : &rts) = "'void *'";
1584 switch (op) { 1584 switch (op) {
1585 case INIT: 1585 case INIT:
1586 case RETURN: 1586 case RETURN:
1587 /* ANSI C forbids conversion of %s to %s */ 1587 /* ANSI C forbids conversion of %s to %s */
1588 warning(303, rts, lts); 1588 warning(303, rts, lts);
1589 break; 1589 break;
1590 case FARG: 1590 case FARG:
1591 /* ANSI C forbids conv. of %s to %s, arg #%d */ 1591 /* ANSI C forbids conv. of %s to %s, arg #%d */
1592 warning(304, rts, lts, arg); 1592 warning(304, rts, lts, arg);
1593 break; 1593 break;
1594 default: 1594 default:
1595 /* ANSI C forbids conv. of %s to %s, op %s */ 1595 /* ANSI C forbids conv. of %s to %s, op %s */
1596 warning(305, rts, lts, mp->m_name); 1596 warning(305, rts, lts, mp->m_name);
1597 break; 1597 break;
1598 } 1598 }
1599 } 1599 }
1600 } 1600 }
1601 1601
1602 if (lt == PTR && rt == PTR && (lst == VOID || rst == VOID || 1602 if (lt == PTR && rt == PTR && (lst == VOID || rst == VOID ||
1603 eqtype(lstp, rstp, true, false, NULL))) { 1603 eqtype(lstp, rstp, true, false, NULL))) {
1604 /* compatible pointer types (qualifiers ignored) */ 1604 /* compatible pointer types (qualifiers ignored) */
1605 if (!tflag && 1605 if (!tflag &&
1606 ((!lstp->t_const && rstp->t_const) || 1606 ((!lstp->t_const && rstp->t_const) ||
1607 (!lstp->t_volatile && rstp->t_volatile))) { 1607 (!lstp->t_volatile && rstp->t_volatile))) {
1608 /* left side has not all qualifiers of right */ 1608 /* left side has not all qualifiers of right */
1609 switch (op) { 1609 switch (op) {
1610 case INIT: 1610 case INIT:
1611 case RETURN: 1611 case RETURN:
1612 /* incompatible pointer types (%s != %s) */ 1612 /* incompatible pointer types (%s != %s) */
1613 warning(182, type_name(lstp), type_name(rstp)); 1613 warning(182, type_name(lstp), type_name(rstp));
1614 break; 1614 break;
1615 case FARG: 1615 case FARG:
1616 /* converting '%s' to incompatible '%s' ... */ 1616 /* converting '%s' to incompatible '%s' ... */
1617 warning(153, 1617 warning(153,
1618 type_name(rtp), type_name(ltp), arg); 1618 type_name(rtp), type_name(ltp), arg);
1619 break; 1619 break;
1620 default: 1620 default:
1621 /* operands have incompatible pointer type... */ 1621 /* operands have incompatible pointer type... */
1622 warning(128, mp->m_name, 1622 warning(128, mp->m_name,
1623 type_name(lstp), type_name(rstp)); 1623 type_name(lstp), type_name(rstp));
1624 break; 1624 break;
1625 } 1625 }
1626 } 1626 }
1627 return true; 1627 return true;
1628 } 1628 }
1629 1629
1630 if ((lt == PTR && is_integer(rt)) || (is_integer(lt) && rt == PTR)) { 1630 if ((lt == PTR && is_integer(rt)) || (is_integer(lt) && rt == PTR)) {
1631 const char *lx = lt == PTR ? "pointer" : "integer"; 1631 const char *lx = lt == PTR ? "pointer" : "integer";
1632 const char *rx = rt == PTR ? "pointer" : "integer"; 1632 const char *rx = rt == PTR ? "pointer" : "integer";
1633 1633
1634 switch (op) { 1634 switch (op) {
1635 case INIT: 1635 case INIT:
1636 case RETURN: 1636 case RETURN:
1637 /* illegal combination of %s (%s) and %s (%s) */ 1637 /* illegal combination of %s (%s) and %s (%s) */
1638 warning(183, lx, type_name(ltp), rx, type_name(rtp)); 1638 warning(183, lx, type_name(ltp), rx, type_name(rtp));
1639 break; 1639 break;
1640 case FARG: 1640 case FARG:
1641 /* illegal comb. of %s (%s) and %s (%s), arg #%d */ 1641 /* illegal comb. of %s (%s) and %s (%s), arg #%d */
1642 warning(154, 1642 warning(154,
1643 lx, type_name(ltp), rx, type_name(rtp), arg); 1643 lx, type_name(ltp), rx, type_name(rtp), arg);
1644 break; 1644 break;
1645 default: 1645 default:
1646 /* illegal combination of %s (%s) and %s (%s), op %s */ 1646 /* illegal combination of %s (%s) and %s (%s), op %s */
1647 warning(123, 1647 warning(123,
1648 lx, type_name(ltp), rx, type_name(rtp), mp->m_name); 1648 lx, type_name(ltp), rx, type_name(rtp), mp->m_name);
1649 break; 1649 break;
1650 } 1650 }
1651 return true; 1651 return true;
1652 } 1652 }
1653 1653
1654 if (lt == PTR && rt == PTR) { 1654 if (lt == PTR && rt == PTR) {
1655 switch (op) { 1655 switch (op) {
1656 case INIT: 1656 case INIT:
1657 case RETURN: 1657 case RETURN:
1658 warn_incompatible_pointers(NULL, ltp, rtp); 1658 warn_incompatible_pointers(NULL, ltp, rtp);
1659 break; 1659 break;
1660 case FARG: 1660 case FARG:
1661 /* converting '%s' to incompatible '%s' for ... */ 1661 /* converting '%s' to incompatible '%s' for ... */
1662 warning(153, type_name(rtp), type_name(ltp), arg); 1662 warning(153, type_name(rtp), type_name(ltp), arg);
1663 break; 1663 break;
1664 default: 1664 default:
1665 warn_incompatible_pointers(mp, ltp, rtp); 1665 warn_incompatible_pointers(mp, ltp, rtp);
1666 break; 1666 break;
1667 } 1667 }
1668 return true; 1668 return true;
1669 } 1669 }
1670 1670
1671 switch (op) { 1671 switch (op) {
1672 case INIT: 1672 case INIT:
1673 /* cannot initialize '%s' from '%s' */ 1673 /* cannot initialize '%s' from '%s' */
1674 error(185, type_name(ltp), type_name(rtp)); 1674 error(185, type_name(ltp), type_name(rtp));
1675 break; 1675 break;
1676 case RETURN: 1676 case RETURN:
1677 /* return value type mismatch (%s) and (%s) */ 1677 /* return value type mismatch (%s) and (%s) */
1678 error(211, type_name(ltp), type_name(rtp)); 1678 error(211, type_name(ltp), type_name(rtp));
1679 break; 1679 break;
1680 case FARG: 1680 case FARG:
1681 /* argument is incompatible with prototype, arg #%d */ 1681 /* argument is incompatible with prototype, arg #%d */
1682 warning(155, arg); 1682 warning(155, arg);
1683 break; 1683 break;
1684 default: 1684 default:
1685 warn_incompatible_types(op, ltp, lt, rtp, rt); 1685 warn_incompatible_types(op, ltp, lt, rtp, rt);
1686 break; 1686 break;
1687 } 1687 }
1688 1688
1689 return false; 1689 return false;
1690} 1690}
1691 1691
1692/* Prints a warning if a strange operator is used on an enum type. */ 1692/* Prints a warning if a strange operator is used on an enum type. */
1693static void 1693static void
1694check_bad_enum_operation(op_t op, const tnode_t *ln, const tnode_t *rn) 1694check_bad_enum_operation(op_t op, const tnode_t *ln, const tnode_t *rn)
1695{ 1695{
1696 1696
1697 if (!eflag) 1697 if (!eflag)
1698 return; 1698 return;
1699 1699
1700 if (!(ln->tn_type->t_is_enum || 1700 if (!(ln->tn_type->t_is_enum ||
1701 (modtab[op].m_binary && rn->tn_type->t_is_enum))) { 1701 (modtab[op].m_binary && rn->tn_type->t_is_enum))) {
1702 return; 1702 return;
1703 } 1703 }
1704 1704
1705 /* 1705 /*
1706 * Enum as offset to a pointer is an exception (otherwise enums 1706 * Enum as offset to a pointer is an exception (otherwise enums
1707 * could not be used as array indices). 1707 * could not be used as array indices).
1708 */ 1708 */
1709 if (op == PLUS && 1709 if (op == PLUS &&
1710 ((ln->tn_type->t_is_enum && rn->tn_type->t_tspec == PTR) || 1710 ((ln->tn_type->t_is_enum && rn->tn_type->t_tspec == PTR) ||
1711 (rn->tn_type->t_is_enum && ln->tn_type->t_tspec == PTR))) { 1711 (rn->tn_type->t_is_enum && ln->tn_type->t_tspec == PTR))) {
1712 return; 1712 return;
1713 } 1713 }
1714 1714
1715 /* dubious operation on enum, op %s */ 1715 /* dubious operation on enum, op %s */
1716 warning(241, getopname(op)); 1716 warning(241, getopname(op));
1717 1717
1718} 1718}
1719 1719
1720/* 1720/*
1721 * Prints a warning if an operator is applied to two different enum types. 1721 * Prints a warning if an operator is applied to two different enum types.
1722 */ 1722 */
1723static void 1723static void
1724check_enum_type_mismatch(op_t op, int arg, const tnode_t *ln, const tnode_t *rn) 1724check_enum_type_mismatch(op_t op, int arg, const tnode_t *ln, const tnode_t *rn)
1725{ 1725{
1726 const mod_t *mp; 1726 const mod_t *mp;
1727 1727
1728 mp = &modtab[op]; 1728 mp = &modtab[op];
1729 1729
1730 if (ln->tn_type->t_enum != rn->tn_type->t_enum) { 1730 if (ln->tn_type->t_enum != rn->tn_type->t_enum) {
1731 switch (op) { 1731 switch (op) {
1732 case INIT: 1732 case INIT:
1733 /* enum type mismatch between '%s' and '%s' in ... */ 1733 /* enum type mismatch between '%s' and '%s' in ... */
1734 warning(210, 1734 warning(210,
1735 type_name(ln->tn_type), type_name(rn->tn_type)); 1735 type_name(ln->tn_type), type_name(rn->tn_type));
1736 break; 1736 break;
1737 case FARG: 1737 case FARG:
1738 /* enum type mismatch, arg #%d (%s != %s) */ 1738 /* enum type mismatch, arg #%d (%s != %s) */
1739 warning(156, arg, 1739 warning(156, arg,
1740 type_name(ln->tn_type), type_name(rn->tn_type)); 1740 type_name(ln->tn_type), type_name(rn->tn_type));
1741 break; 1741 break;
1742 case RETURN: 1742 case RETURN:
1743 /* return value type mismatch (%s) and (%s) */ 1743 /* return value type mismatch (%s) and (%s) */
1744 warning(211, 1744 warning(211,
1745 type_name(ln->tn_type), type_name(rn->tn_type)); 1745 type_name(ln->tn_type), type_name(rn->tn_type));
1746 break; 1746 break;
1747 default: 1747 default:
1748 /* enum type mismatch: '%s' '%s' '%s' */ 1748 /* enum type mismatch: '%s' '%s' '%s' */
1749 warning(130, type_name(ln->tn_type), mp->m_name, 1749 warning(130, type_name(ln->tn_type), mp->m_name,
1750 type_name(rn->tn_type)); 1750 type_name(rn->tn_type));
1751 break; 1751 break;
1752 } 1752 }
1753 } else if (Pflag && mp->m_comparison && op != EQ && op != NE) { 1753 } else if (Pflag && mp->m_comparison && op != EQ && op != NE) {
1754 if (eflag) 1754 if (eflag)
1755 /* dubious comparison of enums, op %s */ 1755 /* dubious comparison of enums, op %s */
1756 warning(243, mp->m_name); 1756 warning(243, mp->m_name);
1757 } 1757 }
1758} 1758}
1759 1759
1760/* Prints a warning if the operands mix between enum and integer. */ 1760/* Prints a warning if the operands mix between enum and integer. */
1761static void 1761static void
1762check_enum_int_mismatch(op_t op, int arg, const tnode_t *ln, const tnode_t *rn) 1762check_enum_int_mismatch(op_t op, int arg, const tnode_t *ln, const tnode_t *rn)
1763{ 1763{
1764 1764
1765 if (!eflag) 1765 if (!eflag)
1766 return; 1766 return;
1767 1767
1768 switch (op) { 1768 switch (op) {
1769 case INIT: 1769 case INIT:
1770 /* 1770 /*
1771 * Initialization with 0 is allowed. Otherwise, all implicit 1771 * Initialization with 0 is allowed. Otherwise, all implicit
1772 * initializations would need to be warned upon as well. 1772 * initializations would need to be warned upon as well.
1773 */ 1773 */
1774 if (!rn->tn_type->t_is_enum && rn->tn_op == CON && 1774 if (!rn->tn_type->t_is_enum && rn->tn_op == CON &&
1775 is_integer(rn->tn_type->t_tspec) && 1775 is_integer(rn->tn_type->t_tspec) &&
1776 rn->tn_val->v_quad == 0) { 1776 rn->tn_val->v_quad == 0) {
1777 return; 1777 return;
1778 } 1778 }
1779 /* initialization of '%s' with '%s' */ 1779 /* initialization of '%s' with '%s' */
1780 warning(277, type_name(ln->tn_type), type_name(rn->tn_type)); 1780 warning(277, type_name(ln->tn_type), type_name(rn->tn_type));
1781 break; 1781 break;
1782 case FARG: 1782 case FARG:
1783 /* combination of '%s' and '%s', arg #%d */ 1783 /* combination of '%s' and '%s', arg #%d */
1784 warning(278, 1784 warning(278,
1785 type_name(ln->tn_type), type_name(rn->tn_type), arg); 1785 type_name(ln->tn_type), type_name(rn->tn_type), arg);
1786 break; 1786 break;
1787 case RETURN: 1787 case RETURN:
1788 /* combination of '%s' and '%s' in return */ 1788 /* combination of '%s' and '%s' in return */
1789 warning(279, type_name(ln->tn_type), type_name(rn->tn_type)); 1789 warning(279, type_name(ln->tn_type), type_name(rn->tn_type));
1790 break; 1790 break;
1791 default: 1791 default:
1792 /* combination of '%s' and '%s', op %s */ 1792 /* combination of '%s' and '%s', op %s */
1793 warning(242, type_name(ln->tn_type), type_name(rn->tn_type), 1793 warning(242, type_name(ln->tn_type), type_name(rn->tn_type),
1794 getopname(op)); 1794 getopname(op));
1795 break; 1795 break;
1796 } 1796 }
1797} 1797}
1798 1798
1799/* 1799/*
1800 * Build and initialize a new node. 1800 * Build and initialize a new node.
1801 */ 1801 */
1802static tnode_t * 1802static tnode_t *
1803new_tnode(op_t op, type_t *type, tnode_t *ln, tnode_t *rn) 1803new_tnode(op_t op, type_t *type, tnode_t *ln, tnode_t *rn)
1804{ 1804{
1805 tnode_t *ntn; 1805 tnode_t *ntn;
1806 tspec_t t; 1806 tspec_t t;
1807#ifdef notyet 1807#ifdef notyet
1808 size_t l; 1808 size_t l;
1809 uint64_t rnum; 1809 uint64_t rnum;
1810#endif 1810#endif
1811 1811
1812 ntn = getnode(); 1812 ntn = getnode();
1813 1813
1814 ntn->tn_op = op; 1814 ntn->tn_op = op;
1815 ntn->tn_type = type; 1815 ntn->tn_type = type;
1816 if (ln->tn_from_system_header) 1816 if (ln->tn_from_system_header)
1817 ntn->tn_from_system_header = true; 1817 ntn->tn_from_system_header = true;
1818 if (rn != NULL && rn->tn_from_system_header) 1818 if (rn != NULL && rn->tn_from_system_header)
1819 ntn->tn_from_system_header = true; 1819 ntn->tn_from_system_header = true;
1820 ntn->tn_left = ln; 1820 ntn->tn_left = ln;
1821 ntn->tn_right = rn; 1821 ntn->tn_right = rn;
1822 1822
1823 switch (op) { 1823 switch (op) {
1824#ifdef notyet 1824#ifdef notyet
1825 case SHR: 1825 case SHR:
1826 if (rn->tn_op != CON) 1826 if (rn->tn_op != CON)
1827 break; 1827 break;
1828 rnum = rn->tn_val->v_quad; 1828 rnum = rn->tn_val->v_quad;
1829 l = type_size_in_bits(ln->tn_type) / CHAR_SIZE; 1829 l = type_size_in_bits(ln->tn_type) / CHAR_SIZE;
1830 t = ln->tn_type->t_tspec; 1830 t = ln->tn_type->t_tspec;
1831 switch (l) { 1831 switch (l) {
1832 case 8: 1832 case 8:
1833 if (rnum >= 56) 1833 if (rnum >= 56)
1834 t = UCHAR; 1834 t = UCHAR;
1835 else if (rnum >= 48) 1835 else if (rnum >= 48)
1836 t = USHORT; 1836 t = USHORT;
1837 else if (rnum >= 32) 1837 else if (rnum >= 32)
1838 t = UINT; 1838 t = UINT;
1839 break; 1839 break;
1840 case 4: 1840 case 4:
1841 if (rnum >= 24) 1841 if (rnum >= 24)
1842 t = UCHAR; 1842 t = UCHAR;
1843 else if (rnum >= 16) 1843 else if (rnum >= 16)
1844 t = USHORT; 1844 t = USHORT;
1845 break; 1845 break;
1846 case 2: 1846 case 2:
1847 if (rnum >= 8) 1847 if (rnum >= 8)
1848 t = UCHAR; 1848 t = UCHAR;
1849 break; 1849 break;
1850 default: 1850 default:
1851 break; 1851 break;
1852 } 1852 }
1853 if (t != ln->tn_type->t_tspec) 1853 if (t != ln->tn_type->t_tspec)
1854 ntn->tn_type->t_tspec = t; 1854 ntn->tn_type->t_tspec = t;
1855 break; 1855 break;
1856#endif 1856#endif
1857 case INDIR: 1857 case INDIR:
1858 case FSEL: 1858 case FSEL:
1859 lint_assert(ln->tn_type->t_tspec == PTR); 1859 lint_assert(ln->tn_type->t_tspec == PTR);
1860 t = ln->tn_type->t_subt->t_tspec; 1860 t = ln->tn_type->t_subt->t_tspec;
1861 if (t != FUNC && t != VOID) 1861 if (t != FUNC && t != VOID)
1862 ntn->tn_lvalue = true; 1862 ntn->tn_lvalue = true;
1863 break; 1863 break;
1864 default: 1864 default:
1865 break; 1865 break;
1866 } 1866 }
1867 1867
1868 return ntn; 1868 return ntn;
1869} 1869}
1870 1870
1871/* 1871/*
1872 * Performs the "integer promotions" (C99 6.3.1.1p2), which convert small 1872 * Performs the "integer promotions" (C99 6.3.1.1p2), which convert small
1873 * integer types to either int or unsigned int. 1873 * integer types to either int or unsigned int.
1874 * 1874 *
1875 * If tflag is set or the operand is a function argument with no type 1875 * If tflag is set or the operand is a function argument with no type
1876 * information (no prototype or variable # of args), converts float to double. 1876 * information (no prototype or variable # of args), converts float to double.
1877 */ 1877 */
1878tnode_t * 1878tnode_t *
1879promote(op_t op, bool farg, tnode_t *tn) 1879promote(op_t op, bool farg, tnode_t *tn)
1880{ 1880{
1881 tspec_t t; 1881 tspec_t t;
1882 type_t *ntp; 1882 type_t *ntp;
1883 u_int len; 1883 u_int len;
1884 1884
1885 t = tn->tn_type->t_tspec; 1885 t = tn->tn_type->t_tspec;
1886 1886
1887 if (!is_arithmetic(t)) 1887 if (!is_arithmetic(t))
1888 return tn; 1888 return tn;
1889 1889
1890 if (!tflag) { 1890 if (!tflag) {
1891 /* 1891 /*
1892 * ANSI C requires that the result is always of type INT 1892 * ANSI C requires that the result is always of type INT
1893 * if INT can represent all possible values of the previous 1893 * if INT can represent all possible values of the previous
1894 * type. 1894 * type.
1895 */ 1895 */
1896 if (tn->tn_type->t_bitfield) { 1896 if (tn->tn_type->t_bitfield) {
1897 len = tn->tn_type->t_flen; 1897 len = tn->tn_type->t_flen;
1898 if (size_in_bits(INT) > len) { 1898 if (size_in_bits(INT) > len) {
1899 t = INT; 1899 t = INT;
1900 } else { 1900 } else {
1901 lint_assert(len == size_in_bits(INT)); 1901 lint_assert(len == size_in_bits(INT));
1902 if (is_uinteger(t)) { 1902 if (is_uinteger(t)) {
1903 t = UINT; 1903 t = UINT;
1904 } else { 1904 } else {
1905 t = INT; 1905 t = INT;
1906 } 1906 }
1907 } 1907 }
1908 } else if (t == CHAR || t == UCHAR || t == SCHAR) { 1908 } else if (t == CHAR || t == UCHAR || t == SCHAR) {
1909 t = (size_in_bits(CHAR) < size_in_bits(INT) 1909 t = (size_in_bits(CHAR) < size_in_bits(INT)
1910 || t != UCHAR) ? INT : UINT; 1910 || t != UCHAR) ? INT : UINT;
1911 } else if (t == SHORT || t == USHORT) { 1911 } else if (t == SHORT || t == USHORT) {
1912 t = (size_in_bits(SHORT) < size_in_bits(INT) 1912 t = (size_in_bits(SHORT) < size_in_bits(INT)
1913 || t == SHORT) ? INT : UINT; 1913 || t == SHORT) ? INT : UINT;
1914 } else if (t == ENUM) { 1914 } else if (t == ENUM) {
1915 t = INT; 1915 t = INT;
1916 } else if (farg && t == FLOAT) { 1916 } else if (farg && t == FLOAT) {
1917 t = DOUBLE; 1917 t = DOUBLE;
1918 } 1918 }
1919 } else { 1919 } else {
1920 /* 1920 /*
1921 * In traditional C, keep unsigned and promote FLOAT 1921 * In traditional C, keep unsigned and promote FLOAT
1922 * to DOUBLE. 1922 * to DOUBLE.
1923 */ 1923 */
1924 if (t == UCHAR || t == USHORT) { 1924 if (t == UCHAR || t == USHORT) {
1925 t = UINT; 1925 t = UINT;
1926 } else if (t == CHAR || t == SCHAR || t == SHORT) { 1926 } else if (t == CHAR || t == SCHAR || t == SHORT) {
1927 t = INT; 1927 t = INT;
1928 } else if (t == FLOAT) { 1928 } else if (t == FLOAT) {
1929 t = DOUBLE; 1929 t = DOUBLE;
1930 } else if (t == ENUM) { 1930 } else if (t == ENUM) {
1931 t = INT; 1931 t = INT;
1932 } 1932 }
1933 } 1933 }
1934 1934
1935 if (t != tn->tn_type->t_tspec) { 1935 if (t != tn->tn_type->t_tspec) {
1936 ntp = tduptyp(tn->tn_type); 1936 ntp = tduptyp(tn->tn_type);
1937 ntp->t_tspec = t; 1937 ntp->t_tspec = t;
1938 /* 1938 /*
1939 * Keep t_is_enum so we are later able to check compatibility 1939 * Keep t_is_enum so we are later able to check compatibility
1940 * of enum types. 1940 * of enum types.
1941 */ 1941 */
1942 tn = convert(op, 0, ntp, tn); 1942 tn = convert(op, 0, ntp, tn);
1943 } 1943 }
1944 1944
1945 return tn; 1945 return tn;
1946} 1946}
1947 1947
1948/* 1948/*
1949 * Apply the "usual arithmetic conversions" (C99 6.3.1.8). 1949 * Apply the "usual arithmetic conversions" (C99 6.3.1.8).
1950 * 1950 *
1951 * This gives both operands the same type. 1951 * This gives both operands the same type.
1952 * This is done in different ways for traditional C and C90. 1952 * This is done in different ways for traditional C and C90.
1953 */ 1953 */
1954static void 1954static void
1955balance(op_t op, tnode_t **lnp, tnode_t **rnp) 1955balance(op_t op, tnode_t **lnp, tnode_t **rnp)
1956{ 1956{
1957 tspec_t lt, rt, t; 1957 tspec_t lt, rt, t;
1958 int i; 1958 int i;
1959 bool u; 1959 bool u;
1960 type_t *ntp; 1960 type_t *ntp;
1961 static const tspec_t tl[] = { 1961 static const tspec_t tl[] = {
1962 LDOUBLE, DOUBLE, FLOAT, UQUAD, QUAD, ULONG, LONG, UINT, INT, 1962 LDOUBLE, DOUBLE, FLOAT, UQUAD, QUAD, ULONG, LONG, UINT, INT,
1963 }; 1963 };
1964 1964
1965 lt = (*lnp)->tn_type->t_tspec; 1965 lt = (*lnp)->tn_type->t_tspec;
1966 rt = (*rnp)->tn_type->t_tspec; 1966 rt = (*rnp)->tn_type->t_tspec;
1967 1967
1968 if (!is_arithmetic(lt) || !is_arithmetic(rt)) 1968 if (!is_arithmetic(lt) || !is_arithmetic(rt))
1969 return; 1969 return;
1970 1970
1971 if (!tflag) { 1971 if (!tflag) {
1972 if (lt == rt) { 1972 if (lt == rt) {
1973 t = lt; 1973 t = lt;
1974 } else if (lt == LCOMPLEX || rt == LCOMPLEX) { 1974 } else if (lt == LCOMPLEX || rt == LCOMPLEX) {
1975 t = LCOMPLEX; 1975 t = LCOMPLEX;
1976 } else if (lt == DCOMPLEX || rt == DCOMPLEX) { 1976 } else if (lt == DCOMPLEX || rt == DCOMPLEX) {
1977 t = DCOMPLEX; 1977 t = DCOMPLEX;
1978 } else if (lt == COMPLEX || rt == COMPLEX) { 1978 } else if (lt == COMPLEX || rt == COMPLEX) {
1979 t = COMPLEX; 1979 t = COMPLEX;
1980 } else if (lt == FCOMPLEX || rt == FCOMPLEX) { 1980 } else if (lt == FCOMPLEX || rt == FCOMPLEX) {
1981 t = FCOMPLEX; 1981 t = FCOMPLEX;
1982 } else if (lt == LDOUBLE || rt == LDOUBLE) { 1982 } else if (lt == LDOUBLE || rt == LDOUBLE) {
1983 t = LDOUBLE; 1983 t = LDOUBLE;
1984 } else if (lt == DOUBLE || rt == DOUBLE) { 1984 } else if (lt == DOUBLE || rt == DOUBLE) {
1985 t = DOUBLE; 1985 t = DOUBLE;
1986 } else if (lt == FLOAT || rt == FLOAT) { 1986 } else if (lt == FLOAT || rt == FLOAT) {
1987 t = FLOAT; 1987 t = FLOAT;
1988 } else { 1988 } else {
1989 /* 1989 /*
1990 * If type A has more bits than type B it should 1990 * If type A has more bits than type B it should
1991 * be able to hold all possible values of type B. 1991 * be able to hold all possible values of type B.
1992 */ 1992 */
1993 if (size_in_bits(lt) > size_in_bits(rt)) { 1993 if (size_in_bits(lt) > size_in_bits(rt)) {
1994 t = lt; 1994 t = lt;
1995 } else if (size_in_bits(lt) < size_in_bits(rt)) { 1995 } else if (size_in_bits(lt) < size_in_bits(rt)) {
1996 t = rt; 1996 t = rt;
1997 } else { 1997 } else {
1998 for (i = 3; tl[i] != INT; i++) { 1998 for (i = 3; tl[i] != INT; i++) {
1999 if (tl[i] == lt || tl[i] == rt) 1999 if (tl[i] == lt || tl[i] == rt)
2000 break; 2000 break;
2001 } 2001 }
2002 if ((is_uinteger(lt) || is_uinteger(rt)) && 2002 if ((is_uinteger(lt) || is_uinteger(rt)) &&
2003 !is_uinteger(tl[i])) { 2003 !is_uinteger(tl[i])) {
2004 i--; 2004 i--;
2005 } 2005 }
2006 t = tl[i]; 2006 t = tl[i];
2007 } 2007 }
2008 } 2008 }
2009 } else { 2009 } else {
2010 /* Keep unsigned in traditional C */ 2010 /* Keep unsigned in traditional C */
2011 u = is_uinteger(lt) || is_uinteger(rt); 2011 u = is_uinteger(lt) || is_uinteger(rt);
2012 for (i = 0; tl[i] != INT; i++) { 2012 for (i = 0; tl[i] != INT; i++) {
2013 if (lt == tl[i] || rt == tl[i]) 2013 if (lt == tl[i] || rt == tl[i])
2014 break; 2014 break;
2015 } 2015 }
2016 t = tl[i]; 2016 t = tl[i];
2017 if (u && is_integer(t) && !is_uinteger(t)) 2017 if (u && is_integer(t) && !is_uinteger(t))
2018 t = unsigned_type(t); 2018 t = unsigned_type(t);
2019 } 2019 }
2020 2020
2021 if (t != lt) { 2021 if (t != lt) {
2022 ntp = tduptyp((*lnp)->tn_type); 2022 ntp = tduptyp((*lnp)->tn_type);
2023 ntp->t_tspec = t; 2023 ntp->t_tspec = t;
2024 *lnp = convert(op, 0, ntp, *lnp); 2024 *lnp = convert(op, 0, ntp, *lnp);
2025 } 2025 }
2026 if (t != rt) { 2026 if (t != rt) {
2027 ntp = tduptyp((*rnp)->tn_type); 2027 ntp = tduptyp((*rnp)->tn_type);
2028 ntp->t_tspec = t; 2028 ntp->t_tspec = t;
2029 *rnp = convert(op, 0, ntp, *rnp); 2029 *rnp = convert(op, 0, ntp, *rnp);
2030 } 2030 }
2031} 2031}
2032 2032
2033/* 2033/*
2034 * Insert a conversion operator, which converts the type of the node 2034 * Insert a conversion operator, which converts the type of the node
2035 * to another given type. 2035 * to another given type.
2036 * If op is FARG, arg is the number of the argument (used for warnings). 2036 * If op is FARG, arg is the number of the argument (used for warnings).
2037 */ 2037 */
2038tnode_t * 2038tnode_t *
2039convert(op_t op, int arg, type_t *tp, tnode_t *tn) 2039convert(op_t op, int arg, type_t *tp, tnode_t *tn)
2040{ 2040{
2041 tnode_t *ntn; 2041 tnode_t *ntn;
2042 tspec_t nt, ot; 2042 tspec_t nt, ot;
2043 2043
2044 nt = tp->t_tspec; 2044 nt = tp->t_tspec;
2045 ot = tn->tn_type->t_tspec; 2045 ot = tn->tn_type->t_tspec;
2046 2046
2047 if (!tflag && !sflag && op == FARG) 2047 if (!tflag && !sflag && op == FARG)
2048 check_prototype_conversion(arg, nt, ot, tp, tn); 2048 check_prototype_conversion(arg, nt, ot, tp, tn);
2049 if (is_integer(nt) && is_integer(ot)) { 2049 if (is_integer(nt) && is_integer(ot)) {
2050 check_integer_conversion(op, arg, nt, ot, tp, tn); 2050 check_integer_conversion(op, arg, nt, ot, tp, tn);
2051 } else if (nt == PTR && is_null_pointer(tn)) { 2051 } else if (nt == PTR && is_null_pointer(tn)) {
2052 /* a null pointer may be assigned to any pointer. */ 2052 /* a null pointer may be assigned to any pointer. */
2053 } else if (is_integer(nt) && nt != BOOL && ot == PTR) { 2053 } else if (is_integer(nt) && nt != BOOL && ot == PTR) {
2054 check_pointer_integer_conversion(op, nt, tp, tn); 2054 check_pointer_integer_conversion(op, nt, tp, tn);
2055 } else if (nt == PTR && ot == PTR) { 2055 } else if (nt == PTR && ot == PTR) {
2056 check_pointer_conversion(op, tn, tp); 2056 check_pointer_conversion(op, tn, tp);
2057 } 2057 }
2058 2058
2059 ntn = getnode(); 2059 ntn = getnode();
2060 ntn->tn_op = CVT; 2060 ntn->tn_op = CVT;
2061 ntn->tn_type = tp; 2061 ntn->tn_type = tp;
2062 ntn->tn_cast = op == CVT; 2062 ntn->tn_cast = op == CVT;
2063 ntn->tn_from_system_header |= tn->tn_from_system_header; 2063 ntn->tn_from_system_header |= tn->tn_from_system_header;
2064 ntn->tn_right = NULL; 2064 ntn->tn_right = NULL;
2065 if (tn->tn_op != CON || nt == VOID) { 2065 if (tn->tn_op != CON || nt == VOID) {
2066 ntn->tn_left = tn; 2066 ntn->tn_left = tn;
2067 } else { 2067 } else {
2068 ntn->tn_op = CON; 2068 ntn->tn_op = CON;
2069 ntn->tn_val = tgetblk(sizeof *ntn->tn_val); 2069 ntn->tn_val = tgetblk(sizeof *ntn->tn_val);
2070 convert_constant(op, arg, ntn->tn_type, ntn->tn_val, 2070 convert_constant(op, arg, ntn->tn_type, ntn->tn_val,
2071 tn->tn_val); 2071 tn->tn_val);
2072 } 2072 }
2073 2073
2074 return ntn; 2074 return ntn;
2075} 2075}
2076 2076
2077/* 2077/*
2078 * Print a warning if a prototype causes a type conversion that is 2078 * Print a warning if a prototype causes a type conversion that is
2079 * different from what would happen to the same argument in the 2079 * different from what would happen to the same argument in the
2080 * absence of a prototype. 2080 * absence of a prototype.
2081 * 2081 *
2082 * Errors/warnings about illegal type combinations are already printed 2082 * Errors/warnings about illegal type combinations are already printed
2083 * in check_assign_types_compatible(). 2083 * in check_assign_types_compatible().
2084 */ 2084 */
2085static void 2085static void
2086check_prototype_conversion(int arg, tspec_t nt, tspec_t ot, type_t *tp, 2086check_prototype_conversion(int arg, tspec_t nt, tspec_t ot, type_t *tp,
2087 tnode_t *tn) 2087 tnode_t *tn)
2088{ 2088{
2089 tnode_t *ptn; 2089 tnode_t *ptn;
2090 2090
2091 if (!is_arithmetic(nt) || !is_arithmetic(ot)) 2091 if (!is_arithmetic(nt) || !is_arithmetic(ot))
2092 return; 2092 return;
2093 2093
2094 /* 2094 /*
2095 * If the type of the formal parameter is char/short, a warning 2095 * If the type of the formal parameter is char/short, a warning
2096 * would be useless, because functions declared the old style 2096 * would be useless, because functions declared the old style
2097 * can't expect char/short arguments. 2097 * can't expect char/short arguments.
2098 */ 2098 */
2099 /* XXX: what about SCHAR? */ 2099 /* XXX: what about SCHAR? */
2100 if (nt == CHAR || nt == UCHAR || nt == SHORT || nt == USHORT) 2100 if (nt == CHAR || nt == UCHAR || nt == SHORT || nt == USHORT)
2101 return; 2101 return;
2102 2102
2103 /* get default promotion */ 2103 /* get default promotion */
2104 ptn = promote(NOOP, true, tn); 2104 ptn = promote(NOOP, true, tn);
2105 ot = ptn->tn_type->t_tspec; 2105 ot = ptn->tn_type->t_tspec;
2106 2106
2107 /* return if types are the same with and without prototype */ 2107 /* return if types are the same with and without prototype */
2108 if (nt == ot || (nt == ENUM && ot == INT)) 2108 if (nt == ot || (nt == ENUM && ot == INT))
2109 return; 2109 return;
2110 2110
2111 if (is_floating(nt) != is_floating(ot) || 2111 if (is_floating(nt) != is_floating(ot) ||
2112 portable_size_in_bits(nt) != portable_size_in_bits(ot)) { 2112 portable_size_in_bits(nt) != portable_size_in_bits(ot)) {
2113 /* representation and/or width change */ 2113 /* representation and/or width change */
2114 if (!is_integer(ot) || 2114 if (!is_integer(ot) ||
2115 portable_size_in_bits(ot) > portable_size_in_bits(INT)) { 2115 portable_size_in_bits(ot) > portable_size_in_bits(INT)) {
2116 /* argument #%d is converted from '%s' to '%s' ... */ 2116 /* argument #%d is converted from '%s' to '%s' ... */
2117 warning(259, 2117 warning(259,
2118 arg, type_name(tn->tn_type), type_name(tp)); 2118 arg, type_name(tn->tn_type), type_name(tp));
2119 } 2119 }
2120 } else if (hflag) { 2120 } else if (hflag) {
2121 /* 2121 /*
2122 * they differ in sign or base type (char, short, int, 2122 * they differ in sign or base type (char, short, int,
2123 * long, long long, float, double, long double) 2123 * long, long long, float, double, long double)
2124 * 2124 *
2125 * if they differ only in sign and the argument is a constant 2125 * if they differ only in sign and the argument is a constant
2126 * and the msb of the argument is not set, print no warning 2126 * and the msb of the argument is not set, print no warning
2127 */ 2127 */
2128 if (ptn->tn_op == CON && is_integer(nt) && 2128 if (ptn->tn_op == CON && is_integer(nt) &&
2129 signed_type(nt) == signed_type(ot) && 2129 signed_type(nt) == signed_type(ot) &&
2130 msb(ptn->tn_val->v_quad, ot, -1) == 0) { 2130 msb(ptn->tn_val->v_quad, ot, -1) == 0) {
2131 /* ok */ 2131 /* ok */
2132 } else { 2132 } else {
2133 /* argument #%d is converted from '%s' to '%s' ... */ 2133 /* argument #%d is converted from '%s' to '%s' ... */
2134 warning(259, 2134 warning(259,
2135 arg, type_name(tn->tn_type), type_name(tp)); 2135 arg, type_name(tn->tn_type), type_name(tp));
2136 } 2136 }
2137 } 2137 }
2138} 2138}
2139 2139
2140/* 2140/*
2141 * Print warnings for conversions of integer types which may cause problems. 2141 * Print warnings for conversions of integer types which may cause problems.
2142 */ 2142 */
2143/* ARGSUSED */ 2143/* ARGSUSED */
2144static void 2144static void
2145check_integer_conversion(op_t op, int arg, tspec_t nt, tspec_t ot, type_t *tp, 2145check_integer_conversion(op_t op, int arg, tspec_t nt, tspec_t ot, type_t *tp,
2146 tnode_t *tn) 2146 tnode_t *tn)
2147{ 2147{
2148 char opbuf[16]; 2148 char opbuf[16];
2149 2149
2150 if (tn->tn_op == CON) 2150 if (tn->tn_op == CON)
2151 return; 2151 return;
2152 2152
2153 if (op == CVT) 2153 if (op == CVT)
2154 return; 2154 return;
2155 2155
2156 if (Pflag && portable_size_in_bits(nt) > portable_size_in_bits(ot) && 2156 if (Pflag && portable_size_in_bits(nt) > portable_size_in_bits(ot) &&
2157 is_uinteger(nt) != is_uinteger(ot)) { 2157 is_uinteger(nt) != is_uinteger(ot)) {
2158 if (aflag > 0 && pflag) { 2158 if (aflag > 0 && pflag) {
2159 if (op == FARG) { 2159 if (op == FARG) {
2160 /* conversion to '%s' may sign-extend ... */ 2160 /* conversion to '%s' may sign-extend ... */
2161 warning(297, type_name(tp), arg); 2161 warning(297, type_name(tp), arg);
2162 } else { 2162 } else {
2163 /* conversion to '%s' may sign-extend ... */ 2163 /* conversion to '%s' may sign-extend ... */
2164 warning(131, type_name(tp)); 2164 warning(131, type_name(tp));
2165 } 2165 }
2166 } 2166 }
2167 } 2167 }
2168 2168
2169 if (Pflag && portable_size_in_bits(nt) > portable_size_in_bits(ot)) { 2169 if (Pflag && portable_size_in_bits(nt) > portable_size_in_bits(ot)) {
2170 switch (tn->tn_op) { 2170 switch (tn->tn_op) {
2171 case PLUS: 2171 case PLUS:
2172 case MINUS: 2172 case MINUS:
2173 case MULT: 2173 case MULT:
2174 case SHL: 2174 case SHL:
2175 /* suggest cast from '%s' to '%s' on op %s to ... */ 2175 /* suggest cast from '%s' to '%s' on op %s to ... */
2176 warning(324, type_name(gettyp(ot)), type_name(tp), 2176 warning(324, type_name(gettyp(ot)), type_name(tp),
2177 print_tnode(opbuf, sizeof opbuf, tn)); 2177 print_tnode(opbuf, sizeof opbuf, tn));
2178 break; 2178 break;
2179 default: 2179 default:
2180 break; 2180 break;
2181 } 2181 }
2182 } 2182 }
2183 2183
2184 if (portable_size_in_bits(nt) < portable_size_in_bits(ot) && 2184 if (portable_size_in_bits(nt) < portable_size_in_bits(ot) &&
2185 (ot == LONG || ot == ULONG || ot == QUAD || ot == UQUAD || 2185 (ot == LONG || ot == ULONG || ot == QUAD || ot == UQUAD ||
2186 aflag > 1)) { 2186 aflag > 1)) {
2187 /* conversion from '%s' may lose accuracy */ 2187 /* conversion from '%s' may lose accuracy */
2188 if (aflag > 0) { 2188 if (aflag > 0) {
2189 if (op == FARG) { 2189 if (op == FARG) {
2190 /* conv. from '%s' to '%s' may lose ... */ 2190 /* conv. from '%s' to '%s' may lose ... */
2191 warning(298, 2191 warning(298,
2192 type_name(tn->tn_type), type_name(tp), arg); 2192 type_name(tn->tn_type), type_name(tp), arg);
2193 } else { 2193 } else {
2194 /* conv. from '%s' to '%s' may lose accuracy */ 2194 /* conv. from '%s' to '%s' may lose accuracy */
2195 warning(132, 2195 warning(132,
2196 type_name(tn->tn_type), type_name(tp)); 2196 type_name(tn->tn_type), type_name(tp));
2197 } 2197 }
2198 } 2198 }
2199 } 2199 }
2200} 2200}
2201 2201
2202/* 2202/*
2203 * Print warnings for dubious conversions of pointer to integer. 2203 * Print warnings for dubious conversions of pointer to integer.
2204 */ 2204 */
2205static void 2205static void
2206check_pointer_integer_conversion(op_t op, tspec_t nt, type_t *tp, tnode_t *tn) 2206check_pointer_integer_conversion(op_t op, tspec_t nt, type_t *tp, tnode_t *tn)
2207{ 2207{
2208 2208
2209 if (tn->tn_op == CON) 2209 if (tn->tn_op == CON)
2210 return; 2210 return;
2211 if (op != CVT) 2211 if (op != CVT)
2212 return; /* We got already an error. */ 2212 return; /* We got already an error. */
2213 if (portable_size_in_bits(nt) >= portable_size_in_bits(PTR)) 2213 if (portable_size_in_bits(nt) >= portable_size_in_bits(PTR))
2214 return; 2214 return;
2215 2215
2216 if (pflag && size_in_bits(nt) >= size_in_bits(PTR)) { 2216 if (pflag && size_in_bits(nt) >= size_in_bits(PTR)) {
2217 /* conversion of pointer to '%s' may lose bits */ 2217 /* conversion of pointer to '%s' may lose bits */
2218 warning(134, type_name(tp)); 2218 warning(134, type_name(tp));
2219 } else { 2219 } else {
2220 /* conversion of pointer to '%s' loses bits */ 2220 /* conversion of pointer to '%s' loses bits */
2221 warning(133, type_name(tp)); 2221 warning(133, type_name(tp));
2222 } 2222 }
2223} 2223}
2224 2224
2225static bool 2225static bool
2226should_warn_about_pointer_cast(const type_t *tp, tspec_t nst, 2226should_warn_about_pointer_cast(const type_t *tp, tspec_t nst,
2227 const tnode_t *tn, tspec_t ost) 2227 const tnode_t *tn, tspec_t ost)
2228{ 2228{
2229 if (nst == STRUCT || nst == UNION) 2229 if (nst == STRUCT || nst == UNION)
2230 if (tp->t_subt->t_str != tn->tn_type->t_subt->t_str) 2230 if (tp->t_subt->t_str != tn->tn_type->t_subt->t_str)
2231 return true; 2231 return true;
2232 2232
2233 if (nst == CHAR || nst == UCHAR) 2233 if (nst == CHAR || nst == UCHAR)
2234 return false; /* for the sake of traditional C code */ 2234 return false; /* for the sake of traditional C code */
2235 2235
2236 /* 
2237 * XXX: Why should it be ok to cast between arbitrary structs that 
2238 * just happen to be of the same size? 
2239 */ 
2240 return portable_size_in_bits(nst) != portable_size_in_bits(ost); 2236 return portable_size_in_bits(nst) != portable_size_in_bits(ost);
2241} 2237}
2242 2238
2243/* 2239/*
2244 * Warn about questionable pointer conversions. 2240 * Warn about questionable pointer conversions.
2245 */ 2241 */
2246static void 2242static void
2247check_pointer_conversion(op_t op, tnode_t *tn, type_t *tp) 2243check_pointer_conversion(op_t op, tnode_t *tn, type_t *tp)
2248{ 2244{
2249 tspec_t nst, ost; 2245 tspec_t nst, ost;
2250 const char *nts, *ots; 2246 const char *nts, *ots;
2251 2247
2252 /* 2248 /*
2253 * We got already an error (pointers of different types 2249 * We got already an error (pointers of different types
2254 * without a cast) or we will not get a warning. 2250 * without a cast) or we will not get a warning.
2255 */ 2251 */
2256 if (op != CVT) 2252 if (op != CVT)
2257 return; 2253 return;
2258 2254
2259 nst = tp->t_subt->t_tspec; 2255 nst = tp->t_subt->t_tspec;
2260 ost = tn->tn_type->t_subt->t_tspec; 2256 ost = tn->tn_type->t_subt->t_tspec;
2261 2257
2262 if (nst == VOID || ost == VOID) { 2258 if (nst == VOID || ost == VOID) {
2263 if (sflag && (nst == FUNC || ost == FUNC)) { 2259 if (sflag && (nst == FUNC || ost == FUNC)) {
2264 /* null pointers are already handled in convert() */ 2260 /* null pointers are already handled in convert() */
2265 *(nst == FUNC ? &nts : &ots) = "function pointer"; 2261 *(nst == FUNC ? &nts : &ots) = "function pointer";
2266 *(nst == VOID ? &nts : &ots) = "'void *'"; 2262 *(nst == VOID ? &nts : &ots) = "'void *'";
2267 /* ANSI C forbids conversion of %s to %s */ 2263 /* ANSI C forbids conversion of %s to %s */
2268 warning(303, ots, nts); 2264 warning(303, ots, nts);
2269 } 2265 }
2270 return; 2266 return;
2271 } else if (nst == FUNC && ost == FUNC) { 2267 } else if (nst == FUNC && ost == FUNC) {
2272 return; 2268 return;
2273 } else if (nst == FUNC || ost == FUNC) { 2269 } else if (nst == FUNC || ost == FUNC) {
2274 /* converting '%s' to '%s' is questionable */ 2270 /* converting '%s' to '%s' is questionable */
2275 warning(229, type_name(tn->tn_type), type_name(tp)); 2271 warning(229, type_name(tn->tn_type), type_name(tp));
2276 return; 2272 return;
2277 } 2273 }
2278 2274
2279 if (hflag && alignment_in_bits(tp->t_subt) > 2275 if (hflag && alignment_in_bits(tp->t_subt) >
2280 alignment_in_bits(tn->tn_type->t_subt)) { 2276 alignment_in_bits(tn->tn_type->t_subt)) {
2281 /* converting '%s' to '%s' may cause alignment problem */ 2277 /* converting '%s' to '%s' may cause alignment problem */
2282 warning(135, type_name(tn->tn_type), type_name(tp)); 2278 warning(135, type_name(tn->tn_type), type_name(tp));
2283 } 2279 }
2284 2280
2285 if (cflag && should_warn_about_pointer_cast(tp, nst, tn, ost)) { 2281 if (cflag && should_warn_about_pointer_cast(tp, nst, tn, ost)) {
2286 /* pointer cast from '%s' to '%s' may be troublesome */ 2282 /* pointer cast from '%s' to '%s' may be troublesome */
2287 warning(247, type_name(tn->tn_type), type_name(tp)); 2283 warning(247, type_name(tn->tn_type), type_name(tp));
2288 } 2284 }
2289} 2285}
2290 2286
2291/* 2287/*
2292 * Converts a typed constant to a constant of another type. 2288 * Converts a typed constant to a constant of another type.
2293 * 2289 *
2294 * op operator which requires conversion 2290 * op operator which requires conversion
2295 * arg if op is FARG, # of argument 2291 * arg if op is FARG, # of argument
2296 * tp type in which to convert the constant 2292 * tp type in which to convert the constant
2297 * nv new constant 2293 * nv new constant
2298 * v old constant 2294 * v old constant
2299 */ 2295 */
2300void 2296void
2301convert_constant(op_t op, int arg, const type_t *tp, val_t *nv, val_t *v) 2297convert_constant(op_t op, int arg, const type_t *tp, val_t *nv, val_t *v)
2302{ 2298{
2303 tspec_t ot, nt; 2299 tspec_t ot, nt;
2304 ldbl_t max = 0.0, min = 0.0; 2300 ldbl_t max = 0.0, min = 0.0;
2305 int sz; 2301 int sz;
2306 bool rchk; 2302 bool rchk;
2307 int64_t xmask, xmsk1; 2303 int64_t xmask, xmsk1;
2308 int osz, nsz; 2304 int osz, nsz;
2309 2305
2310 ot = v->v_tspec; 2306 ot = v->v_tspec;
2311 nt = nv->v_tspec = tp->t_tspec; 2307 nt = nv->v_tspec = tp->t_tspec;
2312 rchk = false; 2308 rchk = false;
2313 2309
2314 if (nt == BOOL) { /* C99 6.3.1.2 */ 2310 if (nt == BOOL) { /* C99 6.3.1.2 */
2315 nv->v_ansiu = false; 2311 nv->v_ansiu = false;
2316 nv->v_quad = is_nonzero_val(v) ? 1 : 0; 2312 nv->v_quad = is_nonzero_val(v) ? 1 : 0;
2317 return; 2313 return;
2318 } 2314 }
2319 2315
2320 if (ot == FLOAT || ot == DOUBLE || ot == LDOUBLE) { 2316 if (ot == FLOAT || ot == DOUBLE || ot == LDOUBLE) {
2321 switch (nt) { 2317 switch (nt) {
2322 case CHAR: 2318 case CHAR:
2323 max = TARG_CHAR_MAX; min = TARG_CHAR_MIN; break; 2319 max = TARG_CHAR_MAX; min = TARG_CHAR_MIN; break;
2324 case UCHAR: 2320 case UCHAR:
2325 max = TARG_UCHAR_MAX; min = 0; break; 2321 max = TARG_UCHAR_MAX; min = 0; break;
2326 case SCHAR: 2322 case SCHAR:
2327 max = TARG_SCHAR_MAX; min = TARG_SCHAR_MIN; break; 2323 max = TARG_SCHAR_MAX; min = TARG_SCHAR_MIN; break;
2328 case SHORT: 2324 case SHORT:
2329 max = TARG_SHRT_MAX; min = TARG_SHRT_MIN; break; 2325 max = TARG_SHRT_MAX; min = TARG_SHRT_MIN; break;
2330 case USHORT: 2326 case USHORT:
2331 max = TARG_USHRT_MAX; min = 0; break; 2327 max = TARG_USHRT_MAX; min = 0; break;
2332 case ENUM: 2328 case ENUM:
2333 case INT: 2329 case INT:
2334 max = TARG_INT_MAX; min = TARG_INT_MIN; break; 2330 max = TARG_INT_MAX; min = TARG_INT_MIN; break;
2335 case UINT: 2331 case UINT:
2336 max = (u_int)TARG_UINT_MAX;min = 0; break; 2332 max = (u_int)TARG_UINT_MAX;min = 0; break;
2337 case LONG: 2333 case LONG:
2338 max = TARG_LONG_MAX; min = TARG_LONG_MIN; break; 2334 max = TARG_LONG_MAX; min = TARG_LONG_MIN; break;
2339 case ULONG: 2335 case ULONG:
2340 max = (u_long)TARG_ULONG_MAX; min = 0; break; 2336 max = (u_long)TARG_ULONG_MAX; min = 0; break;
2341 case QUAD: 2337 case QUAD:
2342 max = QUAD_MAX; min = QUAD_MIN; break; 2338 max = QUAD_MAX; min = QUAD_MIN; break;
2343 case UQUAD: 2339 case UQUAD:
2344 max = (uint64_t)UQUAD_MAX; min = 0; break; 2340 max = (uint64_t)UQUAD_MAX; min = 0; break;
2345 case FLOAT: 2341 case FLOAT:
2346 case FCOMPLEX: 2342 case FCOMPLEX:
2347 max = FLT_MAX; min = -FLT_MAX; break; 2343 max = FLT_MAX; min = -FLT_MAX; break;
2348 case DOUBLE: 2344 case DOUBLE:
2349 case DCOMPLEX: 2345 case DCOMPLEX:
2350 max = DBL_MAX; min = -DBL_MAX; break; 2346 max = DBL_MAX; min = -DBL_MAX; break;
2351 case PTR: 2347 case PTR:
2352 /* Got already an error because of float --> ptr */ 2348 /* Got already an error because of float --> ptr */
2353 case LDOUBLE: 2349 case LDOUBLE:
2354 case LCOMPLEX: 2350 case LCOMPLEX:
2355 max = LDBL_MAX; min = -LDBL_MAX; break; 2351 max = LDBL_MAX; min = -LDBL_MAX; break;
2356 default: 2352 default:
2357 lint_assert(/*CONSTCOND*/false); 2353 lint_assert(/*CONSTCOND*/false);
2358 } 2354 }
2359 if (v->v_ldbl > max || v->v_ldbl < min) { 2355 if (v->v_ldbl > max || v->v_ldbl < min) {
2360 lint_assert(nt != LDOUBLE); 2356 lint_assert(nt != LDOUBLE);
2361 if (op == FARG) { 2357 if (op == FARG) {
2362 /* conv. of '%s' to '%s' is out of range, ... */ 2358 /* conv. of '%s' to '%s' is out of range, ... */
2363 warning(295, 2359 warning(295,
2364 type_name(gettyp(ot)), type_name(tp), arg); 2360 type_name(gettyp(ot)), type_name(tp), arg);
2365 } else { 2361 } else {
2366 /* conversion of '%s' to '%s' is out of range */ 2362 /* conversion of '%s' to '%s' is out of range */
2367 warning(119, 2363 warning(119,
2368 type_name(gettyp(ot)), type_name(tp)); 2364 type_name(gettyp(ot)), type_name(tp));
2369 } 2365 }
2370 v->v_ldbl = v->v_ldbl > 0 ? max : min; 2366 v->v_ldbl = v->v_ldbl > 0 ? max : min;
2371 } 2367 }
2372 if (nt == FLOAT) { 2368 if (nt == FLOAT) {
2373 nv->v_ldbl = (float)v->v_ldbl; 2369 nv->v_ldbl = (float)v->v_ldbl;
2374 } else if (nt == DOUBLE) { 2370 } else if (nt == DOUBLE) {
2375 nv->v_ldbl = (double)v->v_ldbl; 2371 nv->v_ldbl = (double)v->v_ldbl;
2376 } else if (nt == LDOUBLE) { 2372 } else if (nt == LDOUBLE) {
2377 nv->v_ldbl = v->v_ldbl; 2373 nv->v_ldbl = v->v_ldbl;
2378 } else { 2374 } else {
2379 nv->v_quad = (nt == PTR || is_uinteger(nt)) ? 2375 nv->v_quad = (nt == PTR || is_uinteger(nt)) ?
2380 (int64_t)v->v_ldbl : (int64_t)v->v_ldbl; 2376 (int64_t)v->v_ldbl : (int64_t)v->v_ldbl;
2381 } 2377 }
2382 } else { 2378 } else {
2383 if (nt == FLOAT) { 2379 if (nt == FLOAT) {
2384 nv->v_ldbl = (ot == PTR || is_uinteger(ot)) ? 2380 nv->v_ldbl = (ot == PTR || is_uinteger(ot)) ?
2385 (float)(uint64_t)v->v_quad : (float)v->v_quad; 2381 (float)(uint64_t)v->v_quad : (float)v->v_quad;
2386 } else if (nt == DOUBLE) { 2382 } else if (nt == DOUBLE) {
2387 nv->v_ldbl = (ot == PTR || is_uinteger(ot)) ? 2383 nv->v_ldbl = (ot == PTR || is_uinteger(ot)) ?
2388 (double)(uint64_t)v->v_quad : (double)v->v_quad; 2384 (double)(uint64_t)v->v_quad : (double)v->v_quad;
2389 } else if (nt == LDOUBLE) { 2385 } else if (nt == LDOUBLE) {
2390 nv->v_ldbl = (ot == PTR || is_uinteger(ot)) ? 2386 nv->v_ldbl = (ot == PTR || is_uinteger(ot)) ?
2391 (ldbl_t)(uint64_t)v->v_quad : (ldbl_t)v->v_quad; 2387 (ldbl_t)(uint64_t)v->v_quad : (ldbl_t)v->v_quad;
2392 } else { 2388 } else {
2393 rchk = true; /* Check for lost precision. */ 2389 rchk = true; /* Check for lost precision. */
2394 nv->v_quad = v->v_quad; 2390 nv->v_quad = v->v_quad;
2395 } 2391 }
2396 } 2392 }
2397 2393
2398 if (v->v_ansiu && is_floating(nt)) { 2394 if (v->v_ansiu && is_floating(nt)) {
2399 /* ANSI C treats constant as unsigned */ 2395 /* ANSI C treats constant as unsigned */
2400 warning(157); 2396 warning(157);
2401 v->v_ansiu = false; 2397 v->v_ansiu = false;
2402 } else if (v->v_ansiu && (is_integer(nt) && !is_uinteger(nt) && 2398 } else if (v->v_ansiu && (is_integer(nt) && !is_uinteger(nt) &&
2403 portable_size_in_bits(nt) > 2399 portable_size_in_bits(nt) >
2404 portable_size_in_bits(ot))) { 2400 portable_size_in_bits(ot))) {
2405 /* ANSI C treats constant as unsigned */ 2401 /* ANSI C treats constant as unsigned */
2406 warning(157); 2402 warning(157);
2407 v->v_ansiu = false; 2403 v->v_ansiu = false;
2408 } 2404 }
2409 2405
2410 switch (nt) { 2406 switch (nt) {
2411 case FLOAT: 2407 case FLOAT:
2412 case FCOMPLEX: 2408 case FCOMPLEX:
2413 case DOUBLE: 2409 case DOUBLE:
2414 case DCOMPLEX: 2410 case DCOMPLEX:
2415 case LDOUBLE: 2411 case LDOUBLE:
2416 case LCOMPLEX: 2412 case LCOMPLEX:
2417 break; 2413 break;
2418 default: 2414 default:
2419 sz = tp->t_bitfield ? tp->t_flen : size_in_bits(nt); 2415 sz = tp->t_bitfield ? tp->t_flen : size_in_bits(nt);
2420 nv->v_quad = xsign(nv->v_quad, nt, sz); 2416 nv->v_quad = xsign(nv->v_quad, nt, sz);
2421 break; 2417 break;
2422 } 2418 }
2423 2419
2424 if (rchk && op != CVT) { 2420 if (rchk && op != CVT) {
2425 osz = size_in_bits(ot); 2421 osz = size_in_bits(ot);
2426 nsz = tp->t_bitfield ? tp->t_flen : size_in_bits(nt); 2422 nsz = tp->t_bitfield ? tp->t_flen : size_in_bits(nt);
2427 xmask = qlmasks[nsz] ^ qlmasks[osz]; 2423 xmask = qlmasks[nsz] ^ qlmasks[osz];
2428 xmsk1 = qlmasks[nsz] ^ qlmasks[osz - 1]; 2424 xmsk1 = qlmasks[nsz] ^ qlmasks[osz - 1];
2429 /* 2425 /*
2430 * For bitwise operations we are not interested in the 2426 * For bitwise operations we are not interested in the
2431 * value, but in the bits itself. 2427 * value, but in the bits itself.
2432 */ 2428 */
2433 if (op == ORASS || op == BITOR || op == BITXOR) { 2429 if (op == ORASS || op == BITOR || op == BITXOR) {
2434 /* 2430 /*
2435 * Print a warning if bits which were set are 2431 * Print a warning if bits which were set are
2436 * lost due to the conversion. 2432 * lost due to the conversion.
2437 * This can happen with operator ORASS only. 2433 * This can happen with operator ORASS only.
2438 */ 2434 */
2439 if (nsz < osz && (v->v_quad & xmask) != 0) { 2435 if (nsz < osz && (v->v_quad & xmask) != 0) {
2440 /* constant truncated by conv., op %s */ 2436 /* constant truncated by conv., op %s */
2441 warning(306, getopname(op)); 2437 warning(306, getopname(op));
2442 } 2438 }
2443 } else if (op == ANDASS || op == BITAND) { 2439 } else if (op == ANDASS || op == BITAND) {
2444 /* 2440 /*
2445 * Print a warning if additional bits are not all 1 2441 * Print a warning if additional bits are not all 1
2446 * and the most significant bit of the old value is 1, 2442 * and the most significant bit of the old value is 1,
2447 * or if at least one (but not all) removed bit was 0. 2443 * or if at least one (but not all) removed bit was 0.
2448 */ 2444 */
2449 if (nsz > osz && 2445 if (nsz > osz &&
2450 (nv->v_quad & qbmasks[osz - 1]) != 0 && 2446 (nv->v_quad & qbmasks[osz - 1]) != 0 &&
2451 (nv->v_quad & xmask) != xmask) { 2447 (nv->v_quad & xmask) != xmask) {
2452 /* extra bits set to 0 in conv. of '%s' ... */ 2448 /* extra bits set to 0 in conv. of '%s' ... */
2453 warning(309, type_name(gettyp(ot)), 2449 warning(309, type_name(gettyp(ot)),
2454 type_name(tp), getopname(op)); 2450 type_name(tp), getopname(op));
2455 } else if (nsz < osz && 2451 } else if (nsz < osz &&
2456 (v->v_quad & xmask) != xmask && 2452 (v->v_quad & xmask) != xmask &&
2457 (v->v_quad & xmask) != 0) { 2453 (v->v_quad & xmask) != 0) {
2458 /* constant truncated by conv., op %s */ 2454 /* constant truncated by conv., op %s */
2459 warning(306, getopname(op)); 2455 warning(306, getopname(op));
2460 } 2456 }
2461 } else if ((nt != PTR && is_uinteger(nt)) && 2457 } else if ((nt != PTR && is_uinteger(nt)) &&
2462 (ot != PTR && !is_uinteger(ot)) && 2458 (ot != PTR && !is_uinteger(ot)) &&
2463 v->v_quad < 0) { 2459 v->v_quad < 0) {
2464 if (op == ASSIGN) { 2460 if (op == ASSIGN) {
2465 /* assignment of negative constant to ... */ 2461 /* assignment of negative constant to ... */
2466 warning(164); 2462 warning(164);
2467 } else if (op == INIT) { 2463 } else if (op == INIT) {
2468 /* initialization of unsigned with neg... */ 2464 /* initialization of unsigned with neg... */
2469 warning(221); 2465 warning(221);
2470 } else if (op == FARG) { 2466 } else if (op == FARG) {
2471 /* conversion of negative constant to ... */ 2467 /* conversion of negative constant to ... */
2472 warning(296, arg); 2468 warning(296, arg);
2473 } else if (modtab[op].m_comparison) { 2469 } else if (modtab[op].m_comparison) {
2474 /* handled by check_integer_comparison() */ 2470 /* handled by check_integer_comparison() */
2475 } else { 2471 } else {
2476 /* conversion of negative constant to ... */ 2472 /* conversion of negative constant to ... */
2477 warning(222); 2473 warning(222);
2478 } 2474 }
2479 } else if (nv->v_quad != v->v_quad && nsz <= osz && 2475 } else if (nv->v_quad != v->v_quad && nsz <= osz &&
2480 (v->v_quad & xmask) != 0 && 2476 (v->v_quad & xmask) != 0 &&
2481 (is_uinteger(ot) || (v->v_quad & xmsk1) != xmsk1)) { 2477 (is_uinteger(ot) || (v->v_quad & xmsk1) != xmsk1)) {
2482 /* 2478 /*
2483 * Loss of significant bit(s). All truncated bits 2479 * Loss of significant bit(s). All truncated bits
2484 * of unsigned types or all truncated bits plus the 2480 * of unsigned types or all truncated bits plus the
2485 * msb of the target for signed types are considered 2481 * msb of the target for signed types are considered
2486 * to be significant bits. Loss of significant bits 2482 * to be significant bits. Loss of significant bits
2487 * means that at least on of the bits was set in an 2483 * means that at least on of the bits was set in an
2488 * unsigned type or that at least one, but not all of 2484 * unsigned type or that at least one, but not all of
2489 * the bits was set in an signed type. 2485 * the bits was set in an signed type.
2490 * Loss of significant bits means that it is not 2486 * Loss of significant bits means that it is not
2491 * possible, also not with necessary casts, to convert 2487 * possible, also not with necessary casts, to convert
2492 * back to the original type. A example for a 2488 * back to the original type. A example for a
2493 * necessary cast is: 2489 * necessary cast is:
2494 * char c; int i; c = 128; 2490 * char c; int i; c = 128;
2495 * i = c; ** yields -128 ** 2491 * i = c; ** yields -128 **
2496 * i = (unsigned char)c; ** yields 128 ** 2492 * i = (unsigned char)c; ** yields 128 **
2497 */ 2493 */
2498 if (op == ASSIGN && tp->t_bitfield) { 2494 if (op == ASSIGN && tp->t_bitfield) {
2499 /* precision lost in bit-field assignment */ 2495 /* precision lost in bit-field assignment */
2500 warning(166); 2496 warning(166);
2501 } else if (op == ASSIGN) { 2497 } else if (op == ASSIGN) {
2502 /* constant truncated by assignment */ 2498 /* constant truncated by assignment */
2503 warning(165); 2499 warning(165);
2504 } else if (op == INIT && tp->t_bitfield) { 2500 } else if (op == INIT && tp->t_bitfield) {
2505 /* bit-field initializer does not fit */ 2501 /* bit-field initializer does not fit */
2506 warning(180); 2502 warning(180);
2507 } else if (op == INIT) { 2503 } else if (op == INIT) {
2508 /* initializer does not fit */ 2504 /* initializer does not fit */
2509 warning(178); 2505 warning(178);
2510 } else if (op == CASE) { 2506 } else if (op == CASE) {
2511 /* case label affected by conversion */ 2507 /* case label affected by conversion */
2512 warning(196); 2508 warning(196);
2513 } else if (op == FARG) { 2509 } else if (op == FARG) {
2514 /* conv. of '%s' to '%s' is out of range, ... */ 2510 /* conv. of '%s' to '%s' is out of range, ... */
2515 warning(295, 2511 warning(295,
2516 type_name(gettyp(ot)), type_name(tp), arg); 2512 type_name(gettyp(ot)), type_name(tp), arg);
2517 } else { 2513 } else {
2518 /* conversion of '%s' to '%s' is out of range */ 2514 /* conversion of '%s' to '%s' is out of range */
2519 warning(119, 2515 warning(119,
2520 type_name(gettyp(ot)), type_name(tp)); 2516 type_name(gettyp(ot)), type_name(tp));
2521 } 2517 }
2522 } else if (nv->v_quad != v->v_quad) { 2518 } else if (nv->v_quad != v->v_quad) {
2523 if (op == ASSIGN && tp->t_bitfield) { 2519 if (op == ASSIGN && tp->t_bitfield) {
2524 /* precision lost in bit-field assignment */ 2520 /* precision lost in bit-field assignment */
2525 warning(166); 2521 warning(166);
2526 } else if (op == INIT && tp->t_bitfield) { 2522 } else if (op == INIT && tp->t_bitfield) {
2527 /* bit-field initializer out of range */ 2523 /* bit-field initializer out of range */
2528 warning(11); 2524 warning(11);
2529 } else if (op == CASE) { 2525 } else if (op == CASE) {
2530 /* case label affected by conversion */ 2526 /* case label affected by conversion */
2531 warning(196); 2527 warning(196);
2532 } else if (op == FARG) { 2528 } else if (op == FARG) {
2533 /* conv. of '%s' to '%s' is out of range, ... */ 2529 /* conv. of '%s' to '%s' is out of range, ... */
2534 warning(295, 2530 warning(295,
2535 type_name(gettyp(ot)), type_name(tp), arg); 2531 type_name(gettyp(ot)), type_name(tp), arg);
2536 } else { 2532 } else {
2537 /* conversion of '%s' to '%s' is out of range */ 2533 /* conversion of '%s' to '%s' is out of range */
2538 warning(119, 2534 warning(119,
2539 type_name(gettyp(ot)), type_name(tp)); 2535 type_name(gettyp(ot)), type_name(tp));
2540 } 2536 }
2541 } 2537 }
2542 } 2538 }
2543} 2539}
2544 2540
2545/* 2541/*
2546 * Called if incompatible types were detected. 2542 * Called if incompatible types were detected.
2547 * Prints a appropriate warning. 2543 * Prints a appropriate warning.
2548 */ 2544 */
2549static void 2545static void
2550warn_incompatible_types(op_t op, 2546warn_incompatible_types(op_t op,
2551 const type_t *ltp, tspec_t lt, 2547 const type_t *ltp, tspec_t lt,
2552 const type_t *rtp, tspec_t rt) 2548 const type_t *rtp, tspec_t rt)
2553{ 2549{
2554 const mod_t *mp; 2550 const mod_t *mp;
2555 2551
2556 mp = &modtab[op]; 2552 mp = &modtab[op];
2557 2553
2558 if (lt == VOID || (mp->m_binary && rt == VOID)) { 2554 if (lt == VOID || (mp->m_binary && rt == VOID)) {
2559 /* void type illegal in expression */ 2555 /* void type illegal in expression */
2560 error(109); 2556 error(109);
2561 } else if (op == ASSIGN) { 2557 } else if (op == ASSIGN) {
2562 if ((lt == STRUCT || lt == UNION) && 2558 if ((lt == STRUCT || lt == UNION) &&
2563 (rt == STRUCT || rt == UNION)) { 2559 (rt == STRUCT || rt == UNION)) {
2564 /* assignment of different structures (%s != %s) */ 2560 /* assignment of different structures (%s != %s) */
2565 error(240, tspec_name(lt), tspec_name(rt)); 2561 error(240, tspec_name(lt), tspec_name(rt));
2566 } else { 2562 } else {
2567 /* cannot assign to '%s' from '%s' */ 2563 /* cannot assign to '%s' from '%s' */
2568 error(171, type_name(ltp), type_name(rtp)); 2564 error(171, type_name(ltp), type_name(rtp));
2569 } 2565 }
2570 } else if (mp->m_binary) { 2566 } else if (mp->m_binary) {
2571 /* operands of '%s' have incompatible types (%s != %s) */ 2567 /* operands of '%s' have incompatible types (%s != %s) */
2572 error(107, mp->m_name, tspec_name(lt), tspec_name(rt)); 2568 error(107, mp->m_name, tspec_name(lt), tspec_name(rt));
2573 } else { 2569 } else {
2574 lint_assert(rt == NOTSPEC); 2570 lint_assert(rt == NOTSPEC);
2575 /* operand of '%s' has invalid type (%s) */ 2571 /* operand of '%s' has invalid type (%s) */
2576 error(108, mp->m_name, tspec_name(lt)); 2572 error(108, mp->m_name, tspec_name(lt));
2577 } 2573 }
2578} 2574}
2579 2575
2580/* 2576/*
2581 * Called if incompatible pointer types are detected. 2577 * Called if incompatible pointer types are detected.
2582 * Print an appropriate warning. 2578 * Print an appropriate warning.
2583 */ 2579 */
2584static void 2580static void
2585warn_incompatible_pointers(const mod_t *mp, 2581warn_incompatible_pointers(const mod_t *mp,
2586 const type_t *ltp, const type_t *rtp) 2582 const type_t *ltp, const type_t *rtp)
2587{ 2583{
2588 tspec_t lt, rt; 2584 tspec_t lt, rt;
2589 2585
2590 lint_assert(ltp->t_tspec == PTR); 2586 lint_assert(ltp->t_tspec == PTR);
2591 lint_assert(rtp->t_tspec == PTR); 2587 lint_assert(rtp->t_tspec == PTR);
2592 2588
2593 lt = ltp->t_subt->t_tspec; 2589 lt = ltp->t_subt->t_tspec;
2594 rt = rtp->t_subt->t_tspec; 2590 rt = rtp->t_subt->t_tspec;
2595 2591
2596 if ((lt == STRUCT || lt == UNION) && (rt == STRUCT || rt == UNION)) { 2592 if ((lt == STRUCT || lt == UNION) && (rt == STRUCT || rt == UNION)) {
2597 if (mp == NULL) { 2593 if (mp == NULL) {
2598 /* illegal structure pointer combination */ 2594 /* illegal structure pointer combination */
2599 warning(244); 2595 warning(244);
2600 } else { 2596 } else {
2601 /* incompatible structure pointers: '%s' '%s' '%s' */ 2597 /* incompatible structure pointers: '%s' '%s' '%s' */
2602 warning(245, type_name(ltp), mp->m_name, type_name(rtp)); 2598 warning(245, type_name(ltp), mp->m_name, type_name(rtp));
2603 } 2599 }
2604 } else { 2600 } else {
2605 if (mp == NULL) { 2601 if (mp == NULL) {
2606 /* illegal pointer combination */ 2602 /* illegal pointer combination */
2607 warning(184); 2603 warning(184);
2608 } else { 2604 } else {
2609 /* illegal pointer combination (%s) and (%s), op %s */ 2605 /* illegal pointer combination (%s) and (%s), op %s */
2610 warning(124, 2606 warning(124,
2611 type_name(ltp), type_name(rtp), mp->m_name); 2607 type_name(ltp), type_name(rtp), mp->m_name);
2612 } 2608 }
2613 } 2609 }
2614} 2610}
2615 2611
2616/* 2612/*
2617 * Make sure type (*tpp)->t_subt has at least the qualifiers 2613 * Make sure type (*tpp)->t_subt has at least the qualifiers
2618 * of tp1->t_subt and tp2->t_subt. 2614 * of tp1->t_subt and tp2->t_subt.
2619 */ 2615 */
2620static void 2616static void
2621merge_qualifiers(type_t **tpp, type_t *tp1, type_t *tp2) 2617merge_qualifiers(type_t **tpp, type_t *tp1, type_t *tp2)
2622{ 2618{
2623 2619
2624 lint_assert((*tpp)->t_tspec == PTR); 2620 lint_assert((*tpp)->t_tspec == PTR);
2625 lint_assert(tp1->t_tspec == PTR); 2621 lint_assert(tp1->t_tspec == PTR);
2626 lint_assert(tp2->t_tspec == PTR); 2622 lint_assert(tp2->t_tspec == PTR);
2627 2623
2628 if ((*tpp)->t_subt->t_const == 2624 if ((*tpp)->t_subt->t_const ==
2629 (tp1->t_subt->t_const | tp2->t_subt->t_const) && 2625 (tp1->t_subt->t_const | tp2->t_subt->t_const) &&
2630 (*tpp)->t_subt->t_volatile == 2626 (*tpp)->t_subt->t_volatile ==
2631 (tp1->t_subt->t_volatile | tp2->t_subt->t_volatile)) { 2627 (tp1->t_subt->t_volatile | tp2->t_subt->t_volatile)) {
2632 return; 2628 return;
2633 } 2629 }
2634 2630
2635 *tpp = tduptyp(*tpp); 2631 *tpp = tduptyp(*tpp);
2636 (*tpp)->t_subt = tduptyp((*tpp)->t_subt); 2632 (*tpp)->t_subt = tduptyp((*tpp)->t_subt);
2637 (*tpp)->t_subt->t_const = 2633 (*tpp)->t_subt->t_const =
2638 tp1->t_subt->t_const | tp2->t_subt->t_const; 2634 tp1->t_subt->t_const | tp2->t_subt->t_const;
2639 (*tpp)->t_subt->t_volatile = 2635 (*tpp)->t_subt->t_volatile =
2640 tp1->t_subt->t_volatile | tp2->t_subt->t_volatile; 2636 tp1->t_subt->t_volatile | tp2->t_subt->t_volatile;
2641} 2637}
2642 2638
2643/* 2639/*
2644 * Returns true if the given structure or union has a constant member 2640 * Returns true if the given structure or union has a constant member
2645 * (maybe recursively). 2641 * (maybe recursively).
2646 */ 2642 */
2647static bool 2643static bool
2648has_constant_member(const type_t *tp) 2644has_constant_member(const type_t *tp)
2649{ 2645{
2650 sym_t *m; 2646 sym_t *m;
2651 tspec_t t; 2647 tspec_t t;
2652 2648
2653 lint_assert((t = tp->t_tspec) == STRUCT || t == UNION); 2649 lint_assert((t = tp->t_tspec) == STRUCT || t == UNION);
2654 2650
2655 for (m = tp->t_str->sou_first_member; m != NULL; m = m->s_next) { 2651 for (m = tp->t_str->sou_first_member; m != NULL; m = m->s_next) {
2656 tp = m->s_type; 2652 tp = m->s_type;
2657 if (tp->t_const) 2653 if (tp->t_const)
2658 return true; 2654 return true;
2659 if ((t = tp->t_tspec) == STRUCT || t == UNION) { 2655 if ((t = tp->t_tspec) == STRUCT || t == UNION) {
2660 if (has_constant_member(m->s_type)) 2656 if (has_constant_member(m->s_type))
2661 return true; 2657 return true;
2662 } 2658 }
2663 } 2659 }
2664 return false; 2660 return false;
2665} 2661}
2666 2662
2667/* 2663/*
2668 * Create a new node for one of the operators POINT and ARROW. 2664 * Create a new node for one of the operators POINT and ARROW.
2669 */ 2665 */
2670static tnode_t * 2666static tnode_t *
2671build_struct_access(op_t op, tnode_t *ln, tnode_t *rn) 2667build_struct_access(op_t op, tnode_t *ln, tnode_t *rn)
2672{ 2668{
2673 tnode_t *ntn, *ctn; 2669 tnode_t *ntn, *ctn;
2674 bool nolval; 2670 bool nolval;
2675 2671
2676 lint_assert(rn->tn_op == NAME); 2672 lint_assert(rn->tn_op == NAME);
2677 lint_assert(rn->tn_sym->s_value.v_tspec == INT); 2673 lint_assert(rn->tn_sym->s_value.v_tspec == INT);
2678 lint_assert(rn->tn_sym->s_scl == MOS || rn->tn_sym->s_scl == MOU); 2674 lint_assert(rn->tn_sym->s_scl == MOS || rn->tn_sym->s_scl == MOU);
2679 2675
2680 /* 2676 /*
2681 * Remember if the left operand is an lvalue (structure members 2677 * Remember if the left operand is an lvalue (structure members
2682 * are lvalues if and only if the structure itself is an lvalue). 2678 * are lvalues if and only if the structure itself is an lvalue).
2683 */ 2679 */
2684 nolval = op == POINT && !ln->tn_lvalue; 2680 nolval = op == POINT && !ln->tn_lvalue;
2685 2681
2686 if (op == POINT) { 2682 if (op == POINT) {
2687 ln = build_address(ln, true); 2683 ln = build_address(ln, true);
2688 } else if (ln->tn_type->t_tspec != PTR) { 2684 } else if (ln->tn_type->t_tspec != PTR) {
2689 lint_assert(tflag); 2685 lint_assert(tflag);
2690 lint_assert(is_integer(ln->tn_type->t_tspec)); 2686 lint_assert(is_integer(ln->tn_type->t_tspec));
2691 ln = convert(NOOP, 0, tincref(gettyp(VOID), PTR), ln); 2687 ln = convert(NOOP, 0, tincref(gettyp(VOID), PTR), ln);
2692 } 2688 }
2693 2689
2694 ctn = new_integer_constant_node(PTRDIFF_TSPEC, 2690 ctn = new_integer_constant_node(PTRDIFF_TSPEC,
2695 rn->tn_sym->s_value.v_quad / CHAR_SIZE); 2691 rn->tn_sym->s_value.v_quad / CHAR_SIZE);
2696 2692
2697 ntn = new_tnode(PLUS, tincref(rn->tn_type, PTR), ln, ctn); 2693 ntn = new_tnode(PLUS, tincref(rn->tn_type, PTR), ln, ctn);
2698 if (ln->tn_op == CON) 2694 if (ln->tn_op == CON)
2699 ntn = fold(ntn); 2695 ntn = fold(ntn);
2700 2696
2701 if (rn->tn_type->t_bitfield) { 2697 if (rn->tn_type->t_bitfield) {
2702 ntn = new_tnode(FSEL, ntn->tn_type->t_subt, ntn, NULL); 2698 ntn = new_tnode(FSEL, ntn->tn_type->t_subt, ntn, NULL);
2703 } else { 2699 } else {
2704 ntn = new_tnode(INDIR, ntn->tn_type->t_subt, ntn, NULL); 2700 ntn = new_tnode(INDIR, ntn->tn_type->t_subt, ntn, NULL);
2705 } 2701 }
2706 2702
2707 if (nolval) 2703 if (nolval)
2708 ntn->tn_lvalue = false; 2704 ntn->tn_lvalue = false;
2709 2705
2710 return ntn; 2706 return ntn;
2711} 2707}
2712 2708
2713/* 2709/*
2714 * Create a node for INCAFT, INCBEF, DECAFT and DECBEF. 2710 * Create a node for INCAFT, INCBEF, DECAFT and DECBEF.
2715 */ 2711 */
2716static tnode_t * 2712static tnode_t *
2717build_prepost_incdec(op_t op, tnode_t *ln) 2713build_prepost_incdec(op_t op, tnode_t *ln)
2718{ 2714{
2719 tnode_t *cn, *ntn; 2715 tnode_t *cn, *ntn;
2720 2716
2721 lint_assert(ln != NULL); 2717 lint_assert(ln != NULL);
2722 2718
2723 if (ln->tn_type->t_tspec == PTR) { 2719 if (ln->tn_type->t_tspec == PTR) {
2724 cn = plength(ln->tn_type); 2720 cn = plength(ln->tn_type);
2725 } else { 2721 } else {
2726 cn = new_integer_constant_node(INT, (int64_t)1); 2722 cn = new_integer_constant_node(INT, (int64_t)1);
2727 } 2723 }
2728 ntn = new_tnode(op, ln->tn_type, ln, cn); 2724 ntn = new_tnode(op, ln->tn_type, ln, cn);
2729 2725
2730 return ntn; 2726 return ntn;
2731} 2727}
2732 2728
2733/* 2729/*
2734 * Create a node for REAL, IMAG 2730 * Create a node for REAL, IMAG
2735 */ 2731 */
2736static tnode_t * 2732static tnode_t *
2737build_real_imag(op_t op, tnode_t *ln) 2733build_real_imag(op_t op, tnode_t *ln)
2738{ 2734{
2739 tnode_t *cn, *ntn; 2735 tnode_t *cn, *ntn;
2740 2736
2741 lint_assert(ln != NULL); 2737 lint_assert(ln != NULL);
2742 2738
2743 switch (ln->tn_type->t_tspec) { 2739 switch (ln->tn_type->t_tspec) {
2744 case LCOMPLEX: 2740 case LCOMPLEX:
2745 /* XXX: integer and LDOUBLE don't match. */ 2741 /* XXX: integer and LDOUBLE don't match. */
2746 cn = new_integer_constant_node(LDOUBLE, (int64_t)1); 2742 cn = new_integer_constant_node(LDOUBLE, (int64_t)1);
2747 break; 2743 break;
2748 case DCOMPLEX: 2744 case DCOMPLEX:
2749 cn = new_integer_constant_node(DOUBLE, (int64_t)1); 2745 cn = new_integer_constant_node(DOUBLE, (int64_t)1);
2750 break; 2746 break;
2751 case FCOMPLEX: 2747 case FCOMPLEX:
2752 cn = new_integer_constant_node(FLOAT, (int64_t)1); 2748 cn = new_integer_constant_node(FLOAT, (int64_t)1);
2753 break; 2749 break;
2754 default: 2750 default:
2755 /* __%s__ is illegal for type %s */ 2751 /* __%s__ is illegal for type %s */
2756 error(276, op == REAL ? "real" : "imag", 2752 error(276, op == REAL ? "real" : "imag",
2757 type_name(ln->tn_type)); 2753 type_name(ln->tn_type));
2758 return NULL; 2754 return NULL;
2759 } 2755 }
2760 ntn = new_tnode(op, cn->tn_type, ln, cn); 2756 ntn = new_tnode(op, cn->tn_type, ln, cn);
2761 ntn->tn_lvalue = true; 2757 ntn->tn_lvalue = true;
2762 2758
2763 return ntn; 2759 return ntn;
2764} 2760}
2765/* 2761/*
2766 * Create a tree node for the unary & operator 2762 * Create a tree node for the unary & operator
2767 */ 2763 */
2768static tnode_t * 2764static tnode_t *
2769build_address(tnode_t *tn, bool noign) 2765build_address(tnode_t *tn, bool noign)
2770{ 2766{
2771 tspec_t t; 2767 tspec_t t;
2772 2768
2773 if (!noign && ((t = tn->tn_type->t_tspec) == ARRAY || t == FUNC)) { 2769 if (!noign && ((t = tn->tn_type->t_tspec) == ARRAY || t == FUNC)) {
2774 if (tflag) 2770 if (tflag)
2775 /* '&' before array or function: ignored */ 2771 /* '&' before array or function: ignored */
2776 warning(127); 2772 warning(127);
2777 return tn; 2773 return tn;
2778 } 2774 }
2779 2775
2780 /* eliminate &* */ 2776 /* eliminate &* */
2781 if (tn->tn_op == INDIR && 2777 if (tn->tn_op == INDIR &&
2782 tn->tn_left->tn_type->t_tspec == PTR && 2778 tn->tn_left->tn_type->t_tspec == PTR &&
2783 tn->tn_left->tn_type->t_subt == tn->tn_type) { 2779 tn->tn_left->tn_type->t_subt == tn->tn_type) {
2784 return tn->tn_left; 2780 return tn->tn_left;
2785 } 2781 }
2786 2782
2787 return new_tnode(ADDR, tincref(tn->tn_type, PTR), tn, NULL); 2783 return new_tnode(ADDR, tincref(tn->tn_type, PTR), tn, NULL);
2788} 2784}
2789 2785
2790/* 2786/*
2791 * Create a node for operators PLUS and MINUS. 2787 * Create a node for operators PLUS and MINUS.
2792 */ 2788 */
2793static tnode_t * 2789static tnode_t *
2794build_plus_minus(op_t op, tnode_t *ln, tnode_t *rn) 2790build_plus_minus(op_t op, tnode_t *ln, tnode_t *rn)
2795{ 2791{
2796 tnode_t *ntn, *ctn; 2792 tnode_t *ntn, *ctn;
2797 type_t *tp; 2793 type_t *tp;
2798 2794
2799 /* If pointer and integer, then pointer to the lhs. */ 2795 /* If pointer and integer, then pointer to the lhs. */
2800 if (rn->tn_type->t_tspec == PTR && is_integer(ln->tn_type->t_tspec)) { 2796 if (rn->tn_type->t_tspec == PTR && is_integer(ln->tn_type->t_tspec)) {
2801 ntn = ln; 2797 ntn = ln;
2802 ln = rn; 2798 ln = rn;
2803 rn = ntn; 2799 rn = ntn;
2804 } 2800 }
2805 2801
2806 if (ln->tn_type->t_tspec == PTR && rn->tn_type->t_tspec != PTR) { 2802 if (ln->tn_type->t_tspec == PTR && rn->tn_type->t_tspec != PTR) {
2807 2803
2808 lint_assert(is_integer(rn->tn_type->t_tspec)); 2804 lint_assert(is_integer(rn->tn_type->t_tspec));
2809 2805
2810 ctn = plength(ln->tn_type); 2806 ctn = plength(ln->tn_type);
2811 if (rn->tn_type->t_tspec != ctn->tn_type->t_tspec) 2807 if (rn->tn_type->t_tspec != ctn->tn_type->t_tspec)
2812 rn = convert(NOOP, 0, ctn->tn_type, rn); 2808 rn = convert(NOOP, 0, ctn->tn_type, rn);
2813 rn = new_tnode(MULT, rn->tn_type, rn, ctn); 2809 rn = new_tnode(MULT, rn->tn_type, rn, ctn);
2814 if (rn->tn_left->tn_op == CON) 2810 if (rn->tn_left->tn_op == CON)
2815 rn = fold(rn); 2811 rn = fold(rn);
2816 ntn = new_tnode(op, ln->tn_type, ln, rn); 2812 ntn = new_tnode(op, ln->tn_type, ln, rn);
2817 2813
2818 } else if (rn->tn_type->t_tspec == PTR) { 2814 } else if (rn->tn_type->t_tspec == PTR) {
2819 2815
2820 lint_assert(ln->tn_type->t_tspec == PTR); 2816 lint_assert(ln->tn_type->t_tspec == PTR);
2821 lint_assert(op == MINUS); 2817 lint_assert(op == MINUS);
2822 tp = gettyp(PTRDIFF_TSPEC); 2818 tp = gettyp(PTRDIFF_TSPEC);
2823 ntn = new_tnode(op, tp, ln, rn); 2819 ntn = new_tnode(op, tp, ln, rn);
2824 if (ln->tn_op == CON && rn->tn_op == CON) 2820 if (ln->tn_op == CON && rn->tn_op == CON)
2825 ntn = fold(ntn); 2821 ntn = fold(ntn);
2826 ctn = plength(ln->tn_type); 2822 ctn = plength(ln->tn_type);
2827 balance(NOOP, &ntn, &ctn); 2823 balance(NOOP, &ntn, &ctn);
2828 ntn = new_tnode(DIV, tp, ntn, ctn); 2824 ntn = new_tnode(DIV, tp, ntn, ctn);
2829 2825
2830 } else { 2826 } else {
2831 2827
2832 ntn = new_tnode(op, ln->tn_type, ln, rn); 2828 ntn = new_tnode(op, ln->tn_type, ln, rn);
2833 2829
2834 } 2830 }
2835 return ntn; 2831 return ntn;
2836} 2832}
2837 2833
2838/* 2834/*
2839 * Create a node for operators SHL and SHR. 2835 * Create a node for operators SHL and SHR.
2840 */ 2836 */
2841static tnode_t * 2837static tnode_t *
2842build_bit_shift(op_t op, tnode_t *ln, tnode_t *rn) 2838build_bit_shift(op_t op, tnode_t *ln, tnode_t *rn)
2843{ 2839{
2844 tspec_t t; 2840 tspec_t t;
2845 tnode_t *ntn; 2841 tnode_t *ntn;
2846 2842
2847 if ((t = rn->tn_type->t_tspec) != INT && t != UINT) 2843 if ((t = rn->tn_type->t_tspec) != INT && t != UINT)
2848 rn = convert(CVT, 0, gettyp(INT), rn); 2844 rn = convert(CVT, 0, gettyp(INT), rn);
2849 ntn = new_tnode(op, ln->tn_type, ln, rn); 2845 ntn = new_tnode(op, ln->tn_type, ln, rn);
2850 return ntn; 2846 return ntn;
2851} 2847}
2852 2848
2853/* 2849/*
2854 * Create a node for COLON. 2850 * Create a node for COLON.
2855 */ 2851 */
2856static tnode_t * 2852static tnode_t *
2857build_colon(tnode_t *ln, tnode_t *rn) 2853build_colon(tnode_t *ln, tnode_t *rn)
2858{ 2854{
2859 tspec_t lt, rt, pdt; 2855 tspec_t lt, rt, pdt;
2860 type_t *rtp; 2856 type_t *rtp;
2861 tnode_t *ntn; 2857 tnode_t *ntn;
2862 2858
2863 lt = ln->tn_type->t_tspec; 2859 lt = ln->tn_type->t_tspec;
2864 rt = rn->tn_type->t_tspec; 2860 rt = rn->tn_type->t_tspec;
2865 pdt = PTRDIFF_TSPEC; 2861 pdt = PTRDIFF_TSPEC;
2866 2862
2867 /* 2863 /*
2868 * Arithmetic types are balanced, all other type combinations 2864 * Arithmetic types are balanced, all other type combinations
2869 * still need to be handled. 2865 * still need to be handled.
2870 */ 2866 */
2871 if (is_arithmetic(lt) && is_arithmetic(rt)) { 2867 if (is_arithmetic(lt) && is_arithmetic(rt)) {
2872 rtp = ln->tn_type; 2868 rtp = ln->tn_type;
2873 } else if (lt == BOOL && rt == BOOL) { 2869 } else if (lt == BOOL && rt == BOOL) {
2874 rtp = ln->tn_type; 2870 rtp = ln->tn_type;
2875 } else if (lt == VOID || rt == VOID) { 2871 } else if (lt == VOID || rt == VOID) {
2876 rtp = gettyp(VOID); 2872 rtp = gettyp(VOID);
2877 } else if (lt == STRUCT || lt == UNION) { 2873 } else if (lt == STRUCT || lt == UNION) {
2878 /* Both types must be identical. */ 2874 /* Both types must be identical. */
2879 lint_assert(rt == STRUCT || rt == UNION); 2875 lint_assert(rt == STRUCT || rt == UNION);
2880 lint_assert(ln->tn_type->t_str == rn->tn_type->t_str); 2876 lint_assert(ln->tn_type->t_str == rn->tn_type->t_str);
2881 if (is_incomplete(ln->tn_type)) { 2877 if (is_incomplete(ln->tn_type)) {
2882 /* unknown operand size, op %s */ 2878 /* unknown operand size, op %s */
2883 error(138, modtab[COLON].m_name); 2879 error(138, modtab[COLON].m_name);
2884 return NULL; 2880 return NULL;
2885 } 2881 }
2886 rtp = ln->tn_type; 2882 rtp = ln->tn_type;
2887 } else if (lt == PTR && is_integer(rt)) { 2883 } else if (lt == PTR && is_integer(rt)) {
2888 if (rt != pdt) { 2884 if (rt != pdt) {
2889 rn = convert(NOOP, 0, gettyp(pdt), rn); 2885 rn = convert(NOOP, 0, gettyp(pdt), rn);
2890 rt = pdt; 2886 rt = pdt;
2891 } 2887 }
2892 rtp = ln->tn_type; 2888 rtp = ln->tn_type;
2893 } else if (rt == PTR && is_integer(lt)) { 2889 } else if (rt == PTR && is_integer(lt)) {
2894 if (lt != pdt) { 2890 if (lt != pdt) {
2895 ln = convert(NOOP, 0, gettyp(pdt), ln); 2891 ln = convert(NOOP, 0, gettyp(pdt), ln);
2896 lt = pdt; 2892 lt = pdt;
2897 } 2893 }
2898 rtp = rn->tn_type; 2894 rtp = rn->tn_type;
2899 } else if (lt == PTR && ln->tn_type->t_subt->t_tspec == VOID) { 2895 } else if (lt == PTR && ln->tn_type->t_subt->t_tspec == VOID) {
2900 lint_assert(rt == PTR); 2896 lint_assert(rt == PTR);
2901 rtp = rn->tn_type; 2897 rtp = rn->tn_type;
2902 merge_qualifiers(&rtp, ln->tn_type, rn->tn_type); 2898 merge_qualifiers(&rtp, ln->tn_type, rn->tn_type);
2903 } else if (rt == PTR && rn->tn_type->t_subt->t_tspec == VOID) { 2899 } else if (rt == PTR && rn->tn_type->t_subt->t_tspec == VOID) {
2904 lint_assert(lt == PTR); 2900 lint_assert(lt == PTR);
2905 rtp = ln->tn_type; 2901 rtp = ln->tn_type;
2906 merge_qualifiers(&rtp, ln->tn_type, rn->tn_type); 2902 merge_qualifiers(&rtp, ln->tn_type, rn->tn_type);
2907 } else { 2903 } else {
2908 lint_assert(lt == PTR); 2904 lint_assert(lt == PTR);
2909 lint_assert(rt == PTR); 2905 lint_assert(rt == PTR);
2910 /* 2906 /*
2911 * XXX For now we simply take the left type. This is 2907 * XXX For now we simply take the left type. This is
2912 * probably wrong, if one type contains a function prototype 2908 * probably wrong, if one type contains a function prototype
2913 * and the other one, at the same place, only an old style 2909 * and the other one, at the same place, only an old style
2914 * declaration. 2910 * declaration.
2915 */ 2911 */
2916 rtp = ln->tn_type; 2912 rtp = ln->tn_type;
2917 merge_qualifiers(&rtp, ln->tn_type, rn->tn_type); 2913 merge_qualifiers(&rtp, ln->tn_type, rn->tn_type);
2918 } 2914 }
2919 2915
2920 ntn = new_tnode(COLON, rtp, ln, rn); 2916 ntn = new_tnode(COLON, rtp, ln, rn);
2921 2917
2922 return ntn; 2918 return ntn;
2923} 2919}
2924 2920
2925/* 2921/*
2926 * Create a node for an assignment operator (both = and op= ). 2922 * Create a node for an assignment operator (both = and op= ).
2927 */ 2923 */
2928static tnode_t * 2924static tnode_t *
2929build_assignment(op_t op, tnode_t *ln, tnode_t *rn) 2925build_assignment(op_t op, tnode_t *ln, tnode_t *rn)
2930{ 2926{
2931 tspec_t lt, rt; 2927 tspec_t lt, rt;
2932 tnode_t *ntn, *ctn; 2928 tnode_t *ntn, *ctn;
2933 2929
2934 lint_assert(ln != NULL); 2930 lint_assert(ln != NULL);
2935 lint_assert(rn != NULL); 2931 lint_assert(rn != NULL);
2936 2932
2937 lt = ln->tn_type->t_tspec; 2933 lt = ln->tn_type->t_tspec;
2938 rt = rn->tn_type->t_tspec; 2934 rt = rn->tn_type->t_tspec;
2939 2935
2940 if ((op == ADDASS || op == SUBASS) && lt == PTR) { 2936 if ((op == ADDASS || op == SUBASS) && lt == PTR) {
2941 lint_assert(is_integer(rt)); 2937 lint_assert(is_integer(rt));
2942 ctn = plength(ln->tn_type); 2938 ctn = plength(ln->tn_type);
2943 if (rn->tn_type->t_tspec != ctn->tn_type->t_tspec) 2939 if (rn->tn_type->t_tspec != ctn->tn_type->t_tspec)
2944 rn = convert(NOOP, 0, ctn->tn_type, rn); 2940 rn = convert(NOOP, 0, ctn->tn_type, rn);
2945 rn = new_tnode(MULT, rn->tn_type, rn, ctn); 2941 rn = new_tnode(MULT, rn->tn_type, rn, ctn);
2946 if (rn->tn_left->tn_op == CON) 2942 if (rn->tn_left->tn_op == CON)
2947 rn = fold(rn); 2943 rn = fold(rn);
2948 } 2944 }
2949 2945
2950 if ((op == ASSIGN || op == RETURN) && (lt == STRUCT || rt == STRUCT)) { 2946 if ((op == ASSIGN || op == RETURN) && (lt == STRUCT || rt == STRUCT)) {
2951 lint_assert(lt == rt); 2947 lint_assert(lt == rt);
2952 lint_assert(ln->tn_type->t_str == rn->tn_type->t_str); 2948 lint_assert(ln->tn_type->t_str == rn->tn_type->t_str);
2953 if (is_incomplete(ln->tn_type)) { 2949 if (is_incomplete(ln->tn_type)) {
2954 if (op == RETURN) { 2950 if (op == RETURN) {
2955 /* cannot return incomplete type */ 2951 /* cannot return incomplete type */
2956 error(212); 2952 error(212);
2957 } else { 2953 } else {
2958 /* unknown operand size, op %s */ 2954 /* unknown operand size, op %s */
2959 error(138, getopname(op)); 2955 error(138, getopname(op));
2960 } 2956 }
2961 return NULL; 2957 return NULL;
2962 } 2958 }
2963 } 2959 }
2964 2960
2965 if (op == SHLASS) { 2961 if (op == SHLASS) {
2966 if (portable_size_in_bits(lt) < portable_size_in_bits(rt)) { 2962 if (portable_size_in_bits(lt) < portable_size_in_bits(rt)) {
2967 if (hflag) 2963 if (hflag)
2968 /* semantics of '%s' change in ANSI C; ... */ 2964 /* semantics of '%s' change in ANSI C; ... */
2969 warning(118, "<<="); 2965 warning(118, "<<=");
2970 } 2966 }
2971 } else if (op != SHRASS) { 2967 } else if (op != SHRASS) {
2972 if (op == ASSIGN || lt != PTR) { 2968 if (op == ASSIGN || lt != PTR) {
2973 if (lt != rt || 2969 if (lt != rt ||
2974 (ln->tn_type->t_bitfield && rn->tn_op == CON)) { 2970 (ln->tn_type->t_bitfield && rn->tn_op == CON)) {
2975 rn = convert(op, 0, ln->tn_type, rn); 2971 rn = convert(op, 0, ln->tn_type, rn);
2976 rt = lt; 2972 rt = lt;
2977 } 2973 }
2978 } 2974 }
2979 } 2975 }
2980 2976
2981 ntn = new_tnode(op, ln->tn_type, ln, rn); 2977 ntn = new_tnode(op, ln->tn_type, ln, rn);
2982 2978
2983 return ntn; 2979 return ntn;
2984} 2980}
2985 2981
2986/* 2982/*
2987 * Get length of type tp->t_subt. 2983 * Get length of type tp->t_subt.
2988 */ 2984 */
2989static tnode_t * 2985static tnode_t *
2990plength(type_t *tp) 2986plength(type_t *tp)
2991{ 2987{
2992 int elem, elsz; 2988 int elem, elsz;
2993 2989
2994 lint_assert(tp->t_tspec == PTR); 2990 lint_assert(tp->t_tspec == PTR);
2995 tp = tp->t_subt; 2991 tp = tp->t_subt;
2996 2992
2997 elem = 1; 2993 elem = 1;
2998 elsz = 0; 2994 elsz = 0;
2999 2995
3000 while (tp->t_tspec == ARRAY) { 2996 while (tp->t_tspec == ARRAY) {
3001 elem *= tp->t_dim; 2997 elem *= tp->t_dim;
3002 tp = tp->t_subt; 2998 tp = tp->t_subt;
3003 } 2999 }
3004 3000
3005 switch (tp->t_tspec) { 3001 switch (tp->t_tspec) {
3006 case FUNC: 3002 case FUNC:
3007 /* pointer to function is not allowed here */ 3003 /* pointer to function is not allowed here */
3008 error(110); 3004 error(110);
3009 break; 3005 break;
3010 case VOID: 3006 case VOID:
3011 /* cannot do pointer arithmetic on operand of unknown size */ 3007 /* cannot do pointer arithmetic on operand of unknown size */
3012 gnuism(136); 3008 gnuism(136);
3013 break; 3009 break;
3014 case STRUCT: 3010 case STRUCT:
3015 case UNION: 3011 case UNION:
3016 if ((elsz = tp->t_str->sou_size_in_bits) == 0) 3012 if ((elsz = tp->t_str->sou_size_in_bits) == 0)
3017 /* cannot do pointer arithmetic on operand of ... */ 3013 /* cannot do pointer arithmetic on operand of ... */
3018 error(136); 3014 error(136);
3019 break; 3015 break;
3020 case ENUM: 3016 case ENUM:
3021 if (is_incomplete(tp)) { 3017 if (is_incomplete(tp)) {
3022 /* cannot do pointer arithmetic on operand of ... */ 3018 /* cannot do pointer arithmetic on operand of ... */
3023 warning(136); 3019 warning(136);
3024 } 3020 }
3025 /* FALLTHROUGH */ 3021 /* FALLTHROUGH */
3026 default: 3022 default:
3027 if ((elsz = size_in_bits(tp->t_tspec)) == 0) { 3023 if ((elsz = size_in_bits(tp->t_tspec)) == 0) {
3028 /* cannot do pointer arithmetic on operand of ... */ 3024 /* cannot do pointer arithmetic on operand of ... */
3029 error(136); 3025 error(136);
3030 } else { 3026 } else {
3031 lint_assert(elsz != -1); 3027 lint_assert(elsz != -1);
3032 } 3028 }
3033 break; 3029 break;
3034 } 3030 }
3035 3031
3036 if (elem == 0 && elsz != 0) { 3032 if (elem == 0 && elsz != 0) {
3037 /* cannot do pointer arithmetic on operand of unknown size */ 3033 /* cannot do pointer arithmetic on operand of unknown size */
3038 error(136); 3034 error(136);
3039 } 3035 }
3040 3036
3041 if (elsz == 0) 3037 if (elsz == 0)
3042 elsz = CHAR_SIZE; 3038 elsz = CHAR_SIZE;
3043 3039
3044 return new_integer_constant_node(PTRDIFF_TSPEC, 3040 return new_integer_constant_node(PTRDIFF_TSPEC,
3045 (int64_t)(elem * elsz / CHAR_SIZE)); 3041 (int64_t)(elem * elsz / CHAR_SIZE));
3046} 3042}
3047 3043
3048/* 3044/*
3049 * XXX 3045 * XXX
3050 * Note: There appear to be a number of bugs in detecting overflow in 3046 * Note: There appear to be a number of bugs in detecting overflow in
3051 * this function. An audit and a set of proper regression tests are needed. 3047 * this function. An audit and a set of proper regression tests are needed.
3052 * --Perry Metzger, Nov. 16, 2001 3048 * --Perry Metzger, Nov. 16, 2001
3053 */ 3049 */
3054/* 3050/*
3055 * Do only as much as necessary to compute constant expressions. 3051 * Do only as much as necessary to compute constant expressions.
3056 * Called only if the operator allows folding and all operands are constants. 3052 * Called only if the operator allows folding and all operands are constants.
3057 */ 3053 */
3058static tnode_t * 3054static tnode_t *
3059fold(tnode_t *tn) 3055fold(tnode_t *tn)
3060{ 3056{
3061 val_t *v; 3057 val_t *v;
3062 tspec_t t; 3058 tspec_t t;
3063 bool utyp, ovfl; 3059 bool utyp, ovfl;
3064 int64_t sl, sr = 0, q = 0, mask; 3060 int64_t sl, sr = 0, q = 0, mask;
3065 uint64_t ul, ur = 0; 3061 uint64_t ul, ur = 0;
3066 tnode_t *cn; 3062 tnode_t *cn;
3067 3063
3068 v = xcalloc(1, sizeof *v); 3064 v = xcalloc(1, sizeof *v);
3069 v->v_tspec = t = tn->tn_type->t_tspec; 3065 v->v_tspec = t = tn->tn_type->t_tspec;
3070 3066
3071 utyp = t == PTR || is_uinteger(t); 3067 utyp = t == PTR || is_uinteger(t);
3072 ul = sl = tn->tn_left->tn_val->v_quad; 3068 ul = sl = tn->tn_left->tn_val->v_quad;
3073 if (modtab[tn->tn_op].m_binary) 3069 if (modtab[tn->tn_op].m_binary)
3074 ur = sr = tn->tn_right->tn_val->v_quad; 3070 ur = sr = tn->tn_right->tn_val->v_quad;
3075 3071
3076 mask = qlmasks[size_in_bits(t)]; 3072 mask = qlmasks[size_in_bits(t)];
3077 ovfl = false; 3073 ovfl = false;
3078 3074
3079 switch (tn->tn_op) { 3075 switch (tn->tn_op) {
3080 case UPLUS: 3076 case UPLUS:
3081 q = sl; 3077 q = sl;
3082 break; 3078 break;
3083 case UMINUS: 3079 case UMINUS:
3084 q = -sl; 3080 q = -sl;
3085 if (sl != 0 && msb(q, t, -1) == msb(sl, t, -1)) 3081 if (sl != 0 && msb(q, t, -1) == msb(sl, t, -1))
3086 ovfl = true; 3082 ovfl = true;
3087 break; 3083 break;
3088 case COMPL: 3084 case COMPL:
3089 q = ~sl; 3085 q = ~sl;
3090 break; 3086 break;
3091 case MULT: 3087 case MULT:
3092 if (utyp) { 3088 if (utyp) {
3093 q = ul * ur; 3089 q = ul * ur;
3094 if (q != (q & mask)) 3090 if (q != (q & mask))
3095 ovfl = true; 3091 ovfl = true;
3096 else if ((ul != 0) && ((q / ul) != ur)) 3092 else if ((ul != 0) && ((q / ul) != ur))
3097 ovfl = true; 3093 ovfl = true;
3098 } else { 3094 } else {
3099 q = sl * sr; 3095 q = sl * sr;
3100 if (msb(q, t, -1) != (msb(sl, t, -1) ^ msb(sr, t, -1))) 3096 if (msb(q, t, -1) != (msb(sl, t, -1) ^ msb(sr, t, -1)))
3101 ovfl = true; 3097 ovfl = true;
3102 } 3098 }
3103 break; 3099 break;
3104 case DIV: 3100 case DIV:
3105 if (sr == 0) { 3101 if (sr == 0) {
3106 /* division by 0 */ 3102 /* division by 0 */
3107 error(139); 3103 error(139);
3108 q = utyp ? UQUAD_MAX : QUAD_MAX; 3104 q = utyp ? UQUAD_MAX : QUAD_MAX;
3109 } else { 3105 } else {
3110 q = utyp ? (int64_t)(ul / ur) : sl / sr; 3106 q = utyp ? (int64_t)(ul / ur) : sl / sr;
3111 } 3107 }
3112 break; 3108 break;
3113 case MOD: 3109 case MOD:
3114 if (sr == 0) { 3110 if (sr == 0) {
3115 /* modulus by 0 */ 3111 /* modulus by 0 */
3116 error(140); 3112 error(140);
3117 q = 0; 3113 q = 0;
3118 } else { 3114 } else {
3119 q = utyp ? (int64_t)(ul % ur) : sl % sr; 3115 q = utyp ? (int64_t)(ul % ur) : sl % sr;
3120 } 3116 }
3121 break; 3117 break;
3122 case PLUS: 3118 case PLUS:
3123 q = utyp ? (int64_t)(ul + ur) : sl + sr; 3119 q = utyp ? (int64_t)(ul + ur) : sl + sr;
3124 if (msb(sl, t, -1) != 0 && msb(sr, t, -1) != 0) { 3120 if (msb(sl, t, -1) != 0 && msb(sr, t, -1) != 0) {
3125 if (msb(q, t, -1) == 0) 3121 if (msb(q, t, -1) == 0)
3126 ovfl = true; 3122 ovfl = true;
3127 } else if (msb(sl, t, -1) == 0 && msb(sr, t, -1) == 0) { 3123 } else if (msb(sl, t, -1) == 0 && msb(sr, t, -1) == 0) {
3128 if (msb(q, t, -1) != 0) 3124 if (msb(q, t, -1) != 0)
3129 ovfl = true; 3125 ovfl = true;
3130 } 3126 }
3131 break; 3127 break;
3132 case MINUS: 3128 case MINUS:
3133 q = utyp ? (int64_t)(ul - ur) : sl - sr; 3129 q = utyp ? (int64_t)(ul - ur) : sl - sr;
3134 if (msb(sl, t, -1) != 0 && msb(sr, t, -1) == 0) { 3130 if (msb(sl, t, -1) != 0 && msb(sr, t, -1) == 0) {
3135 if (msb(q, t, -1) == 0) 3131 if (msb(q, t, -1) == 0)
3136 ovfl = true; 3132 ovfl = true;
3137 } else if (msb(sl, t, -1) == 0 && msb(sr, t, -1) != 0) { 3133 } else if (msb(sl, t, -1) == 0 && msb(sr, t, -1) != 0) {
3138 if (msb(q, t, -1) != 0) 3134 if (msb(q, t, -1) != 0)
3139 ovfl = true; 3135 ovfl = true;
3140 } 3136 }
3141 break; 3137 break;
3142 case SHL: 3138 case SHL:
3143 q = utyp ? (int64_t)(ul << sr) : sl << sr; 3139 q = utyp ? (int64_t)(ul << sr) : sl << sr;
3144 break; 3140 break;
3145 case SHR: 3141 case SHR:
3146 /* 3142 /*
3147 * The sign must be explicitly extended because 3143 * The sign must be explicitly extended because
3148 * shifts of signed values are implementation dependent. 3144 * shifts of signed values are implementation dependent.
3149 */ 3145 */
3150 q = ul >> sr; 3146 q = ul >> sr;
3151 q = xsign(q, t, size_in_bits(t) - (int)sr); 3147 q = xsign(q, t, size_in_bits(t) - (int)sr);
3152 break; 3148 break;
3153 case LT: 3149 case LT:
3154 q = (utyp ? ul < ur : sl < sr) ? 1 : 0; 3150 q = (utyp ? ul < ur : sl < sr) ? 1 : 0;
3155 break; 3151 break;
3156 case LE: 3152 case LE:
3157 q = (utyp ? ul <= ur : sl <= sr) ? 1 : 0; 3153 q = (utyp ? ul <= ur : sl <= sr) ? 1 : 0;
3158 break; 3154 break;
3159 case GE: 3155 case GE:
3160 q = (utyp ? ul >= ur : sl >= sr) ? 1 : 0; 3156 q = (utyp ? ul >= ur : sl >= sr) ? 1 : 0;
3161 break; 3157 break;
3162 case GT: 3158 case GT:
3163 q = (utyp ? ul > ur : sl > sr) ? 1 : 0; 3159 q = (utyp ? ul > ur : sl > sr) ? 1 : 0;
3164 break; 3160 break;
3165 case EQ: 3161 case EQ:
3166 q = (utyp ? ul == ur : sl == sr) ? 1 : 0; 3162 q = (utyp ? ul == ur : sl == sr) ? 1 : 0;
3167 break; 3163 break;
3168 case NE: 3164 case NE:
3169 q = (utyp ? ul != ur : sl != sr) ? 1 : 0; 3165 q = (utyp ? ul != ur : sl != sr) ? 1 : 0;
3170 break; 3166 break;
3171 case BITAND: 3167 case BITAND:
3172 q = utyp ? (int64_t)(ul & ur) : sl & sr; 3168 q = utyp ? (int64_t)(ul & ur) : sl & sr;
3173 break; 3169 break;
3174 case BITXOR: 3170 case BITXOR:
3175 q = utyp ? (int64_t)(ul ^ ur) : sl ^ sr; 3171 q = utyp ? (int64_t)(ul ^ ur) : sl ^ sr;
3176 break; 3172 break;
3177 case BITOR: 3173 case BITOR:
3178 q = utyp ? (int64_t)(ul | ur) : sl | sr; 3174 q = utyp ? (int64_t)(ul | ur) : sl | sr;
3179 break; 3175 break;
3180 default: 3176 default:
3181 lint_assert(/*CONSTCOND*/false); 3177 lint_assert(/*CONSTCOND*/false);
3182 } 3178 }
3183 3179
3184 /* XXX does not work for quads. */ 3180 /* XXX does not work for quads. */
3185 if (ovfl || ((uint64_t)(q | mask) != ~(uint64_t)0 && 3181 if (ovfl || ((uint64_t)(q | mask) != ~(uint64_t)0 &&
3186 (q & ~mask) != 0)) { 3182 (q & ~mask) != 0)) {
3187 if (hflag) 3183 if (hflag)
3188 /* integer overflow detected, op %s */ 3184 /* integer overflow detected, op %s */
3189 warning(141, modtab[tn->tn_op].m_name); 3185 warning(141, modtab[tn->tn_op].m_name);
3190 } 3186 }
3191 3187
3192 v->v_quad = xsign(q, t, -1); 3188 v->v_quad = xsign(q, t, -1);
3193 3189
3194 cn = new_constant_node(tn->tn_type, v); 3190 cn = new_constant_node(tn->tn_type, v);
3195 if (tn->tn_left->tn_system_dependent) 3191 if (tn->tn_left->tn_system_dependent)
3196 cn->tn_system_dependent = true; 3192 cn->tn_system_dependent = true;
3197 if (modtab[tn->tn_op].m_binary && tn->tn_right->tn_system_dependent) 3193 if (modtab[tn->tn_op].m_binary && tn->tn_right->tn_system_dependent)
3198 cn->tn_system_dependent = true; 3194 cn->tn_system_dependent = true;
3199 3195
3200 return cn; 3196 return cn;
3201} 3197}
3202 3198
3203/* 3199/*
3204 * Fold constant nodes, as much as is needed for comparing the value with 0 3200 * Fold constant nodes, as much as is needed for comparing the value with 0
3205 * (test context, for controlling expressions). 3201 * (test context, for controlling expressions).
3206 */ 3202 */
3207static tnode_t * 3203static tnode_t *
3208fold_test(tnode_t *tn) 3204fold_test(tnode_t *tn)
3209{ 3205{
3210 bool l, r; 3206 bool l, r;
3211 val_t *v; 3207 val_t *v;
3212 3208
3213 v = xcalloc(1, sizeof *v); 3209 v = xcalloc(1, sizeof *v);
3214 v->v_tspec = tn->tn_type->t_tspec; 3210 v->v_tspec = tn->tn_type->t_tspec;
3215 lint_assert(v->v_tspec == INT || (Tflag && v->v_tspec == BOOL)); 3211 lint_assert(v->v_tspec == INT || (Tflag && v->v_tspec == BOOL));
3216 3212
3217 l = constant_is_nonzero(tn->tn_left); 3213 l = constant_is_nonzero(tn->tn_left);
3218 r = modtab[tn->tn_op].m_binary && constant_is_nonzero(tn->tn_right); 3214 r = modtab[tn->tn_op].m_binary && constant_is_nonzero(tn->tn_right);
3219 3215
3220 switch (tn->tn_op) { 3216 switch (tn->tn_op) {
3221 case NOT: 3217 case NOT:
3222 if (hflag && !constcond_flag) 3218 if (hflag && !constcond_flag)
3223 /* constant argument to NOT */ 3219 /* constant argument to NOT */
3224 warning(239); 3220 warning(239);
3225 v->v_quad = !l ? 1 : 0; 3221 v->v_quad = !l ? 1 : 0;
3226 break; 3222 break;
3227 case LOGAND: 3223 case LOGAND:
3228 v->v_quad = l && r ? 1 : 0; 3224 v->v_quad = l && r ? 1 : 0;
3229 break; 3225 break;
3230 case LOGOR: 3226 case LOGOR:
3231 v->v_quad = l || r ? 1 : 0; 3227 v->v_quad = l || r ? 1 : 0;
3232 break; 3228 break;
3233 default: 3229 default:
3234 lint_assert(/*CONSTCOND*/false); 3230 lint_assert(/*CONSTCOND*/false);
3235 } 3231 }
3236 3232
3237 return new_constant_node(tn->tn_type, v); 3233 return new_constant_node(tn->tn_type, v);
3238} 3234}