Mon Jan 4 17:06:21 2021 UTC ()
lint: in debug mode, print node tree for precedence

>From the code alone, it is too difficult to see how the various internal
operators are combined and what properties they have.  A simple tree
visualization helps to see all the details.

This is used to track down the typo in check_precedence_confusion, to
see whether it could have possibly had any influence at all.


(rillig)
diff -r1.123 -r1.124 src/usr.bin/xlint/lint1/tree.c

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

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