Sun Feb 27 10:44:45 2022 UTC ()
lint: unabbreviate some fields in sym_t

No functional change.


(rillig)
diff -r1.247 -r1.248 src/usr.bin/xlint/lint1/decl.c
diff -r1.127 -r1.128 src/usr.bin/xlint/lint1/func.c
diff -r1.101 -r1.102 src/usr.bin/xlint/lint1/lex.c
diff -r1.138 -r1.139 src/usr.bin/xlint/lint1/lint1.h
diff -r1.406 -r1.407 src/usr.bin/xlint/lint1/tree.c

cvs diff -r1.247 -r1.248 src/usr.bin/xlint/lint1/decl.c (switch to unified diff)

--- src/usr.bin/xlint/lint1/decl.c 2022/02/27 10:31:58 1.247
+++ src/usr.bin/xlint/lint1/decl.c 2022/02/27 10:44:45 1.248
@@ -1,3353 +1,3353 @@ @@ -1,3353 +1,3353 @@
1/* $NetBSD: decl.c,v 1.247 2022/02/27 10:31:58 rillig Exp $ */ 1/* $NetBSD: decl.c,v 1.248 2022/02/27 10:44:45 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. 4 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
5 * Copyright (c) 1994, 1995 Jochen Pohl 5 * Copyright (c) 1994, 1995 Jochen Pohl
6 * All Rights Reserved. 6 * All Rights Reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement: 17 * must display the following acknowledgement:
18 * This product includes software developed by Jochen Pohl for 18 * This product includes software developed by Jochen Pohl for
19 * The NetBSD Project. 19 * The NetBSD Project.
20 * 4. The name of the author may not be used to endorse or promote products 20 * 4. The name of the author may not be used to endorse or promote products
21 * derived from this software without specific prior written permission. 21 * derived from this software without specific prior written permission.
22 * 22 *
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */ 33 */
34 34
35#if HAVE_NBTOOL_CONFIG_H 35#if HAVE_NBTOOL_CONFIG_H
36#include "nbtool_config.h" 36#include "nbtool_config.h"
37#endif 37#endif
38 38
39#include <sys/cdefs.h> 39#include <sys/cdefs.h>
40#if defined(__RCSID) && !defined(lint) 40#if defined(__RCSID) && !defined(lint)
41__RCSID("$NetBSD: decl.c,v 1.247 2022/02/27 10:31:58 rillig Exp $"); 41__RCSID("$NetBSD: decl.c,v 1.248 2022/02/27 10:44:45 rillig Exp $");
42#endif 42#endif
43 43
44#include <sys/param.h> 44#include <sys/param.h>
45#include <limits.h> 45#include <limits.h>
46#include <stdlib.h> 46#include <stdlib.h>
47#include <string.h> 47#include <string.h>
48 48
49#include "lint1.h" 49#include "lint1.h"
50 50
51const char *unnamed = "<unnamed>"; 51const char *unnamed = "<unnamed>";
52 52
53/* shared type structures for arithmetic types and void */ 53/* shared type structures for arithmetic types and void */
54static type_t *typetab; 54static type_t *typetab;
55 55
56/* value of next enumerator during declaration of enum types */ 56/* value of next enumerator during declaration of enum types */
57int enumval; 57int enumval;
58 58
59/* 59/*
60 * pointer to top element of a stack which contains information local 60 * pointer to top element of a stack which contains information local
61 * to nested declarations 61 * to nested declarations
62 */ 62 */
63dinfo_t *dcs; 63dinfo_t *dcs;
64 64
65static type_t *tdeferr(type_t *, tspec_t); 65static type_t *tdeferr(type_t *, tspec_t);
66static void settdsym(type_t *, sym_t *); 66static void settdsym(type_t *, sym_t *);
67static void align(unsigned int, unsigned int); 67static void align(unsigned int, unsigned int);
68static sym_t *newtag(sym_t *, scl_t, bool, bool); 68static sym_t *newtag(sym_t *, scl_t, bool, bool);
69static bool eqargs(const type_t *, const type_t *, bool *); 69static bool eqargs(const type_t *, const type_t *, bool *);
70static bool mnoarg(const type_t *, bool *); 70static bool mnoarg(const type_t *, bool *);
71static bool check_old_style_definition(sym_t *, sym_t *); 71static bool check_old_style_definition(sym_t *, sym_t *);
72static bool check_prototype_declaration(sym_t *, sym_t *); 72static bool check_prototype_declaration(sym_t *, sym_t *);
73static sym_t *new_style_function(sym_t *, sym_t *); 73static sym_t *new_style_function(sym_t *, sym_t *);
74static void old_style_function(sym_t *, sym_t *); 74static void old_style_function(sym_t *, sym_t *);
75static void declare_external_in_block(sym_t *); 75static void declare_external_in_block(sym_t *);
76static bool check_init(sym_t *); 76static bool check_init(sym_t *);
77static void check_argument_usage(bool, sym_t *); 77static void check_argument_usage(bool, sym_t *);
78static void check_variable_usage(bool, sym_t *); 78static void check_variable_usage(bool, sym_t *);
79static void check_label_usage(sym_t *); 79static void check_label_usage(sym_t *);
80static void check_tag_usage(sym_t *); 80static void check_tag_usage(sym_t *);
81static void check_global_variable(const sym_t *); 81static void check_global_variable(const sym_t *);
82static void check_global_variable_size(const sym_t *); 82static void check_global_variable_size(const sym_t *);
83 83
84/* 84/*
85 * initializes all global vars used in declarations 85 * initializes all global vars used in declarations
86 */ 86 */
87void 87void
88#ifdef __sh3__ 88#ifdef __sh3__
89/* XXX port-sh3/56311 */ 89/* XXX port-sh3/56311 */
90__attribute__((optimize("O0"))) 90__attribute__((optimize("O0")))
91#endif 91#endif
92initdecl(void) 92initdecl(void)
93{ 93{
94 int i; 94 int i;
95 95
96 /* declaration stack */ 96 /* declaration stack */
97 dcs = xcalloc(1, sizeof(*dcs)); 97 dcs = xcalloc(1, sizeof(*dcs));
98 dcs->d_ctx = EXTERN; 98 dcs->d_ctx = EXTERN;
99 dcs->d_ldlsym = &dcs->d_dlsyms; 99 dcs->d_ldlsym = &dcs->d_dlsyms;
100 100
101 /* type information and classification */ 101 /* type information and classification */
102 inittyp(); 102 inittyp();
103 103
104 /* shared type structures */ 104 /* shared type structures */
105 typetab = xcalloc(NTSPEC, sizeof(*typetab)); 105 typetab = xcalloc(NTSPEC, sizeof(*typetab));
106 for (i = 0; i < NTSPEC; i++) 106 for (i = 0; i < NTSPEC; i++)
107 typetab[i].t_tspec = NOTSPEC; 107 typetab[i].t_tspec = NOTSPEC;
108 108
109 /* 109 /*
110 * The following two are not real types. They are only used by the 110 * The following two are not real types. They are only used by the
111 * parser to handle the keywords "signed" and "unsigned". 111 * parser to handle the keywords "signed" and "unsigned".
112 */ 112 */
113 typetab[SIGNED].t_tspec = SIGNED; 113 typetab[SIGNED].t_tspec = SIGNED;
114 typetab[UNSIGN].t_tspec = UNSIGN; 114 typetab[UNSIGN].t_tspec = UNSIGN;
115 115
116 typetab[BOOL].t_tspec = BOOL; 116 typetab[BOOL].t_tspec = BOOL;
117 typetab[CHAR].t_tspec = CHAR; 117 typetab[CHAR].t_tspec = CHAR;
118 typetab[SCHAR].t_tspec = SCHAR; 118 typetab[SCHAR].t_tspec = SCHAR;
119 typetab[UCHAR].t_tspec = UCHAR; 119 typetab[UCHAR].t_tspec = UCHAR;
120 typetab[SHORT].t_tspec = SHORT; 120 typetab[SHORT].t_tspec = SHORT;
121 typetab[USHORT].t_tspec = USHORT; 121 typetab[USHORT].t_tspec = USHORT;
122 typetab[INT].t_tspec = INT; 122 typetab[INT].t_tspec = INT;
123 typetab[UINT].t_tspec = UINT; 123 typetab[UINT].t_tspec = UINT;
124 typetab[LONG].t_tspec = LONG; 124 typetab[LONG].t_tspec = LONG;
125 typetab[ULONG].t_tspec = ULONG; 125 typetab[ULONG].t_tspec = ULONG;
126 typetab[QUAD].t_tspec = QUAD; 126 typetab[QUAD].t_tspec = QUAD;
127 typetab[UQUAD].t_tspec = UQUAD; 127 typetab[UQUAD].t_tspec = UQUAD;
128#ifdef INT128_SIZE 128#ifdef INT128_SIZE
129 typetab[INT128].t_tspec = INT128; 129 typetab[INT128].t_tspec = INT128;
130 typetab[UINT128].t_tspec = UINT128; 130 typetab[UINT128].t_tspec = UINT128;
131#endif 131#endif
132 typetab[FLOAT].t_tspec = FLOAT; 132 typetab[FLOAT].t_tspec = FLOAT;
133 typetab[DOUBLE].t_tspec = DOUBLE; 133 typetab[DOUBLE].t_tspec = DOUBLE;
134 typetab[LDOUBLE].t_tspec = LDOUBLE; 134 typetab[LDOUBLE].t_tspec = LDOUBLE;
135 typetab[VOID].t_tspec = VOID; 135 typetab[VOID].t_tspec = VOID;
136 /* struct, union, enum, ptr, array and func are not shared. */ 136 /* struct, union, enum, ptr, array and func are not shared. */
137 typetab[COMPLEX].t_tspec = COMPLEX; 137 typetab[COMPLEX].t_tspec = COMPLEX;
138 typetab[FCOMPLEX].t_tspec = FCOMPLEX; 138 typetab[FCOMPLEX].t_tspec = FCOMPLEX;
139 typetab[DCOMPLEX].t_tspec = DCOMPLEX; 139 typetab[DCOMPLEX].t_tspec = DCOMPLEX;
140 typetab[LCOMPLEX].t_tspec = LCOMPLEX; 140 typetab[LCOMPLEX].t_tspec = LCOMPLEX;
141} 141}
142 142
143#ifdef DEBUG 143#ifdef DEBUG
144/* Return the name of the "storage class" in the wider sense. */ 144/* Return the name of the "storage class" in the wider sense. */
145const char * 145const char *
146scl_name(scl_t scl) 146scl_name(scl_t scl)
147{ 147{
148 static const char *const names[] = { 148 static const char *const names[] = {
149 "none", "extern", "static", "auto", "register", "typedef", 149 "none", "extern", "static", "auto", "register", "typedef",
150 "struct", "union", "enum", "member of struct", "member of union", 150 "struct", "union", "enum", "member of struct", "member of union",
151 "compile-time constant", "abstract", 151 "compile-time constant", "abstract",
152 "old-style function argument", "prototype argument", "inline" 152 "old-style function argument", "prototype argument", "inline"
153 }; 153 };
154 154
155 return names[scl]; 155 return names[scl];
156} 156}
157#endif 157#endif
158 158
159/* 159/*
160 * Returns a shared type structure for arithmetic types and void. 160 * Returns a shared type structure for arithmetic types and void.
161 * 161 *
162 * It's important to duplicate this structure using block_dup_type or 162 * It's important to duplicate this structure using block_dup_type or
163 * expr_dup_type if it is to be modified (adding qualifiers or anything 163 * expr_dup_type if it is to be modified (adding qualifiers or anything
164 * else). 164 * else).
165 */ 165 */
166type_t * 166type_t *
167gettyp(tspec_t t) 167gettyp(tspec_t t)
168{ 168{
169 169
170 /* TODO: make the return type 'const' */ 170 /* TODO: make the return type 'const' */
171 return &typetab[t]; 171 return &typetab[t];
172} 172}
173 173
174type_t * 174type_t *
175block_dup_type(const type_t *tp) 175block_dup_type(const type_t *tp)
176{ 176{
177 type_t *ntp; 177 type_t *ntp;
178 178
179 ntp = block_zero_alloc(sizeof(*ntp)); 179 ntp = block_zero_alloc(sizeof(*ntp));
180 *ntp = *tp; 180 *ntp = *tp;
181 return ntp; 181 return ntp;
182} 182}
183 183
184/* Duplicate a type, free the allocated memory after the expression. */ 184/* Duplicate a type, free the allocated memory after the expression. */
185type_t * 185type_t *
186expr_dup_type(const type_t *tp) 186expr_dup_type(const type_t *tp)
187{ 187{
188 type_t *ntp; 188 type_t *ntp;
189 189
190 ntp = expr_zero_alloc(sizeof(*ntp)); 190 ntp = expr_zero_alloc(sizeof(*ntp));
191 *ntp = *tp; 191 *ntp = *tp;
192 return ntp; 192 return ntp;
193} 193}
194 194
195/* 195/*
196 * Return the unqualified version of the type. The returned type is freed at 196 * Return the unqualified version of the type. The returned type is freed at
197 * the end of the current expression. 197 * the end of the current expression.
198 * 198 *
199 * See C99 6.2.5p25. 199 * See C99 6.2.5p25.
200 */ 200 */
201type_t * 201type_t *
202expr_unqualified_type(const type_t *tp) 202expr_unqualified_type(const type_t *tp)
203{ 203{
204 type_t *ntp; 204 type_t *ntp;
205 205
206 ntp = expr_zero_alloc(sizeof(*ntp)); 206 ntp = expr_zero_alloc(sizeof(*ntp));
207 *ntp = *tp; 207 *ntp = *tp;
208 ntp->t_const = false; 208 ntp->t_const = false;
209 ntp->t_volatile = false; 209 ntp->t_volatile = false;
210 210
211 /* 211 /*
212 * In case of a struct or union type, the members should lose their 212 * In case of a struct or union type, the members should lose their
213 * qualifiers as well, but that would require a deep copy of the 213 * qualifiers as well, but that would require a deep copy of the
214 * struct or union type. This in turn would defeat the type 214 * struct or union type. This in turn would defeat the type
215 * comparison in eqtype, which simply tests whether tp1->t_str == 215 * comparison in eqtype, which simply tests whether tp1->t_str ==
216 * tp2->t_str. 216 * tp2->t_str.
217 */ 217 */
218 218
219 return ntp; 219 return ntp;
220} 220}
221 221
222/* 222/*
223 * Returns whether the argument is void or an incomplete array, 223 * Returns whether the argument is void or an incomplete array,
224 * struct, union or enum type. 224 * struct, union or enum type.
225 */ 225 */
226bool 226bool
227is_incomplete(const type_t *tp) 227is_incomplete(const type_t *tp)
228{ 228{
229 tspec_t t; 229 tspec_t t;
230 230
231 if ((t = tp->t_tspec) == VOID) { 231 if ((t = tp->t_tspec) == VOID) {
232 return true; 232 return true;
233 } else if (t == ARRAY) { 233 } else if (t == ARRAY) {
234 return tp->t_incomplete_array; 234 return tp->t_incomplete_array;
235 } else if (t == STRUCT || t == UNION) { 235 } else if (t == STRUCT || t == UNION) {
236 return tp->t_str->sou_incomplete; 236 return tp->t_str->sou_incomplete;
237 } else if (t == ENUM) { 237 } else if (t == ENUM) {
238 return tp->t_enum->en_incomplete; 238 return tp->t_enum->en_incomplete;
239 } 239 }
240 return false; 240 return false;
241} 241}
242 242
243/* 243/*
244 * Mark an array, struct, union or enum type as complete or incomplete. 244 * Mark an array, struct, union or enum type as complete or incomplete.
245 */ 245 */
246void 246void
247setcomplete(type_t *tp, bool complete) 247setcomplete(type_t *tp, bool complete)
248{ 248{
249 tspec_t t; 249 tspec_t t;
250 250
251 lint_assert(tp != NULL); 251 lint_assert(tp != NULL);
252 if ((t = tp->t_tspec) == ARRAY) { 252 if ((t = tp->t_tspec) == ARRAY) {
253 tp->t_incomplete_array = !complete; 253 tp->t_incomplete_array = !complete;
254 } else if (t == STRUCT || t == UNION) { 254 } else if (t == STRUCT || t == UNION) {
255 tp->t_str->sou_incomplete = !complete; 255 tp->t_str->sou_incomplete = !complete;
256 } else { 256 } else {
257 lint_assert(t == ENUM); 257 lint_assert(t == ENUM);
258 tp->t_enum->en_incomplete = !complete; 258 tp->t_enum->en_incomplete = !complete;
259 } 259 }
260} 260}
261 261
262/* 262/*
263 * Remember the storage class of the current declaration in dcs->d_scl 263 * Remember the storage class of the current declaration in dcs->d_scl
264 * (the top element of the declaration stack) and detect multiple 264 * (the top element of the declaration stack) and detect multiple
265 * storage classes. 265 * storage classes.
266 */ 266 */
267void 267void
268add_storage_class(scl_t sc) 268add_storage_class(scl_t sc)
269{ 269{
270 270
271 if (sc == INLINE) { 271 if (sc == INLINE) {
272 if (dcs->d_inline) 272 if (dcs->d_inline)
273 /* duplicate '%s' */ 273 /* duplicate '%s' */
274 warning(10, "inline"); 274 warning(10, "inline");
275 dcs->d_inline = true; 275 dcs->d_inline = true;
276 return; 276 return;
277 } 277 }
278 if (dcs->d_type != NULL || dcs->d_abstract_type != NOTSPEC || 278 if (dcs->d_type != NULL || dcs->d_abstract_type != NOTSPEC ||
279 dcs->d_sign_mod != NOTSPEC || dcs->d_rank_mod != NOTSPEC) { 279 dcs->d_sign_mod != NOTSPEC || dcs->d_rank_mod != NOTSPEC) {
280 /* storage class after type is obsolescent */ 280 /* storage class after type is obsolescent */
281 warning(83); 281 warning(83);
282 } 282 }
283 if (dcs->d_scl == NOSCL) { 283 if (dcs->d_scl == NOSCL) {
284 dcs->d_scl = sc; 284 dcs->d_scl = sc;
285 } else { 285 } else {
286 dcs->d_multiple_storage_classes = true; 286 dcs->d_multiple_storage_classes = true;
287 } 287 }
288} 288}
289 289
290/* 290/*
291 * Remember the type, modifier or typedef name returned by the parser 291 * Remember the type, modifier or typedef name returned by the parser
292 * in *dcs (top element of decl stack). This information is used in 292 * in *dcs (top element of decl stack). This information is used in
293 * end_type() to build the type used for all declarators in this 293 * end_type() to build the type used for all declarators in this
294 * declaration. 294 * declaration.
295 * 295 *
296 * If tp->t_typedef is 1, the type comes from a previously defined typename. 296 * If tp->t_typedef is 1, the type comes from a previously defined typename.
297 * Otherwise it comes from a type specifier (int, long, ...) or a 297 * Otherwise it comes from a type specifier (int, long, ...) or a
298 * struct/union/enum tag. 298 * struct/union/enum tag.
299 */ 299 */
300void 300void
301add_type(type_t *tp) 301add_type(type_t *tp)
302{ 302{
303 tspec_t t; 303 tspec_t t;
304 304
305 debug_step("%s: %s", __func__, type_name(tp)); 305 debug_step("%s: %s", __func__, type_name(tp));
306 if (tp->t_typedef) { 306 if (tp->t_typedef) {
307 /* 307 /*
308 * something like "typedef int a; int a b;" 308 * something like "typedef int a; int a b;"
309 * This should not happen with current grammar. 309 * This should not happen with current grammar.
310 */ 310 */
311 lint_assert(dcs->d_type == NULL); 311 lint_assert(dcs->d_type == NULL);
312 lint_assert(dcs->d_abstract_type == NOTSPEC); 312 lint_assert(dcs->d_abstract_type == NOTSPEC);
313 lint_assert(dcs->d_sign_mod == NOTSPEC); 313 lint_assert(dcs->d_sign_mod == NOTSPEC);
314 lint_assert(dcs->d_rank_mod == NOTSPEC); 314 lint_assert(dcs->d_rank_mod == NOTSPEC);
315 315
316 dcs->d_type = tp; 316 dcs->d_type = tp;
317 return; 317 return;
318 } 318 }
319 319
320 t = tp->t_tspec; 320 t = tp->t_tspec;
321 321
322 if (t == STRUCT || t == UNION || t == ENUM) { 322 if (t == STRUCT || t == UNION || t == ENUM) {
323 /* 323 /*
324 * something like "int struct a ..." 324 * something like "int struct a ..."
325 * struct/union/enum with anything else is not allowed 325 * struct/union/enum with anything else is not allowed
326 */ 326 */
327 if (dcs->d_type != NULL || dcs->d_abstract_type != NOTSPEC || 327 if (dcs->d_type != NULL || dcs->d_abstract_type != NOTSPEC ||
328 dcs->d_rank_mod != NOTSPEC || dcs->d_sign_mod != NOTSPEC) { 328 dcs->d_rank_mod != NOTSPEC || dcs->d_sign_mod != NOTSPEC) {
329 dcs->d_invalid_type_combination = true; 329 dcs->d_invalid_type_combination = true;
330 dcs->d_abstract_type = NOTSPEC; 330 dcs->d_abstract_type = NOTSPEC;
331 dcs->d_sign_mod = NOTSPEC; 331 dcs->d_sign_mod = NOTSPEC;
332 dcs->d_rank_mod = NOTSPEC; 332 dcs->d_rank_mod = NOTSPEC;
333 } 333 }
334 dcs->d_type = tp; 334 dcs->d_type = tp;
335 return; 335 return;
336 } 336 }
337 337
338 if (dcs->d_type != NULL && !dcs->d_type->t_typedef) { 338 if (dcs->d_type != NULL && !dcs->d_type->t_typedef) {
339 /* 339 /*
340 * something like "struct a int" 340 * something like "struct a int"
341 * struct/union/enum with anything else is not allowed 341 * struct/union/enum with anything else is not allowed
342 */ 342 */
343 dcs->d_invalid_type_combination = true; 343 dcs->d_invalid_type_combination = true;
344 return; 344 return;
345 } 345 }
346 346
347 if (t == COMPLEX) { 347 if (t == COMPLEX) {
348 if (dcs->d_complex_mod == FLOAT) 348 if (dcs->d_complex_mod == FLOAT)
349 t = FCOMPLEX; 349 t = FCOMPLEX;
350 else if (dcs->d_complex_mod == DOUBLE) 350 else if (dcs->d_complex_mod == DOUBLE)
351 t = DCOMPLEX; 351 t = DCOMPLEX;
352 else { 352 else {
353 /* invalid type for _Complex */ 353 /* invalid type for _Complex */
354 error(308); 354 error(308);
355 t = DCOMPLEX; /* just as a fallback */ 355 t = DCOMPLEX; /* just as a fallback */
356 } 356 }
357 dcs->d_complex_mod = NOTSPEC; 357 dcs->d_complex_mod = NOTSPEC;
358 } 358 }
359 359
360 if (t == LONG && dcs->d_rank_mod == LONG) { 360 if (t == LONG && dcs->d_rank_mod == LONG) {
361 /* "long long" or "long ... long" */ 361 /* "long long" or "long ... long" */
362 t = QUAD; 362 t = QUAD;
363 dcs->d_rank_mod = NOTSPEC; 363 dcs->d_rank_mod = NOTSPEC;
364 if (!quadflg) 364 if (!quadflg)
365 /* %s does not support 'long long' */ 365 /* %s does not support 'long long' */
366 c99ism(265, tflag ? "traditional C" : "C90"); 366 c99ism(265, tflag ? "traditional C" : "C90");
367 } 367 }
368 368
369 if (dcs->d_type != NULL && dcs->d_type->t_typedef) { 369 if (dcs->d_type != NULL && dcs->d_type->t_typedef) {
370 /* something like "typedef int a; a long ..." */ 370 /* something like "typedef int a; a long ..." */
371 dcs->d_type = tdeferr(dcs->d_type, t); 371 dcs->d_type = tdeferr(dcs->d_type, t);
372 return; 372 return;
373 } 373 }
374 374
375 /* now it can be only a combination of arithmetic types and void */ 375 /* now it can be only a combination of arithmetic types and void */
376 if (t == SIGNED || t == UNSIGN) { 376 if (t == SIGNED || t == UNSIGN) {
377 /* 377 /*
378 * remember specifiers "signed" & "unsigned" in 378 * remember specifiers "signed" & "unsigned" in
379 * dcs->d_sign_mod 379 * dcs->d_sign_mod
380 */ 380 */
381 if (dcs->d_sign_mod != NOTSPEC) 381 if (dcs->d_sign_mod != NOTSPEC)
382 /* more than one "signed" and/or "unsigned" */ 382 /* more than one "signed" and/or "unsigned" */
383 dcs->d_invalid_type_combination = true; 383 dcs->d_invalid_type_combination = true;
384 dcs->d_sign_mod = t; 384 dcs->d_sign_mod = t;
385 } else if (t == SHORT || t == LONG || t == QUAD) { 385 } else if (t == SHORT || t == LONG || t == QUAD) {
386 /* 386 /*
387 * remember specifiers "short", "long" and "long long" in 387 * remember specifiers "short", "long" and "long long" in
388 * dcs->d_rank_mod 388 * dcs->d_rank_mod
389 */ 389 */
390 if (dcs->d_rank_mod != NOTSPEC) 390 if (dcs->d_rank_mod != NOTSPEC)
391 dcs->d_invalid_type_combination = true; 391 dcs->d_invalid_type_combination = true;
392 dcs->d_rank_mod = t; 392 dcs->d_rank_mod = t;
393 } else if (t == FLOAT || t == DOUBLE) { 393 } else if (t == FLOAT || t == DOUBLE) {
394 if (dcs->d_rank_mod == NOTSPEC || dcs->d_rank_mod == LONG) { 394 if (dcs->d_rank_mod == NOTSPEC || dcs->d_rank_mod == LONG) {
395 if (dcs->d_complex_mod != NOTSPEC 395 if (dcs->d_complex_mod != NOTSPEC
396 || (t == FLOAT && dcs->d_rank_mod == LONG)) 396 || (t == FLOAT && dcs->d_rank_mod == LONG))
397 dcs->d_invalid_type_combination = true; 397 dcs->d_invalid_type_combination = true;
398 dcs->d_complex_mod = t; 398 dcs->d_complex_mod = t;
399 } else { 399 } else {
400 if (dcs->d_abstract_type != NOTSPEC) 400 if (dcs->d_abstract_type != NOTSPEC)
401 dcs->d_invalid_type_combination = true; 401 dcs->d_invalid_type_combination = true;
402 dcs->d_abstract_type = t; 402 dcs->d_abstract_type = t;
403 } 403 }
404 } else if (t == PTR) { 404 } else if (t == PTR) {
405 dcs->d_type = tp; 405 dcs->d_type = tp;
406 } else { 406 } else {
407 /* 407 /*
408 * remember specifiers "void", "char", "int", 408 * remember specifiers "void", "char", "int",
409 * or "_Complex" in dcs->d_abstract_type 409 * or "_Complex" in dcs->d_abstract_type
410 */ 410 */
411 if (dcs->d_abstract_type != NOTSPEC) 411 if (dcs->d_abstract_type != NOTSPEC)
412 dcs->d_invalid_type_combination = true; 412 dcs->d_invalid_type_combination = true;
413 dcs->d_abstract_type = t; 413 dcs->d_abstract_type = t;
414 } 414 }
415} 415}
416 416
417/* Merge the signedness into the abstract type. */ 417/* Merge the signedness into the abstract type. */
418static tspec_t 418static tspec_t
419merge_signedness(tspec_t t, tspec_t s) 419merge_signedness(tspec_t t, tspec_t s)
420{ 420{
421 421
422 if (s == SIGNED) 422 if (s == SIGNED)
423 return t == CHAR ? SCHAR : t; 423 return t == CHAR ? SCHAR : t;
424 if (s != UNSIGN) 424 if (s != UNSIGN)
425 return t; 425 return t;
426 return t == CHAR ? UCHAR 426 return t == CHAR ? UCHAR
427 : t == SHORT ? USHORT 427 : t == SHORT ? USHORT
428 : t == INT ? UINT 428 : t == INT ? UINT
429 : t == LONG ? ULONG 429 : t == LONG ? ULONG
430 : t == QUAD ? UQUAD 430 : t == QUAD ? UQUAD
431 : t; 431 : t;
432} 432}
433 433
434/* 434/*
435 * called if a list of declaration specifiers contains a typedef name 435 * called if a list of declaration specifiers contains a typedef name
436 * and other specifiers (except struct, union, enum, typedef name) 436 * and other specifiers (except struct, union, enum, typedef name)
437 */ 437 */
438static type_t * 438static type_t *
439tdeferr(type_t *td, tspec_t t) 439tdeferr(type_t *td, tspec_t t)
440{ 440{
441 tspec_t t2; 441 tspec_t t2;
442 442
443 t2 = td->t_tspec; 443 t2 = td->t_tspec;
444 444
445 if ((t == SIGNED || t == UNSIGN) && 445 if ((t == SIGNED || t == UNSIGN) &&
446 (t2 == CHAR || t2 == SHORT || t2 == INT || 446 (t2 == CHAR || t2 == SHORT || t2 == INT ||
447 t2 == LONG || t2 == QUAD)) { 447 t2 == LONG || t2 == QUAD)) {
448 if (!tflag) 448 if (!tflag)
449 /* modifying typedef with '%s'; only qualifiers... */ 449 /* modifying typedef with '%s'; only qualifiers... */
450 warning(5, tspec_name(t)); 450 warning(5, tspec_name(t));
451 td = block_dup_type(gettyp(merge_signedness(t2, t))); 451 td = block_dup_type(gettyp(merge_signedness(t2, t)));
452 td->t_typedef = true; 452 td->t_typedef = true;
453 return td; 453 return td;
454 } 454 }
455 455
456 if (t == SHORT && (t2 == INT || t2 == UINT)) { 456 if (t == SHORT && (t2 == INT || t2 == UINT)) {
457 /* modifying typedef with '%s'; only qualifiers allowed */ 457 /* modifying typedef with '%s'; only qualifiers allowed */
458 warning(5, "short"); 458 warning(5, "short");
459 td = block_dup_type(gettyp(t2 == INT ? SHORT : USHORT)); 459 td = block_dup_type(gettyp(t2 == INT ? SHORT : USHORT));
460 td->t_typedef = true; 460 td->t_typedef = true;
461 return td; 461 return td;
462 } 462 }
463 463
464 if (t == LONG && 464 if (t == LONG &&
465 (t2 == INT || t2 == UINT || t2 == LONG || t2 == ULONG || 465 (t2 == INT || t2 == UINT || t2 == LONG || t2 == ULONG ||
466 t2 == FLOAT || t2 == DOUBLE || t2 == DCOMPLEX)) { 466 t2 == FLOAT || t2 == DOUBLE || t2 == DCOMPLEX)) {
467 /* modifying typedef with '%s'; only qualifiers allowed */ 467 /* modifying typedef with '%s'; only qualifiers allowed */
468 warning(5, "long"); 468 warning(5, "long");
469 if (t2 == INT) { 469 if (t2 == INT) {
470 td = gettyp(LONG); 470 td = gettyp(LONG);
471 } else if (t2 == UINT) { 471 } else if (t2 == UINT) {
472 td = gettyp(ULONG); 472 td = gettyp(ULONG);
473 } else if (t2 == LONG) { 473 } else if (t2 == LONG) {
474 td = gettyp(QUAD); 474 td = gettyp(QUAD);
475 } else if (t2 == ULONG) { 475 } else if (t2 == ULONG) {
476 td = gettyp(UQUAD); 476 td = gettyp(UQUAD);
477 } else if (t2 == FLOAT) { 477 } else if (t2 == FLOAT) {
478 td = gettyp(DOUBLE); 478 td = gettyp(DOUBLE);
479 } else if (t2 == DOUBLE) { 479 } else if (t2 == DOUBLE) {
480 td = gettyp(LDOUBLE); 480 td = gettyp(LDOUBLE);
481 } else if (t2 == DCOMPLEX) { 481 } else if (t2 == DCOMPLEX) {
482 td = gettyp(LCOMPLEX); 482 td = gettyp(LCOMPLEX);
483 } 483 }
484 td = block_dup_type(td); 484 td = block_dup_type(td);
485 td->t_typedef = true; 485 td->t_typedef = true;
486 return td; 486 return td;
487 } 487 }
488 488
489 /* Anything else is not accepted. */ 489 /* Anything else is not accepted. */
490 dcs->d_invalid_type_combination = true; 490 dcs->d_invalid_type_combination = true;
491 return td; 491 return td;
492} 492}
493 493
494/* 494/*
495 * Remember the symbol of a typedef name (2nd arg) in a struct, union 495 * Remember the symbol of a typedef name (2nd arg) in a struct, union
496 * or enum tag if the typedef name is the first defined for this tag. 496 * or enum tag if the typedef name is the first defined for this tag.
497 * 497 *
498 * If the tag is unnamed, the typedef name is used for identification 498 * If the tag is unnamed, the typedef name is used for identification
499 * of this tag in lint2. Although it's possible that more than one typedef 499 * of this tag in lint2. Although it's possible that more than one typedef
500 * name is defined for one tag, the first name defined should be unique 500 * name is defined for one tag, the first name defined should be unique
501 * if the tag is unnamed. 501 * if the tag is unnamed.
502 */ 502 */
503static void 503static void
504settdsym(type_t *tp, sym_t *sym) 504settdsym(type_t *tp, sym_t *sym)
505{ 505{
506 tspec_t t; 506 tspec_t t;
507 507
508 if ((t = tp->t_tspec) == STRUCT || t == UNION) { 508 if ((t = tp->t_tspec) == STRUCT || t == UNION) {
509 if (tp->t_str->sou_first_typedef == NULL) 509 if (tp->t_str->sou_first_typedef == NULL)
510 tp->t_str->sou_first_typedef = sym; 510 tp->t_str->sou_first_typedef = sym;
511 } else if (t == ENUM) { 511 } else if (t == ENUM) {
512 if (tp->t_enum->en_first_typedef == NULL) 512 if (tp->t_enum->en_first_typedef == NULL)
513 tp->t_enum->en_first_typedef = sym; 513 tp->t_enum->en_first_typedef = sym;
514 } 514 }
515} 515}
516 516
517static unsigned int 517static unsigned int
518bitfieldsize(sym_t **mem) 518bitfieldsize(sym_t **mem)
519{ 519{
520 unsigned int len = (*mem)->s_type->t_flen; 520 unsigned int len = (*mem)->s_type->t_flen;
521 while (*mem != NULL && (*mem)->s_type->t_bitfield) { 521 while (*mem != NULL && (*mem)->s_type->t_bitfield) {
522 len += (*mem)->s_type->t_flen; 522 len += (*mem)->s_type->t_flen;
523 *mem = (*mem)->s_next; 523 *mem = (*mem)->s_next;
524 } 524 }
525 return len - len % INT_SIZE; 525 return len - len % INT_SIZE;
526} 526}
527 527
528static void 528static void
529setpackedsize(type_t *tp) 529setpackedsize(type_t *tp)
530{ 530{
531 struct_or_union *sp; 531 struct_or_union *sp;
532 sym_t *mem; 532 sym_t *mem;
533 533
534 switch (tp->t_tspec) { 534 switch (tp->t_tspec) {
535 case STRUCT: 535 case STRUCT:
536 case UNION: 536 case UNION:
537 sp = tp->t_str; 537 sp = tp->t_str;
538 sp->sou_size_in_bits = 0; 538 sp->sou_size_in_bits = 0;
539 for (mem = sp->sou_first_member; 539 for (mem = sp->sou_first_member;
540 mem != NULL; mem = mem->s_next) { 540 mem != NULL; mem = mem->s_next) {
541 unsigned int x; 541 unsigned int x;
542 542
543 if (mem->s_type->t_bitfield) { 543 if (mem->s_type->t_bitfield) {
544 sp->sou_size_in_bits += bitfieldsize(&mem); 544 sp->sou_size_in_bits += bitfieldsize(&mem);
545 if (mem == NULL) 545 if (mem == NULL)
546 break; 546 break;
547 } 547 }
548 x = type_size_in_bits(mem->s_type); 548 x = type_size_in_bits(mem->s_type);
549 if (tp->t_tspec == STRUCT) 549 if (tp->t_tspec == STRUCT)
550 sp->sou_size_in_bits += x; 550 sp->sou_size_in_bits += x;
551 else if (x > sp->sou_size_in_bits) 551 else if (x > sp->sou_size_in_bits)
552 sp->sou_size_in_bits = x; 552 sp->sou_size_in_bits = x;
553 } 553 }
554 break; 554 break;
555 default: 555 default:
556 /* %s attribute ignored for %s */ 556 /* %s attribute ignored for %s */
557 warning(326, "packed", type_name(tp)); 557 warning(326, "packed", type_name(tp));
558 break; 558 break;
559 } 559 }
560} 560}
561 561
562void 562void
563addpacked(void) 563addpacked(void)
564{ 564{
565 if (dcs->d_type == NULL) 565 if (dcs->d_type == NULL)
566 dcs->d_packed = true; 566 dcs->d_packed = true;
567 else 567 else
568 setpackedsize(dcs->d_type); 568 setpackedsize(dcs->d_type);
569} 569}
570 570
571void 571void
572add_attr_used(void) 572add_attr_used(void)
573{ 573{
574 dcs->d_used = true; 574 dcs->d_used = true;
575} 575}
576 576
577/* 577/*
578 * Remember a qualifier which is part of the declaration specifiers 578 * Remember a qualifier which is part of the declaration specifiers
579 * (and not the declarator) in the top element of the declaration stack. 579 * (and not the declarator) in the top element of the declaration stack.
580 * Also detect multiple qualifiers of the same kind. 580 * Also detect multiple qualifiers of the same kind.
581 581
582 * The remembered qualifier is used by end_type() to construct the type 582 * The remembered qualifier is used by end_type() to construct the type
583 * for all declarators. 583 * for all declarators.
584 */ 584 */
585void 585void
586add_qualifier(tqual_t q) 586add_qualifier(tqual_t q)
587{ 587{
588 588
589 if (q == CONST) { 589 if (q == CONST) {
590 if (dcs->d_const) { 590 if (dcs->d_const) {
591 /* duplicate '%s' */ 591 /* duplicate '%s' */
592 warning(10, "const"); 592 warning(10, "const");
593 } 593 }
594 dcs->d_const = true; 594 dcs->d_const = true;
595 } else if (q == VOLATILE) { 595 } else if (q == VOLATILE) {
596 if (dcs->d_volatile) { 596 if (dcs->d_volatile) {
597 /* duplicate '%s' */ 597 /* duplicate '%s' */
598 warning(10, "volatile"); 598 warning(10, "volatile");
599 } 599 }
600 dcs->d_volatile = true; 600 dcs->d_volatile = true;
601 } else { 601 } else {
602 lint_assert(q == RESTRICT || q == THREAD); 602 lint_assert(q == RESTRICT || q == THREAD);
603 /* Silently ignore these qualifiers. */ 603 /* Silently ignore these qualifiers. */
604 } 604 }
605} 605}
606 606
607/* 607/*
608 * Go to the next declaration level (structs, nested structs, blocks, 608 * Go to the next declaration level (structs, nested structs, blocks,
609 * argument declaration lists ...) 609 * argument declaration lists ...)
610 */ 610 */
611void 611void
612begin_declaration_level(scl_t sc) 612begin_declaration_level(scl_t sc)
613{ 613{
614 dinfo_t *di; 614 dinfo_t *di;
615 615
616 /* put a new element on the declaration stack */ 616 /* put a new element on the declaration stack */
617 di = xcalloc(1, sizeof(*di)); 617 di = xcalloc(1, sizeof(*di));
618 di->d_next = dcs; 618 di->d_next = dcs;
619 dcs = di; 619 dcs = di;
620 di->d_ctx = sc; 620 di->d_ctx = sc;
621 di->d_ldlsym = &di->d_dlsyms; 621 di->d_ldlsym = &di->d_dlsyms;
622 debug_step("%s(%p %s)", __func__, dcs, scl_name(sc)); 622 debug_step("%s(%p %s)", __func__, dcs, scl_name(sc));
623} 623}
624 624
625/* 625/*
626 * Go back to previous declaration level 626 * Go back to previous declaration level
627 */ 627 */
628void 628void
629end_declaration_level(void) 629end_declaration_level(void)
630{ 630{
631 dinfo_t *di; 631 dinfo_t *di;
632 632
633 debug_step("%s(%p %s)", __func__, dcs, scl_name(dcs->d_ctx)); 633 debug_step("%s(%p %s)", __func__, dcs, scl_name(dcs->d_ctx));
634 634
635 lint_assert(dcs->d_next != NULL); 635 lint_assert(dcs->d_next != NULL);
636 di = dcs; 636 di = dcs;
637 dcs = di->d_next; 637 dcs = di->d_next;
638 switch (di->d_ctx) { 638 switch (di->d_ctx) {
639 case MOS: 639 case MOS:
640 case MOU: 640 case MOU:
641 case CTCONST: 641 case CTCONST:
642 /* 642 /*
643 * Symbols declared in (nested) structs or enums are 643 * Symbols declared in (nested) structs or enums are
644 * part of the next level (they are removed from the 644 * part of the next level (they are removed from the
645 * symbol table if the symbols of the outer level are 645 * symbol table if the symbols of the outer level are
646 * removed). 646 * removed).
647 */ 647 */
648 if ((*dcs->d_ldlsym = di->d_dlsyms) != NULL) 648 if ((*dcs->d_ldlsym = di->d_dlsyms) != NULL)
649 dcs->d_ldlsym = di->d_ldlsym; 649 dcs->d_ldlsym = di->d_ldlsym;
650 break; 650 break;
651 case OLD_STYLE_ARG: 651 case OLD_STYLE_ARG:
652 /* 652 /*
653 * All symbols in dcs->d_dlsyms are introduced in old style 653 * All symbols in dcs->d_dlsyms are introduced in old style
654 * argument declarations (it's not clean, but possible). 654 * argument declarations (it's not clean, but possible).
655 * They are appended to the list of symbols declared in 655 * They are appended to the list of symbols declared in
656 * an old style argument identifier list or a new style 656 * an old style argument identifier list or a new style
657 * parameter type list. 657 * parameter type list.
658 */ 658 */
659 if (di->d_dlsyms != NULL) { 659 if (di->d_dlsyms != NULL) {
660 *di->d_ldlsym = dcs->d_func_proto_syms; 660 *di->d_ldlsym = dcs->d_func_proto_syms;
661 dcs->d_func_proto_syms = di->d_dlsyms; 661 dcs->d_func_proto_syms = di->d_dlsyms;
662 } 662 }
663 break; 663 break;
664 case ABSTRACT: 664 case ABSTRACT:
665 /* 665 /*
666 * casts and sizeof 666 * casts and sizeof
667 * Append all symbols declared in the abstract declaration 667 * Append all symbols declared in the abstract declaration
668 * to the list of symbols declared in the surrounding 668 * to the list of symbols declared in the surrounding
669 * declaration or block. 669 * declaration or block.
670 * XXX I'm not sure whether they should be removed from the 670 * XXX I'm not sure whether they should be removed from the
671 * symbol table now or later. 671 * symbol table now or later.
672 */ 672 */
673 if ((*dcs->d_ldlsym = di->d_dlsyms) != NULL) 673 if ((*dcs->d_ldlsym = di->d_dlsyms) != NULL)
674 dcs->d_ldlsym = di->d_ldlsym; 674 dcs->d_ldlsym = di->d_ldlsym;
675 break; 675 break;
676 case AUTO: 676 case AUTO:
677 /* check usage of local vars */ 677 /* check usage of local vars */
678 check_usage(di); 678 check_usage(di);
679 /* FALLTHROUGH */ 679 /* FALLTHROUGH */
680 case PROTO_ARG: 680 case PROTO_ARG:
681 /* usage of arguments will be checked by funcend() */ 681 /* usage of arguments will be checked by funcend() */
682 rmsyms(di->d_dlsyms); 682 rmsyms(di->d_dlsyms);
683 break; 683 break;
684 case EXTERN: 684 case EXTERN:
685 /* there is nothing after external declarations */ 685 /* there is nothing after external declarations */
686 /* FALLTHROUGH */ 686 /* FALLTHROUGH */
687 default: 687 default:
688 lint_assert(/*CONSTCOND*/false); 688 lint_assert(/*CONSTCOND*/false);
689 } 689 }
690 free(di); 690 free(di);
691} 691}
692 692
693/* 693/*
694 * Set flag d_asm in all declaration stack elements up to the 694 * Set flag d_asm in all declaration stack elements up to the
695 * outermost one. 695 * outermost one.
696 * 696 *
697 * This is used to mark compound statements which have, possibly in 697 * This is used to mark compound statements which have, possibly in
698 * nested compound statements, asm statements. For these compound 698 * nested compound statements, asm statements. For these compound
699 * statements no warnings about unused or uninitialized variables are 699 * statements no warnings about unused or uninitialized variables are
700 * printed. 700 * printed.
701 * 701 *
702 * There is no need to clear d_asm in dinfo structs with context AUTO, 702 * There is no need to clear d_asm in dinfo structs with context AUTO,
703 * because these structs are freed at the end of the compound statement. 703 * because these structs are freed at the end of the compound statement.
704 * But it must be cleared in the outermost dinfo struct, which has 704 * But it must be cleared in the outermost dinfo struct, which has
705 * context EXTERN. This could be done in begin_type() and would work for C90, 705 * context EXTERN. This could be done in begin_type() and would work for C90,
706 * but not for C99 or C++ (due to mixed statements and declarations). Thus 706 * but not for C99 or C++ (due to mixed statements and declarations). Thus
707 * we clear it in global_clean_up_decl(), which is used to do some cleanup 707 * we clear it in global_clean_up_decl(), which is used to do some cleanup
708 * after global declarations/definitions. 708 * after global declarations/definitions.
709 */ 709 */
710void 710void
711setasm(void) 711setasm(void)
712{ 712{
713 dinfo_t *di; 713 dinfo_t *di;
714 714
715 for (di = dcs; di != NULL; di = di->d_next) 715 for (di = dcs; di != NULL; di = di->d_next)
716 di->d_asm = true; 716 di->d_asm = true;
717} 717}
718 718
719/* 719/*
720 * Clean all elements of the top element of declaration stack which 720 * Clean all elements of the top element of declaration stack which
721 * will be used by the next declaration 721 * will be used by the next declaration
722 */ 722 */
723void 723void
724begin_type(void) 724begin_type(void)
725{ 725{
726 726
727 dcs->d_abstract_type = NOTSPEC; 727 dcs->d_abstract_type = NOTSPEC;
728 dcs->d_complex_mod = NOTSPEC; 728 dcs->d_complex_mod = NOTSPEC;
729 dcs->d_sign_mod = NOTSPEC; 729 dcs->d_sign_mod = NOTSPEC;
730 dcs->d_rank_mod = NOTSPEC; 730 dcs->d_rank_mod = NOTSPEC;
731 dcs->d_scl = NOSCL; 731 dcs->d_scl = NOSCL;
732 dcs->d_type = NULL; 732 dcs->d_type = NULL;
733 dcs->d_const = false; 733 dcs->d_const = false;
734 dcs->d_volatile = false; 734 dcs->d_volatile = false;
735 dcs->d_inline = false; 735 dcs->d_inline = false;
736 dcs->d_multiple_storage_classes = false; 736 dcs->d_multiple_storage_classes = false;
737 dcs->d_invalid_type_combination = false; 737 dcs->d_invalid_type_combination = false;
738 dcs->d_nonempty_decl = false; 738 dcs->d_nonempty_decl = false;
739 dcs->d_notyp = false; 739 dcs->d_notyp = false;
740} 740}
741 741
742static void 742static void
743dcs_adjust_storage_class(void) 743dcs_adjust_storage_class(void)
744{ 744{
745 if (dcs->d_ctx == EXTERN) { 745 if (dcs->d_ctx == EXTERN) {
746 if (dcs->d_scl == REG || dcs->d_scl == AUTO) { 746 if (dcs->d_scl == REG || dcs->d_scl == AUTO) {
747 /* illegal storage class */ 747 /* illegal storage class */
748 error(8); 748 error(8);
749 dcs->d_scl = NOSCL; 749 dcs->d_scl = NOSCL;
750 } 750 }
751 } else if (dcs->d_ctx == OLD_STYLE_ARG || dcs->d_ctx == PROTO_ARG) { 751 } else if (dcs->d_ctx == OLD_STYLE_ARG || dcs->d_ctx == PROTO_ARG) {
752 if (dcs->d_scl != NOSCL && dcs->d_scl != REG) { 752 if (dcs->d_scl != NOSCL && dcs->d_scl != REG) {
753 /* only register valid as formal parameter storage... */ 753 /* only register valid as formal parameter storage... */
754 error(9); 754 error(9);
755 dcs->d_scl = NOSCL; 755 dcs->d_scl = NOSCL;
756 } 756 }
757 } 757 }
758} 758}
759 759
760/* 760/*
761 * Merge the declaration specifiers from dcs into dcs->d_type. 761 * Merge the declaration specifiers from dcs into dcs->d_type.
762 * 762 *
763 * See C99 6.7.2 "Type specifiers". 763 * See C99 6.7.2 "Type specifiers".
764 */ 764 */
765static void 765static void
766dcs_merge_declaration_specifiers(void) 766dcs_merge_declaration_specifiers(void)
767{ 767{
768 tspec_t t, s, l, c; 768 tspec_t t, s, l, c;
769 type_t *tp; 769 type_t *tp;
770 770
771 t = dcs->d_abstract_type; /* VOID, BOOL, CHAR, INT or COMPLEX */ 771 t = dcs->d_abstract_type; /* VOID, BOOL, CHAR, INT or COMPLEX */
772 c = dcs->d_complex_mod; /* FLOAT or DOUBLE */ 772 c = dcs->d_complex_mod; /* FLOAT or DOUBLE */
773 s = dcs->d_sign_mod; /* SIGNED or UNSIGN */ 773 s = dcs->d_sign_mod; /* SIGNED or UNSIGN */
774 l = dcs->d_rank_mod; /* SHORT, LONG or QUAD */ 774 l = dcs->d_rank_mod; /* SHORT, LONG or QUAD */
775 tp = dcs->d_type; 775 tp = dcs->d_type;
776 776
777 debug_step("%s: %s", __func__, type_name(tp)); 777 debug_step("%s: %s", __func__, type_name(tp));
778 if (t == NOTSPEC && s == NOTSPEC && l == NOTSPEC && c == NOTSPEC && 778 if (t == NOTSPEC && s == NOTSPEC && l == NOTSPEC && c == NOTSPEC &&
779 tp == NULL) 779 tp == NULL)
780 dcs->d_notyp = true; 780 dcs->d_notyp = true;
781 if (t == NOTSPEC && s == NOTSPEC && (l == NOTSPEC || l == LONG) && 781 if (t == NOTSPEC && s == NOTSPEC && (l == NOTSPEC || l == LONG) &&
782 tp == NULL) 782 tp == NULL)
783 t = c; 783 t = c;
784 784
785 if (tp != NULL) { 785 if (tp != NULL) {
786 lint_assert(t == NOTSPEC); 786 lint_assert(t == NOTSPEC);
787 lint_assert(s == NOTSPEC); 787 lint_assert(s == NOTSPEC);
788 lint_assert(l == NOTSPEC); 788 lint_assert(l == NOTSPEC);
789 return; 789 return;
790 } 790 }
791 791
792 if (t == NOTSPEC) 792 if (t == NOTSPEC)
793 t = INT; 793 t = INT;
794 if (s == NOTSPEC && t == INT) 794 if (s == NOTSPEC && t == INT)
795 s = SIGNED; 795 s = SIGNED;
796 if (l != NOTSPEC && t == CHAR) { 796 if (l != NOTSPEC && t == CHAR) {
797 dcs->d_invalid_type_combination = true; 797 dcs->d_invalid_type_combination = true;
798 l = NOTSPEC; 798 l = NOTSPEC;
799 } 799 }
800 if (l == LONG && t == FLOAT) { 800 if (l == LONG && t == FLOAT) {
801 l = NOTSPEC; 801 l = NOTSPEC;
802 t = DOUBLE; 802 t = DOUBLE;
803 if (!tflag) 803 if (!tflag)
804 /* use 'double' instead of 'long float' */ 804 /* use 'double' instead of 'long float' */
805 warning(6); 805 warning(6);
806 } 806 }
807 if ((l == LONG && t == DOUBLE) || t == LDOUBLE) { 807 if ((l == LONG && t == DOUBLE) || t == LDOUBLE) {
808 l = NOTSPEC; 808 l = NOTSPEC;
809 t = LDOUBLE; 809 t = LDOUBLE;
810 } 810 }
811 if (t == LDOUBLE && tflag) { 811 if (t == LDOUBLE && tflag) {
812 /* 'long double' is illegal in traditional C */ 812 /* 'long double' is illegal in traditional C */
813 warning(266); 813 warning(266);
814 } 814 }
815 if (l == LONG && t == DCOMPLEX) { 815 if (l == LONG && t == DCOMPLEX) {
816 l = NOTSPEC; 816 l = NOTSPEC;
817 t = LCOMPLEX; 817 t = LCOMPLEX;
818 } 818 }
819 819
820 if (t != INT && t != CHAR && (s != NOTSPEC || l != NOTSPEC)) { 820 if (t != INT && t != CHAR && (s != NOTSPEC || l != NOTSPEC)) {
821 dcs->d_invalid_type_combination = true; 821 dcs->d_invalid_type_combination = true;
822 l = s = NOTSPEC; 822 l = s = NOTSPEC;
823 } 823 }
824 if (l != NOTSPEC) 824 if (l != NOTSPEC)
825 t = l; 825 t = l;
826 dcs->d_type = gettyp(merge_signedness(t, s)); 826 dcs->d_type = gettyp(merge_signedness(t, s));
827} 827}
828 828
829/* 829/*
830 * Create a type structure from the information gathered in 830 * Create a type structure from the information gathered in
831 * the declaration stack. 831 * the declaration stack.
832 * Complain about storage classes which are not possible in current 832 * Complain about storage classes which are not possible in current
833 * context. 833 * context.
834 */ 834 */
835void 835void
836end_type(void) 836end_type(void)
837{ 837{
838 838
839 dcs_merge_declaration_specifiers(); 839 dcs_merge_declaration_specifiers();
840 840
841 if (dcs->d_multiple_storage_classes) { 841 if (dcs->d_multiple_storage_classes) {
842 /* only one storage class allowed */ 842 /* only one storage class allowed */
843 error(7); 843 error(7);
844 } 844 }
845 if (dcs->d_invalid_type_combination) { 845 if (dcs->d_invalid_type_combination) {
846 /* illegal type combination */ 846 /* illegal type combination */
847 error(4); 847 error(4);
848 } 848 }
849 849
850 dcs_adjust_storage_class(); 850 dcs_adjust_storage_class();
851 851
852 if (dcs->d_const && dcs->d_type->t_const) { 852 if (dcs->d_const && dcs->d_type->t_const) {
853 lint_assert(dcs->d_type->t_typedef); 853 lint_assert(dcs->d_type->t_typedef);
854 /* typedef already qualified with '%s' */ 854 /* typedef already qualified with '%s' */
855 warning(68, "const"); 855 warning(68, "const");
856 } 856 }
857 if (dcs->d_volatile && dcs->d_type->t_volatile) { 857 if (dcs->d_volatile && dcs->d_type->t_volatile) {
858 lint_assert(dcs->d_type->t_typedef); 858 lint_assert(dcs->d_type->t_typedef);
859 /* typedef already qualified with '%s' */ 859 /* typedef already qualified with '%s' */
860 warning(68, "volatile"); 860 warning(68, "volatile");
861 } 861 }
862 862
863 if (dcs->d_const || dcs->d_volatile) { 863 if (dcs->d_const || dcs->d_volatile) {
864 dcs->d_type = block_dup_type(dcs->d_type); 864 dcs->d_type = block_dup_type(dcs->d_type);
865 dcs->d_type->t_const |= dcs->d_const; 865 dcs->d_type->t_const |= dcs->d_const;
866 dcs->d_type->t_volatile |= dcs->d_volatile; 866 dcs->d_type->t_volatile |= dcs->d_volatile;
867 } 867 }
868} 868}
869 869
870/* 870/*
871 * Return the length of a type in bits. 871 * Return the length of a type in bits.
872 * 872 *
873 * Printing a message if the outermost dimension of an array is 0 must 873 * Printing a message if the outermost dimension of an array is 0 must
874 * be done by the caller. All other problems are reported by length() 874 * be done by the caller. All other problems are reported by length()
875 * if name is not NULL. 875 * if name is not NULL.
876 */ 876 */
877int 877int
878length(const type_t *tp, const char *name) 878length(const type_t *tp, const char *name)
879{ 879{
880 unsigned int elem, elsz; 880 unsigned int elem, elsz;
881 881
882 elem = 1; 882 elem = 1;
883 while (tp != NULL && tp->t_tspec == ARRAY) { 883 while (tp != NULL && tp->t_tspec == ARRAY) {
884 elem *= tp->t_dim; 884 elem *= tp->t_dim;
885 tp = tp->t_subt; 885 tp = tp->t_subt;
886 } 886 }
887 if (tp == NULL) 887 if (tp == NULL)
888 return -1; 888 return -1;
889 889
890 switch (tp->t_tspec) { 890 switch (tp->t_tspec) {
891 case FUNC: 891 case FUNC:
892 /* compiler takes size of function */ 892 /* compiler takes size of function */
893 INTERNAL_ERROR("%s", msgs[12]); 893 INTERNAL_ERROR("%s", msgs[12]);
894 /* NOTREACHED */ 894 /* NOTREACHED */
895 case STRUCT: 895 case STRUCT:
896 case UNION: 896 case UNION:
897 if (is_incomplete(tp) && name != NULL) { 897 if (is_incomplete(tp) && name != NULL) {
898 /* '%s' has incomplete type '%s' */ 898 /* '%s' has incomplete type '%s' */
899 error(31, name, type_name(tp)); 899 error(31, name, type_name(tp));
900 } 900 }
901 elsz = tp->t_str->sou_size_in_bits; 901 elsz = tp->t_str->sou_size_in_bits;
902 break; 902 break;
903 case ENUM: 903 case ENUM:
904 if (is_incomplete(tp) && name != NULL) { 904 if (is_incomplete(tp) && name != NULL) {
905 /* incomplete enum type: %s */ 905 /* incomplete enum type: %s */
906 warning(13, name); 906 warning(13, name);
907 } 907 }
908 /* FALLTHROUGH */ 908 /* FALLTHROUGH */
909 default: 909 default:
910 elsz = size_in_bits(tp->t_tspec); 910 elsz = size_in_bits(tp->t_tspec);
911 lint_assert(elsz > 0); 911 lint_assert(elsz > 0);
912 break; 912 break;
913 } 913 }
914 return (int)(elem * elsz); 914 return (int)(elem * elsz);
915} 915}
916 916
917unsigned int 917unsigned int
918alignment_in_bits(const type_t *tp) 918alignment_in_bits(const type_t *tp)
919{ 919{
920 unsigned int a; 920 unsigned int a;
921 tspec_t t; 921 tspec_t t;
922 922
923 while (tp->t_tspec == ARRAY) 923 while (tp->t_tspec == ARRAY)
924 tp = tp->t_subt; 924 tp = tp->t_subt;
925 925
926 if ((t = tp->t_tspec) == STRUCT || t == UNION) { 926 if ((t = tp->t_tspec) == STRUCT || t == UNION) {
927 a = tp->t_str->sou_align_in_bits; 927 a = tp->t_str->sou_align_in_bits;
928 } else if (t == FUNC) { 928 } else if (t == FUNC) {
929 /* compiler takes alignment of function */ 929 /* compiler takes alignment of function */
930 error(14); 930 error(14);
931 a = WORST_ALIGN(1) * CHAR_SIZE; 931 a = WORST_ALIGN(1) * CHAR_SIZE;
932 } else { 932 } else {
933 if ((a = size_in_bits(t)) == 0) { 933 if ((a = size_in_bits(t)) == 0) {
934 a = CHAR_SIZE; 934 a = CHAR_SIZE;
935 } else if (a > WORST_ALIGN(1) * CHAR_SIZE) { 935 } else if (a > WORST_ALIGN(1) * CHAR_SIZE) {
936 a = WORST_ALIGN(1) * CHAR_SIZE; 936 a = WORST_ALIGN(1) * CHAR_SIZE;
937 } 937 }
938 } 938 }
939 lint_assert(a >= CHAR_SIZE); 939 lint_assert(a >= CHAR_SIZE);
940 lint_assert(a <= WORST_ALIGN(1) * CHAR_SIZE); 940 lint_assert(a <= WORST_ALIGN(1) * CHAR_SIZE);
941 return a; 941 return a;
942} 942}
943 943
944/* 944/*
945 * Concatenate two lists of symbols by s_next. Used by declarations of 945 * Concatenate two lists of symbols by s_next. Used by declarations of
946 * struct/union/enum elements and parameters. 946 * struct/union/enum elements and parameters.
947 */ 947 */
948sym_t * 948sym_t *
949lnklst(sym_t *l1, sym_t *l2) 949lnklst(sym_t *l1, sym_t *l2)
950{ 950{
951 sym_t *l; 951 sym_t *l;
952 952
953 if ((l = l1) == NULL) 953 if ((l = l1) == NULL)
954 return l2; 954 return l2;
955 while (l1->s_next != NULL) 955 while (l1->s_next != NULL)
956 l1 = l1->s_next; 956 l1 = l1->s_next;
957 l1->s_next = l2; 957 l1->s_next = l2;
958 return l; 958 return l;
959} 959}
960 960
961/* 961/*
962 * Check if the type of the given symbol is valid and print an error 962 * Check if the type of the given symbol is valid and print an error
963 * message if it is not. 963 * message if it is not.
964 * 964 *
965 * Invalid types are: 965 * Invalid types are:
966 * - arrays of incomplete types or functions 966 * - arrays of incomplete types or functions
967 * - functions returning arrays or functions 967 * - functions returning arrays or functions
968 * - void types other than type of function or pointer 968 * - void types other than type of function or pointer
969 */ 969 */
970void 970void
971check_type(sym_t *sym) 971check_type(sym_t *sym)
972{ 972{
973 tspec_t to, t; 973 tspec_t to, t;
974 type_t **tpp, *tp; 974 type_t **tpp, *tp;
975 975
976 tpp = &sym->s_type; 976 tpp = &sym->s_type;
977 to = NOTSPEC; 977 to = NOTSPEC;
978 while ((tp = *tpp) != NULL) { 978 while ((tp = *tpp) != NULL) {
979 t = tp->t_tspec; 979 t = tp->t_tspec;
980 /* 980 /*
981 * If this is the type of an old style function definition, 981 * If this is the type of an old style function definition,
982 * a better warning is printed in funcdef(). 982 * a better warning is printed in funcdef().
983 */ 983 */
984 if (t == FUNC && !tp->t_proto && 984 if (t == FUNC && !tp->t_proto &&
985 !(to == NOTSPEC && sym->s_osdef)) { 985 !(to == NOTSPEC && sym->s_osdef)) {
986 if (sflag && hflag) 986 if (sflag && hflag)
987 /* function declaration is not a prototype */ 987 /* function declaration is not a prototype */
988 warning(287); 988 warning(287);
989 } 989 }
990 if (to == FUNC) { 990 if (to == FUNC) {
991 if (t == FUNC || t == ARRAY) { 991 if (t == FUNC || t == ARRAY) {
992 /* function returns illegal type */ 992 /* function returns illegal type */
993 error(15); 993 error(15);
994 if (t == FUNC) { 994 if (t == FUNC) {
995 *tpp = block_derive_type(*tpp, PTR); 995 *tpp = block_derive_type(*tpp, PTR);
996 } else { 996 } else {
997 *tpp = block_derive_type( 997 *tpp = block_derive_type(
998 (*tpp)->t_subt, PTR); 998 (*tpp)->t_subt, PTR);
999 } 999 }
1000 return; 1000 return;
1001 } else if (tp->t_const || tp->t_volatile) { 1001 } else if (tp->t_const || tp->t_volatile) {
1002 if (sflag) { /* XXX or better !tflag ? */ 1002 if (sflag) { /* XXX or better !tflag ? */
1003 /* function cannot return const... */ 1003 /* function cannot return const... */
1004 warning(228); 1004 warning(228);
1005 } 1005 }
1006 } 1006 }
1007 } if (to == ARRAY) { 1007 } if (to == ARRAY) {
1008 if (t == FUNC) { 1008 if (t == FUNC) {
1009 /* array of function is illegal */ 1009 /* array of function is illegal */
1010 error(16); 1010 error(16);
1011 *tpp = gettyp(INT); 1011 *tpp = gettyp(INT);
1012 return; 1012 return;
1013 } else if (t == ARRAY && tp->t_dim == 0) { 1013 } else if (t == ARRAY && tp->t_dim == 0) {
1014 /* null dimension */ 1014 /* null dimension */
1015 error(17); 1015 error(17);
1016 return; 1016 return;
1017 } else if (t == VOID) { 1017 } else if (t == VOID) {
1018 /* illegal use of 'void' */ 1018 /* illegal use of 'void' */
1019 error(18); 1019 error(18);
1020 *tpp = gettyp(INT); 1020 *tpp = gettyp(INT);
1021#if 0 /* errors are produced by length() */ 1021#if 0 /* errors are produced by length() */
1022 } else if (is_incomplete(tp)) { 1022 } else if (is_incomplete(tp)) {
1023 /* array of incomplete type */ 1023 /* array of incomplete type */
1024 if (sflag) { 1024 if (sflag) {
1025 /* array of incomplete type */ 1025 /* array of incomplete type */
1026 error(301); 1026 error(301);
1027 } else { 1027 } else {
1028 /* array of incomplete type */ 1028 /* array of incomplete type */
1029 warning(301); 1029 warning(301);
1030 } 1030 }
1031#endif 1031#endif
1032 } 1032 }
1033 } else if (to == NOTSPEC && t == VOID) { 1033 } else if (to == NOTSPEC && t == VOID) {
1034 if (dcs->d_ctx == PROTO_ARG) { 1034 if (dcs->d_ctx == PROTO_ARG) {
1035 if (sym->s_scl != ABSTRACT) { 1035 if (sym->s_scl != ABSTRACT) {
1036 lint_assert(sym->s_name != unnamed); 1036 lint_assert(sym->s_name != unnamed);
1037 /* void parameter cannot have ... */ 1037 /* void parameter cannot have ... */
1038 error(61, sym->s_name); 1038 error(61, sym->s_name);
1039 *tpp = gettyp(INT); 1039 *tpp = gettyp(INT);
1040 } 1040 }
1041 } else if (dcs->d_ctx == ABSTRACT) { 1041 } else if (dcs->d_ctx == ABSTRACT) {
1042 /* ok */ 1042 /* ok */
1043 } else if (sym->s_scl != TYPEDEF) { 1043 } else if (sym->s_scl != TYPEDEF) {
1044 /* void type for '%s' */ 1044 /* void type for '%s' */
1045 error(19, sym->s_name); 1045 error(19, sym->s_name);
1046 *tpp = gettyp(INT); 1046 *tpp = gettyp(INT);
1047 } 1047 }
1048 } 1048 }
1049 if (t == VOID && to != PTR) { 1049 if (t == VOID && to != PTR) {
1050 if (tp->t_const || tp->t_volatile) { 1050 if (tp->t_const || tp->t_volatile) {
1051 /* inappropriate qualifiers with 'void' */ 1051 /* inappropriate qualifiers with 'void' */
1052 warning(69); 1052 warning(69);
1053 tp->t_const = tp->t_volatile = false; 1053 tp->t_const = tp->t_volatile = false;
1054 } 1054 }
1055 } 1055 }
1056 tpp = &tp->t_subt; 1056 tpp = &tp->t_subt;
1057 to = t; 1057 to = t;
1058 } 1058 }
1059} 1059}
1060 1060
1061/* 1061/*
1062 * In traditional C, the only portable type for bit-fields is unsigned int. 1062 * In traditional C, the only portable type for bit-fields is unsigned int.
1063 * 1063 *
1064 * In C90, the only allowed types for bit-fields are int, signed int and 1064 * In C90, the only allowed types for bit-fields are int, signed int and
1065 * unsigned int (3.5.2.1). There is no mention of implementation-defined 1065 * unsigned int (3.5.2.1). There is no mention of implementation-defined
1066 * types. 1066 * types.
1067 * 1067 *
1068 * In C99, the only portable types for bit-fields are _Bool, signed int and 1068 * In C99, the only portable types for bit-fields are _Bool, signed int and
1069 * unsigned int (6.7.2.1p4). In addition, C99 allows "or some other 1069 * unsigned int (6.7.2.1p4). In addition, C99 allows "or some other
1070 * implementation-defined type". 1070 * implementation-defined type".
1071 */ 1071 */
1072static void 1072static void
1073check_bit_field_type(sym_t *dsym, type_t **const inout_tp, tspec_t *inout_t) 1073check_bit_field_type(sym_t *dsym, type_t **const inout_tp, tspec_t *inout_t)
1074{ 1074{
1075 type_t *tp = *inout_tp; 1075 type_t *tp = *inout_tp;
1076 tspec_t t = *inout_t; 1076 tspec_t t = *inout_t;
1077 1077
1078 if (t == CHAR || t == UCHAR || t == SCHAR || 1078 if (t == CHAR || t == UCHAR || t == SCHAR ||
1079 t == SHORT || t == USHORT || t == ENUM) { 1079 t == SHORT || t == USHORT || t == ENUM) {
1080 if (!bitfieldtype_ok) { 1080 if (!bitfieldtype_ok) {
1081 if (sflag) { 1081 if (sflag) {
1082 /* bit-field type '%s' invalid in ANSI C */ 1082 /* bit-field type '%s' invalid in ANSI C */
1083 warning(273, type_name(tp)); 1083 warning(273, type_name(tp));
1084 } else if (pflag) { 1084 } else if (pflag) {
1085 /* nonportable bit-field type '%s' */ 1085 /* nonportable bit-field type '%s' */
1086 warning(34, type_name(tp)); 1086 warning(34, type_name(tp));
1087 } 1087 }
1088 } 1088 }
1089 } else if (t == INT && dcs->d_sign_mod == NOTSPEC) { 1089 } else if (t == INT && dcs->d_sign_mod == NOTSPEC) {
1090 if (pflag && !bitfieldtype_ok) { 1090 if (pflag && !bitfieldtype_ok) {
1091 /* bit-field of type plain 'int' has ... */ 1091 /* bit-field of type plain 'int' has ... */
1092 warning(344); 1092 warning(344);
1093 } 1093 }
1094 } else if (t != INT && t != UINT && t != BOOL) { 1094 } else if (t != INT && t != UINT && t != BOOL) {
1095 /* 1095 /*
1096 * Non-integer types are always illegal for bitfields, 1096 * Non-integer types are always illegal for bitfields,
1097 * regardless of BITFIELDTYPE. Integer types not dealt with 1097 * regardless of BITFIELDTYPE. Integer types not dealt with
1098 * above are okay only if BITFIELDTYPE is in effect. 1098 * above are okay only if BITFIELDTYPE is in effect.
1099 */ 1099 */
1100 if (!(bitfieldtype_ok || gflag) || !is_integer(t)) { 1100 if (!(bitfieldtype_ok || gflag) || !is_integer(t)) {
1101 unsigned int sz; 1101 unsigned int sz;
1102 1102
1103 /* illegal bit-field type '%s' */ 1103 /* illegal bit-field type '%s' */
1104 warning(35, type_name(tp)); 1104 warning(35, type_name(tp));
1105 sz = tp->t_flen; 1105 sz = tp->t_flen;
1106 dsym->s_type = tp = block_dup_type(gettyp(t = INT)); 1106 dsym->s_type = tp = block_dup_type(gettyp(t = INT));
1107 if ((tp->t_flen = sz) > size_in_bits(t)) 1107 if ((tp->t_flen = sz) > size_in_bits(t))
1108 tp->t_flen = size_in_bits(t); 1108 tp->t_flen = size_in_bits(t);
1109 *inout_t = t; 1109 *inout_t = t;
1110 *inout_tp = tp; 1110 *inout_tp = tp;
1111 } 1111 }
1112 } 1112 }
1113} 1113}
1114 1114
1115static void 1115static void
1116declare_bit_field(sym_t *dsym, tspec_t *inout_t, type_t **const inout_tp) 1116declare_bit_field(sym_t *dsym, tspec_t *inout_t, type_t **const inout_tp)
1117{ 1117{
1118 type_t *tp; 1118 type_t *tp;
1119 tspec_t t; 1119 tspec_t t;
1120 1120
1121 check_bit_field_type(dsym, inout_tp, inout_t); 1121 check_bit_field_type(dsym, inout_tp, inout_t);
1122 1122
1123 tp = *inout_tp; 1123 tp = *inout_tp;
1124 t = *inout_t; 1124 t = *inout_t;
1125 if (tp->t_flen > size_in_bits(t)) { 1125 if (tp->t_flen > size_in_bits(t)) {
1126 /* illegal bit-field size: %d */ 1126 /* illegal bit-field size: %d */
1127 error(36, tp->t_flen); 1127 error(36, tp->t_flen);
1128 tp->t_flen = size_in_bits(t); 1128 tp->t_flen = size_in_bits(t);
1129 } else if (tp->t_flen == 0 && dsym->s_name != unnamed) { 1129 } else if (tp->t_flen == 0 && dsym->s_name != unnamed) {
1130 /* zero size bit-field */ 1130 /* zero size bit-field */
1131 error(37); 1131 error(37);
1132 tp->t_flen = size_in_bits(t); 1132 tp->t_flen = size_in_bits(t);
1133 } 1133 }
1134 if (dsym->s_scl == MOU) { 1134 if (dsym->s_scl == MOU) {
1135 /* bit-field in union is very unusual */ 1135 /* bit-field in union is very unusual */
1136 warning(41); 1136 warning(41);
1137 dsym->s_type->t_bitfield = false; 1137 dsym->s_type->t_bitfield = false;
1138 dsym->s_bitfield = false; 1138 dsym->s_bitfield = false;
1139 } 1139 }
1140} 1140}
1141 1141
1142/* 1142/*
1143 * Process the declarator of a struct/union element. 1143 * Process the declarator of a struct/union element.
1144 */ 1144 */
1145sym_t * 1145sym_t *
1146declarator_1_struct_union(sym_t *dsym) 1146declarator_1_struct_union(sym_t *dsym)
1147{ 1147{
1148 type_t *tp; 1148 type_t *tp;
1149 tspec_t t; 1149 tspec_t t;
1150 int sz; 1150 int sz;
1151 unsigned int o = 0; /* Appease GCC */ 1151 unsigned int o = 0; /* Appease GCC */
1152 1152
1153 lint_assert(dsym->s_scl == MOS || dsym->s_scl == MOU); 1153 lint_assert(dsym->s_scl == MOS || dsym->s_scl == MOU);
1154 1154
1155 if (dcs->d_redeclared_symbol != NULL) { 1155 if (dcs->d_redeclared_symbol != NULL) {
1156 /* should be ensured by storesym() */ 1156 /* should be ensured by storesym() */
1157 lint_assert(dcs->d_redeclared_symbol->s_scl == MOS || 1157 lint_assert(dcs->d_redeclared_symbol->s_scl == MOS ||
1158 dcs->d_redeclared_symbol->s_scl == MOU); 1158 dcs->d_redeclared_symbol->s_scl == MOU);
1159 1159
1160 if (dsym->s_styp == dcs->d_redeclared_symbol->s_styp) { 1160 if (dsym->s_styp == dcs->d_redeclared_symbol->s_styp) {
1161 /* duplicate member name: %s */ 1161 /* duplicate member name: %s */
1162 error(33, dsym->s_name); 1162 error(33, dsym->s_name);
1163 rmsym(dcs->d_redeclared_symbol); 1163 rmsym(dcs->d_redeclared_symbol);
1164 } 1164 }
1165 } 1165 }
1166 1166
1167 check_type(dsym); 1167 check_type(dsym);
1168 1168
1169 t = (tp = dsym->s_type)->t_tspec; 1169 t = (tp = dsym->s_type)->t_tspec;
1170 1170
1171 if (dsym->s_bitfield) { 1171 if (dsym->s_bitfield) {
1172 declare_bit_field(dsym, &t, &tp); 1172 declare_bit_field(dsym, &t, &tp);
1173 } else if (t == FUNC) { 1173 } else if (t == FUNC) {
1174 /* function illegal in structure or union */ 1174 /* function illegal in structure or union */
1175 error(38); 1175 error(38);
1176 dsym->s_type = tp = block_derive_type(tp, t = PTR); 1176 dsym->s_type = tp = block_derive_type(tp, t = PTR);
1177 } 1177 }
1178 1178
1179 /* 1179 /*
1180 * bit-fields of length 0 are not warned about because length() 1180 * bit-fields of length 0 are not warned about because length()
1181 * does not return the length of the bit-field but the length 1181 * does not return the length of the bit-field but the length
1182 * of the type the bit-field is packed in (it's ok) 1182 * of the type the bit-field is packed in (it's ok)
1183 */ 1183 */
1184 if ((sz = length(dsym->s_type, dsym->s_name)) == 0) { 1184 if ((sz = length(dsym->s_type, dsym->s_name)) == 0) {
1185 if (t == ARRAY && dsym->s_type->t_dim == 0) { 1185 if (t == ARRAY && dsym->s_type->t_dim == 0) {
1186 /* zero sized array in struct is a C99 extension: %s */ 1186 /* zero sized array in struct is a C99 extension: %s */
1187 c99ism(39, dsym->s_name); 1187 c99ism(39, dsym->s_name);
1188 } 1188 }
1189 } 1189 }
1190 1190
1191 if (dcs->d_ctx == MOU) { 1191 if (dcs->d_ctx == MOU) {
1192 o = dcs->d_offset; 1192 o = dcs->d_offset;
1193 dcs->d_offset = 0; 1193 dcs->d_offset = 0;
1194 } 1194 }
1195 if (dsym->s_bitfield) { 1195 if (dsym->s_bitfield) {
1196 align(alignment_in_bits(tp), tp->t_flen); 1196 align(alignment_in_bits(tp), tp->t_flen);
1197 dsym->s_value.v_quad = 1197 dsym->s_value.v_quad =
1198 dcs->d_offset - dcs->d_offset % size_in_bits(t); 1198 dcs->d_offset - dcs->d_offset % size_in_bits(t);
1199 tp->t_foffs = dcs->d_offset - (int)dsym->s_value.v_quad; 1199 tp->t_foffs = dcs->d_offset - (int)dsym->s_value.v_quad;
1200 dcs->d_offset += tp->t_flen; 1200 dcs->d_offset += tp->t_flen;
1201 } else { 1201 } else {
1202 align(alignment_in_bits(tp), 0); 1202 align(alignment_in_bits(tp), 0);
1203 dsym->s_value.v_quad = dcs->d_offset; 1203 dsym->s_value.v_quad = dcs->d_offset;
1204 dcs->d_offset += sz; 1204 dcs->d_offset += sz;
1205 } 1205 }
1206 if (dcs->d_ctx == MOU) { 1206 if (dcs->d_ctx == MOU) {
1207 if (o > dcs->d_offset) 1207 if (o > dcs->d_offset)
1208 dcs->d_offset = o; 1208 dcs->d_offset = o;
1209 } 1209 }
1210 1210
1211 check_function_definition(dsym, false); 1211 check_function_definition(dsym, false);
1212 1212
1213 /* 1213 /*
1214 * Clear the BITFIELDTYPE indicator after processing each 1214 * Clear the BITFIELDTYPE indicator after processing each
1215 * structure element. 1215 * structure element.
1216 */ 1216 */
1217 bitfieldtype_ok = false; 1217 bitfieldtype_ok = false;
1218 1218
1219 return dsym; 1219 return dsym;
1220} 1220}
1221 1221
1222/* 1222/*
1223 * Aligns next structure element as required. 1223 * Aligns next structure element as required.
1224 * 1224 *
1225 * al contains the required alignment, len the length of a bit-field. 1225 * al contains the required alignment, len the length of a bit-field.
1226 */ 1226 */
1227static void 1227static void
1228align(unsigned int al, unsigned int len) 1228align(unsigned int al, unsigned int len)
1229{ 1229{
1230 unsigned int no; 1230 unsigned int no;
1231 1231
1232 /* 1232 /*
1233 * The alignment of the current element becomes the alignment of 1233 * The alignment of the current element becomes the alignment of
1234 * the struct/union if it is larger than the current alignment 1234 * the struct/union if it is larger than the current alignment
1235 * of the struct/union. 1235 * of the struct/union.
1236 */ 1236 */
1237 if (al > dcs->d_sou_align_in_bits) 1237 if (al > dcs->d_sou_align_in_bits)
1238 dcs->d_sou_align_in_bits = al; 1238 dcs->d_sou_align_in_bits = al;
1239 1239
1240 no = (dcs->d_offset + (al - 1)) & ~(al - 1); 1240 no = (dcs->d_offset + (al - 1)) & ~(al - 1);
1241 if (len == 0 || dcs->d_offset + len > no) 1241 if (len == 0 || dcs->d_offset + len > no)
1242 dcs->d_offset = no; 1242 dcs->d_offset = no;
1243} 1243}
1244 1244
1245/* 1245/*
1246 * Remember the width of the field in its type structure. 1246 * Remember the width of the field in its type structure.
1247 */ 1247 */
1248sym_t * 1248sym_t *
1249bitfield(sym_t *dsym, int len) 1249bitfield(sym_t *dsym, int len)
1250{ 1250{
1251 1251
1252 if (dsym == NULL) { 1252 if (dsym == NULL) {
1253 dsym = block_zero_alloc(sizeof(*dsym)); 1253 dsym = block_zero_alloc(sizeof(*dsym));
1254 dsym->s_name = unnamed; 1254 dsym->s_name = unnamed;
1255 dsym->s_kind = FMEMBER; 1255 dsym->s_kind = FMEMBER;
1256 dsym->s_scl = MOS; 1256 dsym->s_scl = MOS;
1257 dsym->s_type = gettyp(UINT); 1257 dsym->s_type = gettyp(UINT);
1258 dsym->s_block_level = -1; 1258 dsym->s_block_level = -1;
1259 } 1259 }
1260 dsym->s_type = block_dup_type(dsym->s_type); 1260 dsym->s_type = block_dup_type(dsym->s_type);
1261 dsym->s_type->t_bitfield = true; 1261 dsym->s_type->t_bitfield = true;
1262 dsym->s_type->t_flen = len; 1262 dsym->s_type->t_flen = len;
1263 dsym->s_bitfield = true; 1263 dsym->s_bitfield = true;
1264 return dsym; 1264 return dsym;
1265} 1265}
1266 1266
1267/* 1267/*
1268 * A sequence of asterisks and qualifiers, from right to left. For example, 1268 * A sequence of asterisks and qualifiers, from right to left. For example,
1269 * 'const ***volatile **const volatile' results in [cvp, p, vp, p, p]. The 1269 * 'const ***volatile **const volatile' results in [cvp, p, vp, p, p]. The
1270 * leftmost 'const' is not included in this list, it is stored in dcs->d_const 1270 * leftmost 'const' is not included in this list, it is stored in dcs->d_const
1271 * instead. 1271 * instead.
1272 */ 1272 */
1273qual_ptr * 1273qual_ptr *
1274merge_qualified_pointer(qual_ptr *p1, qual_ptr *p2) 1274merge_qualified_pointer(qual_ptr *p1, qual_ptr *p2)
1275{ 1275{
1276 qual_ptr *tail; 1276 qual_ptr *tail;
1277 1277
1278 if (p2 == NULL) 1278 if (p2 == NULL)
1279 return p1; /* for optional qualifiers */ 1279 return p1; /* for optional qualifiers */
1280 1280
1281 if (p2->p_pointer) { 1281 if (p2->p_pointer) {
1282 /* append p1 to p2, keeping p2 */ 1282 /* append p1 to p2, keeping p2 */
1283 for (tail = p2; tail->p_next != NULL; tail = tail->p_next) 1283 for (tail = p2; tail->p_next != NULL; tail = tail->p_next)
1284 continue; 1284 continue;
1285 tail->p_next = p1; 1285 tail->p_next = p1;
1286 return p2; 1286 return p2;
1287 } 1287 }
1288 1288
1289 /* merge p2 into p1, keeping p1 */ 1289 /* merge p2 into p1, keeping p1 */
1290 if (p2->p_const) { 1290 if (p2->p_const) {
1291 if (p1->p_const) { 1291 if (p1->p_const) {
1292 /* duplicate '%s' */ 1292 /* duplicate '%s' */
1293 warning(10, "const"); 1293 warning(10, "const");
1294 } 1294 }
1295 p1->p_const = true; 1295 p1->p_const = true;
1296 } 1296 }
1297 if (p2->p_volatile) { 1297 if (p2->p_volatile) {
1298 if (p1->p_volatile) { 1298 if (p1->p_volatile) {
1299 /* duplicate '%s' */ 1299 /* duplicate '%s' */
1300 warning(10, "volatile"); 1300 warning(10, "volatile");
1301 } 1301 }
1302 p1->p_volatile = true; 1302 p1->p_volatile = true;
1303 } 1303 }
1304 free(p2); 1304 free(p2);
1305 return p1; 1305 return p1;
1306} 1306}
1307 1307
1308/* 1308/*
1309 * The following 3 functions extend the type of a declarator with 1309 * The following 3 functions extend the type of a declarator with
1310 * pointer, function and array types. 1310 * pointer, function and array types.
1311 * 1311 *
1312 * The current type is the type built by end_type() (dcs->d_type) and 1312 * The current type is the type built by end_type() (dcs->d_type) and
1313 * pointer, function and array types already added for this 1313 * pointer, function and array types already added for this
1314 * declarator. The new type extension is inserted between both. 1314 * declarator. The new type extension is inserted between both.
1315 */ 1315 */
1316sym_t * 1316sym_t *
1317add_pointer(sym_t *decl, qual_ptr *p) 1317add_pointer(sym_t *decl, qual_ptr *p)
1318{ 1318{
1319 type_t **tpp, *tp; 1319 type_t **tpp, *tp;
1320 qual_ptr *next; 1320 qual_ptr *next;
1321 1321
1322 tpp = &decl->s_type; 1322 tpp = &decl->s_type;
1323 while (*tpp != NULL && *tpp != dcs->d_type) 1323 while (*tpp != NULL && *tpp != dcs->d_type)
1324 tpp = &(*tpp)->t_subt; 1324 tpp = &(*tpp)->t_subt;
1325 if (*tpp == NULL) 1325 if (*tpp == NULL)
1326 return decl; 1326 return decl;
1327 1327
1328 while (p != NULL) { 1328 while (p != NULL) {
1329 *tpp = tp = block_zero_alloc(sizeof(*tp)); 1329 *tpp = tp = block_zero_alloc(sizeof(*tp));
1330 tp->t_tspec = PTR; 1330 tp->t_tspec = PTR;
1331 tp->t_const = p->p_const; 1331 tp->t_const = p->p_const;
1332 tp->t_volatile = p->p_volatile; 1332 tp->t_volatile = p->p_volatile;
1333 *(tpp = &tp->t_subt) = dcs->d_type; 1333 *(tpp = &tp->t_subt) = dcs->d_type;
1334 next = p->p_next; 1334 next = p->p_next;
1335 free(p); 1335 free(p);
1336 p = next; 1336 p = next;
1337 } 1337 }
1338 return decl; 1338 return decl;
1339} 1339}
1340 1340
1341/* 1341/*
1342 * If a dimension was specified, dim is true, otherwise false 1342 * If a dimension was specified, dim is true, otherwise false
1343 * n is the specified dimension 1343 * n is the specified dimension
1344 */ 1344 */
1345sym_t * 1345sym_t *
1346add_array(sym_t *decl, bool dim, int n) 1346add_array(sym_t *decl, bool dim, int n)
1347{ 1347{
1348 type_t **tpp, *tp; 1348 type_t **tpp, *tp;
1349 1349
1350 tpp = &decl->s_type; 1350 tpp = &decl->s_type;
1351 while (*tpp != NULL && *tpp != dcs->d_type) 1351 while (*tpp != NULL && *tpp != dcs->d_type)
1352 tpp = &(*tpp)->t_subt; 1352 tpp = &(*tpp)->t_subt;
1353 if (*tpp == NULL) 1353 if (*tpp == NULL)
1354 return decl; 1354 return decl;
1355 1355
1356 *tpp = tp = block_zero_alloc(sizeof(*tp)); 1356 *tpp = tp = block_zero_alloc(sizeof(*tp));
1357 tp->t_tspec = ARRAY; 1357 tp->t_tspec = ARRAY;
1358 tp->t_subt = dcs->d_type; 1358 tp->t_subt = dcs->d_type;
1359 tp->t_dim = n; 1359 tp->t_dim = n;
1360 1360
1361 if (n < 0) { 1361 if (n < 0) {
1362 /* negative array dimension (%d) */ 1362 /* negative array dimension (%d) */
1363 error(20, n); 1363 error(20, n);
1364 n = 0; 1364 n = 0;
1365 } else if (n == 0 && dim) { 1365 } else if (n == 0 && dim) {
1366 /* zero sized array is a C99 extension */ 1366 /* zero sized array is a C99 extension */
1367 c99ism(322); 1367 c99ism(322);
1368 } else if (n == 0 && !dim) { 1368 } else if (n == 0 && !dim) {
1369 setcomplete(tp, false); 1369 setcomplete(tp, false);
1370 } 1370 }
1371 1371
1372 return decl; 1372 return decl;
1373} 1373}
1374 1374
1375sym_t * 1375sym_t *
1376add_function(sym_t *decl, sym_t *args) 1376add_function(sym_t *decl, sym_t *args)
1377{ 1377{
1378 type_t **tpp, *tp; 1378 type_t **tpp, *tp;
1379 1379
1380 if (dcs->d_proto) { 1380 if (dcs->d_proto) {
1381 if (tflag) 1381 if (tflag)
1382 /* function prototypes are illegal in traditional C */ 1382 /* function prototypes are illegal in traditional C */
1383 warning(270); 1383 warning(270);
1384 args = new_style_function(decl, args); 1384 args = new_style_function(decl, args);
1385 } else { 1385 } else {
1386 old_style_function(decl, args); 1386 old_style_function(decl, args);
1387 } 1387 }
1388 1388
1389 /* 1389 /*
1390 * The symbols are removed from the symbol table by 1390 * The symbols are removed from the symbol table by
1391 * end_declaration_level after add_function. To be able to restore 1391 * end_declaration_level after add_function. To be able to restore
1392 * them if this is a function definition, a pointer to the list of all 1392 * them if this is a function definition, a pointer to the list of all
1393 * symbols is stored in dcs->d_next->d_func_proto_syms. Also a list of 1393 * symbols is stored in dcs->d_next->d_func_proto_syms. Also a list of
1394 * the arguments (concatenated by s_next) is stored in 1394 * the arguments (concatenated by s_next) is stored in
1395 * dcs->d_next->d_func_args. (dcs->d_next must be used because *dcs is 1395 * dcs->d_next->d_func_args. (dcs->d_next must be used because *dcs is
1396 * the declaration stack element created for the list of params and is 1396 * the declaration stack element created for the list of params and is
1397 * removed after add_function.) 1397 * removed after add_function.)
1398 */ 1398 */
1399 if (dcs->d_next->d_ctx == EXTERN && 1399 if (dcs->d_next->d_ctx == EXTERN &&
1400 decl->s_type == dcs->d_next->d_type) { 1400 decl->s_type == dcs->d_next->d_type) {
1401 dcs->d_next->d_func_proto_syms = dcs->d_dlsyms; 1401 dcs->d_next->d_func_proto_syms = dcs->d_dlsyms;
1402 dcs->d_next->d_func_args = args; 1402 dcs->d_next->d_func_args = args;
1403 } 1403 }
1404 1404
1405 /* 1405 /*
1406 * XXX: What is this code doing on a semantic level, and why? 1406 * XXX: What is this code doing on a semantic level, and why?
1407 * Returning decl leads to the wrong function types in msg_347. 1407 * Returning decl leads to the wrong function types in msg_347.
1408 */ 1408 */
1409 tpp = &decl->s_type; 1409 tpp = &decl->s_type;
1410 while (*tpp != NULL && *tpp != dcs->d_next->d_type) 1410 while (*tpp != NULL && *tpp != dcs->d_next->d_type)
1411 /* 1411 /*
1412 * XXX: accessing INT->t_subt feels strange, even though it 1412 * XXX: accessing INT->t_subt feels strange, even though it
1413 * may even be guaranteed to be NULL. 1413 * may even be guaranteed to be NULL.
1414 */ 1414 */
1415 tpp = &(*tpp)->t_subt; 1415 tpp = &(*tpp)->t_subt;
1416 if (*tpp == NULL) 1416 if (*tpp == NULL)
1417 return decl; /* see msg_347 */ 1417 return decl; /* see msg_347 */
1418 1418
1419 *tpp = tp = block_zero_alloc(sizeof(*tp)); 1419 *tpp = tp = block_zero_alloc(sizeof(*tp));
1420 tp->t_tspec = FUNC; 1420 tp->t_tspec = FUNC;
1421 tp->t_subt = dcs->d_next->d_type; 1421 tp->t_subt = dcs->d_next->d_type;
1422 if ((tp->t_proto = dcs->d_proto) != false) 1422 if ((tp->t_proto = dcs->d_proto) != false)
1423 tp->t_args = args; 1423 tp->t_args = args;
1424 tp->t_vararg = dcs->d_vararg; 1424 tp->t_vararg = dcs->d_vararg;
1425 1425
1426 return decl; 1426 return decl;
1427} 1427}
1428 1428
1429/* 1429/*
1430 * Called for new style function declarations. 1430 * Called for new style function declarations.
1431 */ 1431 */
1432/* ARGSUSED */ 1432/* ARGSUSED */
1433static sym_t * 1433static sym_t *
1434new_style_function(sym_t *decl, sym_t *args) 1434new_style_function(sym_t *decl, sym_t *args)
1435{ 1435{
1436 sym_t *arg, *sym; 1436 sym_t *arg, *sym;
1437 scl_t sc; 1437 scl_t sc;
1438 1438
1439 /* 1439 /*
1440 * Declarations of structs/unions/enums in param lists are legal, 1440 * Declarations of structs/unions/enums in param lists are legal,
1441 * but senseless. 1441 * but senseless.
1442 */ 1442 */
1443 for (sym = dcs->d_dlsyms; sym != NULL; sym = sym->s_dlnxt) { 1443 for (sym = dcs->d_dlsyms; sym != NULL; sym = sym->s_level_next) {
1444 sc = sym->s_scl; 1444 sc = sym->s_scl;
1445 if (sc == STRUCT_TAG || sc == UNION_TAG || sc == ENUM_TAG) { 1445 if (sc == STRUCT_TAG || sc == UNION_TAG || sc == ENUM_TAG) {
1446 /* dubious tag declaration: %s %s */ 1446 /* dubious tag declaration: %s %s */
1447 warning(85, storage_class_name(sc), sym->s_name); 1447 warning(85, storage_class_name(sc), sym->s_name);
1448 } 1448 }
1449 } 1449 }
1450 1450
1451 for (arg = args; arg != NULL; arg = arg->s_next) { 1451 for (arg = args; arg != NULL; arg = arg->s_next) {
1452 if (arg->s_type->t_tspec == VOID && 1452 if (arg->s_type->t_tspec == VOID &&
1453 !(arg == args && arg->s_next == NULL)) { 1453 !(arg == args && arg->s_next == NULL)) {
1454 /* void must be sole parameter */ 1454 /* void must be sole parameter */
1455 error(60); 1455 error(60);
1456 arg->s_type = gettyp(INT); 1456 arg->s_type = gettyp(INT);
1457 } 1457 }
1458 } 1458 }
1459 1459
1460 if (args == NULL || args->s_type->t_tspec == VOID) 1460 if (args == NULL || args->s_type->t_tspec == VOID)
1461 return NULL; 1461 return NULL;
1462 return args; 1462 return args;
1463} 1463}
1464 1464
1465/* 1465/*
1466 * Called for old style function declarations. 1466 * Called for old style function declarations.
1467 */ 1467 */
1468static void 1468static void
1469old_style_function(sym_t *decl, sym_t *args) 1469old_style_function(sym_t *decl, sym_t *args)
1470{ 1470{
1471 1471
1472 /* 1472 /*
1473 * Remember list of params only if this is really seams to be 1473 * Remember list of params only if this is really seams to be
1474 * a function definition. 1474 * a function definition.
1475 */ 1475 */
1476 if (dcs->d_next->d_ctx == EXTERN && 1476 if (dcs->d_next->d_ctx == EXTERN &&
1477 decl->s_type == dcs->d_next->d_type) { 1477 decl->s_type == dcs->d_next->d_type) {
1478 /* 1478 /*
1479 * We assume that this becomes a function definition. If 1479 * We assume that this becomes a function definition. If
1480 * we are wrong, it's corrected in check_function_definition(). 1480 * we are wrong, it's corrected in check_function_definition().
1481 */ 1481 */
1482 if (args != NULL) { 1482 if (args != NULL) {
1483 decl->s_osdef = true; 1483 decl->s_osdef = true;
1484 decl->s_args = args; 1484 decl->s_args = args;
1485 } 1485 }
1486 } else { 1486 } else {
1487 if (args != NULL) 1487 if (args != NULL)
1488 /* function prototype parameters must have types */ 1488 /* function prototype parameters must have types */
1489 warning(62); 1489 warning(62);
1490 } 1490 }
1491} 1491}
1492 1492
1493/* 1493/*
1494 * Lists of identifiers in functions declarations are allowed only if 1494 * Lists of identifiers in functions declarations are allowed only if
1495 * it's also a function definition. If this is not the case, print an 1495 * it's also a function definition. If this is not the case, print an
1496 * error message. 1496 * error message.
1497 */ 1497 */
1498void 1498void
1499check_function_definition(sym_t *sym, bool msg) 1499check_function_definition(sym_t *sym, bool msg)
1500{ 1500{
1501 1501
1502 if (sym->s_osdef) { 1502 if (sym->s_osdef) {
1503 if (msg) { 1503 if (msg) {
1504 /* incomplete or misplaced function definition */ 1504 /* incomplete or misplaced function definition */
1505 error(22); 1505 error(22);
1506 } 1506 }
1507 sym->s_osdef = false; 1507 sym->s_osdef = false;
1508 sym->s_args = NULL; 1508 sym->s_args = NULL;
1509 } 1509 }
1510} 1510}
1511 1511
1512/* 1512/*
1513 * Process the name in a declarator. 1513 * Process the name in a declarator.
1514 * The symbol gets one of the storage classes EXTERN, STATIC, AUTO or 1514 * The symbol gets one of the storage classes EXTERN, STATIC, AUTO or
1515 * TYPEDEF. 1515 * TYPEDEF.
1516 * s_def and s_reg are valid after declarator_name(). 1516 * s_def and s_reg are valid after declarator_name().
1517 */ 1517 */
1518sym_t * 1518sym_t *
1519declarator_name(sym_t *sym) 1519declarator_name(sym_t *sym)
1520{ 1520{
1521 scl_t sc = NOSCL; 1521 scl_t sc = NOSCL;
1522 1522
1523 if (sym->s_scl == NOSCL) { 1523 if (sym->s_scl == NOSCL) {
1524 dcs->d_redeclared_symbol = NULL; 1524 dcs->d_redeclared_symbol = NULL;
1525 } else if (sym->s_defarg) { 1525 } else if (sym->s_defarg) {
1526 sym->s_defarg = false; 1526 sym->s_defarg = false;
1527 dcs->d_redeclared_symbol = NULL; 1527 dcs->d_redeclared_symbol = NULL;
1528 } else { 1528 } else {
1529 dcs->d_redeclared_symbol = sym; 1529 dcs->d_redeclared_symbol = sym;
1530 sym = pushdown(sym); 1530 sym = pushdown(sym);
1531 } 1531 }
1532 1532
1533 switch (dcs->d_ctx) { 1533 switch (dcs->d_ctx) {
1534 case MOS: 1534 case MOS:
1535 case MOU: 1535 case MOU:
1536 /* Set parent */ 1536 /* Set parent */
1537 sym->s_styp = dcs->d_tagtyp->t_str; 1537 sym->s_styp = dcs->d_tagtyp->t_str;
1538 sym->s_def = DEF; 1538 sym->s_def = DEF;
1539 sym->s_value.v_tspec = INT; 1539 sym->s_value.v_tspec = INT;
1540 sc = dcs->d_ctx; 1540 sc = dcs->d_ctx;
1541 break; 1541 break;
1542 case EXTERN: 1542 case EXTERN:
1543 /* 1543 /*
1544 * static and external symbols without "extern" are 1544 * static and external symbols without "extern" are
1545 * considered to be tentative defined, external 1545 * considered to be tentative defined, external
1546 * symbols with "extern" are declared, and typedef names 1546 * symbols with "extern" are declared, and typedef names
1547 * are defined. Tentative defined and declared symbols 1547 * are defined. Tentative defined and declared symbols
1548 * may become defined if an initializer is present or 1548 * may become defined if an initializer is present or
1549 * this is a function definition. 1549 * this is a function definition.
1550 */ 1550 */
1551 if ((sc = dcs->d_scl) == NOSCL) { 1551 if ((sc = dcs->d_scl) == NOSCL) {
1552 sc = EXTERN; 1552 sc = EXTERN;
1553 sym->s_def = TDEF; 1553 sym->s_def = TDEF;
1554 } else if (sc == STATIC) { 1554 } else if (sc == STATIC) {
1555 sym->s_def = TDEF; 1555 sym->s_def = TDEF;
1556 } else if (sc == TYPEDEF) { 1556 } else if (sc == TYPEDEF) {
1557 sym->s_def = DEF; 1557 sym->s_def = DEF;
1558 } else { 1558 } else {
1559 lint_assert(sc == EXTERN); 1559 lint_assert(sc == EXTERN);
1560 sym->s_def = DECL; 1560 sym->s_def = DECL;
1561 } 1561 }
1562 break; 1562 break;
1563 case PROTO_ARG: 1563 case PROTO_ARG:
1564 sym->s_arg = true; 1564 sym->s_arg = true;
1565 /* FALLTHROUGH */ 1565 /* FALLTHROUGH */
1566 case OLD_STYLE_ARG: 1566 case OLD_STYLE_ARG:
1567 if ((sc = dcs->d_scl) == NOSCL) { 1567 if ((sc = dcs->d_scl) == NOSCL) {
1568 sc = AUTO; 1568 sc = AUTO;
1569 } else { 1569 } else {
1570 lint_assert(sc == REG); 1570 lint_assert(sc == REG);
1571 sym->s_reg = true; 1571 sym->s_reg = true;
1572 sc = AUTO; 1572 sc = AUTO;
1573 } 1573 }
1574 sym->s_def = DEF; 1574 sym->s_def = DEF;
1575 break; 1575 break;
1576 case AUTO: 1576 case AUTO:
1577 if ((sc = dcs->d_scl) == NOSCL) { 1577 if ((sc = dcs->d_scl) == NOSCL) {
1578 /* 1578 /*
1579 * XXX somewhat ugly because we dont know whether 1579 * XXX somewhat ugly because we dont know whether
1580 * this is AUTO or EXTERN (functions). If we are 1580 * this is AUTO or EXTERN (functions). If we are
1581 * wrong it must be corrected in declare_local(), 1581 * wrong it must be corrected in declare_local(),
1582 * where we have the necessary type information. 1582 * where we have the necessary type information.
1583 */ 1583 */
1584 sc = AUTO; 1584 sc = AUTO;
1585 sym->s_def = DEF; 1585 sym->s_def = DEF;
1586 } else if (sc == AUTO || sc == STATIC || sc == TYPEDEF) { 1586 } else if (sc == AUTO || sc == STATIC || sc == TYPEDEF) {
1587 sym->s_def = DEF; 1587 sym->s_def = DEF;
1588 } else if (sc == REG) { 1588 } else if (sc == REG) {
1589 sym->s_reg = true; 1589 sym->s_reg = true;
1590 sc = AUTO; 1590 sc = AUTO;
1591 sym->s_def = DEF; 1591 sym->s_def = DEF;
1592 } else { 1592 } else {
1593 lint_assert(sc == EXTERN); 1593 lint_assert(sc == EXTERN);
1594 sym->s_def = DECL; 1594 sym->s_def = DECL;
1595 } 1595 }
1596 break; 1596 break;
1597 default: 1597 default:
1598 lint_assert(/*CONSTCOND*/false); 1598 lint_assert(/*CONSTCOND*/false);
1599 } 1599 }
1600 sym->s_scl = sc; 1600 sym->s_scl = sc;
1601 1601
1602 sym->s_type = dcs->d_type; 1602 sym->s_type = dcs->d_type;
1603 1603
1604 dcs->d_func_proto_syms = NULL; 1604 dcs->d_func_proto_syms = NULL;
1605 1605
1606 return sym; 1606 return sym;
1607} 1607}
1608 1608
1609/* 1609/*
1610 * Process a name in the list of formal parameters in an old style function 1610 * Process a name in the list of formal parameters in an old style function
1611 * definition. 1611 * definition.
1612 */ 1612 */
1613sym_t * 1613sym_t *
1614old_style_function_name(sym_t *sym) 1614old_style_function_name(sym_t *sym)
1615{ 1615{
1616 1616
1617 if (sym->s_scl != NOSCL) { 1617 if (sym->s_scl != NOSCL) {
1618 if (block_level == sym->s_block_level) { 1618 if (block_level == sym->s_block_level) {
1619 /* redeclaration of formal parameter %s */ 1619 /* redeclaration of formal parameter %s */
1620 error(21, sym->s_name); 1620 error(21, sym->s_name);
1621 lint_assert(sym->s_defarg); 1621 lint_assert(sym->s_defarg);
1622 } 1622 }
1623 sym = pushdown(sym); 1623 sym = pushdown(sym);
1624 } 1624 }
1625 sym->s_type = gettyp(INT); 1625 sym->s_type = gettyp(INT);
1626 sym->s_scl = AUTO; 1626 sym->s_scl = AUTO;
1627 sym->s_def = DEF; 1627 sym->s_def = DEF;
1628 sym->s_defarg = sym->s_arg = true; 1628 sym->s_defarg = sym->s_arg = true;
1629 return sym; 1629 return sym;
1630} 1630}
1631 1631
1632/* 1632/*
1633 * Create the type of a tag. 1633 * Create the type of a tag.
1634 * 1634 *
1635 * tag points to the symbol table entry of the tag 1635 * tag points to the symbol table entry of the tag
1636 * kind is the kind of the tag (STRUCT/UNION/ENUM) 1636 * kind is the kind of the tag (STRUCT/UNION/ENUM)
1637 * decl is true if the type of the tag will be completed in this declaration 1637 * decl is true if the type of the tag will be completed in this declaration
1638 * (the following token is T_LBRACE) 1638 * (the following token is T_LBRACE)
1639 * semi is true if the following token is T_SEMI 1639 * semi is true if the following token is T_SEMI
1640 */ 1640 */
1641type_t * 1641type_t *
1642mktag(sym_t *tag, tspec_t kind, bool decl, bool semi) 1642mktag(sym_t *tag, tspec_t kind, bool decl, bool semi)
1643{ 1643{
1644 scl_t scl; 1644 scl_t scl;
1645 type_t *tp; 1645 type_t *tp;
1646 1646
1647 if (kind == STRUCT) { 1647 if (kind == STRUCT) {
1648 scl = STRUCT_TAG; 1648 scl = STRUCT_TAG;
1649 } else if (kind == UNION) { 1649 } else if (kind == UNION) {
1650 scl = UNION_TAG; 1650 scl = UNION_TAG;
1651 } else { 1651 } else {
1652 lint_assert(kind == ENUM); 1652 lint_assert(kind == ENUM);
1653 scl = ENUM_TAG; 1653 scl = ENUM_TAG;
1654 } 1654 }
1655 1655
1656 if (tag != NULL) { 1656 if (tag != NULL) {
1657 if (tag->s_scl != NOSCL) { 1657 if (tag->s_scl != NOSCL) {
1658 tag = newtag(tag, scl, decl, semi); 1658 tag = newtag(tag, scl, decl, semi);
1659 } else { 1659 } else {
1660 /* a new tag, no empty declaration */ 1660 /* a new tag, no empty declaration */
1661 dcs->d_next->d_nonempty_decl = true; 1661 dcs->d_next->d_nonempty_decl = true;
1662 if (scl == ENUM_TAG && !decl) { 1662 if (scl == ENUM_TAG && !decl) {
1663 if (!tflag && (sflag || pflag)) 1663 if (!tflag && (sflag || pflag))
1664 /* forward reference to enum type */ 1664 /* forward reference to enum type */
1665 warning(42); 1665 warning(42);
1666 } 1666 }
1667 } 1667 }
1668 if (tag->s_scl == NOSCL) { 1668 if (tag->s_scl == NOSCL) {
1669 tag->s_scl = scl; 1669 tag->s_scl = scl;
1670 tag->s_type = tp = block_zero_alloc(sizeof(*tp)); 1670 tag->s_type = tp = block_zero_alloc(sizeof(*tp));
1671 tp->t_packed = dcs->d_packed; 1671 tp->t_packed = dcs->d_packed;
1672 } else { 1672 } else {
1673 tp = tag->s_type; 1673 tp = tag->s_type;
1674 } 1674 }
1675 } else { 1675 } else {
1676 tag = block_zero_alloc(sizeof(*tag)); 1676 tag = block_zero_alloc(sizeof(*tag));
1677 tag->s_name = unnamed; 1677 tag->s_name = unnamed;
1678 UNIQUE_CURR_POS(tag->s_def_pos); 1678 UNIQUE_CURR_POS(tag->s_def_pos);
1679 tag->s_kind = FTAG; 1679 tag->s_kind = FTAG;
1680 tag->s_scl = scl; 1680 tag->s_scl = scl;
1681 tag->s_block_level = -1; 1681 tag->s_block_level = -1;
1682 tag->s_type = tp = block_zero_alloc(sizeof(*tp)); 1682 tag->s_type = tp = block_zero_alloc(sizeof(*tp));
1683 tp->t_packed = dcs->d_packed; 1683 tp->t_packed = dcs->d_packed;
1684 dcs->d_next->d_nonempty_decl = true; 1684 dcs->d_next->d_nonempty_decl = true;
1685 } 1685 }
1686 1686
1687 if (tp->t_tspec == NOTSPEC) { 1687 if (tp->t_tspec == NOTSPEC) {
1688 tp->t_tspec = kind; 1688 tp->t_tspec = kind;
1689 if (kind != ENUM) { 1689 if (kind != ENUM) {
1690 tp->t_str = block_zero_alloc(sizeof(*tp->t_str)); 1690 tp->t_str = block_zero_alloc(sizeof(*tp->t_str));
1691 tp->t_str->sou_align_in_bits = CHAR_SIZE; 1691 tp->t_str->sou_align_in_bits = CHAR_SIZE;
1692 tp->t_str->sou_tag = tag; 1692 tp->t_str->sou_tag = tag;
1693 } else { 1693 } else {
1694 tp->t_is_enum = true; 1694 tp->t_is_enum = true;
1695 tp->t_enum = block_zero_alloc(sizeof(*tp->t_enum)); 1695 tp->t_enum = block_zero_alloc(sizeof(*tp->t_enum));
1696 tp->t_enum->en_tag = tag; 1696 tp->t_enum->en_tag = tag;
1697 } 1697 }
1698 setcomplete(tp, false); 1698 setcomplete(tp, false);
1699 } 1699 }
1700 return tp; 1700 return tp;
1701} 1701}
1702 1702
1703/* 1703/*
1704 * Checks all possible cases of tag redeclarations. 1704 * Checks all possible cases of tag redeclarations.
1705 * decl is true if T_LBRACE follows 1705 * decl is true if T_LBRACE follows
1706 * semi is true if T_SEMI follows 1706 * semi is true if T_SEMI follows
1707 */ 1707 */
1708static sym_t * 1708static sym_t *
1709newtag(sym_t *tag, scl_t scl, bool decl, bool semi) 1709newtag(sym_t *tag, scl_t scl, bool decl, bool semi)
1710{ 1710{
1711 1711
1712 if (tag->s_block_level < block_level) { 1712 if (tag->s_block_level < block_level) {
1713 if (semi) { 1713 if (semi) {
1714 /* "struct a;" */ 1714 /* "struct a;" */
1715 if (!tflag) { 1715 if (!tflag) {
1716 if (!sflag) 1716 if (!sflag)
1717 /* declaration introduces new ... */ 1717 /* declaration introduces new ... */
1718 warning(44, storage_class_name(scl), 1718 warning(44, storage_class_name(scl),
1719 tag->s_name); 1719 tag->s_name);
1720 tag = pushdown(tag); 1720 tag = pushdown(tag);
1721 } else if (tag->s_scl != scl) { 1721 } else if (tag->s_scl != scl) {
1722 /* base type is really '%s %s' */ 1722 /* base type is really '%s %s' */
1723 warning(45, storage_class_name(tag->s_scl), 1723 warning(45, storage_class_name(tag->s_scl),
1724 tag->s_name); 1724 tag->s_name);
1725 } 1725 }
1726 dcs->d_next->d_nonempty_decl = true; 1726 dcs->d_next->d_nonempty_decl = true;
1727 } else if (decl) { 1727 } else if (decl) {
1728 /* "struct a { ... } " */ 1728 /* "struct a { ... } " */
1729 if (hflag) 1729 if (hflag)
1730 /* redefinition hides earlier one: %s */ 1730 /* redefinition hides earlier one: %s */
1731 warning(43, tag->s_name); 1731 warning(43, tag->s_name);
1732 tag = pushdown(tag); 1732 tag = pushdown(tag);
1733 dcs->d_next->d_nonempty_decl = true; 1733 dcs->d_next->d_nonempty_decl = true;
1734 } else if (tag->s_scl != scl) { 1734 } else if (tag->s_scl != scl) {
1735 /* base type is really '%s %s' */ 1735 /* base type is really '%s %s' */
1736 warning(45, storage_class_name(tag->s_scl), 1736 warning(45, storage_class_name(tag->s_scl),
1737 tag->s_name); 1737 tag->s_name);
1738 if (!sflag) { 1738 if (!sflag) {
1739 /* declaration introduces new type in ... */ 1739 /* declaration introduces new type in ... */
1740 warning(44, storage_class_name(scl), 1740 warning(44, storage_class_name(scl),
1741 tag->s_name); 1741 tag->s_name);
1742 } 1742 }
1743 tag = pushdown(tag); 1743 tag = pushdown(tag);
1744 dcs->d_next->d_nonempty_decl = true; 1744 dcs->d_next->d_nonempty_decl = true;
1745 } 1745 }
1746 } else { 1746 } else {
1747 if (tag->s_scl != scl || 1747 if (tag->s_scl != scl ||
1748 (decl && !is_incomplete(tag->s_type))) { 1748 (decl && !is_incomplete(tag->s_type))) {
1749 /* %s tag '%s' redeclared as %s */ 1749 /* %s tag '%s' redeclared as %s */
1750 error(46, storage_class_name(tag->s_scl), 1750 error(46, storage_class_name(tag->s_scl),
1751 tag->s_name, storage_class_name(scl)); 1751 tag->s_name, storage_class_name(scl));
1752 print_previous_declaration(-1, tag); 1752 print_previous_declaration(-1, tag);
1753 tag = pushdown(tag); 1753 tag = pushdown(tag);
1754 dcs->d_next->d_nonempty_decl = true; 1754 dcs->d_next->d_nonempty_decl = true;
1755 } else if (semi || decl) { 1755 } else if (semi || decl) {
1756 dcs->d_next->d_nonempty_decl = true; 1756 dcs->d_next->d_nonempty_decl = true;
1757 } 1757 }
1758 } 1758 }
1759 return tag; 1759 return tag;
1760} 1760}
1761 1761
1762const char * 1762const char *
1763storage_class_name(scl_t sc) 1763storage_class_name(scl_t sc)
1764{ 1764{
1765 switch (sc) { 1765 switch (sc) {
1766 case EXTERN: return "extern"; 1766 case EXTERN: return "extern";
1767 case STATIC: return "static"; 1767 case STATIC: return "static";
1768 case AUTO: return "auto"; 1768 case AUTO: return "auto";
1769 case REG: return "register"; 1769 case REG: return "register";
1770 case TYPEDEF: return "typedef"; 1770 case TYPEDEF: return "typedef";
1771 case STRUCT_TAG:return "struct"; 1771 case STRUCT_TAG:return "struct";
1772 case UNION_TAG: return "union"; 1772 case UNION_TAG: return "union";
1773 case ENUM_TAG: return "enum"; 1773 case ENUM_TAG: return "enum";
1774 default: lint_assert(/*CONSTCOND*/false); 1774 default: lint_assert(/*CONSTCOND*/false);
1775 } 1775 }
1776 /* NOTREACHED */ 1776 /* NOTREACHED */
1777} 1777}
1778 1778
1779/* 1779/*
1780 * tp points to the type of the tag, fmem to the list of members. 1780 * tp points to the type of the tag, fmem to the list of members.
1781 */ 1781 */
1782type_t * 1782type_t *
1783complete_tag_struct_or_union(type_t *tp, sym_t *fmem) 1783complete_tag_struct_or_union(type_t *tp, sym_t *fmem)
1784{ 1784{
1785 tspec_t t; 1785 tspec_t t;
1786 struct_or_union *sp; 1786 struct_or_union *sp;
1787 int n; 1787 int n;
1788 sym_t *mem; 1788 sym_t *mem;
1789 1789
1790 if (tp == NULL) /* in case of syntax errors */ 1790 if (tp == NULL) /* in case of syntax errors */
1791 return gettyp(INT); 1791 return gettyp(INT);
1792 1792
1793 setcomplete(tp, true); 1793 setcomplete(tp, true);
1794 1794
1795 t = tp->t_tspec; 1795 t = tp->t_tspec;
1796 align((u_int)dcs->d_sou_align_in_bits, 0); 1796 align((u_int)dcs->d_sou_align_in_bits, 0);
1797 sp = tp->t_str; 1797 sp = tp->t_str;
1798 sp->sou_align_in_bits = dcs->d_sou_align_in_bits; 1798 sp->sou_align_in_bits = dcs->d_sou_align_in_bits;
1799 sp->sou_first_member = fmem; 1799 sp->sou_first_member = fmem;
1800 if (tp->t_packed) 1800 if (tp->t_packed)
1801 setpackedsize(tp); 1801 setpackedsize(tp);
1802 else 1802 else
1803 sp->sou_size_in_bits = dcs->d_offset; 1803 sp->sou_size_in_bits = dcs->d_offset;
1804 1804
1805 if (sp->sou_size_in_bits == 0) { 1805 if (sp->sou_size_in_bits == 0) {
1806 /* zero sized %s is a C9X feature */ 1806 /* zero sized %s is a C9X feature */
1807 c99ism(47, ttab[t].tt_name); 1807 c99ism(47, ttab[t].tt_name);
1808 } 1808 }
1809 1809
1810 n = 0; 1810 n = 0;
1811 for (mem = fmem; mem != NULL; mem = mem->s_next) { 1811 for (mem = fmem; mem != NULL; mem = mem->s_next) {
1812 /* bind anonymous members to the structure */ 1812 /* bind anonymous members to the structure */
1813 if (mem->s_styp == NULL) { 1813 if (mem->s_styp == NULL) {
1814 mem->s_styp = sp; 1814 mem->s_styp = sp;
1815 if (mem->s_type->t_bitfield) { 1815 if (mem->s_type->t_bitfield) {
1816 sp->sou_size_in_bits += bitfieldsize(&mem); 1816 sp->sou_size_in_bits += bitfieldsize(&mem);
1817 if (mem == NULL) 1817 if (mem == NULL)
1818 break; 1818 break;
1819 } 1819 }
1820 sp->sou_size_in_bits += 1820 sp->sou_size_in_bits +=
1821 type_size_in_bits(mem->s_type); 1821 type_size_in_bits(mem->s_type);
1822 } 1822 }
1823 if (mem->s_name != unnamed) 1823 if (mem->s_name != unnamed)
1824 n++; 1824 n++;
1825 } 1825 }
1826 1826
1827 if (n == 0 && sp->sou_size_in_bits != 0) { 1827 if (n == 0 && sp->sou_size_in_bits != 0) {
1828 /* %s has no named members */ 1828 /* %s has no named members */
1829 warning(65, t == STRUCT ? "structure" : "union"); 1829 warning(65, t == STRUCT ? "structure" : "union");
1830 } 1830 }
1831 return tp; 1831 return tp;
1832} 1832}
1833 1833
1834type_t * 1834type_t *
1835complete_tag_enum(type_t *tp, sym_t *fmem) 1835complete_tag_enum(type_t *tp, sym_t *fmem)
1836{ 1836{
1837 1837
1838 setcomplete(tp, true); 1838 setcomplete(tp, true);
1839 tp->t_enum->en_first_enumerator = fmem; 1839 tp->t_enum->en_first_enumerator = fmem;
1840 return tp; 1840 return tp;
1841} 1841}
1842 1842
1843/* 1843/*
1844 * Processes the name of an enumerator in an enum declaration. 1844 * Processes the name of an enumerator in an enum declaration.
1845 * 1845 *
1846 * sym points to the enumerator 1846 * sym points to the enumerator
1847 * val is the value of the enumerator 1847 * val is the value of the enumerator
1848 * impl is true if the value of the enumerator was not explicitly specified. 1848 * impl is true if the value of the enumerator was not explicitly specified.
1849 */ 1849 */
1850sym_t * 1850sym_t *
1851enumeration_constant(sym_t *sym, int val, bool impl) 1851enumeration_constant(sym_t *sym, int val, bool impl)
1852{ 1852{
1853 1853
1854 if (sym->s_scl != NOSCL) { 1854 if (sym->s_scl != NOSCL) {
1855 if (sym->s_block_level == block_level) { 1855 if (sym->s_block_level == block_level) {
1856 /* no hflag, because this is illegal!!! */ 1856 /* no hflag, because this is illegal!!! */
1857 if (sym->s_arg) { 1857 if (sym->s_arg) {
1858 /* enumeration constant hides parameter: %s */ 1858 /* enumeration constant hides parameter: %s */
1859 warning(57, sym->s_name); 1859 warning(57, sym->s_name);
1860 } else { 1860 } else {
1861 /* redeclaration of %s */ 1861 /* redeclaration of %s */
1862 error(27, sym->s_name); 1862 error(27, sym->s_name);
1863 /* 1863 /*
1864 * inside blocks it should not be too 1864 * inside blocks it should not be too
1865 * complicated to find the position of the 1865 * complicated to find the position of the
1866 * previous declaration 1866 * previous declaration
1867 */ 1867 */
1868 if (block_level == 0) 1868 if (block_level == 0)
1869 print_previous_declaration(-1, sym); 1869 print_previous_declaration(-1, sym);
1870 } 1870 }
1871 } else { 1871 } else {
1872 if (hflag) 1872 if (hflag)
1873 /* redefinition hides earlier one: %s */ 1873 /* redefinition hides earlier one: %s */
1874 warning(43, sym->s_name); 1874 warning(43, sym->s_name);
1875 } 1875 }
1876 sym = pushdown(sym); 1876 sym = pushdown(sym);
1877 } 1877 }
1878 sym->s_scl = CTCONST; 1878 sym->s_scl = CTCONST;
1879 sym->s_type = dcs->d_tagtyp; 1879 sym->s_type = dcs->d_tagtyp;
1880 sym->s_value.v_tspec = INT; 1880 sym->s_value.v_tspec = INT;
1881 sym->s_value.v_quad = val; 1881 sym->s_value.v_quad = val;
1882 if (impl && val - 1 == TARG_INT_MAX) { 1882 if (impl && val - 1 == TARG_INT_MAX) {
1883 /* overflow in enumeration values: %s */ 1883 /* overflow in enumeration values: %s */
1884 warning(48, sym->s_name); 1884 warning(48, sym->s_name);
1885 } 1885 }
1886 enumval = val + 1; 1886 enumval = val + 1;
1887 return sym; 1887 return sym;
1888} 1888}
1889 1889
1890/* 1890/*
1891 * Process a single external declarator. 1891 * Process a single external declarator.
1892 */ 1892 */
1893static void 1893static void
1894declare_extern(sym_t *dsym, bool initflg, sbuf_t *renaming) 1894declare_extern(sym_t *dsym, bool initflg, sbuf_t *renaming)
1895{ 1895{
1896 bool dowarn, rval, redec; 1896 bool dowarn, rval, redec;
1897 sym_t *rdsym; 1897 sym_t *rdsym;
1898 char *s; 1898 char *s;
1899 1899
1900 if (renaming != NULL) { 1900 if (renaming != NULL) {
1901 lint_assert(dsym->s_rename == NULL); 1901 lint_assert(dsym->s_rename == NULL);
1902 1902
1903 s = level_zero_alloc(1, renaming->sb_len + 1); 1903 s = level_zero_alloc(1, renaming->sb_len + 1);
1904 (void)memcpy(s, renaming->sb_name, renaming->sb_len + 1); 1904 (void)memcpy(s, renaming->sb_name, renaming->sb_len + 1);
1905 dsym->s_rename = s; 1905 dsym->s_rename = s;
1906 } 1906 }
1907 1907
1908 check_function_definition(dsym, true); 1908 check_function_definition(dsym, true);
1909 1909
1910 check_type(dsym); 1910 check_type(dsym);
1911 1911
1912 if (initflg && !check_init(dsym)) 1912 if (initflg && !check_init(dsym))
1913 dsym->s_def = DEF; 1913 dsym->s_def = DEF;
1914 1914
1915 /* 1915 /*
1916 * Declarations of functions are marked as "tentative" in 1916 * Declarations of functions are marked as "tentative" in
1917 * declarator_name(). This is wrong because there are no 1917 * declarator_name(). This is wrong because there are no
1918 * tentative function definitions. 1918 * tentative function definitions.
1919 */ 1919 */
1920 if (dsym->s_type->t_tspec == FUNC && dsym->s_def == TDEF) 1920 if (dsym->s_type->t_tspec == FUNC && dsym->s_def == TDEF)
1921 dsym->s_def = DECL; 1921 dsym->s_def = DECL;
1922 1922
1923 if (dcs->d_inline) { 1923 if (dcs->d_inline) {
1924 if (dsym->s_type->t_tspec == FUNC) { 1924 if (dsym->s_type->t_tspec == FUNC) {
1925 dsym->s_inline = true; 1925 dsym->s_inline = true;
1926 } else { 1926 } else {
1927 /* variable declared inline: %s */ 1927 /* variable declared inline: %s */
1928 warning(268, dsym->s_name); 1928 warning(268, dsym->s_name);
1929 } 1929 }
1930 } 1930 }
1931 1931
1932 /* Write the declaration into the output file */ 1932 /* Write the declaration into the output file */
1933 if (plibflg && llibflg && 1933 if (plibflg && llibflg &&
1934 dsym->s_type->t_tspec == FUNC && dsym->s_type->t_proto) { 1934 dsym->s_type->t_tspec == FUNC && dsym->s_type->t_proto) {
1935 /* 1935 /*
1936 * With both LINTLIBRARY and PROTOLIB the prototype is 1936 * With both LINTLIBRARY and PROTOLIB the prototype is
1937 * written as a function definition to the output file. 1937 * written as a function definition to the output file.
1938 */ 1938 */
1939 rval = dsym->s_type->t_subt->t_tspec != VOID; 1939 rval = dsym->s_type->t_subt->t_tspec != VOID;
1940 outfdef(dsym, &dsym->s_def_pos, rval, false, NULL); 1940 outfdef(dsym, &dsym->s_def_pos, rval, false, NULL);
1941 } else if (!is_compiler_builtin(dsym->s_name)) { 1941 } else if (!is_compiler_builtin(dsym->s_name)) {
1942 outsym(dsym, dsym->s_scl, dsym->s_def); 1942 outsym(dsym, dsym->s_scl, dsym->s_def);
1943 } 1943 }
1944 1944
1945 if ((rdsym = dcs->d_redeclared_symbol) != NULL) { 1945 if ((rdsym = dcs->d_redeclared_symbol) != NULL) {
1946 1946
1947 /* 1947 /*
1948 * If the old symbol stems from an old style function 1948 * If the old symbol stems from an old style function
1949 * definition, we have remembered the params in rdsmy->s_args 1949 * definition, we have remembered the params in rdsmy->s_args
1950 * and compare them with the params of the prototype. 1950 * and compare them with the params of the prototype.
1951 */ 1951 */
1952 if (rdsym->s_osdef && dsym->s_type->t_proto) { 1952 if (rdsym->s_osdef && dsym->s_type->t_proto) {
1953 redec = check_old_style_definition(rdsym, dsym); 1953 redec = check_old_style_definition(rdsym, dsym);
1954 } else { 1954 } else {
1955 redec = false; 1955 redec = false;
1956 } 1956 }
1957 1957
1958 if (!redec && 1958 if (!redec &&
1959 !check_redeclaration(dsym, (dowarn = false, &dowarn))) { 1959 !check_redeclaration(dsym, (dowarn = false, &dowarn))) {
1960 1960
1961 if (dowarn) { 1961 if (dowarn) {
1962 if (sflag) 1962 if (sflag)
1963 /* redeclaration of %s */ 1963 /* redeclaration of %s */
1964 error(27, dsym->s_name); 1964 error(27, dsym->s_name);
1965 else 1965 else
1966 /* redeclaration of %s */ 1966 /* redeclaration of %s */
1967 warning(27, dsym->s_name); 1967 warning(27, dsym->s_name);
1968 print_previous_declaration(-1, rdsym); 1968 print_previous_declaration(-1, rdsym);
1969 } 1969 }
1970 1970
1971 /* 1971 /*
1972 * Take over the remembered params if the new symbol 1972 * Take over the remembered params if the new symbol
1973 * is not a prototype. 1973 * is not a prototype.
1974 */ 1974 */
1975 if (rdsym->s_osdef && !dsym->s_type->t_proto) { 1975 if (rdsym->s_osdef && !dsym->s_type->t_proto) {
1976 dsym->s_osdef = rdsym->s_osdef; 1976 dsym->s_osdef = rdsym->s_osdef;
1977 dsym->s_args = rdsym->s_args; 1977 dsym->s_args = rdsym->s_args;
1978 dsym->s_def_pos = rdsym->s_def_pos; 1978 dsym->s_def_pos = rdsym->s_def_pos;
1979 } 1979 }
1980 1980
1981 /* 1981 /*
1982 * Remember the position of the declaration if the 1982 * Remember the position of the declaration if the
1983 * old symbol was a prototype and the new is not. 1983 * old symbol was a prototype and the new is not.
1984 * Also remember the position if the old symbol 1984 * Also remember the position if the old symbol
1985 * was defined and the new is not. 1985 * was defined and the new is not.
1986 */ 1986 */
1987 if (rdsym->s_type->t_proto && !dsym->s_type->t_proto) { 1987 if (rdsym->s_type->t_proto && !dsym->s_type->t_proto) {
1988 dsym->s_def_pos = rdsym->s_def_pos; 1988 dsym->s_def_pos = rdsym->s_def_pos;
1989 } else if (rdsym->s_def == DEF && dsym->s_def != DEF) { 1989 } else if (rdsym->s_def == DEF && dsym->s_def != DEF) {
1990 dsym->s_def_pos = rdsym->s_def_pos; 1990 dsym->s_def_pos = rdsym->s_def_pos;
1991 } 1991 }
1992 1992
1993 /* 1993 /*
1994 * Copy usage information of the name into the new 1994 * Copy usage information of the name into the new
1995 * symbol. 1995 * symbol.
1996 */ 1996 */
1997 copy_usage_info(dsym, rdsym); 1997 copy_usage_info(dsym, rdsym);
1998 1998
1999 /* Once a name is defined, it remains defined. */ 1999 /* Once a name is defined, it remains defined. */
2000 if (rdsym->s_def == DEF) 2000 if (rdsym->s_def == DEF)
2001 dsym->s_def = DEF; 2001 dsym->s_def = DEF;
2002 2002
2003 /* once a function is inline, it remains inline */ 2003 /* once a function is inline, it remains inline */
2004 if (rdsym->s_inline) 2004 if (rdsym->s_inline)
2005 dsym->s_inline = true; 2005 dsym->s_inline = true;
2006 2006
2007 complete_type(dsym, rdsym); 2007 complete_type(dsym, rdsym);
2008 2008
2009 } 2009 }
2010 2010
2011 rmsym(rdsym); 2011 rmsym(rdsym);
2012 } 2012 }
2013 2013
2014 if (dsym->s_scl == TYPEDEF) { 2014 if (dsym->s_scl == TYPEDEF) {
2015 dsym->s_type = block_dup_type(dsym->s_type); 2015 dsym->s_type = block_dup_type(dsym->s_type);
2016 dsym->s_type->t_typedef = true; 2016 dsym->s_type->t_typedef = true;
2017 settdsym(dsym->s_type, dsym); 2017 settdsym(dsym->s_type, dsym);
2018 } 2018 }
2019 2019
2020} 2020}
2021 2021
2022void 2022void
2023declare(sym_t *decl, bool initflg, sbuf_t *renaming) 2023declare(sym_t *decl, bool initflg, sbuf_t *renaming)
2024{ 2024{
2025 2025
2026 if (dcs->d_ctx == EXTERN) { 2026 if (dcs->d_ctx == EXTERN) {
2027 declare_extern(decl, initflg, renaming); 2027 declare_extern(decl, initflg, renaming);
2028 } else if (dcs->d_ctx == OLD_STYLE_ARG || dcs->d_ctx == PROTO_ARG) { 2028 } else if (dcs->d_ctx == OLD_STYLE_ARG || dcs->d_ctx == PROTO_ARG) {
2029 if (renaming != NULL) { 2029 if (renaming != NULL) {
2030 /* symbol renaming can't be used on function arguments */ 2030 /* symbol renaming can't be used on function arguments */
2031 error(310); 2031 error(310);
2032 } else 2032 } else
2033 (void)declare_argument(decl, initflg); 2033 (void)declare_argument(decl, initflg);
2034 } else { 2034 } else {
2035 lint_assert(dcs->d_ctx == AUTO); 2035 lint_assert(dcs->d_ctx == AUTO);
2036 if (renaming != NULL) { 2036 if (renaming != NULL) {
2037 /* symbol renaming can't be used on automatic variables */ 2037 /* symbol renaming can't be used on automatic variables */
2038 error(311); 2038 error(311);
2039 } else 2039 } else
2040 declare_local(decl, initflg); 2040 declare_local(decl, initflg);
2041 } 2041 }
2042} 2042}
2043 2043
2044/* 2044/*
2045 * Copies information about usage into a new symbol table entry of 2045 * Copies information about usage into a new symbol table entry of
2046 * the same symbol. 2046 * the same symbol.
2047 */ 2047 */
2048void 2048void
2049copy_usage_info(sym_t *sym, sym_t *rdsym) 2049copy_usage_info(sym_t *sym, sym_t *rdsym)
2050{ 2050{
2051 2051
2052 sym->s_set_pos = rdsym->s_set_pos; 2052 sym->s_set_pos = rdsym->s_set_pos;
2053 sym->s_use_pos = rdsym->s_use_pos; 2053 sym->s_use_pos = rdsym->s_use_pos;
2054 sym->s_set = rdsym->s_set; 2054 sym->s_set = rdsym->s_set;
2055 sym->s_used = rdsym->s_used; 2055 sym->s_used = rdsym->s_used;
2056} 2056}
2057 2057
2058/* 2058/*
2059 * Prints an error and returns true if a symbol is redeclared/redefined. 2059 * Prints an error and returns true if a symbol is redeclared/redefined.
2060 * Otherwise returns false and, in some cases of minor problems, prints 2060 * Otherwise returns false and, in some cases of minor problems, prints
2061 * a warning. 2061 * a warning.
2062 */ 2062 */
2063bool 2063bool
2064check_redeclaration(sym_t *dsym, bool *dowarn) 2064check_redeclaration(sym_t *dsym, bool *dowarn)
2065{ 2065{
2066 sym_t *rsym; 2066 sym_t *rsym;
2067 2067
2068 if ((rsym = dcs->d_redeclared_symbol)->s_scl == CTCONST) { 2068 if ((rsym = dcs->d_redeclared_symbol)->s_scl == CTCONST) {
2069 /* redeclaration of %s */ 2069 /* redeclaration of %s */
2070 error(27, dsym->s_name); 2070 error(27, dsym->s_name);
2071 print_previous_declaration(-1, rsym); 2071 print_previous_declaration(-1, rsym);
2072 return true; 2072 return true;
2073 } 2073 }
2074 if (rsym->s_scl == TYPEDEF) { 2074 if (rsym->s_scl == TYPEDEF) {
2075 /* typedef redeclared: %s */ 2075 /* typedef redeclared: %s */
2076 error(89, dsym->s_name); 2076 error(89, dsym->s_name);
2077 print_previous_declaration(-1, rsym); 2077 print_previous_declaration(-1, rsym);
2078 return true; 2078 return true;
2079 } 2079 }
2080 if (dsym->s_scl == TYPEDEF) { 2080 if (dsym->s_scl == TYPEDEF) {
2081 /* redeclaration of %s */ 2081 /* redeclaration of %s */
2082 error(27, dsym->s_name); 2082 error(27, dsym->s_name);
2083 print_previous_declaration(-1, rsym); 2083 print_previous_declaration(-1, rsym);
2084 return true; 2084 return true;
2085 } 2085 }
2086 if (rsym->s_def == DEF && dsym->s_def == DEF) { 2086 if (rsym->s_def == DEF && dsym->s_def == DEF) {
2087 /* redefinition of %s */ 2087 /* redefinition of %s */
2088 error(28, dsym->s_name); 2088 error(28, dsym->s_name);
2089 print_previous_declaration(-1, rsym); 2089 print_previous_declaration(-1, rsym);
2090 return true; 2090 return true;
2091 } 2091 }
2092 if (!eqtype(rsym->s_type, dsym->s_type, false, false, dowarn)) { 2092 if (!eqtype(rsym->s_type, dsym->s_type, false, false, dowarn)) {
2093 /* redeclaration of '%s' with type '%s', expected '%s' */ 2093 /* redeclaration of '%s' with type '%s', expected '%s' */
2094 error(347, dsym->s_name, 2094 error(347, dsym->s_name,
2095 type_name(dsym->s_type), type_name(rsym->s_type)); 2095 type_name(dsym->s_type), type_name(rsym->s_type));
2096 print_previous_declaration(-1, rsym); 2096 print_previous_declaration(-1, rsym);
2097 return true; 2097 return true;
2098 } 2098 }
2099 if (rsym->s_scl == EXTERN && dsym->s_scl == EXTERN) 2099 if (rsym->s_scl == EXTERN && dsym->s_scl == EXTERN)
2100 return false; 2100 return false;
2101 if (rsym->s_scl == STATIC && dsym->s_scl == STATIC) 2101 if (rsym->s_scl == STATIC && dsym->s_scl == STATIC)
2102 return false; 2102 return false;
2103 if (rsym->s_scl == STATIC && dsym->s_def == DECL) 2103 if (rsym->s_scl == STATIC && dsym->s_def == DECL)
2104 return false; 2104 return false;
2105 if (rsym->s_scl == EXTERN && rsym->s_def == DEF) { 2105 if (rsym->s_scl == EXTERN && rsym->s_def == DEF) {
2106 /* 2106 /*
2107 * All cases except "int a = 1; static int a;" are caught 2107 * All cases except "int a = 1; static int a;" are caught
2108 * above with or without a warning 2108 * above with or without a warning
2109 */ 2109 */
2110 /* redeclaration of %s */ 2110 /* redeclaration of %s */
2111 error(27, dsym->s_name); 2111 error(27, dsym->s_name);
2112 print_previous_declaration(-1, rsym); 2112 print_previous_declaration(-1, rsym);
2113 return true; 2113 return true;
2114 } 2114 }
2115 if (rsym->s_scl == EXTERN) { 2115 if (rsym->s_scl == EXTERN) {
2116 /* previously declared extern, becomes static: %s */ 2116 /* previously declared extern, becomes static: %s */
2117 warning(29, dsym->s_name); 2117 warning(29, dsym->s_name);
2118 print_previous_declaration(-1, rsym); 2118 print_previous_declaration(-1, rsym);
2119 return false; 2119 return false;
2120 } 2120 }
2121 /* 2121 /*
2122 * Now it's one of: 2122 * Now it's one of:
2123 * "static a; int a;", "static a; int a = 1;", "static a = 1; int a;" 2123 * "static a; int a;", "static a; int a = 1;", "static a = 1; int a;"
2124 */ 2124 */
2125 /* redeclaration of %s; ANSI C requires "static" */ 2125 /* redeclaration of %s; ANSI C requires "static" */
2126 if (sflag) { 2126 if (sflag) {
2127 /* redeclaration of %s; ANSI C requires static */ 2127 /* redeclaration of %s; ANSI C requires static */
2128 warning(30, dsym->s_name); 2128 warning(30, dsym->s_name);
2129 print_previous_declaration(-1, rsym); 2129 print_previous_declaration(-1, rsym);
2130 } 2130 }
2131 dsym->s_scl = STATIC; 2131 dsym->s_scl = STATIC;
2132 return false; 2132 return false;
2133} 2133}
2134 2134
2135static bool 2135static bool
2136qualifiers_correspond(const type_t *tp1, const type_t *tp2, bool ignqual) 2136qualifiers_correspond(const type_t *tp1, const type_t *tp2, bool ignqual)
2137{ 2137{
2138 if (tp1->t_const != tp2->t_const && !ignqual && !tflag) 2138 if (tp1->t_const != tp2->t_const && !ignqual && !tflag)
2139 return false; 2139 return false;
2140 2140
2141 if (tp1->t_volatile != tp2->t_volatile && !ignqual && !tflag) 2141 if (tp1->t_volatile != tp2->t_volatile && !ignqual && !tflag)
2142 return false; 2142 return false;
2143 2143
2144 return true; 2144 return true;
2145} 2145}
2146 2146
2147bool 2147bool
2148eqptrtype(const type_t *tp1, const type_t *tp2, bool ignqual) 2148eqptrtype(const type_t *tp1, const type_t *tp2, bool ignqual)
2149{ 2149{
2150 if (tp1->t_tspec != VOID && tp2->t_tspec != VOID) 2150 if (tp1->t_tspec != VOID && tp2->t_tspec != VOID)
2151 return false; 2151 return false;
2152 2152
2153 if (!qualifiers_correspond(tp1, tp2, ignqual)) 2153 if (!qualifiers_correspond(tp1, tp2, ignqual))
2154 return false; 2154 return false;
2155 2155
2156 return true; 2156 return true;
2157} 2157}
2158 2158
2159 2159
2160/* 2160/*
2161 * Checks if two types are compatible. 2161 * Checks if two types are compatible.
2162 * 2162 *
2163 * ignqual ignore qualifiers of type; used for function params 2163 * ignqual ignore qualifiers of type; used for function params
2164 * promot promote left type; used for comparison of params of 2164 * promot promote left type; used for comparison of params of
2165 * old style function definitions with params of prototypes. 2165 * old style function definitions with params of prototypes.
2166 * *dowarn set to true if an old style function declaration is not 2166 * *dowarn set to true if an old style function declaration is not
2167 * compatible with a prototype 2167 * compatible with a prototype
2168 */ 2168 */
2169bool 2169bool
2170eqtype(const type_t *tp1, const type_t *tp2, 2170eqtype(const type_t *tp1, const type_t *tp2,
2171 bool ignqual, bool promot, bool *dowarn) 2171 bool ignqual, bool promot, bool *dowarn)
2172{ 2172{
2173 tspec_t t; 2173 tspec_t t;
2174 2174
2175 while (tp1 != NULL && tp2 != NULL) { 2175 while (tp1 != NULL && tp2 != NULL) {
2176 2176
2177 t = tp1->t_tspec; 2177 t = tp1->t_tspec;
2178 if (promot) { 2178 if (promot) {
2179 if (t == FLOAT) { 2179 if (t == FLOAT) {
2180 t = DOUBLE; 2180 t = DOUBLE;
2181 } else if (t == CHAR || t == SCHAR) { 2181 } else if (t == CHAR || t == SCHAR) {
2182 t = INT; 2182 t = INT;
2183 } else if (t == UCHAR) { 2183 } else if (t == UCHAR) {
2184 t = tflag ? UINT : INT; 2184 t = tflag ? UINT : INT;
2185 } else if (t == SHORT) { 2185 } else if (t == SHORT) {
2186 t = INT; 2186 t = INT;
2187 } else if (t == USHORT) { 2187 } else if (t == USHORT) {
2188 /* CONSTCOND */ 2188 /* CONSTCOND */
2189 t = TARG_INT_MAX < TARG_USHRT_MAX || tflag ? UINT : INT; 2189 t = TARG_INT_MAX < TARG_USHRT_MAX || tflag ? UINT : INT;
2190 } 2190 }
2191 } 2191 }
2192 2192
2193 if (t != tp2->t_tspec) 2193 if (t != tp2->t_tspec)
2194 return false; 2194 return false;
2195 2195
2196 if (!qualifiers_correspond(tp1, tp2, ignqual)) 2196 if (!qualifiers_correspond(tp1, tp2, ignqual))
2197 return false; 2197 return false;
2198 2198
2199 if (t == STRUCT || t == UNION) 2199 if (t == STRUCT || t == UNION)
2200 return tp1->t_str == tp2->t_str; 2200 return tp1->t_str == tp2->t_str;
2201 2201
2202 if (t == ENUM && eflag) 2202 if (t == ENUM && eflag)
2203 return tp1->t_enum == tp2->t_enum; 2203 return tp1->t_enum == tp2->t_enum;
2204 2204
2205 if (t == ARRAY && tp1->t_dim != tp2->t_dim) { 2205 if (t == ARRAY && tp1->t_dim != tp2->t_dim) {
2206 if (tp1->t_dim != 0 && tp2->t_dim != 0) 2206 if (tp1->t_dim != 0 && tp2->t_dim != 0)
2207 return false; 2207 return false;
2208 } 2208 }
2209 2209
2210 /* don't check prototypes for traditional */ 2210 /* don't check prototypes for traditional */
2211 if (t == FUNC && !tflag) { 2211 if (t == FUNC && !tflag) {
2212 if (tp1->t_proto && tp2->t_proto) { 2212 if (tp1->t_proto && tp2->t_proto) {
2213 if (!eqargs(tp1, tp2, dowarn)) 2213 if (!eqargs(tp1, tp2, dowarn))
2214 return false; 2214 return false;
2215 } else if (tp1->t_proto) { 2215 } else if (tp1->t_proto) {
2216 if (!mnoarg(tp1, dowarn)) 2216 if (!mnoarg(tp1, dowarn))
2217 return false; 2217 return false;
2218 } else if (tp2->t_proto) { 2218 } else if (tp2->t_proto) {
2219 if (!mnoarg(tp2, dowarn)) 2219 if (!mnoarg(tp2, dowarn))
2220 return false; 2220 return false;
2221 } 2221 }
2222 } 2222 }
2223 2223
2224 tp1 = tp1->t_subt; 2224 tp1 = tp1->t_subt;
2225 tp2 = tp2->t_subt; 2225 tp2 = tp2->t_subt;
2226 ignqual = promot = false; 2226 ignqual = promot = false;
2227 2227
2228 } 2228 }
2229 2229
2230 return tp1 == tp2; 2230 return tp1 == tp2;
2231} 2231}
2232 2232
2233/* 2233/*
2234 * Compares the parameter types of two prototypes. 2234 * Compares the parameter types of two prototypes.
2235 */ 2235 */
2236static bool 2236static bool
2237eqargs(const type_t *tp1, const type_t *tp2, bool *dowarn) 2237eqargs(const type_t *tp1, const type_t *tp2, bool *dowarn)
2238{ 2238{
2239 sym_t *a1, *a2; 2239 sym_t *a1, *a2;
2240 2240
2241 if (tp1->t_vararg != tp2->t_vararg) 2241 if (tp1->t_vararg != tp2->t_vararg)
2242 return false; 2242 return false;
2243 2243
2244 a1 = tp1->t_args; 2244 a1 = tp1->t_args;
2245 a2 = tp2->t_args; 2245 a2 = tp2->t_args;
2246 2246
2247 while (a1 != NULL && a2 != NULL) { 2247 while (a1 != NULL && a2 != NULL) {
2248 2248
2249 if (!eqtype(a1->s_type, a2->s_type, true, false, dowarn)) 2249 if (!eqtype(a1->s_type, a2->s_type, true, false, dowarn))
2250 return false; 2250 return false;
2251 2251
2252 a1 = a1->s_next; 2252 a1 = a1->s_next;
2253 a2 = a2->s_next; 2253 a2 = a2->s_next;
2254 2254
2255 } 2255 }
2256 2256
2257 return a1 == a2; 2257 return a1 == a2;
2258} 2258}
2259 2259
2260/* 2260/*
2261 * mnoarg() (matches functions with no argument type information) 2261 * mnoarg() (matches functions with no argument type information)
2262 * returns whether all parameters of a prototype are compatible with 2262 * returns whether all parameters of a prototype are compatible with
2263 * an old style function declaration. 2263 * an old style function declaration.
2264 * This is the case if the following conditions are met: 2264 * This is the case if the following conditions are met:
2265 * 1. the prototype has a fixed number of parameters 2265 * 1. the prototype has a fixed number of parameters
2266 * 2. no parameter is of type float 2266 * 2. no parameter is of type float
2267 * 3. no parameter is converted to another type if integer promotion 2267 * 3. no parameter is converted to another type if integer promotion
2268 * is applied on it 2268 * is applied on it
2269 */ 2269 */
2270static bool 2270static bool
2271mnoarg(const type_t *tp, bool *dowarn) 2271mnoarg(const type_t *tp, bool *dowarn)
2272{ 2272{
2273 sym_t *arg; 2273 sym_t *arg;
2274 tspec_t t; 2274 tspec_t t;
2275 2275
2276 if (tp->t_vararg) { 2276 if (tp->t_vararg) {
2277 if (dowarn != NULL) 2277 if (dowarn != NULL)
2278 *dowarn = true; 2278 *dowarn = true;
2279 } 2279 }
2280 for (arg = tp->t_args; arg != NULL; arg = arg->s_next) { 2280 for (arg = tp->t_args; arg != NULL; arg = arg->s_next) {
2281 if ((t = arg->s_type->t_tspec) == FLOAT || 2281 if ((t = arg->s_type->t_tspec) == FLOAT ||
2282 t == CHAR || t == SCHAR || t == UCHAR || 2282 t == CHAR || t == SCHAR || t == UCHAR ||
2283 t == SHORT || t == USHORT) { 2283 t == SHORT || t == USHORT) {
2284 if (dowarn != NULL) 2284 if (dowarn != NULL)
2285 *dowarn = true; 2285 *dowarn = true;
2286 } 2286 }
2287 } 2287 }
2288 return true; 2288 return true;
2289} 2289}
2290 2290
2291/* 2291/*
2292 * Compares a prototype declaration with the remembered arguments of 2292 * Compares a prototype declaration with the remembered arguments of
2293 * a previous old style function definition. 2293 * a previous old style function definition.
2294 */ 2294 */
2295static bool 2295static bool
2296check_old_style_definition(sym_t *rdsym, sym_t *dsym) 2296check_old_style_definition(sym_t *rdsym, sym_t *dsym)
2297{ 2297{
2298 sym_t *args, *pargs, *arg, *parg; 2298 sym_t *args, *pargs, *arg, *parg;
2299 int narg, nparg, n; 2299 int narg, nparg, n;
2300 bool dowarn, msg; 2300 bool dowarn, msg;
2301 2301
2302 args = rdsym->s_args; 2302 args = rdsym->s_args;
2303 pargs = dsym->s_type->t_args; 2303 pargs = dsym->s_type->t_args;
2304 2304
2305 msg = false; 2305 msg = false;
2306 2306
2307 narg = nparg = 0; 2307 narg = nparg = 0;
2308 for (arg = args; arg != NULL; arg = arg->s_next) 2308 for (arg = args; arg != NULL; arg = arg->s_next)
2309 narg++; 2309 narg++;
2310 for (parg = pargs; parg != NULL; parg = parg->s_next) 2310 for (parg = pargs; parg != NULL; parg = parg->s_next)
2311 nparg++; 2311 nparg++;
2312 if (narg != nparg) { 2312 if (narg != nparg) {
2313 /* prototype does not match old-style definition */ 2313 /* prototype does not match old-style definition */
2314 error(63); 2314 error(63);
2315 msg = true; 2315 msg = true;
2316 goto end; 2316 goto end;
2317 } 2317 }
2318 2318
2319 arg = args; 2319 arg = args;
2320 parg = pargs; 2320 parg = pargs;
2321 n = 1; 2321 n = 1;
2322 while (narg-- > 0) { 2322 while (narg-- > 0) {
2323 dowarn = false; 2323 dowarn = false;
2324 /* 2324 /*
2325 * If it does not match due to promotion and sflag is 2325 * If it does not match due to promotion and sflag is
2326 * not set we print only a warning. 2326 * not set we print only a warning.
2327 */ 2327 */
2328 if (!eqtype(arg->s_type, parg->s_type, true, true, &dowarn) || 2328 if (!eqtype(arg->s_type, parg->s_type, true, true, &dowarn) ||
2329 dowarn) { 2329 dowarn) {
2330 /* prototype does not match old style ... */ 2330 /* prototype does not match old style ... */
2331 error(299, n); 2331 error(299, n);
2332 msg = true; 2332 msg = true;
2333 } 2333 }
2334 arg = arg->s_next; 2334 arg = arg->s_next;
2335 parg = parg->s_next; 2335 parg = parg->s_next;
2336 n++; 2336 n++;
2337 } 2337 }
2338 2338
2339 end: 2339 end:
2340 if (msg) 2340 if (msg)
2341 /* old style definition */ 2341 /* old style definition */
2342 print_previous_declaration(300, rdsym); 2342 print_previous_declaration(300, rdsym);
2343 2343
2344 return msg; 2344 return msg;
2345} 2345}
2346 2346
2347/* 2347/*
2348 * Completes a type by copying the dimension and prototype information 2348 * Completes a type by copying the dimension and prototype information
2349 * from a second compatible type. 2349 * from a second compatible type.
2350 * 2350 *
2351 * Following lines are legal: 2351 * Following lines are legal:
2352 * "typedef a[]; a b; a b[10]; a c; a c[20];" 2352 * "typedef a[]; a b; a b[10]; a c; a c[20];"
2353 * "typedef ft(); ft f; f(int); ft g; g(long);" 2353 * "typedef ft(); ft f; f(int); ft g; g(long);"
2354 * This means that, if a type is completed, the type structure must 2354 * This means that, if a type is completed, the type structure must
2355 * be duplicated. 2355 * be duplicated.
2356 */ 2356 */
2357void 2357void
2358complete_type(sym_t *dsym, sym_t *ssym) 2358complete_type(sym_t *dsym, sym_t *ssym)
2359{ 2359{
2360 type_t **dstp, *src; 2360 type_t **dstp, *src;
2361 type_t *dst; 2361 type_t *dst;
2362 2362
2363 dstp = &dsym->s_type; 2363 dstp = &dsym->s_type;
2364 src = ssym->s_type; 2364 src = ssym->s_type;
2365 2365
2366 while ((dst = *dstp) != NULL) { 2366 while ((dst = *dstp) != NULL) {
2367 lint_assert(src != NULL); 2367 lint_assert(src != NULL);
2368 lint_assert(dst->t_tspec == src->t_tspec); 2368 lint_assert(dst->t_tspec == src->t_tspec);
2369 if (dst->t_tspec == ARRAY) { 2369 if (dst->t_tspec == ARRAY) {
2370 if (dst->t_dim == 0 && src->t_dim != 0) { 2370 if (dst->t_dim == 0 && src->t_dim != 0) {
2371 *dstp = dst = block_dup_type(dst); 2371 *dstp = dst = block_dup_type(dst);
2372 dst->t_dim = src->t_dim; 2372 dst->t_dim = src->t_dim;
2373 setcomplete(dst, true); 2373 setcomplete(dst, true);
2374 } 2374 }
2375 } else if (dst->t_tspec == FUNC) { 2375 } else if (dst->t_tspec == FUNC) {
2376 if (!dst->t_proto && src->t_proto) { 2376 if (!dst->t_proto && src->t_proto) {
2377 *dstp = dst = block_dup_type(dst); 2377 *dstp = dst = block_dup_type(dst);
2378 dst->t_proto = true; 2378 dst->t_proto = true;
2379 dst->t_args = src->t_args; 2379 dst->t_args = src->t_args;
2380 } 2380 }
2381 } 2381 }
2382 dstp = &dst->t_subt; 2382 dstp = &dst->t_subt;
2383 src = src->t_subt; 2383 src = src->t_subt;
2384 } 2384 }
2385} 2385}
2386 2386
2387/* 2387/*
2388 * Completes the declaration of a single argument. 2388 * Completes the declaration of a single argument.
2389 */ 2389 */
2390sym_t * 2390sym_t *
2391declare_argument(sym_t *sym, bool initflg) 2391declare_argument(sym_t *sym, bool initflg)
2392{ 2392{
2393 tspec_t t; 2393 tspec_t t;
2394 2394
2395 check_function_definition(sym, true); 2395 check_function_definition(sym, true);
2396 2396
2397 check_type(sym); 2397 check_type(sym);
2398 2398
2399 if (dcs->d_redeclared_symbol != NULL && 2399 if (dcs->d_redeclared_symbol != NULL &&
2400 dcs->d_redeclared_symbol->s_block_level == block_level) { 2400 dcs->d_redeclared_symbol->s_block_level == block_level) {
2401 /* redeclaration of formal parameter %s */ 2401 /* redeclaration of formal parameter %s */
2402 error(237, sym->s_name); 2402 error(237, sym->s_name);
2403 rmsym(dcs->d_redeclared_symbol); 2403 rmsym(dcs->d_redeclared_symbol);
2404 sym->s_arg = true; 2404 sym->s_arg = true;
2405 } 2405 }
2406 2406
2407 if (!sym->s_arg) { 2407 if (!sym->s_arg) {
2408 /* declared argument %s is missing */ 2408 /* declared argument %s is missing */
2409 error(53, sym->s_name); 2409 error(53, sym->s_name);
2410 sym->s_arg = true; 2410 sym->s_arg = true;
2411 } 2411 }
2412 2412
2413 if (initflg) { 2413 if (initflg) {
2414 /* cannot initialize parameter: %s */ 2414 /* cannot initialize parameter: %s */
2415 error(52, sym->s_name); 2415 error(52, sym->s_name);
2416 } 2416 }
2417 2417
2418 if (sym->s_type == NULL) /* for c(void()) */ 2418 if (sym->s_type == NULL) /* for c(void()) */
2419 sym->s_type = gettyp(VOID); 2419 sym->s_type = gettyp(VOID);
2420 2420
2421 if ((t = sym->s_type->t_tspec) == ARRAY) { 2421 if ((t = sym->s_type->t_tspec) == ARRAY) {
2422 sym->s_type = block_derive_type(sym->s_type->t_subt, PTR); 2422 sym->s_type = block_derive_type(sym->s_type->t_subt, PTR);
2423 } else if (t == FUNC) { 2423 } else if (t == FUNC) {
2424 if (tflag) 2424 if (tflag)
2425 /* a function is declared as an argument: %s */ 2425 /* a function is declared as an argument: %s */
2426 warning(50, sym->s_name); 2426 warning(50, sym->s_name);
2427 sym->s_type = block_derive_type(sym->s_type, PTR); 2427 sym->s_type = block_derive_type(sym->s_type, PTR);
2428 } else if (t == FLOAT) { 2428 } else if (t == FLOAT) {
2429 if (tflag) 2429 if (tflag)
2430 sym->s_type = gettyp(DOUBLE); 2430 sym->s_type = gettyp(DOUBLE);
2431 } 2431 }
2432 2432
2433 if (dcs->d_inline) 2433 if (dcs->d_inline)
2434 /* argument declared inline: %s */ 2434 /* argument declared inline: %s */
2435 warning(269, sym->s_name); 2435 warning(269, sym->s_name);
2436 2436
2437 /* 2437 /*
2438 * Arguments must have complete types. length() prints the needed 2438 * Arguments must have complete types. length() prints the needed
2439 * error messages (null dimension is impossible because arrays are 2439 * error messages (null dimension is impossible because arrays are
2440 * converted to pointers). 2440 * converted to pointers).
2441 */ 2441 */
2442 if (sym->s_type->t_tspec != VOID) 2442 if (sym->s_type->t_tspec != VOID)
2443 (void)length(sym->s_type, sym->s_name); 2443 (void)length(sym->s_type, sym->s_name);
2444 2444
2445 sym->s_used = dcs->d_used; 2445 sym->s_used = dcs->d_used;
2446 mark_as_set(sym); 2446 mark_as_set(sym);
2447 2447
2448 return sym; 2448 return sym;
2449} 2449}
2450 2450
2451void 2451void
2452check_func_lint_directives(void) 2452check_func_lint_directives(void)
2453{ 2453{
2454 sym_t *arg; 2454 sym_t *arg;
2455 int narg, n; 2455 int narg, n;
2456 tspec_t t; 2456 tspec_t t;
2457 2457
2458 /* check for illegal combinations of lint directives */ 2458 /* check for illegal combinations of lint directives */
2459 if (printflike_argnum != -1 && scanflike_argnum != -1) { 2459 if (printflike_argnum != -1 && scanflike_argnum != -1) {
2460 /* can't be used together: ** PRINTFLIKE ** ** SCANFLIKE ** */ 2460 /* can't be used together: ** PRINTFLIKE ** ** SCANFLIKE ** */
2461 warning(289); 2461 warning(289);
2462 printflike_argnum = scanflike_argnum = -1; 2462 printflike_argnum = scanflike_argnum = -1;
2463 } 2463 }
2464 if (nvararg != -1 && 2464 if (nvararg != -1 &&
2465 (printflike_argnum != -1 || scanflike_argnum != -1)) { 2465 (printflike_argnum != -1 || scanflike_argnum != -1)) {
2466 /* dubious use of ** VARARGS ** with ** %s ** */ 2466 /* dubious use of ** VARARGS ** with ** %s ** */
2467 warning(288, 2467 warning(288,
2468 printflike_argnum != -1 ? "PRINTFLIKE" : "SCANFLIKE"); 2468 printflike_argnum != -1 ? "PRINTFLIKE" : "SCANFLIKE");
2469 nvararg = -1; 2469 nvararg = -1;
2470 } 2470 }
2471 2471
2472 /* 2472 /*
2473 * check if the argument of a lint directive is compatible with the 2473 * check if the argument of a lint directive is compatible with the
2474 * number of arguments. 2474 * number of arguments.
2475 */ 2475 */
2476 narg = 0; 2476 narg = 0;
2477 for (arg = dcs->d_func_args; arg != NULL; arg = arg->s_next) 2477 for (arg = dcs->d_func_args; arg != NULL; arg = arg->s_next)
2478 narg++; 2478 narg++;
2479 if (nargusg > narg) { 2479 if (nargusg > narg) {
2480 /* argument number mismatch with directive: ** %s ** */ 2480 /* argument number mismatch with directive: ** %s ** */
2481 warning(283, "ARGSUSED"); 2481 warning(283, "ARGSUSED");
2482 nargusg = 0; 2482 nargusg = 0;
2483 } 2483 }
2484 if (nvararg > narg) { 2484 if (nvararg > narg) {
2485 /* argument number mismatch with directive: ** %s ** */ 2485 /* argument number mismatch with directive: ** %s ** */
2486 warning(283, "VARARGS"); 2486 warning(283, "VARARGS");
2487 nvararg = 0; 2487 nvararg = 0;
2488 } 2488 }
2489 if (printflike_argnum > narg) { 2489 if (printflike_argnum > narg) {
2490 /* argument number mismatch with directive: ** %s ** */ 2490 /* argument number mismatch with directive: ** %s ** */
2491 warning(283, "PRINTFLIKE"); 2491 warning(283, "PRINTFLIKE");
2492 printflike_argnum = -1; 2492 printflike_argnum = -1;
2493 } else if (printflike_argnum == 0) { 2493 } else if (printflike_argnum == 0) {
2494 printflike_argnum = -1; 2494 printflike_argnum = -1;
2495 } 2495 }
2496 if (scanflike_argnum > narg) { 2496 if (scanflike_argnum > narg) {
2497 /* argument number mismatch with directive: ** %s ** */ 2497 /* argument number mismatch with directive: ** %s ** */
2498 warning(283, "SCANFLIKE"); 2498 warning(283, "SCANFLIKE");
2499 scanflike_argnum = -1; 2499 scanflike_argnum = -1;
2500 } else if (scanflike_argnum == 0) { 2500 } else if (scanflike_argnum == 0) {
2501 scanflike_argnum = -1; 2501 scanflike_argnum = -1;
2502 } 2502 }
2503 if (printflike_argnum != -1 || scanflike_argnum != -1) { 2503 if (printflike_argnum != -1 || scanflike_argnum != -1) {
2504 narg = printflike_argnum != -1 2504 narg = printflike_argnum != -1
2505 ? printflike_argnum : scanflike_argnum; 2505 ? printflike_argnum : scanflike_argnum;
2506 arg = dcs->d_func_args; 2506 arg = dcs->d_func_args;
2507 for (n = 1; n < narg; n++) 2507 for (n = 1; n < narg; n++)
2508 arg = arg->s_next; 2508 arg = arg->s_next;
2509 if (arg->s_type->t_tspec != PTR || 2509 if (arg->s_type->t_tspec != PTR ||
2510 ((t = arg->s_type->t_subt->t_tspec) != CHAR && 2510 ((t = arg->s_type->t_subt->t_tspec) != CHAR &&
2511 t != UCHAR && t != SCHAR)) { 2511 t != UCHAR && t != SCHAR)) {
2512 /* argument %d must be 'char *' for PRINTFLIKE/... */ 2512 /* argument %d must be 'char *' for PRINTFLIKE/... */
2513 warning(293, narg); 2513 warning(293, narg);
2514 printflike_argnum = scanflike_argnum = -1; 2514 printflike_argnum = scanflike_argnum = -1;
2515 } 2515 }
2516 } 2516 }
2517} 2517}
2518 2518
2519/* 2519/*
2520 * Warn about arguments in old style function definitions that default to int. 2520 * Warn about arguments in old style function definitions that default to int.
2521 * Check that an old style function definition is compatible to a previous 2521 * Check that an old style function definition is compatible to a previous
2522 * prototype. 2522 * prototype.
2523 */ 2523 */
2524void 2524void
2525check_func_old_style_arguments(void) 2525check_func_old_style_arguments(void)
2526{ 2526{
2527 sym_t *args, *arg, *pargs, *parg; 2527 sym_t *args, *arg, *pargs, *parg;
2528 int narg, nparg; 2528 int narg, nparg;
2529 bool msg; 2529 bool msg;
2530 2530
2531 args = funcsym->s_args; 2531 args = funcsym->s_args;
2532 pargs = funcsym->s_type->t_args; 2532 pargs = funcsym->s_type->t_args;
2533 2533
2534 /* 2534 /*
2535 * print a warning for each argument of an old style function 2535 * print a warning for each argument of an old style function
2536 * definition which defaults to int 2536 * definition which defaults to int
2537 */ 2537 */
2538 for (arg = args; arg != NULL; arg = arg->s_next) { 2538 for (arg = args; arg != NULL; arg = arg->s_next) {
2539 if (arg->s_defarg) { 2539 if (arg->s_defarg) {
2540 /* argument type defaults to 'int': %s */ 2540 /* argument type defaults to 'int': %s */
2541 warning(32, arg->s_name); 2541 warning(32, arg->s_name);
2542 arg->s_defarg = false; 2542 arg->s_defarg = false;
2543 mark_as_set(arg); 2543 mark_as_set(arg);
2544 } 2544 }
2545 } 2545 }
2546 2546
2547 /* 2547 /*
2548 * If this is an old style function definition and a prototype 2548 * If this is an old style function definition and a prototype
2549 * exists, compare the types of arguments. 2549 * exists, compare the types of arguments.
2550 */ 2550 */
2551 if (funcsym->s_osdef && funcsym->s_type->t_proto) { 2551 if (funcsym->s_osdef && funcsym->s_type->t_proto) {
2552 /* 2552 /*
2553 * If the number of arguments does not match, we need not 2553 * If the number of arguments does not match, we need not
2554 * continue. 2554 * continue.
2555 */ 2555 */
2556 narg = nparg = 0; 2556 narg = nparg = 0;
2557 msg = false; 2557 msg = false;
2558 for (parg = pargs; parg != NULL; parg = parg->s_next) 2558 for (parg = pargs; parg != NULL; parg = parg->s_next)
2559 nparg++; 2559 nparg++;
2560 for (arg = args; arg != NULL; arg = arg->s_next) 2560 for (arg = args; arg != NULL; arg = arg->s_next)
2561 narg++; 2561 narg++;
2562 if (narg != nparg) { 2562 if (narg != nparg) {
2563 /* parameter mismatch: %d declared, %d defined */ 2563 /* parameter mismatch: %d declared, %d defined */
2564 error(51, nparg, narg); 2564 error(51, nparg, narg);
2565 msg = true; 2565 msg = true;
2566 } else { 2566 } else {
2567 parg = pargs; 2567 parg = pargs;
2568 arg = args; 2568 arg = args;
2569 while (narg-- > 0) { 2569 while (narg-- > 0) {
2570 msg |= check_prototype_declaration(arg, parg); 2570 msg |= check_prototype_declaration(arg, parg);
2571 parg = parg->s_next; 2571 parg = parg->s_next;
2572 arg = arg->s_next; 2572 arg = arg->s_next;
2573 } 2573 }
2574 } 2574 }
2575 if (msg) 2575 if (msg)
2576 /* prototype declaration */ 2576 /* prototype declaration */
2577 print_previous_declaration(285, 2577 print_previous_declaration(285,
2578 dcs->d_redeclared_symbol); 2578 dcs->d_redeclared_symbol);
2579 2579
2580 /* from now on the prototype is valid */ 2580 /* from now on the prototype is valid */
2581 funcsym->s_osdef = false; 2581 funcsym->s_osdef = false;
2582 funcsym->s_args = NULL; 2582 funcsym->s_args = NULL;
2583 } 2583 }
2584} 2584}
2585 2585
2586/* 2586/*
2587 * Checks compatibility of an old style function definition with a previous 2587 * Checks compatibility of an old style function definition with a previous
2588 * prototype declaration. 2588 * prototype declaration.
2589 * Returns true if the position of the previous declaration should be reported. 2589 * Returns true if the position of the previous declaration should be reported.
2590 */ 2590 */
2591static bool 2591static bool
2592check_prototype_declaration(sym_t *arg, sym_t *parg) 2592check_prototype_declaration(sym_t *arg, sym_t *parg)
2593{ 2593{
2594 type_t *tp, *ptp; 2594 type_t *tp, *ptp;
2595 bool dowarn, msg; 2595 bool dowarn, msg;
2596 2596
2597 tp = arg->s_type; 2597 tp = arg->s_type;
2598 ptp = parg->s_type; 2598 ptp = parg->s_type;
2599 2599
2600 msg = false; 2600 msg = false;
2601 dowarn = false; 2601 dowarn = false;
2602 2602
2603 if (!eqtype(tp, ptp, true, true, &dowarn)) { 2603 if (!eqtype(tp, ptp, true, true, &dowarn)) {
2604 if (eqtype(tp, ptp, true, false, &dowarn)) { 2604 if (eqtype(tp, ptp, true, false, &dowarn)) {
2605 /* type does not match prototype: %s */ 2605 /* type does not match prototype: %s */
2606 gnuism(58, arg->s_name); 2606 gnuism(58, arg->s_name);
2607 msg = sflag || !gflag; 2607 msg = sflag || !gflag;
2608 } else { 2608 } else {
2609 /* type does not match prototype: %s */ 2609 /* type does not match prototype: %s */
2610 error(58, arg->s_name); 2610 error(58, arg->s_name);
2611 msg = true; 2611 msg = true;
2612 } 2612 }
2613 } else if (dowarn) { 2613 } else if (dowarn) {
2614 if (sflag) 2614 if (sflag)
2615 /* type does not match prototype: %s */ 2615 /* type does not match prototype: %s */
2616 error(58, arg->s_name); 2616 error(58, arg->s_name);
2617 else 2617 else
2618 /* type does not match prototype: %s */ 2618 /* type does not match prototype: %s */
2619 warning(58, arg->s_name); 2619 warning(58, arg->s_name);
2620 msg = true; 2620 msg = true;
2621 } 2621 }
2622 2622
2623 return msg; 2623 return msg;
2624} 2624}
2625 2625
2626static void 2626static void
2627check_local_hiding(const sym_t *dsym) 2627check_local_hiding(const sym_t *dsym)
2628{ 2628{
2629 switch (dsym->s_scl) { 2629 switch (dsym->s_scl) {
2630 case AUTO: 2630 case AUTO:
2631 /* automatic hides external declaration: %s */ 2631 /* automatic hides external declaration: %s */
2632 warning(86, dsym->s_name); 2632 warning(86, dsym->s_name);
2633 break; 2633 break;
2634 case STATIC: 2634 case STATIC:
2635 /* static hides external declaration: %s */ 2635 /* static hides external declaration: %s */
2636 warning(87, dsym->s_name); 2636 warning(87, dsym->s_name);
2637 break; 2637 break;
2638 case TYPEDEF: 2638 case TYPEDEF:
2639 /* typedef hides external declaration: %s */ 2639 /* typedef hides external declaration: %s */
2640 warning(88, dsym->s_name); 2640 warning(88, dsym->s_name);
2641 break; 2641 break;
2642 case EXTERN: 2642 case EXTERN:
2643 /* Already checked in declare_external_in_block. */ 2643 /* Already checked in declare_external_in_block. */
2644 break; 2644 break;
2645 default: 2645 default:
2646 lint_assert(/*CONSTCOND*/false); 2646 lint_assert(/*CONSTCOND*/false);
2647 } 2647 }
2648} 2648}
2649 2649
2650static void 2650static void
2651check_local_redeclaration(const sym_t *dsym, sym_t *rsym) 2651check_local_redeclaration(const sym_t *dsym, sym_t *rsym)
2652{ 2652{
2653 if (rsym->s_block_level == 0) { 2653 if (rsym->s_block_level == 0) {
2654 if (hflag) 2654 if (hflag)
2655 check_local_hiding(dsym); 2655 check_local_hiding(dsym);
2656 2656
2657 } else if (rsym->s_block_level == block_level) { 2657 } else if (rsym->s_block_level == block_level) {
2658 2658
2659 /* no hflag, because it's illegal! */ 2659 /* no hflag, because it's illegal! */
2660 if (rsym->s_arg) { 2660 if (rsym->s_arg) {
2661 /* 2661 /*
2662 * if !tflag, a "redeclaration of %s" error 2662 * if !tflag, a "redeclaration of %s" error
2663 * is produced below 2663 * is produced below
2664 */ 2664 */
2665 if (tflag) { 2665 if (tflag) {
2666 if (hflag) 2666 if (hflag)
2667 /* declaration hides parameter: %s */ 2667 /* declaration hides parameter: %s */
2668 warning(91, dsym->s_name); 2668 warning(91, dsym->s_name);
2669 rmsym(rsym); 2669 rmsym(rsym);
2670 } 2670 }
2671 } 2671 }
2672 2672
2673 } else if (rsym->s_block_level < block_level) { 2673 } else if (rsym->s_block_level < block_level) {
2674 if (hflag) 2674 if (hflag)
2675 /* declaration hides earlier one: %s */ 2675 /* declaration hides earlier one: %s */
2676 warning(95, dsym->s_name); 2676 warning(95, dsym->s_name);
2677 } 2677 }
2678 2678
2679 if (rsym->s_block_level == block_level) { 2679 if (rsym->s_block_level == block_level) {
2680 /* redeclaration of %s */ 2680 /* redeclaration of %s */
2681 error(27, dsym->s_name); 2681 error(27, dsym->s_name);
2682 rmsym(rsym); 2682 rmsym(rsym);
2683 } 2683 }
2684} 2684}
2685 2685
2686/* 2686/*
2687 * Completes a single local declaration/definition. 2687 * Completes a single local declaration/definition.
2688 */ 2688 */
2689void 2689void
2690declare_local(sym_t *dsym, bool initflg) 2690declare_local(sym_t *dsym, bool initflg)
2691{ 2691{
2692 2692
2693 /* Correct a mistake done in declarator_name(). */ 2693 /* Correct a mistake done in declarator_name(). */
2694 if (dsym->s_type->t_tspec == FUNC) { 2694 if (dsym->s_type->t_tspec == FUNC) {
2695 dsym->s_def = DECL; 2695 dsym->s_def = DECL;
2696 if (dcs->d_scl == NOSCL) 2696 if (dcs->d_scl == NOSCL)
2697 dsym->s_scl = EXTERN; 2697 dsym->s_scl = EXTERN;
2698 } 2698 }
2699 2699
2700 if (dsym->s_type->t_tspec == FUNC) { 2700 if (dsym->s_type->t_tspec == FUNC) {
2701 if (dsym->s_scl == STATIC) { 2701 if (dsym->s_scl == STATIC) {
2702 /* dubious static function at block level: %s */ 2702 /* dubious static function at block level: %s */
2703 warning(93, dsym->s_name); 2703 warning(93, dsym->s_name);
2704 dsym->s_scl = EXTERN; 2704 dsym->s_scl = EXTERN;
2705 } else if (dsym->s_scl != EXTERN && dsym->s_scl != TYPEDEF) { 2705 } else if (dsym->s_scl != EXTERN && dsym->s_scl != TYPEDEF) {
2706 /* function has illegal storage class: %s */ 2706 /* function has illegal storage class: %s */
2707 error(94, dsym->s_name); 2707 error(94, dsym->s_name);
2708 dsym->s_scl = EXTERN; 2708 dsym->s_scl = EXTERN;
2709 } 2709 }
2710 } 2710 }
2711 2711
2712 /* 2712 /*
2713 * functions may be declared inline at local scope, although 2713 * functions may be declared inline at local scope, although
2714 * this has no effect for a later definition of the same 2714 * this has no effect for a later definition of the same
2715 * function. 2715 * function.
2716 * XXX it should have an effect if tflag is set. this would 2716 * XXX it should have an effect if tflag is set. this would
2717 * also be the way gcc behaves. 2717 * also be the way gcc behaves.
2718 */ 2718 */
2719 if (dcs->d_inline) { 2719 if (dcs->d_inline) {
2720 if (dsym->s_type->t_tspec == FUNC) { 2720 if (dsym->s_type->t_tspec == FUNC) {
2721 dsym->s_inline = true; 2721 dsym->s_inline = true;
2722 } else { 2722 } else {
2723 /* variable declared inline: %s */ 2723 /* variable declared inline: %s */
2724 warning(268, dsym->s_name); 2724 warning(268, dsym->s_name);
2725 } 2725 }
2726 } 2726 }
2727 2727
2728 check_function_definition(dsym, true); 2728 check_function_definition(dsym, true);
2729 2729
2730 check_type(dsym); 2730 check_type(dsym);
2731 2731
2732 if (dcs->d_redeclared_symbol != NULL && dsym->s_scl == EXTERN) 2732 if (dcs->d_redeclared_symbol != NULL && dsym->s_scl == EXTERN)
2733 declare_external_in_block(dsym); 2733 declare_external_in_block(dsym);
2734 2734
2735 if (dsym->s_scl == EXTERN) { 2735 if (dsym->s_scl == EXTERN) {
2736 /* 2736 /*
2737 * XXX if the static variable at level 0 is only defined 2737 * XXX if the static variable at level 0 is only defined
2738 * later, checking will be possible. 2738 * later, checking will be possible.
2739 */ 2739 */
2740 if (dsym->s_ext_sym == NULL) { 2740 if (dsym->s_ext_sym == NULL) {
2741 outsym(dsym, EXTERN, dsym->s_def); 2741 outsym(dsym, EXTERN, dsym->s_def);
2742 } else { 2742 } else {
2743 outsym(dsym, dsym->s_ext_sym->s_scl, dsym->s_def); 2743 outsym(dsym, dsym->s_ext_sym->s_scl, dsym->s_def);
2744 } 2744 }
2745 } 2745 }
2746 2746
2747 if (dcs->d_redeclared_symbol != NULL) 2747 if (dcs->d_redeclared_symbol != NULL)
2748 check_local_redeclaration(dsym, dcs->d_redeclared_symbol); 2748 check_local_redeclaration(dsym, dcs->d_redeclared_symbol);
2749 2749
2750 if (initflg && !check_init(dsym)) { 2750 if (initflg && !check_init(dsym)) {
2751 dsym->s_def = DEF; 2751 dsym->s_def = DEF;
2752 mark_as_set(dsym); 2752 mark_as_set(dsym);
2753 } 2753 }
2754 2754
2755 if (dsym->s_scl == TYPEDEF) { 2755 if (dsym->s_scl == TYPEDEF) {
2756 dsym->s_type = block_dup_type(dsym->s_type); 2756 dsym->s_type = block_dup_type(dsym->s_type);
2757 dsym->s_type->t_typedef = true; 2757 dsym->s_type->t_typedef = true;
2758 settdsym(dsym->s_type, dsym); 2758 settdsym(dsym->s_type, dsym);
2759 } 2759 }
2760 2760
2761 /* 2761 /*
2762 * Before we can check the size we must wait for a initialization 2762 * Before we can check the size we must wait for a initialization
2763 * which may follow. 2763 * which may follow.
2764 */ 2764 */
2765} 2765}
2766 2766
2767/* 2767/*
2768 * Processes (re)declarations of external symbols inside blocks. 2768 * Processes (re)declarations of external symbols inside blocks.
2769 */ 2769 */
2770static void 2770static void
2771declare_external_in_block(sym_t *dsym) 2771declare_external_in_block(sym_t *dsym)
2772{ 2772{
2773 bool eqt, dowarn; 2773 bool eqt, dowarn;
2774 sym_t *esym; 2774 sym_t *esym;
2775 2775
2776 /* look for a symbol with the same name */ 2776 /* look for a symbol with the same name */
2777 esym = dcs->d_redeclared_symbol; 2777 esym = dcs->d_redeclared_symbol;
2778 while (esym != NULL && esym->s_block_level != 0) { 2778 while (esym != NULL && esym->s_block_level != 0) {
2779 while ((esym = esym->s_link) != NULL) { 2779 while ((esym = esym->s_symtab_next) != NULL) {
2780 if (esym->s_kind != FVFT) 2780 if (esym->s_kind != FVFT)
2781 continue; 2781 continue;
2782 if (strcmp(dsym->s_name, esym->s_name) == 0) 2782 if (strcmp(dsym->s_name, esym->s_name) == 0)
2783 break; 2783 break;
2784 } 2784 }
2785 } 2785 }
2786 if (esym == NULL) 2786 if (esym == NULL)
2787 return; 2787 return;
2788 if (esym->s_scl != EXTERN && esym->s_scl != STATIC) { 2788 if (esym->s_scl != EXTERN && esym->s_scl != STATIC) {
2789 /* gcc accepts this without a warning, pcc prints an error. */ 2789 /* gcc accepts this without a warning, pcc prints an error. */
2790 /* redeclaration of %s */ 2790 /* redeclaration of %s */
2791 warning(27, dsym->s_name); 2791 warning(27, dsym->s_name);
2792 print_previous_declaration(-1, esym); 2792 print_previous_declaration(-1, esym);
2793 return; 2793 return;
2794 } 2794 }
2795 2795
2796 dowarn = false; 2796 dowarn = false;
2797 eqt = eqtype(esym->s_type, dsym->s_type, false, false, &dowarn); 2797 eqt = eqtype(esym->s_type, dsym->s_type, false, false, &dowarn);
2798 2798
2799 if (!eqt || dowarn) { 2799 if (!eqt || dowarn) {
2800 if (esym->s_scl == EXTERN) { 2800 if (esym->s_scl == EXTERN) {
2801 /* inconsistent redeclaration of extern: %s */ 2801 /* inconsistent redeclaration of extern: %s */
2802 warning(90, dsym->s_name); 2802 warning(90, dsym->s_name);
2803 print_previous_declaration(-1, esym); 2803 print_previous_declaration(-1, esym);
2804 } else { 2804 } else {
2805 /* inconsistent redeclaration of static: %s */ 2805 /* inconsistent redeclaration of static: %s */
2806 warning(92, dsym->s_name); 2806 warning(92, dsym->s_name);
2807 print_previous_declaration(-1, esym); 2807 print_previous_declaration(-1, esym);
2808 } 2808 }
2809 } 2809 }
2810 2810
2811 if (eqt) { 2811 if (eqt) {
2812 /* 2812 /*
2813 * Remember the external symbol so we can update usage 2813 * Remember the external symbol so we can update usage
2814 * information at the end of the block. 2814 * information at the end of the block.
2815 */ 2815 */
2816 dsym->s_ext_sym = esym; 2816 dsym->s_ext_sym = esym;
2817 } 2817 }
2818} 2818}
2819 2819
2820/* 2820/*
2821 * Print an error or a warning if the symbol cannot be initialized due 2821 * Print an error or a warning if the symbol cannot be initialized due
2822 * to type/storage class. Return whether an error has been detected. 2822 * to type/storage class. Return whether an error has been detected.
2823 */ 2823 */
2824static bool 2824static bool
2825check_init(sym_t *sym) 2825check_init(sym_t *sym)
2826{ 2826{
2827 bool erred; 2827 bool erred;
2828 2828
2829 erred = false; 2829 erred = false;
2830 2830
2831 if (sym->s_type->t_tspec == FUNC) { 2831 if (sym->s_type->t_tspec == FUNC) {
2832 /* cannot initialize function: %s */ 2832 /* cannot initialize function: %s */
2833 error(24, sym->s_name); 2833 error(24, sym->s_name);
2834 erred = true; 2834 erred = true;
2835 } else if (sym->s_scl == TYPEDEF) { 2835 } else if (sym->s_scl == TYPEDEF) {
2836 /* cannot initialize typedef: %s */ 2836 /* cannot initialize typedef: %s */
2837 error(25, sym->s_name); 2837 error(25, sym->s_name);
2838 erred = true; 2838 erred = true;
2839 } else if (sym->s_scl == EXTERN && sym->s_def == DECL) { 2839 } else if (sym->s_scl == EXTERN && sym->s_def == DECL) {
2840 /* cannot initialize "extern" declaration: %s */ 2840 /* cannot initialize "extern" declaration: %s */
2841 if (dcs->d_ctx == EXTERN) { 2841 if (dcs->d_ctx == EXTERN) {
2842 /* cannot initialize extern declaration: %s */ 2842 /* cannot initialize extern declaration: %s */
2843 warning(26, sym->s_name); 2843 warning(26, sym->s_name);
2844 } else { 2844 } else {
2845 /* cannot initialize extern declaration: %s */ 2845 /* cannot initialize extern declaration: %s */
2846 error(26, sym->s_name); 2846 error(26, sym->s_name);
2847 erred = true; 2847 erred = true;
2848 } 2848 }
2849 } 2849 }
2850 2850
2851 return erred; 2851 return erred;
2852} 2852}
2853 2853
2854/* 2854/*
2855 * Create a symbol for an abstract declaration. 2855 * Create a symbol for an abstract declaration.
2856 */ 2856 */
2857sym_t * 2857sym_t *
2858abstract_name(void) 2858abstract_name(void)
2859{ 2859{
2860 sym_t *sym; 2860 sym_t *sym;
2861 2861
2862 lint_assert(dcs->d_ctx == ABSTRACT || dcs->d_ctx == PROTO_ARG); 2862 lint_assert(dcs->d_ctx == ABSTRACT || dcs->d_ctx == PROTO_ARG);
2863 2863
2864 sym = block_zero_alloc(sizeof(*sym)); 2864 sym = block_zero_alloc(sizeof(*sym));
2865 2865
2866 sym->s_name = unnamed; 2866 sym->s_name = unnamed;
2867 sym->s_def = DEF; 2867 sym->s_def = DEF;
2868 sym->s_scl = ABSTRACT; 2868 sym->s_scl = ABSTRACT;
2869 sym->s_block_level = -1; 2869 sym->s_block_level = -1;
2870 2870
2871 if (dcs->d_ctx == PROTO_ARG) 2871 if (dcs->d_ctx == PROTO_ARG)
2872 sym->s_arg = true; 2872 sym->s_arg = true;
2873 2873
2874 /* 2874 /*
2875 * At this point, dcs->d_type contains only the basic type. That 2875 * At this point, dcs->d_type contains only the basic type. That
2876 * type will be updated later, adding pointers, arrays and functions 2876 * type will be updated later, adding pointers, arrays and functions
2877 * as necessary. 2877 * as necessary.
2878 */ 2878 */
2879 /* 2879 /*
2880 * XXX: This is not the correct type. For example in msg_347, it is 2880 * XXX: This is not the correct type. For example in msg_347, it is
2881 * the type of the last prototype parameter, but it should rather be 2881 * the type of the last prototype parameter, but it should rather be
2882 * the return type of the function. 2882 * the return type of the function.
2883 */ 2883 */
2884 sym->s_type = dcs->d_type; 2884 sym->s_type = dcs->d_type;
2885 dcs->d_redeclared_symbol = NULL; 2885 dcs->d_redeclared_symbol = NULL;
2886 dcs->d_vararg = false; 2886 dcs->d_vararg = false;
2887 2887
2888 return sym; 2888 return sym;
2889} 2889}
2890 2890
2891/* 2891/*
2892 * Removes anything which has nothing to do on global level. 2892 * Removes anything which has nothing to do on global level.
2893 */ 2893 */
2894void 2894void
2895global_clean_up(void) 2895global_clean_up(void)
2896{ 2896{
2897 2897
2898 while (dcs->d_next != NULL) 2898 while (dcs->d_next != NULL)
2899 end_declaration_level(); 2899 end_declaration_level();
2900 2900
2901 cleanup(); 2901 cleanup();
2902 block_level = 0; 2902 block_level = 0;
2903 mem_block_level = 0; 2903 mem_block_level = 0;
2904 2904
2905 /* 2905 /*
2906 * remove all information about pending lint directives without 2906 * remove all information about pending lint directives without
2907 * warnings. 2907 * warnings.
2908 */ 2908 */
2909 global_clean_up_decl(true); 2909 global_clean_up_decl(true);
2910} 2910}
2911 2911
2912/* 2912/*
2913 * Process an abstract type declaration 2913 * Process an abstract type declaration
2914 */ 2914 */
2915sym_t * 2915sym_t *
2916declare_1_abstract(sym_t *sym) 2916declare_1_abstract(sym_t *sym)
2917{ 2917{
2918 2918
2919 check_function_definition(sym, true); 2919 check_function_definition(sym, true);
2920 check_type(sym); 2920 check_type(sym);
2921 return sym; 2921 return sym;
2922} 2922}
2923 2923
2924/* 2924/*
2925 * Checks size after declarations of variables and their initialization. 2925 * Checks size after declarations of variables and their initialization.
2926 */ 2926 */
2927void 2927void
2928check_size(sym_t *dsym) 2928check_size(sym_t *dsym)
2929{ 2929{
2930 2930
2931 if (dsym->s_def != DEF) 2931 if (dsym->s_def != DEF)
2932 return; 2932 return;
2933 if (dsym->s_scl == TYPEDEF) 2933 if (dsym->s_scl == TYPEDEF)
2934 return; 2934 return;
2935 if (dsym->s_type->t_tspec == FUNC) 2935 if (dsym->s_type->t_tspec == FUNC)
2936 return; 2936 return;
2937 2937
2938 if (length(dsym->s_type, dsym->s_name) == 0 && 2938 if (length(dsym->s_type, dsym->s_name) == 0 &&
2939 dsym->s_type->t_tspec == ARRAY && dsym->s_type->t_dim == 0) { 2939 dsym->s_type->t_tspec == ARRAY && dsym->s_type->t_dim == 0) {
2940 if (tflag) { 2940 if (tflag) {
2941 /* empty array declaration: %s */ 2941 /* empty array declaration: %s */
2942 warning(190, dsym->s_name); 2942 warning(190, dsym->s_name);
2943 } else { 2943 } else {
2944 /* empty array declaration: %s */ 2944 /* empty array declaration: %s */
2945 error(190, dsym->s_name); 2945 error(190, dsym->s_name);
2946 } 2946 }
2947 } 2947 }
2948} 2948}
2949 2949
2950/* 2950/*
2951 * Mark an object as set if it is not already 2951 * Mark an object as set if it is not already
2952 */ 2952 */
2953void 2953void
2954mark_as_set(sym_t *sym) 2954mark_as_set(sym_t *sym)
2955{ 2955{
2956 2956
2957 if (!sym->s_set) { 2957 if (!sym->s_set) {
2958 sym->s_set = true; 2958 sym->s_set = true;
2959 UNIQUE_CURR_POS(sym->s_set_pos); 2959 UNIQUE_CURR_POS(sym->s_set_pos);
2960 } 2960 }
2961} 2961}
2962 2962
2963/* 2963/*
2964 * Mark an object as used if it is not already 2964 * Mark an object as used if it is not already
2965 */ 2965 */
2966void 2966void
2967mark_as_used(sym_t *sym, bool fcall, bool szof) 2967mark_as_used(sym_t *sym, bool fcall, bool szof)
2968{ 2968{
2969 2969
2970 if (!sym->s_used) { 2970 if (!sym->s_used) {
2971 sym->s_used = true; 2971 sym->s_used = true;
2972 UNIQUE_CURR_POS(sym->s_use_pos); 2972 UNIQUE_CURR_POS(sym->s_use_pos);
2973 } 2973 }
2974 /* 2974 /*
2975 * for function calls another record is written 2975 * for function calls another record is written
2976 * 2976 *
2977 * XXX Should symbols used in sizeof() be treated as used or not? 2977 * XXX Should symbols used in sizeof() be treated as used or not?
2978 * Probably not, because there is no sense to declare an 2978 * Probably not, because there is no sense to declare an
2979 * external variable only to get their size. 2979 * external variable only to get their size.
2980 */ 2980 */
2981 if (!fcall && !szof && sym->s_kind == FVFT && sym->s_scl == EXTERN) 2981 if (!fcall && !szof && sym->s_kind == FVFT && sym->s_scl == EXTERN)
2982 outusg(sym); 2982 outusg(sym);
2983} 2983}
2984 2984
2985/* 2985/*
2986 * Prints warnings for a list of variables and labels (concatenated 2986 * Prints warnings for a list of variables and labels (concatenated
2987 * with s_dlnxt) if these are not used or only set. 2987 * with s_level_next) if these are not used or only set.
2988 */ 2988 */
2989void 2989void
2990check_usage(dinfo_t *di) 2990check_usage(dinfo_t *di)
2991{ 2991{
2992 sym_t *sym; 2992 sym_t *sym;
2993 int mklwarn; 2993 int mklwarn;
2994 2994
2995 /* for this warning LINTED has no effect */ 2995 /* for this warning LINTED has no effect */
2996 mklwarn = lwarn; 2996 mklwarn = lwarn;
2997 lwarn = LWARN_ALL; 2997 lwarn = LWARN_ALL;
2998 2998
2999 debug_step("begin lwarn %d", lwarn); 2999 debug_step("begin lwarn %d", lwarn);
3000 for (sym = di->d_dlsyms; sym != NULL; sym = sym->s_dlnxt) 3000 for (sym = di->d_dlsyms; sym != NULL; sym = sym->s_level_next)
3001 check_usage_sym(di->d_asm, sym); 3001 check_usage_sym(di->d_asm, sym);
3002 lwarn = mklwarn; 3002 lwarn = mklwarn;
3003 debug_step("end lwarn %d", lwarn); 3003 debug_step("end lwarn %d", lwarn);
3004} 3004}
3005 3005
3006/* 3006/*
3007 * Prints a warning for a single variable or label if it is not used or 3007 * Prints a warning for a single variable or label if it is not used or
3008 * only set. 3008 * only set.
3009 */ 3009 */
3010void 3010void
3011check_usage_sym(bool novar, sym_t *sym) 3011check_usage_sym(bool novar, sym_t *sym)
3012{ 3012{
3013 3013
3014 if (sym->s_block_level == -1) 3014 if (sym->s_block_level == -1)
3015 return; 3015 return;
3016 3016
3017 if (sym->s_kind == FVFT && sym->s_arg) 3017 if (sym->s_kind == FVFT && sym->s_arg)
3018 check_argument_usage(novar, sym); 3018 check_argument_usage(novar, sym);
3019 else if (sym->s_kind == FVFT) 3019 else if (sym->s_kind == FVFT)
3020 check_variable_usage(novar, sym); 3020 check_variable_usage(novar, sym);
3021 else if (sym->s_kind == FLABEL) 3021 else if (sym->s_kind == FLABEL)
3022 check_label_usage(sym); 3022 check_label_usage(sym);
3023 else if (sym->s_kind == FTAG) 3023 else if (sym->s_kind == FTAG)
3024 check_tag_usage(sym); 3024 check_tag_usage(sym);
3025} 3025}
3026 3026
3027static void 3027static void
3028check_argument_usage(bool novar, sym_t *arg) 3028check_argument_usage(bool novar, sym_t *arg)
3029{ 3029{
3030 3030
3031 lint_assert(arg->s_set); 3031 lint_assert(arg->s_set);
3032 3032
3033 if (novar) 3033 if (novar)
3034 return; 3034 return;
3035 3035
3036 if (!arg->s_used && vflag) { 3036 if (!arg->s_used && vflag) {
3037 /* argument '%s' unused in function '%s' */ 3037 /* argument '%s' unused in function '%s' */
3038 warning_at(231, &arg->s_def_pos, arg->s_name, funcsym->s_name); 3038 warning_at(231, &arg->s_def_pos, arg->s_name, funcsym->s_name);
3039 } 3039 }
3040} 3040}
3041 3041
3042static void 3042static void
3043check_variable_usage(bool novar, sym_t *sym) 3043check_variable_usage(bool novar, sym_t *sym)
3044{ 3044{
3045 scl_t sc; 3045 scl_t sc;
3046 sym_t *xsym; 3046 sym_t *xsym;
3047 3047
3048 lint_assert(block_level != 0); 3048 lint_assert(block_level != 0);
3049 3049
3050 /* example at file scope: int c = ({ return 3; }); */ 3050 /* example at file scope: int c = ({ return 3; }); */
3051 if (sym->s_block_level == 0 && ch_isdigit(sym->s_name[0])) 3051 if (sym->s_block_level == 0 && ch_isdigit(sym->s_name[0]))
3052 return; 3052 return;
3053 3053
3054 /* errors in expressions easily cause lots of these warnings */ 3054 /* errors in expressions easily cause lots of these warnings */
3055 if (nerr != 0) 3055 if (nerr != 0)
3056 return; 3056 return;
3057 3057
3058 /* 3058 /*
3059 * XXX Only variables are checked, although types should 3059 * XXX Only variables are checked, although types should
3060 * probably also be checked 3060 * probably also be checked
3061 */ 3061 */
3062 if ((sc = sym->s_scl) != EXTERN && sc != STATIC && 3062 if ((sc = sym->s_scl) != EXTERN && sc != STATIC &&
3063 sc != AUTO && sc != REG) { 3063 sc != AUTO && sc != REG) {
3064 return; 3064 return;
3065 } 3065 }
3066 3066
3067 if (novar) 3067 if (novar)
3068 return; 3068 return;
3069 3069
3070 if (sc == EXTERN) { 3070 if (sc == EXTERN) {
3071 if (!sym->s_used && !sym->s_set) { 3071 if (!sym->s_used && !sym->s_set) {
3072 /* '%s' unused in function '%s' */ 3072 /* '%s' unused in function '%s' */
3073 warning_at(192, &sym->s_def_pos, 3073 warning_at(192, &sym->s_def_pos,
3074 sym->s_name, funcsym->s_name); 3074 sym->s_name, funcsym->s_name);
3075 } 3075 }
3076 } else { 3076 } else {
3077 if (sym->s_set && !sym->s_used) { 3077 if (sym->s_set && !sym->s_used) {
3078 /* '%s' set but not used in function '%s' */ 3078 /* '%s' set but not used in function '%s' */
3079 warning_at(191, &sym->s_set_pos, 3079 warning_at(191, &sym->s_set_pos,
3080 sym->s_name, funcsym->s_name); 3080 sym->s_name, funcsym->s_name);
3081 } else if (!sym->s_used) { 3081 } else if (!sym->s_used) {
3082 /* '%s' unused in function '%s' */ 3082 /* '%s' unused in function '%s' */
3083 warning_at(192, &sym->s_def_pos, 3083 warning_at(192, &sym->s_def_pos,
3084 sym->s_name, funcsym->s_name); 3084 sym->s_name, funcsym->s_name);
3085 } 3085 }
3086 } 3086 }
3087 3087
3088 if (sc == EXTERN) { 3088 if (sc == EXTERN) {
3089 /* 3089 /*
3090 * information about usage is taken over into the symbol 3090 * information about usage is taken over into the symbol
3091 * table entry at level 0 if the symbol was locally declared 3091 * table entry at level 0 if the symbol was locally declared
3092 * as an external symbol. 3092 * as an external symbol.
3093 * 3093 *
3094 * XXX This is wrong for symbols declared static at level 0 3094 * XXX This is wrong for symbols declared static at level 0
3095 * if the usage information stems from sizeof(). This is 3095 * if the usage information stems from sizeof(). This is
3096 * because symbols at level 0 only used in sizeof() are 3096 * because symbols at level 0 only used in sizeof() are
3097 * considered to not be used. 3097 * considered to not be used.
3098 */ 3098 */
3099 if ((xsym = sym->s_ext_sym) != NULL) { 3099 if ((xsym = sym->s_ext_sym) != NULL) {
3100 if (sym->s_used && !xsym->s_used) { 3100 if (sym->s_used && !xsym->s_used) {
3101 xsym->s_used = true; 3101 xsym->s_used = true;
3102 xsym->s_use_pos = sym->s_use_pos; 3102 xsym->s_use_pos = sym->s_use_pos;
3103 } 3103 }
3104 if (sym->s_set && !xsym->s_set) { 3104 if (sym->s_set && !xsym->s_set) {
3105 xsym->s_set = true; 3105 xsym->s_set = true;
3106 xsym->s_set_pos = sym->s_set_pos; 3106 xsym->s_set_pos = sym->s_set_pos;
3107 } 3107 }
3108 } 3108 }
3109 } 3109 }
3110} 3110}
3111 3111
3112static void 3112static void
3113check_label_usage(sym_t *lab) 3113check_label_usage(sym_t *lab)
3114{ 3114{
3115 3115
3116 lint_assert(block_level == 1); 3116 lint_assert(block_level == 1);
3117 lint_assert(lab->s_block_level == 1); 3117 lint_assert(lab->s_block_level == 1);
3118 3118
3119 if (lab->s_set && !lab->s_used) { 3119 if (lab->s_set && !lab->s_used) {
3120 /* label '%s' unused in function '%s' */ 3120 /* label '%s' unused in function '%s' */
3121 warning_at(232, &lab->s_set_pos, lab->s_name, funcsym->s_name); 3121 warning_at(232, &lab->s_set_pos, lab->s_name, funcsym->s_name);
3122 } else if (!lab->s_set) { 3122 } else if (!lab->s_set) {
3123 /* undefined label '%s' */ 3123 /* undefined label '%s' */
3124 warning_at(23, &lab->s_use_pos, lab->s_name); 3124 warning_at(23, &lab->s_use_pos, lab->s_name);
3125 } 3125 }
3126} 3126}
3127 3127
3128static void 3128static void
3129check_tag_usage(sym_t *sym) 3129check_tag_usage(sym_t *sym)
3130{ 3130{
3131 3131
3132 if (!is_incomplete(sym->s_type)) 3132 if (!is_incomplete(sym->s_type))
3133 return; 3133 return;
3134 3134
3135 /* always complain about incomplete tags declared inside blocks */ 3135 /* always complain about incomplete tags declared inside blocks */
3136 if (!zflag || dcs->d_ctx != EXTERN) 3136 if (!zflag || dcs->d_ctx != EXTERN)
3137 return; 3137 return;
3138 3138
3139 switch (sym->s_type->t_tspec) { 3139 switch (sym->s_type->t_tspec) {
3140 case STRUCT: 3140 case STRUCT:
3141 /* struct %s never defined */ 3141 /* struct %s never defined */
3142 warning_at(233, &sym->s_def_pos, sym->s_name); 3142 warning_at(233, &sym->s_def_pos, sym->s_name);
3143 break; 3143 break;
3144 case UNION: 3144 case UNION:
3145 /* union %s never defined */ 3145 /* union %s never defined */
3146 warning_at(234, &sym->s_def_pos, sym->s_name); 3146 warning_at(234, &sym->s_def_pos, sym->s_name);
3147 break; 3147 break;
3148 case ENUM: 3148 case ENUM:
3149 /* enum %s never defined */ 3149 /* enum %s never defined */
3150 warning_at(235, &sym->s_def_pos, sym->s_name); 3150 warning_at(235, &sym->s_def_pos, sym->s_name);
3151 break; 3151 break;
3152 default: 3152 default:
3153 lint_assert(/*CONSTCOND*/false); 3153 lint_assert(/*CONSTCOND*/false);
3154 } 3154 }
3155} 3155}
3156 3156
3157/* 3157/*
3158 * Called after the entire translation unit has been parsed. 3158 * Called after the entire translation unit has been parsed.
3159 * Changes tentative definitions into definitions. 3159 * Changes tentative definitions into definitions.
3160 * Performs some tests on global symbols. Detected problems are: 3160 * Performs some tests on global symbols. Detected problems are:
3161 * - defined variables of incomplete type 3161 * - defined variables of incomplete type
3162 * - constant variables which are not initialized 3162 * - constant variables which are not initialized
3163 * - static symbols which are never used 3163 * - static symbols which are never used
3164 */ 3164 */
3165void 3165void
3166check_global_symbols(void) 3166check_global_symbols(void)
3167{ 3167{
3168 sym_t *sym; 3168 sym_t *sym;
3169 3169
3170 if (block_level != 0 || dcs->d_next != NULL) 3170 if (block_level != 0 || dcs->d_next != NULL)
3171 norecover(); 3171 norecover();
3172 3172
3173 for (sym = dcs->d_dlsyms; sym != NULL; sym = sym->s_dlnxt) { 3173 for (sym = dcs->d_dlsyms; sym != NULL; sym = sym->s_level_next) {
3174 if (sym->s_block_level == -1) 3174 if (sym->s_block_level == -1)
3175 continue; 3175 continue;
3176 if (sym->s_kind == FVFT) { 3176 if (sym->s_kind == FVFT) {
3177 check_global_variable(sym); 3177 check_global_variable(sym);
3178 } else if (sym->s_kind == FTAG) { 3178 } else if (sym->s_kind == FTAG) {
3179 check_tag_usage(sym); 3179 check_tag_usage(sym);
3180 } else { 3180 } else {
3181 lint_assert(sym->s_kind == FMEMBER); 3181 lint_assert(sym->s_kind == FMEMBER);
3182 } 3182 }
3183 } 3183 }
3184} 3184}
3185 3185
3186static void 3186static void
3187check_unused_static_global_variable(const sym_t *sym) 3187check_unused_static_global_variable(const sym_t *sym)
3188{ 3188{
3189 if (sym->s_type->t_tspec == FUNC) { 3189 if (sym->s_type->t_tspec == FUNC) {
3190 if (sym->s_def == DEF) { 3190 if (sym->s_def == DEF) {
3191 if (!sym->s_inline) 3191 if (!sym->s_inline)
3192 /* static function %s unused */ 3192 /* static function %s unused */
3193 warning_at(236, &sym->s_def_pos, sym->s_name); 3193 warning_at(236, &sym->s_def_pos, sym->s_name);
3194 } else { 3194 } else {
3195 /* static function %s declared but not defined */ 3195 /* static function %s declared but not defined */
3196 warning_at(290, &sym->s_def_pos, sym->s_name); 3196 warning_at(290, &sym->s_def_pos, sym->s_name);
3197 } 3197 }
3198 } else if (!sym->s_set) { 3198 } else if (!sym->s_set) {
3199 /* static variable %s unused */ 3199 /* static variable %s unused */
3200 warning_at(226, &sym->s_def_pos, sym->s_name); 3200 warning_at(226, &sym->s_def_pos, sym->s_name);
3201 } else { 3201 } else {
3202 /* static variable %s set but not used */ 3202 /* static variable %s set but not used */
3203 warning_at(307, &sym->s_def_pos, sym->s_name); 3203 warning_at(307, &sym->s_def_pos, sym->s_name);
3204 } 3204 }
3205} 3205}
3206 3206
3207static void 3207static void
3208check_static_global_variable(const sym_t *sym) 3208check_static_global_variable(const sym_t *sym)
3209{ 3209{
3210 if (sym->s_type->t_tspec == FUNC && sym->s_used && sym->s_def != DEF) { 3210 if (sym->s_type->t_tspec == FUNC && sym->s_used && sym->s_def != DEF) {
3211 /* static function called but not defined: %s() */ 3211 /* static function called but not defined: %s() */
3212 error_at(225, &sym->s_use_pos, sym->s_name); 3212 error_at(225, &sym->s_use_pos, sym->s_name);
3213 } 3213 }
3214 3214
3215 if (!sym->s_used) 3215 if (!sym->s_used)
3216 check_unused_static_global_variable(sym); 3216 check_unused_static_global_variable(sym);
3217 3217
3218 if (!tflag && sym->s_def == TDEF && sym->s_type->t_const) { 3218 if (!tflag && sym->s_def == TDEF && sym->s_type->t_const) {
3219 /* const object %s should have initializer */ 3219 /* const object %s should have initializer */
3220 warning_at(227, &sym->s_def_pos, sym->s_name); 3220 warning_at(227, &sym->s_def_pos, sym->s_name);
3221 } 3221 }
3222} 3222}
3223 3223
3224static void 3224static void
3225check_global_variable(const sym_t *sym) 3225check_global_variable(const sym_t *sym)
3226{ 3226{
3227 3227
3228 if (sym->s_scl == TYPEDEF || sym->s_scl == CTCONST) 3228 if (sym->s_scl == TYPEDEF || sym->s_scl == CTCONST)
3229 return; 3229 return;
3230 3230
3231 if (sym->s_scl == NOSCL) 3231 if (sym->s_scl == NOSCL)
3232 return; /* May be caused by a syntax error. */ 3232 return; /* May be caused by a syntax error. */
3233 3233
3234 lint_assert(sym->s_scl == EXTERN || sym->s_scl == STATIC); 3234 lint_assert(sym->s_scl == EXTERN || sym->s_scl == STATIC);
3235 3235
3236 check_global_variable_size(sym); 3236 check_global_variable_size(sym);
3237 3237
3238 if (sym->s_scl == STATIC) 3238 if (sym->s_scl == STATIC)
3239 check_static_global_variable(sym); 3239 check_static_global_variable(sym);
3240} 3240}
3241 3241
3242static void 3242static void
3243check_global_variable_size(const sym_t *sym) 3243check_global_variable_size(const sym_t *sym)
3244{ 3244{
3245 pos_t cpos; 3245 pos_t cpos;
3246 int length_in_bits; 3246 int length_in_bits;
3247 3247
3248 if (sym->s_def != TDEF) 3248 if (sym->s_def != TDEF)
3249 return; 3249 return;
3250 if (sym->s_type->t_tspec == FUNC) 3250 if (sym->s_type->t_tspec == FUNC)
3251 /* 3251 /*
3252 * this can happen if a syntax error occurred after a 3252 * this can happen if a syntax error occurred after a
3253 * function declaration 3253 * function declaration
3254 */ 3254 */
3255 return; 3255 return;
3256 if (sym->s_def == TDEF && sym->s_type->t_tspec == VOID) 3256 if (sym->s_def == TDEF && sym->s_type->t_tspec == VOID)
3257 return; /* prevent internal error in length() below */ 3257 return; /* prevent internal error in length() below */
3258 3258
3259 cpos = curr_pos; 3259 cpos = curr_pos;
3260 curr_pos = sym->s_def_pos; 3260 curr_pos = sym->s_def_pos;
3261 length_in_bits = length(sym->s_type, sym->s_name); 3261 length_in_bits = length(sym->s_type, sym->s_name);
3262 curr_pos = cpos; 3262 curr_pos = cpos;
3263 3263
3264 if (length_in_bits == 0 && 3264 if (length_in_bits == 0 &&
3265 sym->s_type->t_tspec == ARRAY && sym->s_type->t_dim == 0) { 3265 sym->s_type->t_tspec == ARRAY && sym->s_type->t_dim == 0) {
3266 if (tflag || (sym->s_scl == EXTERN && !sflag)) { 3266 if (tflag || (sym->s_scl == EXTERN && !sflag)) {
3267 /* empty array declaration: %s */ 3267 /* empty array declaration: %s */
3268 warning_at(190, &sym->s_def_pos, sym->s_name); 3268 warning_at(190, &sym->s_def_pos, sym->s_name);
3269 } else { 3269 } else {
3270 /* empty array declaration: %s */ 3270 /* empty array declaration: %s */
3271 error_at(190, &sym->s_def_pos, sym->s_name); 3271 error_at(190, &sym->s_def_pos, sym->s_name);
3272 } 3272 }
3273 } 3273 }
3274} 3274}
3275 3275
3276/* 3276/*
3277 * Prints information about location of previous definition/declaration. 3277 * Prints information about location of previous definition/declaration.
3278 */ 3278 */
3279void 3279void
3280print_previous_declaration(int msg, const sym_t *psym) 3280print_previous_declaration(int msg, const sym_t *psym)
3281{ 3281{
3282 3282
3283 if (!rflag) 3283 if (!rflag)
3284 return; 3284 return;
3285 3285
3286 if (msg != -1) { 3286 if (msg != -1) {
3287 (message_at)(msg, &psym->s_def_pos); 3287 (message_at)(msg, &psym->s_def_pos);
3288 } else if (psym->s_def == DEF || psym->s_def == TDEF) { 3288 } else if (psym->s_def == DEF || psym->s_def == TDEF) {
3289 /* previous definition of %s */ 3289 /* previous definition of %s */
3290 message_at(261, &psym->s_def_pos, psym->s_name); 3290 message_at(261, &psym->s_def_pos, psym->s_name);
3291 } else { 3291 } else {
3292 /* previous declaration of %s */ 3292 /* previous declaration of %s */
3293 message_at(260, &psym->s_def_pos, psym->s_name); 3293 message_at(260, &psym->s_def_pos, psym->s_name);
3294 } 3294 }
3295} 3295}
3296 3296
3297/* 3297/*
3298 * Gets a node for a constant and returns the value of this constant 3298 * Gets a node for a constant and returns the value of this constant
3299 * as integer. 3299 * as integer.
3300 * 3300 *
3301 * If the node is not constant or too large for int or of type float, 3301 * If the node is not constant or too large for int or of type float,
3302 * a warning will be printed. 3302 * a warning will be printed.
3303 * 3303 *
3304 * to_int_constant() should be used only inside declarations. If it is used in 3304 * to_int_constant() should be used only inside declarations. If it is used in
3305 * expressions, it frees the memory used for the expression. 3305 * expressions, it frees the memory used for the expression.
3306 */ 3306 */
3307int 3307int
3308to_int_constant(tnode_t *tn, bool required) 3308to_int_constant(tnode_t *tn, bool required)
3309{ 3309{
3310 int i; 3310 int i;
3311 tspec_t t; 3311 tspec_t t;
3312 val_t *v; 3312 val_t *v;
3313 3313
3314 v = constant(tn, required); 3314 v = constant(tn, required);
3315 3315
3316 if (tn == NULL) { 3316 if (tn == NULL) {
3317 i = 1; 3317 i = 1;
3318 goto done; 3318 goto done;
3319 } 3319 }
3320 3320
3321 /* 3321 /*
3322 * Abstract declarations are used inside expression. To free 3322 * Abstract declarations are used inside expression. To free
3323 * the memory would be a fatal error. 3323 * the memory would be a fatal error.
3324 * We don't free blocks that are inside casts because these 3324 * We don't free blocks that are inside casts because these
3325 * will be used later to match types. 3325 * will be used later to match types.
3326 */ 3326 */
3327 if (tn->tn_op != CON && dcs->d_ctx != ABSTRACT) 3327 if (tn->tn_op != CON && dcs->d_ctx != ABSTRACT)
3328 expr_free_all(); 3328 expr_free_all();
3329 3329
3330 if ((t = v->v_tspec) == FLOAT || t == DOUBLE || t == LDOUBLE) { 3330 if ((t = v->v_tspec) == FLOAT || t == DOUBLE || t == LDOUBLE) {
3331 i = (int)v->v_ldbl; 3331 i = (int)v->v_ldbl;
3332 /* integral constant expression expected */ 3332 /* integral constant expression expected */
3333 error(55); 3333 error(55);
3334 } else { 3334 } else {
3335 i = (int)v->v_quad; 3335 i = (int)v->v_quad;
3336 if (is_uinteger(t)) { 3336 if (is_uinteger(t)) {
3337 if ((uint64_t)v->v_quad > (uint64_t)TARG_INT_MAX) { 3337 if ((uint64_t)v->v_quad > (uint64_t)TARG_INT_MAX) {
3338 /* integral constant too large */ 3338 /* integral constant too large */
3339 warning(56); 3339 warning(56);
3340 } 3340 }
3341 } else { 3341 } else {
3342 if (v->v_quad > (int64_t)TARG_INT_MAX || 3342 if (v->v_quad > (int64_t)TARG_INT_MAX ||
3343 v->v_quad < (int64_t)TARG_INT_MIN) { 3343 v->v_quad < (int64_t)TARG_INT_MIN) {
3344 /* integral constant too large */ 3344 /* integral constant too large */
3345 warning(56); 3345 warning(56);
3346 } 3346 }
3347 } 3347 }
3348 } 3348 }
3349 3349
3350done: 3350done:
3351 free(v); 3351 free(v);
3352 return i; 3352 return i;
3353} 3353}

cvs diff -r1.127 -r1.128 src/usr.bin/xlint/lint1/func.c (switch to unified diff)

--- src/usr.bin/xlint/lint1/func.c 2022/02/27 08:31:26 1.127
+++ src/usr.bin/xlint/lint1/func.c 2022/02/27 10:44:45 1.128
@@ -1,1237 +1,1238 @@ @@ -1,1237 +1,1238 @@
1/* $NetBSD: func.c,v 1.127 2022/02/27 08:31:26 rillig Exp $ */ 1/* $NetBSD: func.c,v 1.128 2022/02/27 10:44:45 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: func.c,v 1.127 2022/02/27 08:31:26 rillig Exp $"); 40__RCSID("$NetBSD: func.c,v 1.128 2022/02/27 10:44:45 rillig Exp $");
41#endif 41#endif
42 42
43#include <stdlib.h> 43#include <stdlib.h>
44#include <string.h> 44#include <string.h>
45 45
46#include "lint1.h" 46#include "lint1.h"
47#include "cgram.h" 47#include "cgram.h"
48 48
49/* 49/*
50 * Contains a pointer to the symbol table entry of the current function 50 * Contains a pointer to the symbol table entry of the current function
51 * definition. 51 * definition.
52 */ 52 */
53sym_t *funcsym; 53sym_t *funcsym;
54 54
55/* Is set as long as a statement can be reached. Must be set at level 0. */ 55/* Is set as long as a statement can be reached. Must be set at level 0. */
56bool reached = true; 56bool reached = true;
57 57
58/* 58/*
59 * Is true by default, can be cleared by NOTREACHED. 59 * Is true by default, can be cleared by NOTREACHED.
60 * Is reset to true whenever 'reached' changes. 60 * Is reset to true whenever 'reached' changes.
61 */ 61 */
62bool warn_about_unreachable; 62bool warn_about_unreachable;
63 63
64/* 64/*
65 * In conjunction with 'reached', controls printing of "fallthrough on ..." 65 * In conjunction with 'reached', controls printing of "fallthrough on ..."
66 * warnings. 66 * warnings.
67 * Reset by each statement and set by FALLTHROUGH, switch (switch1()) 67 * Reset by each statement and set by FALLTHROUGH, switch (switch1())
68 * and case (label()). 68 * and case (label()).
69 * 69 *
70 * Control statements if, for, while and switch do not reset seen_fallthrough 70 * Control statements if, for, while and switch do not reset seen_fallthrough
71 * because this must be done by the controlled statement. At least for if this 71 * because this must be done by the controlled statement. At least for if this
72 * is important because ** FALLTHROUGH ** after "if (expr) statement" is 72 * is important because ** FALLTHROUGH ** after "if (expr) statement" is
73 * evaluated before the following token, which causes reduction of above. 73 * evaluated before the following token, which causes reduction of above.
74 * This means that ** FALLTHROUGH ** after "if ..." would always be ignored. 74 * This means that ** FALLTHROUGH ** after "if ..." would always be ignored.
75 */ 75 */
76bool seen_fallthrough; 76bool seen_fallthrough;
77 77
78/* The innermost control statement */ 78/* The innermost control statement */
79control_statement *cstmt; 79control_statement *cstmt;
80 80
81/* 81/*
82 * Number of arguments which will be checked for usage in following 82 * Number of arguments which will be checked for usage in following
83 * function definition. -1 stands for all arguments. 83 * function definition. -1 stands for all arguments.
84 * 84 *
85 * The position of the last ARGSUSED comment is stored in argsused_pos. 85 * The position of the last ARGSUSED comment is stored in argsused_pos.
86 */ 86 */
87int nargusg = -1; 87int nargusg = -1;
88pos_t argsused_pos; 88pos_t argsused_pos;
89 89
90/* 90/*
91 * Number of arguments of the following function definition whose types 91 * Number of arguments of the following function definition whose types
92 * shall be checked by lint2. -1 stands for all arguments. 92 * shall be checked by lint2. -1 stands for all arguments.
93 * 93 *
94 * The position of the last VARARGS comment is stored in vapos. 94 * The position of the last VARARGS comment is stored in vapos.
95 */ 95 */
96int nvararg = -1; 96int nvararg = -1;
97pos_t vapos; 97pos_t vapos;
98 98
99/* 99/*
100 * Both printflike_argnum and scanflike_argnum contain the 1-based number 100 * Both printflike_argnum and scanflike_argnum contain the 1-based number
101 * of the string argument which shall be used to check the types of remaining 101 * of the string argument which shall be used to check the types of remaining
102 * arguments (for PRINTFLIKE and SCANFLIKE). 102 * arguments (for PRINTFLIKE and SCANFLIKE).
103 * 103 *
104 * printflike_pos and scanflike_pos are the positions of the last PRINTFLIKE 104 * printflike_pos and scanflike_pos are the positions of the last PRINTFLIKE
105 * or SCANFLIKE comment. 105 * or SCANFLIKE comment.
106 */ 106 */
107int printflike_argnum = -1; 107int printflike_argnum = -1;
108int scanflike_argnum = -1; 108int scanflike_argnum = -1;
109pos_t printflike_pos; 109pos_t printflike_pos;
110pos_t scanflike_pos; 110pos_t scanflike_pos;
111 111
112/* 112/*
113 * If both plibflg and llibflg are set, prototypes are written as function 113 * If both plibflg and llibflg are set, prototypes are written as function
114 * definitions to the output file. 114 * definitions to the output file.
115 */ 115 */
116bool plibflg; 116bool plibflg;
117 117
118/* 118/*
119 * True means that no warnings about constants in conditional 119 * True means that no warnings about constants in conditional
120 * context are printed. 120 * context are printed.
121 */ 121 */
122bool constcond_flag; 122bool constcond_flag;
123 123
124/* 124/*
125 * llibflg is set if a lint library shall be created. The effect of 125 * llibflg is set if a lint library shall be created. The effect of
126 * llibflg is that all defined symbols are treated as used. 126 * llibflg is that all defined symbols are treated as used.
127 * (The LINTLIBRARY comment also resets vflag.) 127 * (The LINTLIBRARY comment also resets vflag.)
128 */ 128 */
129bool llibflg; 129bool llibflg;
130 130
131/* 131/*
132 * Nonzero if warnings are suppressed by a LINTED directive 132 * Nonzero if warnings are suppressed by a LINTED directive
133 * LWARN_BAD: error 133 * LWARN_BAD: error
134 * LWARN_ALL: warnings on 134 * LWARN_ALL: warnings on
135 * LWARN_NONE: all warnings ignored 135 * LWARN_NONE: all warnings ignored
136 * 0..n: warning n ignored 136 * 0..n: warning n ignored
137 */ 137 */
138int lwarn = LWARN_ALL; 138int lwarn = LWARN_ALL;
139 139
140/* 140/*
141 * Whether bitfield type errors are suppressed by a BITFIELDTYPE 141 * Whether bitfield type errors are suppressed by a BITFIELDTYPE
142 * directive. 142 * directive.
143 */ 143 */
144bool bitfieldtype_ok; 144bool bitfieldtype_ok;
145 145
146/* 146/*
147 * Whether complaints about use of "long long" are suppressed in 147 * Whether complaints about use of "long long" are suppressed in
148 * the next statement or declaration. 148 * the next statement or declaration.
149 */ 149 */
150bool quadflg; 150bool quadflg;
151 151
152/* 152/*
153 * Puts a new element at the top of the stack used for control statements. 153 * Puts a new element at the top of the stack used for control statements.
154 */ 154 */
155void 155void
156begin_control_statement(control_statement_kind kind) 156begin_control_statement(control_statement_kind kind)
157{ 157{
158 control_statement *cs; 158 control_statement *cs;
159 159
160 cs = xcalloc(1, sizeof(*cs)); 160 cs = xcalloc(1, sizeof(*cs));
161 cs->c_kind = kind; 161 cs->c_kind = kind;
162 cs->c_surrounding = cstmt; 162 cs->c_surrounding = cstmt;
163 cstmt = cs; 163 cstmt = cs;
164} 164}
165 165
166/* 166/*
167 * Removes the top element of the stack used for control statements. 167 * Removes the top element of the stack used for control statements.
168 */ 168 */
169void 169void
170end_control_statement(control_statement_kind kind) 170end_control_statement(control_statement_kind kind)
171{ 171{
172 control_statement *cs; 172 control_statement *cs;
173 case_label_t *cl, *next; 173 case_label_t *cl, *next;
174 174
175 lint_assert(cstmt != NULL); 175 lint_assert(cstmt != NULL);
176 176
177 while (cstmt->c_kind != kind) 177 while (cstmt->c_kind != kind)
178 cstmt = cstmt->c_surrounding; 178 cstmt = cstmt->c_surrounding;
179 179
180 cs = cstmt; 180 cs = cstmt;
181 cstmt = cs->c_surrounding; 181 cstmt = cs->c_surrounding;
182 182
183 for (cl = cs->c_case_labels; cl != NULL; cl = next) { 183 for (cl = cs->c_case_labels; cl != NULL; cl = next) {
184 next = cl->cl_next; 184 next = cl->cl_next;
185 free(cl); 185 free(cl);
186 } 186 }
187 187
188 free(cs->c_switch_type); 188 free(cs->c_switch_type);
189 free(cs); 189 free(cs);
190} 190}
191 191
192static void 192static void
193set_reached(bool new_reached) 193set_reached(bool new_reached)
194{ 194{
195 debug_step("%s -> %s", 195 debug_step("%s -> %s",
196 reached ? "reachable" : "unreachable", 196 reached ? "reachable" : "unreachable",
197 new_reached ? "reachable" : "unreachable"); 197 new_reached ? "reachable" : "unreachable");
198 reached = new_reached; 198 reached = new_reached;
199 warn_about_unreachable = true; 199 warn_about_unreachable = true;
200} 200}
201 201
202/* 202/*
203 * Prints a warning if a statement cannot be reached. 203 * Prints a warning if a statement cannot be reached.
204 */ 204 */
205void 205void
206check_statement_reachable(void) 206check_statement_reachable(void)
207{ 207{
208 if (!reached && warn_about_unreachable) { 208 if (!reached && warn_about_unreachable) {
209 /* statement not reached */ 209 /* statement not reached */
210 warning(193); 210 warning(193);
211 warn_about_unreachable = false; 211 warn_about_unreachable = false;
212 } 212 }
213} 213}
214 214
215/* 215/*
216 * Called after a function declaration which introduces a function definition 216 * Called after a function declaration which introduces a function definition
217 * and before an (optional) old style argument declaration list. 217 * and before an (optional) old style argument declaration list.
218 * 218 *
219 * Puts all symbols declared in the prototype or in an old style argument 219 * Puts all symbols declared in the prototype or in an old style argument
220 * list back to the symbol table. 220 * list back to the symbol table.
221 * 221 *
222 * Does the usual checking of storage class, type (return value), 222 * Does the usual checking of storage class, type (return value),
223 * redeclaration, etc. 223 * redeclaration, etc.
224 */ 224 */
225void 225void
226funcdef(sym_t *fsym) 226funcdef(sym_t *fsym)
227{ 227{
228 int n; 228 int n;
229 bool dowarn; 229 bool dowarn;
230 sym_t *arg, *sym, *rdsym; 230 sym_t *arg, *sym, *rdsym;
231 231
232 funcsym = fsym; 232 funcsym = fsym;
233 233
234 /* 234 /*
235 * Put all symbols declared in the argument list back to the 235 * Put all symbols declared in the argument list back to the
236 * symbol table. 236 * symbol table.
237 */ 237 */
238 for (sym = dcs->d_func_proto_syms; sym != NULL; sym = sym->s_dlnxt) { 238 for (sym = dcs->d_func_proto_syms; sym != NULL;
 239 sym = sym->s_level_next) {
239 if (sym->s_block_level != -1) { 240 if (sym->s_block_level != -1) {
240 lint_assert(sym->s_block_level == 1); 241 lint_assert(sym->s_block_level == 1);
241 inssym(1, sym); 242 inssym(1, sym);
242 } 243 }
243 } 244 }
244 245
245 /* 246 /*
246 * In old_style_function() we did not know whether it is an old 247 * In old_style_function() we did not know whether it is an old
247 * style function definition or only an old style declaration, 248 * style function definition or only an old style declaration,
248 * if there are no arguments inside the argument list ("f()"). 249 * if there are no arguments inside the argument list ("f()").
249 */ 250 */
250 if (!fsym->s_type->t_proto && fsym->s_args == NULL) 251 if (!fsym->s_type->t_proto && fsym->s_args == NULL)
251 fsym->s_osdef = true; 252 fsym->s_osdef = true;
252 253
253 check_type(fsym); 254 check_type(fsym);
254 255
255 /* 256 /*
256 * check_type() checks for almost all possible errors, but not for 257 * check_type() checks for almost all possible errors, but not for
257 * incomplete return values (these are allowed in declarations) 258 * incomplete return values (these are allowed in declarations)
258 */ 259 */
259 if (fsym->s_type->t_subt->t_tspec != VOID && 260 if (fsym->s_type->t_subt->t_tspec != VOID &&
260 is_incomplete(fsym->s_type->t_subt)) { 261 is_incomplete(fsym->s_type->t_subt)) {
261 /* cannot return incomplete type */ 262 /* cannot return incomplete type */
262 error(67); 263 error(67);
263 } 264 }
264 265
265 fsym->s_def = DEF; 266 fsym->s_def = DEF;
266 267
267 if (fsym->s_scl == TYPEDEF) { 268 if (fsym->s_scl == TYPEDEF) {
268 fsym->s_scl = EXTERN; 269 fsym->s_scl = EXTERN;
269 /* illegal storage class */ 270 /* illegal storage class */
270 error(8); 271 error(8);
271 } 272 }
272 273
273 if (dcs->d_inline) 274 if (dcs->d_inline)
274 fsym->s_inline = true; 275 fsym->s_inline = true;
275 276
276 /* 277 /*
277 * Arguments in new style function declarations need a name. 278 * Arguments in new style function declarations need a name.
278 * (void is already removed from the list of arguments) 279 * (void is already removed from the list of arguments)
279 */ 280 */
280 n = 1; 281 n = 1;
281 for (arg = fsym->s_type->t_args; arg != NULL; arg = arg->s_next) { 282 for (arg = fsym->s_type->t_args; arg != NULL; arg = arg->s_next) {
282 if (arg->s_scl == ABSTRACT) { 283 if (arg->s_scl == ABSTRACT) {
283 lint_assert(arg->s_name == unnamed); 284 lint_assert(arg->s_name == unnamed);
284 /* formal parameter lacks name: param #%d */ 285 /* formal parameter lacks name: param #%d */
285 error(59, n); 286 error(59, n);
286 } else { 287 } else {
287 lint_assert(arg->s_name != unnamed); 288 lint_assert(arg->s_name != unnamed);
288 } 289 }
289 n++; 290 n++;
290 } 291 }
291 292
292 /* 293 /*
293 * We must also remember the position. s_def_pos is overwritten 294 * We must also remember the position. s_def_pos is overwritten
294 * if this is an old style definition and we had already a 295 * if this is an old style definition and we had already a
295 * prototype. 296 * prototype.
296 */ 297 */
297 dcs->d_func_def_pos = fsym->s_def_pos; 298 dcs->d_func_def_pos = fsym->s_def_pos;
298 299
299 if ((rdsym = dcs->d_redeclared_symbol) != NULL) { 300 if ((rdsym = dcs->d_redeclared_symbol) != NULL) {
300 301
301 if (!check_redeclaration(fsym, (dowarn = false, &dowarn))) { 302 if (!check_redeclaration(fsym, (dowarn = false, &dowarn))) {
302 303
303 /* 304 /*
304 * Print nothing if the newly defined function 305 * Print nothing if the newly defined function
305 * is defined in old style. A better warning will 306 * is defined in old style. A better warning will
306 * be printed in check_func_lint_directives(). 307 * be printed in check_func_lint_directives().
307 */ 308 */
308 if (dowarn && !fsym->s_osdef) { 309 if (dowarn && !fsym->s_osdef) {
309 if (sflag) 310 if (sflag)
310 /* redeclaration of %s */ 311 /* redeclaration of %s */
311 error(27, fsym->s_name); 312 error(27, fsym->s_name);
312 else 313 else
313 /* redeclaration of %s */ 314 /* redeclaration of %s */
314 warning(27, fsym->s_name); 315 warning(27, fsym->s_name);
315 print_previous_declaration(-1, rdsym); 316 print_previous_declaration(-1, rdsym);
316 } 317 }
317 318
318 copy_usage_info(fsym, rdsym); 319 copy_usage_info(fsym, rdsym);
319 320
320 /* 321 /*
321 * If the old symbol was a prototype and the new 322 * If the old symbol was a prototype and the new
322 * one is none, overtake the position of the 323 * one is none, overtake the position of the
323 * declaration of the prototype. 324 * declaration of the prototype.
324 */ 325 */
325 if (fsym->s_osdef && rdsym->s_type->t_proto) 326 if (fsym->s_osdef && rdsym->s_type->t_proto)
326 fsym->s_def_pos = rdsym->s_def_pos; 327 fsym->s_def_pos = rdsym->s_def_pos;
327 328
328 complete_type(fsym, rdsym); 329 complete_type(fsym, rdsym);
329 330
330 if (rdsym->s_inline) 331 if (rdsym->s_inline)
331 fsym->s_inline = true; 332 fsym->s_inline = true;
332 333
333 } 334 }
334 335
335 /* remove the old symbol from the symbol table */ 336 /* remove the old symbol from the symbol table */
336 rmsym(rdsym); 337 rmsym(rdsym);
337 338
338 } 339 }
339 340
340 if (fsym->s_osdef && !fsym->s_type->t_proto) { 341 if (fsym->s_osdef && !fsym->s_type->t_proto) {
341 if (sflag && hflag && strcmp(fsym->s_name, "main") != 0) 342 if (sflag && hflag && strcmp(fsym->s_name, "main") != 0)
342 /* function definition is not a prototype */ 343 /* function definition is not a prototype */
343 warning(286); 344 warning(286);
344 } 345 }
345 346
346 if (dcs->d_notyp) 347 if (dcs->d_notyp)
347 fsym->s_return_type_implicit_int = true; 348 fsym->s_return_type_implicit_int = true;
348 349
349 set_reached(true); 350 set_reached(true);
350} 351}
351 352
352static void 353static void
353check_missing_return_value(void) 354check_missing_return_value(void)
354{ 355{
355 if (funcsym->s_type->t_subt->t_tspec == VOID) 356 if (funcsym->s_type->t_subt->t_tspec == VOID)
356 return; 357 return;
357 if (funcsym->s_return_type_implicit_int) 358 if (funcsym->s_return_type_implicit_int)
358 return; 359 return;
359 360
360 /* C99 5.1.2.2.3 "Program termination" p1 */ 361 /* C99 5.1.2.2.3 "Program termination" p1 */
361 if (Sflag && strcmp(funcsym->s_name, "main") == 0) 362 if (Sflag && strcmp(funcsym->s_name, "main") == 0)
362 return; 363 return;
363 364
364 /* function %s falls off bottom without returning value */ 365 /* function %s falls off bottom without returning value */
365 warning(217, funcsym->s_name); 366 warning(217, funcsym->s_name);
366} 367}
367 368
368/* 369/*
369 * Called at the end of a function definition. 370 * Called at the end of a function definition.
370 */ 371 */
371void 372void
372funcend(void) 373funcend(void)
373{ 374{
374 sym_t *arg; 375 sym_t *arg;
375 int n; 376 int n;
376 377
377 if (reached) { 378 if (reached) {
378 cstmt->c_had_return_noval = true; 379 cstmt->c_had_return_noval = true;
379 check_missing_return_value(); 380 check_missing_return_value();
380 } 381 }
381 382
382 /* 383 /*
383 * This warning is printed only if the return value was implicitly 384 * This warning is printed only if the return value was implicitly
384 * declared to be int. Otherwise the wrong return statement 385 * declared to be int. Otherwise the wrong return statement
385 * has already printed a warning. 386 * has already printed a warning.
386 */ 387 */
387 if (cstmt->c_had_return_noval && cstmt->c_had_return_value && 388 if (cstmt->c_had_return_noval && cstmt->c_had_return_value &&
388 funcsym->s_return_type_implicit_int) 389 funcsym->s_return_type_implicit_int)
389 /* function %s has return (e); and return; */ 390 /* function %s has return (e); and return; */
390 warning(216, funcsym->s_name); 391 warning(216, funcsym->s_name);
391 392
392 /* Print warnings for unused arguments */ 393 /* Print warnings for unused arguments */
393 arg = dcs->d_func_args; 394 arg = dcs->d_func_args;
394 n = 0; 395 n = 0;
395 while (arg != NULL && (nargusg == -1 || n < nargusg)) { 396 while (arg != NULL && (nargusg == -1 || n < nargusg)) {
396 check_usage_sym(dcs->d_asm, arg); 397 check_usage_sym(dcs->d_asm, arg);
397 arg = arg->s_next; 398 arg = arg->s_next;
398 n++; 399 n++;
399 } 400 }
400 nargusg = -1; 401 nargusg = -1;
401 402
402 /* 403 /*
403 * write the information about the function definition to the 404 * write the information about the function definition to the
404 * output file 405 * output file
405 * inline functions explicitly declared extern are written as 406 * inline functions explicitly declared extern are written as
406 * declarations only. 407 * declarations only.
407 */ 408 */
408 if (dcs->d_scl == EXTERN && funcsym->s_inline) { 409 if (dcs->d_scl == EXTERN && funcsym->s_inline) {
409 outsym(funcsym, funcsym->s_scl, DECL); 410 outsym(funcsym, funcsym->s_scl, DECL);
410 } else { 411 } else {
411 outfdef(funcsym, &dcs->d_func_def_pos, 412 outfdef(funcsym, &dcs->d_func_def_pos,
412 cstmt->c_had_return_value, funcsym->s_osdef, 413 cstmt->c_had_return_value, funcsym->s_osdef,
413 dcs->d_func_args); 414 dcs->d_func_args);
414 } 415 }
415 416
416 /* clean up after syntax errors, see test stmt_for.c. */ 417 /* clean up after syntax errors, see test stmt_for.c. */
417 while (dcs->d_next != NULL) 418 while (dcs->d_next != NULL)
418 dcs = dcs->d_next; 419 dcs = dcs->d_next;
419 420
420 /* 421 /*
421 * remove all symbols declared during argument declaration from 422 * remove all symbols declared during argument declaration from
422 * the symbol table 423 * the symbol table
423 */ 424 */
424 lint_assert(dcs->d_next == NULL); 425 lint_assert(dcs->d_next == NULL);
425 lint_assert(dcs->d_ctx == EXTERN); 426 lint_assert(dcs->d_ctx == EXTERN);
426 rmsyms(dcs->d_func_proto_syms); 427 rmsyms(dcs->d_func_proto_syms);
427 428
428 /* must be set on level 0 */ 429 /* must be set on level 0 */
429 set_reached(true); 430 set_reached(true);
430} 431}
431 432
432void 433void
433named_label(sym_t *sym) 434named_label(sym_t *sym)
434{ 435{
435 436
436 if (sym->s_set) { 437 if (sym->s_set) {
437 /* label %s redefined */ 438 /* label %s redefined */
438 error(194, sym->s_name); 439 error(194, sym->s_name);
439 } else { 440 } else {
440 mark_as_set(sym); 441 mark_as_set(sym);
441 } 442 }
442 443
443 set_reached(true); 444 set_reached(true);
444} 445}
445 446
446static void 447static void
447check_case_label_bitand(const tnode_t *case_expr, const tnode_t *switch_expr) 448check_case_label_bitand(const tnode_t *case_expr, const tnode_t *switch_expr)
448{ 449{
449 uint64_t case_value, mask; 450 uint64_t case_value, mask;
450 451
451 if (switch_expr->tn_op != BITAND || 452 if (switch_expr->tn_op != BITAND ||
452 switch_expr->tn_right->tn_op != CON) 453 switch_expr->tn_right->tn_op != CON)
453 return; 454 return;
454 455
455 lint_assert(case_expr->tn_op == CON); 456 lint_assert(case_expr->tn_op == CON);
456 case_value = case_expr->tn_val->v_quad; 457 case_value = case_expr->tn_val->v_quad;
457 mask = switch_expr->tn_right->tn_val->v_quad; 458 mask = switch_expr->tn_right->tn_val->v_quad;
458 459
459 if ((case_value & ~mask) != 0) { 460 if ((case_value & ~mask) != 0) {
460 /* statement not reached */ 461 /* statement not reached */
461 warning(193); 462 warning(193);
462 } 463 }
463} 464}
464 465
465static void 466static void
466check_case_label_enum(const tnode_t *tn, const control_statement *cs) 467check_case_label_enum(const tnode_t *tn, const control_statement *cs)
467{ 468{
468 /* similar to typeok_enum in tree.c */ 469 /* similar to typeok_enum in tree.c */
469 470
470 if (!(tn->tn_type->t_is_enum || cs->c_switch_type->t_is_enum)) 471 if (!(tn->tn_type->t_is_enum || cs->c_switch_type->t_is_enum))
471 return; 472 return;
472 if (tn->tn_type->t_is_enum && cs->c_switch_type->t_is_enum && 473 if (tn->tn_type->t_is_enum && cs->c_switch_type->t_is_enum &&
473 tn->tn_type->t_enum == cs->c_switch_type->t_enum) 474 tn->tn_type->t_enum == cs->c_switch_type->t_enum)
474 return; 475 return;
475 476
476#if 0 /* not yet ready, see msg_130.c */ 477#if 0 /* not yet ready, see msg_130.c */
477 /* enum type mismatch: '%s' '%s' '%s' */ 478 /* enum type mismatch: '%s' '%s' '%s' */
478 warning(130, type_name(cs->c_switch_type), op_name(EQ), 479 warning(130, type_name(cs->c_switch_type), op_name(EQ),
479 type_name(tn->tn_type)); 480 type_name(tn->tn_type));
480#endif 481#endif
481} 482}
482 483
483static void 484static void
484check_case_label(tnode_t *tn, control_statement *cs) 485check_case_label(tnode_t *tn, control_statement *cs)
485{ 486{
486 case_label_t *cl; 487 case_label_t *cl;
487 val_t *v; 488 val_t *v;
488 val_t nv; 489 val_t nv;
489 tspec_t t; 490 tspec_t t;
490 491
491 if (cs == NULL) { 492 if (cs == NULL) {
492 /* case not in switch */ 493 /* case not in switch */
493 error(195); 494 error(195);
494 return; 495 return;
495 } 496 }
496 497
497 if (tn != NULL && tn->tn_op != CON) { 498 if (tn != NULL && tn->tn_op != CON) {
498 /* non-constant case expression */ 499 /* non-constant case expression */
499 error(197); 500 error(197);
500 return; 501 return;
501 } 502 }
502 503
503 if (tn != NULL && !is_integer(tn->tn_type->t_tspec)) { 504 if (tn != NULL && !is_integer(tn->tn_type->t_tspec)) {
504 /* non-integral case expression */ 505 /* non-integral case expression */
505 error(198); 506 error(198);
506 return; 507 return;
507 } 508 }
508 509
509 check_case_label_bitand(tn, cs->c_switch_expr); 510 check_case_label_bitand(tn, cs->c_switch_expr);
510 check_case_label_enum(tn, cs); 511 check_case_label_enum(tn, cs);
511 512
512 lint_assert(cs->c_switch_type != NULL); 513 lint_assert(cs->c_switch_type != NULL);
513 514
514 if (reached && !seen_fallthrough) { 515 if (reached && !seen_fallthrough) {
515 if (hflag) 516 if (hflag)
516 /* fallthrough on case statement */ 517 /* fallthrough on case statement */
517 warning(220); 518 warning(220);
518 } 519 }
519 520
520 t = tn->tn_type->t_tspec; 521 t = tn->tn_type->t_tspec;
521 if (t == LONG || t == ULONG || 522 if (t == LONG || t == ULONG ||
522 t == QUAD || t == UQUAD) { 523 t == QUAD || t == UQUAD) {
523 if (tflag) 524 if (tflag)
524 /* case label must be of type 'int' in traditional C */ 525 /* case label must be of type 'int' in traditional C */
525 warning(203); 526 warning(203);
526 } 527 }
527 528
528 /* 529 /*
529 * get the value of the expression and convert it 530 * get the value of the expression and convert it
530 * to the type of the switch expression 531 * to the type of the switch expression
531 */ 532 */
532 v = constant(tn, true); 533 v = constant(tn, true);
533 (void)memset(&nv, 0, sizeof(nv)); 534 (void)memset(&nv, 0, sizeof(nv));
534 convert_constant(CASE, 0, cs->c_switch_type, &nv, v); 535 convert_constant(CASE, 0, cs->c_switch_type, &nv, v);
535 free(v); 536 free(v);
536 537
537 /* look if we had this value already */ 538 /* look if we had this value already */
538 for (cl = cs->c_case_labels; cl != NULL; cl = cl->cl_next) { 539 for (cl = cs->c_case_labels; cl != NULL; cl = cl->cl_next) {
539 if (cl->cl_val.v_quad == nv.v_quad) 540 if (cl->cl_val.v_quad == nv.v_quad)
540 break; 541 break;
541 } 542 }
542 if (cl != NULL && is_uinteger(nv.v_tspec)) { 543 if (cl != NULL && is_uinteger(nv.v_tspec)) {
543 /* duplicate case in switch: %lu */ 544 /* duplicate case in switch: %lu */
544 error(200, (unsigned long)nv.v_quad); 545 error(200, (unsigned long)nv.v_quad);
545 } else if (cl != NULL) { 546 } else if (cl != NULL) {
546 /* duplicate case in switch: %ld */ 547 /* duplicate case in switch: %ld */
547 error(199, (long)nv.v_quad); 548 error(199, (long)nv.v_quad);
548 } else { 549 } else {
549 check_getopt_case_label(nv.v_quad); 550 check_getopt_case_label(nv.v_quad);
550 551
551 /* append the value to the list of case values */ 552 /* append the value to the list of case values */
552 cl = xcalloc(1, sizeof(*cl)); 553 cl = xcalloc(1, sizeof(*cl));
553 cl->cl_val = nv; 554 cl->cl_val = nv;
554 cl->cl_next = cs->c_case_labels; 555 cl->cl_next = cs->c_case_labels;
555 cs->c_case_labels = cl; 556 cs->c_case_labels = cl;
556 } 557 }
557} 558}
558 559
559void 560void
560case_label(tnode_t *tn) 561case_label(tnode_t *tn)
561{ 562{
562 control_statement *cs; 563 control_statement *cs;
563 564
564 /* find the innermost switch statement */ 565 /* find the innermost switch statement */
565 for (cs = cstmt; cs != NULL && !cs->c_switch; cs = cs->c_surrounding) 566 for (cs = cstmt; cs != NULL && !cs->c_switch; cs = cs->c_surrounding)
566 continue; 567 continue;
567 568
568 check_case_label(tn, cs); 569 check_case_label(tn, cs);
569 570
570 expr_free_all(); 571 expr_free_all();
571 572
572 set_reached(true); 573 set_reached(true);
573} 574}
574 575
575void 576void
576default_label(void) 577default_label(void)
577{ 578{
578 control_statement *cs; 579 control_statement *cs;
579 580
580 /* find the innermost switch statement */ 581 /* find the innermost switch statement */
581 for (cs = cstmt; cs != NULL && !cs->c_switch; cs = cs->c_surrounding) 582 for (cs = cstmt; cs != NULL && !cs->c_switch; cs = cs->c_surrounding)
582 continue; 583 continue;
583 584
584 if (cs == NULL) { 585 if (cs == NULL) {
585 /* default outside switch */ 586 /* default outside switch */
586 error(201); 587 error(201);
587 } else if (cs->c_default) { 588 } else if (cs->c_default) {
588 /* duplicate default in switch */ 589 /* duplicate default in switch */
589 error(202); 590 error(202);
590 } else { 591 } else {
591 if (reached && !seen_fallthrough) { 592 if (reached && !seen_fallthrough) {
592 if (hflag) 593 if (hflag)
593 /* fallthrough on default statement */ 594 /* fallthrough on default statement */
594 warning(284); 595 warning(284);
595 } 596 }
596 cs->c_default = true; 597 cs->c_default = true;
597 } 598 }
598 599
599 set_reached(true); 600 set_reached(true);
600} 601}
601 602
602static tnode_t * 603static tnode_t *
603check_controlling_expression(tnode_t *tn) 604check_controlling_expression(tnode_t *tn)
604{ 605{
605 606
606 tn = cconv(tn); 607 tn = cconv(tn);
607 if (tn != NULL) 608 if (tn != NULL)
608 tn = promote(NOOP, false, tn); 609 tn = promote(NOOP, false, tn);
609 610
610 if (tn != NULL && !is_scalar(tn->tn_type->t_tspec)) { 611 if (tn != NULL && !is_scalar(tn->tn_type->t_tspec)) {
611 /* C99 6.5.15p4 for the ?: operator; see typeok:QUEST */ 612 /* C99 6.5.15p4 for the ?: operator; see typeok:QUEST */
612 /* C99 6.8.4.1p1 for if statements */ 613 /* C99 6.8.4.1p1 for if statements */
613 /* C99 6.8.5p2 for while, do and for loops */ 614 /* C99 6.8.5p2 for while, do and for loops */
614 /* controlling expressions must have scalar type */ 615 /* controlling expressions must have scalar type */
615 error(204); 616 error(204);
616 return NULL; 617 return NULL;
617 } 618 }
618 619
619 if (tn != NULL && Tflag && !is_typeok_bool_operand(tn)) { 620 if (tn != NULL && Tflag && !is_typeok_bool_operand(tn)) {
620 /* controlling expression must be bool, not '%s' */ 621 /* controlling expression must be bool, not '%s' */
621 error(333, tspec_name(tn->tn_type->t_tspec)); 622 error(333, tspec_name(tn->tn_type->t_tspec));
622 } 623 }
623 624
624 return tn; 625 return tn;
625} 626}
626 627
627/* 628/*
628 * T_IF T_LPAREN expr T_RPAREN 629 * T_IF T_LPAREN expr T_RPAREN
629 */ 630 */
630void 631void
631if1(tnode_t *tn) 632if1(tnode_t *tn)
632{ 633{
633 634
634 if (tn != NULL) 635 if (tn != NULL)
635 tn = check_controlling_expression(tn); 636 tn = check_controlling_expression(tn);
636 if (tn != NULL) 637 if (tn != NULL)
637 expr(tn, false, true, false, false); 638 expr(tn, false, true, false, false);
638 begin_control_statement(CS_IF); 639 begin_control_statement(CS_IF);
639 640
640 if (tn != NULL && tn->tn_op == CON && !tn->tn_system_dependent) { 641 if (tn != NULL && tn->tn_op == CON && !tn->tn_system_dependent) {
641 /* XXX: what if inside 'if (0)'? */ 642 /* XXX: what if inside 'if (0)'? */
642 set_reached(constant_is_nonzero(tn)); 643 set_reached(constant_is_nonzero(tn));
643 /* XXX: what about always_else? */ 644 /* XXX: what about always_else? */
644 cstmt->c_always_then = reached; 645 cstmt->c_always_then = reached;
645 } 646 }
646} 647}
647 648
648/* 649/*
649 * if_without_else 650 * if_without_else
650 * if_without_else T_ELSE 651 * if_without_else T_ELSE
651 */ 652 */
652void 653void
653if2(void) 654if2(void)
654{ 655{
655 656
656 cstmt->c_reached_end_of_then = reached; 657 cstmt->c_reached_end_of_then = reached;
657 /* XXX: what if inside 'if (0)'? */ 658 /* XXX: what if inside 'if (0)'? */
658 set_reached(!cstmt->c_always_then); 659 set_reached(!cstmt->c_always_then);
659} 660}
660 661
661/* 662/*
662 * if_without_else 663 * if_without_else
663 * if_without_else T_ELSE statement 664 * if_without_else T_ELSE statement
664 */ 665 */
665void 666void
666if3(bool els) 667if3(bool els)
667{ 668{
668 if (cstmt->c_reached_end_of_then) 669 if (cstmt->c_reached_end_of_then)
669 set_reached(true); 670 set_reached(true);
670 else if (cstmt->c_always_then) 671 else if (cstmt->c_always_then)
671 set_reached(false); 672 set_reached(false);
672 else if (!els) 673 else if (!els)
673 set_reached(true); 674 set_reached(true);
674 675
675 end_control_statement(CS_IF); 676 end_control_statement(CS_IF);
676} 677}
677 678
678/* 679/*
679 * T_SWITCH T_LPAREN expr T_RPAREN 680 * T_SWITCH T_LPAREN expr T_RPAREN
680 */ 681 */
681void 682void
682switch1(tnode_t *tn) 683switch1(tnode_t *tn)
683{ 684{
684 tspec_t t; 685 tspec_t t;
685 type_t *tp; 686 type_t *tp;
686 687
687 if (tn != NULL) 688 if (tn != NULL)
688 tn = cconv(tn); 689 tn = cconv(tn);
689 if (tn != NULL) 690 if (tn != NULL)
690 tn = promote(NOOP, false, tn); 691 tn = promote(NOOP, false, tn);
691 if (tn != NULL && !is_integer(tn->tn_type->t_tspec)) { 692 if (tn != NULL && !is_integer(tn->tn_type->t_tspec)) {
692 /* switch expression must have integral type */ 693 /* switch expression must have integral type */
693 error(205); 694 error(205);
694 tn = NULL; 695 tn = NULL;
695 } 696 }
696 if (tn != NULL && tflag) { 697 if (tn != NULL && tflag) {
697 t = tn->tn_type->t_tspec; 698 t = tn->tn_type->t_tspec;
698 if (t == LONG || t == ULONG || t == QUAD || t == UQUAD) { 699 if (t == LONG || t == ULONG || t == QUAD || t == UQUAD) {
699 /* switch expression must be of type 'int' in ... */ 700 /* switch expression must be of type 'int' in ... */
700 warning(271); 701 warning(271);
701 } 702 }
702 } 703 }
703 704
704 /* 705 /*
705 * Remember the type of the expression. Because it's possible 706 * Remember the type of the expression. Because it's possible
706 * that (*tp) is allocated on tree memory, the type must be 707 * that (*tp) is allocated on tree memory, the type must be
707 * duplicated. This is not too complicated because it is 708 * duplicated. This is not too complicated because it is
708 * only an integer type. 709 * only an integer type.
709 */ 710 */
710 tp = xcalloc(1, sizeof(*tp)); 711 tp = xcalloc(1, sizeof(*tp));
711 if (tn != NULL) { 712 if (tn != NULL) {
712 tp->t_tspec = tn->tn_type->t_tspec; 713 tp->t_tspec = tn->tn_type->t_tspec;
713 if ((tp->t_is_enum = tn->tn_type->t_is_enum) != false) 714 if ((tp->t_is_enum = tn->tn_type->t_is_enum) != false)
714 tp->t_enum = tn->tn_type->t_enum; 715 tp->t_enum = tn->tn_type->t_enum;
715 } else { 716 } else {
716 tp->t_tspec = INT; 717 tp->t_tspec = INT;
717 } 718 }
718 719
719 /* leak the memory, for check_case_label_bitand */ 720 /* leak the memory, for check_case_label_bitand */
720 (void)expr_save_memory(); 721 (void)expr_save_memory();
721 722
722 check_getopt_begin_switch(); 723 check_getopt_begin_switch();
723 expr(tn, true, false, false, false); 724 expr(tn, true, false, false, false);
724 725
725 begin_control_statement(CS_SWITCH); 726 begin_control_statement(CS_SWITCH);
726 cstmt->c_switch = true; 727 cstmt->c_switch = true;
727 cstmt->c_switch_type = tp; 728 cstmt->c_switch_type = tp;
728 cstmt->c_switch_expr = tn; 729 cstmt->c_switch_expr = tn;
729 730
730 set_reached(false); 731 set_reached(false);
731 seen_fallthrough = true; 732 seen_fallthrough = true;
732} 733}
733 734
734/* 735/*
735 * switch_expr statement 736 * switch_expr statement
736 */ 737 */
737void 738void
738switch2(void) 739switch2(void)
739{ 740{
740 int nenum = 0, nclab = 0; 741 int nenum = 0, nclab = 0;
741 sym_t *esym; 742 sym_t *esym;
742 case_label_t *cl; 743 case_label_t *cl;
743 744
744 lint_assert(cstmt->c_switch_type != NULL); 745 lint_assert(cstmt->c_switch_type != NULL);
745 746
746 if (cstmt->c_switch_type->t_is_enum) { 747 if (cstmt->c_switch_type->t_is_enum) {
747 /* 748 /*
748 * Warn if the number of case labels is different from the 749 * Warn if the number of case labels is different from the
749 * number of enumerators. 750 * number of enumerators.
750 */ 751 */
751 nenum = nclab = 0; 752 nenum = nclab = 0;
752 lint_assert(cstmt->c_switch_type->t_enum != NULL); 753 lint_assert(cstmt->c_switch_type->t_enum != NULL);
753 for (esym = cstmt->c_switch_type->t_enum->en_first_enumerator; 754 for (esym = cstmt->c_switch_type->t_enum->en_first_enumerator;
754 esym != NULL; esym = esym->s_next) { 755 esym != NULL; esym = esym->s_next) {
755 nenum++; 756 nenum++;
756 } 757 }
757 for (cl = cstmt->c_case_labels; cl != NULL; cl = cl->cl_next) 758 for (cl = cstmt->c_case_labels; cl != NULL; cl = cl->cl_next)
758 nclab++; 759 nclab++;
759 if (hflag && eflag && nenum != nclab && !cstmt->c_default) { 760 if (hflag && eflag && nenum != nclab && !cstmt->c_default) {
760 /* enumeration value(s) not handled in switch */ 761 /* enumeration value(s) not handled in switch */
761 warning(206); 762 warning(206);
762 } 763 }
763 } 764 }
764 765
765 check_getopt_end_switch(); 766 check_getopt_end_switch();
766 767
767 if (cstmt->c_break) { 768 if (cstmt->c_break) {
768 /* 769 /*
769 * The end of the switch statement is always reached since 770 * The end of the switch statement is always reached since
770 * c_break is only set if a break statement can actually 771 * c_break is only set if a break statement can actually
771 * be reached. 772 * be reached.
772 */ 773 */
773 set_reached(true); 774 set_reached(true);
774 } else if (cstmt->c_default || 775 } else if (cstmt->c_default ||
775 (hflag && cstmt->c_switch_type->t_is_enum && 776 (hflag && cstmt->c_switch_type->t_is_enum &&
776 nenum == nclab)) { 777 nenum == nclab)) {
777 /* 778 /*
778 * The end of the switch statement is reached if the end 779 * The end of the switch statement is reached if the end
779 * of the last statement inside it is reached. 780 * of the last statement inside it is reached.
780 */ 781 */
781 } else { 782 } else {
782 /* 783 /*
783 * There are possible values that are not handled in the 784 * There are possible values that are not handled in the
784 * switch statement. 785 * switch statement.
785 */ 786 */
786 set_reached(true); 787 set_reached(true);
787 } 788 }
788 789
789 end_control_statement(CS_SWITCH); 790 end_control_statement(CS_SWITCH);
790} 791}
791 792
792/* 793/*
793 * T_WHILE T_LPAREN expr T_RPAREN 794 * T_WHILE T_LPAREN expr T_RPAREN
794 */ 795 */
795void 796void
796while1(tnode_t *tn) 797while1(tnode_t *tn)
797{ 798{
798 bool body_reached; 799 bool body_reached;
799 800
800 if (!reached) { 801 if (!reached) {
801 /* loop not entered at top */ 802 /* loop not entered at top */
802 warning(207); 803 warning(207);
803 /* FIXME: that's plain wrong. */ 804 /* FIXME: that's plain wrong. */
804 set_reached(true); 805 set_reached(true);
805 } 806 }
806 807
807 if (tn != NULL) 808 if (tn != NULL)
808 tn = check_controlling_expression(tn); 809 tn = check_controlling_expression(tn);
809 810
810 begin_control_statement(CS_WHILE); 811 begin_control_statement(CS_WHILE);
811 cstmt->c_loop = true; 812 cstmt->c_loop = true;
812 cstmt->c_maybe_endless = is_nonzero(tn); 813 cstmt->c_maybe_endless = is_nonzero(tn);
813 body_reached = !is_zero(tn); 814 body_reached = !is_zero(tn);
814 815
815 check_getopt_begin_while(tn); 816 check_getopt_begin_while(tn);
816 expr(tn, false, true, true, false); 817 expr(tn, false, true, true, false);
817 818
818 set_reached(body_reached); 819 set_reached(body_reached);
819} 820}
820 821
821/* 822/*
822 * while_expr statement 823 * while_expr statement
823 * while_expr error 824 * while_expr error
824 */ 825 */
825void 826void
826while2(void) 827while2(void)
827{ 828{
828 829
829 /* 830 /*
830 * The end of the loop can be reached if it is no endless loop 831 * The end of the loop can be reached if it is no endless loop
831 * or there was a break statement which was reached. 832 * or there was a break statement which was reached.
832 */ 833 */
833 set_reached(!cstmt->c_maybe_endless || cstmt->c_break); 834 set_reached(!cstmt->c_maybe_endless || cstmt->c_break);
834 835
835 check_getopt_end_while(); 836 check_getopt_end_while();
836 end_control_statement(CS_WHILE); 837 end_control_statement(CS_WHILE);
837} 838}
838 839
839/* 840/*
840 * T_DO 841 * T_DO
841 */ 842 */
842void 843void
843do1(void) 844do1(void)
844{ 845{
845 846
846 if (!reached) { 847 if (!reached) {
847 /* loop not entered at top */ 848 /* loop not entered at top */
848 warning(207); 849 warning(207);
849 set_reached(true); 850 set_reached(true);
850 } 851 }
851 852
852 begin_control_statement(CS_DO_WHILE); 853 begin_control_statement(CS_DO_WHILE);
853 cstmt->c_loop = true; 854 cstmt->c_loop = true;
854} 855}
855 856
856/* 857/*
857 * do statement do_while_expr 858 * do statement do_while_expr
858 * do error 859 * do error
859 */ 860 */
860void 861void
861do2(tnode_t *tn) 862do2(tnode_t *tn)
862{ 863{
863 864
864 /* 865 /*
865 * If there was a continue statement, the expression controlling the 866 * If there was a continue statement, the expression controlling the
866 * loop is reached. 867 * loop is reached.
867 */ 868 */
868 if (cstmt->c_continue) 869 if (cstmt->c_continue)
869 set_reached(true); 870 set_reached(true);
870 871
871 if (tn != NULL) 872 if (tn != NULL)
872 tn = check_controlling_expression(tn); 873 tn = check_controlling_expression(tn);
873 874
874 if (tn != NULL && tn->tn_op == CON) { 875 if (tn != NULL && tn->tn_op == CON) {
875 cstmt->c_maybe_endless = constant_is_nonzero(tn); 876 cstmt->c_maybe_endless = constant_is_nonzero(tn);
876 if (!cstmt->c_maybe_endless && cstmt->c_continue) 877 if (!cstmt->c_maybe_endless && cstmt->c_continue)
877 /* continue in 'do ... while (0)' loop */ 878 /* continue in 'do ... while (0)' loop */
878 error(323); 879 error(323);
879 } 880 }
880 881
881 expr(tn, false, true, true, true); 882 expr(tn, false, true, true, true);
882 883
883 if (cstmt->c_maybe_endless) 884 if (cstmt->c_maybe_endless)
884 set_reached(false); 885 set_reached(false);
885 if (cstmt->c_break) 886 if (cstmt->c_break)
886 set_reached(true); 887 set_reached(true);
887 888
888 end_control_statement(CS_DO_WHILE); 889 end_control_statement(CS_DO_WHILE);
889} 890}
890 891
891/* 892/*
892 * T_FOR T_LPAREN opt_expr T_SEMI opt_expr T_SEMI opt_expr T_RPAREN 893 * T_FOR T_LPAREN opt_expr T_SEMI opt_expr T_SEMI opt_expr T_RPAREN
893 */ 894 */
894void 895void
895for1(tnode_t *tn1, tnode_t *tn2, tnode_t *tn3) 896for1(tnode_t *tn1, tnode_t *tn2, tnode_t *tn3)
896{ 897{
897 898
898 /* 899 /*
899 * If there is no initialization expression it is possible that 900 * If there is no initialization expression it is possible that
900 * it is intended not to enter the loop at top. 901 * it is intended not to enter the loop at top.
901 */ 902 */
902 if (tn1 != NULL && !reached) { 903 if (tn1 != NULL && !reached) {
903 /* loop not entered at top */ 904 /* loop not entered at top */
904 warning(207); 905 warning(207);
905 set_reached(true); 906 set_reached(true);
906 } 907 }
907 908
908 begin_control_statement(CS_FOR); 909 begin_control_statement(CS_FOR);
909 cstmt->c_loop = true; 910 cstmt->c_loop = true;
910 911
911 /* 912 /*
912 * Store the tree memory for the reinitialization expression. 913 * Store the tree memory for the reinitialization expression.
913 * Also remember this expression itself. We must check it at 914 * Also remember this expression itself. We must check it at
914 * the end of the loop to get "used but not set" warnings correct. 915 * the end of the loop to get "used but not set" warnings correct.
915 */ 916 */
916 cstmt->c_for_expr3_mem = expr_save_memory(); 917 cstmt->c_for_expr3_mem = expr_save_memory();
917 cstmt->c_for_expr3 = tn3; 918 cstmt->c_for_expr3 = tn3;
918 cstmt->c_for_expr3_pos = curr_pos; 919 cstmt->c_for_expr3_pos = curr_pos;
919 cstmt->c_for_expr3_csrc_pos = csrc_pos; 920 cstmt->c_for_expr3_csrc_pos = csrc_pos;
920 921
921 if (tn1 != NULL) 922 if (tn1 != NULL)
922 expr(tn1, false, false, true, false); 923 expr(tn1, false, false, true, false);
923 924
924 if (tn2 != NULL) 925 if (tn2 != NULL)
925 tn2 = check_controlling_expression(tn2); 926 tn2 = check_controlling_expression(tn2);
926 if (tn2 != NULL) 927 if (tn2 != NULL)
927 expr(tn2, false, true, true, false); 928 expr(tn2, false, true, true, false);
928 929
929 cstmt->c_maybe_endless = tn2 == NULL || is_nonzero(tn2); 930 cstmt->c_maybe_endless = tn2 == NULL || is_nonzero(tn2);
930 931
931 /* Checking the reinitialization expression is done in for2() */ 932 /* Checking the reinitialization expression is done in for2() */
932 933
933 set_reached(!is_zero(tn2)); 934 set_reached(!is_zero(tn2));
934} 935}
935 936
936/* 937/*
937 * for_exprs statement 938 * for_exprs statement
938 * for_exprs error 939 * for_exprs error
939 */ 940 */
940void 941void
941for2(void) 942for2(void)
942{ 943{
943 pos_t cpos, cspos; 944 pos_t cpos, cspos;
944 tnode_t *tn3; 945 tnode_t *tn3;
945 946
946 if (cstmt->c_continue) 947 if (cstmt->c_continue)
947 set_reached(true); 948 set_reached(true);
948 949
949 cpos = curr_pos; 950 cpos = curr_pos;
950 cspos = csrc_pos; 951 cspos = csrc_pos;
951 952
952 /* Restore the tree memory for the reinitialization expression */ 953 /* Restore the tree memory for the reinitialization expression */
953 expr_restore_memory(cstmt->c_for_expr3_mem); 954 expr_restore_memory(cstmt->c_for_expr3_mem);
954 tn3 = cstmt->c_for_expr3; 955 tn3 = cstmt->c_for_expr3;
955 curr_pos = cstmt->c_for_expr3_pos; 956 curr_pos = cstmt->c_for_expr3_pos;
956 csrc_pos = cstmt->c_for_expr3_csrc_pos; 957 csrc_pos = cstmt->c_for_expr3_csrc_pos;
957 958
958 /* simply "statement not reached" would be confusing */ 959 /* simply "statement not reached" would be confusing */
959 if (!reached && warn_about_unreachable) { 960 if (!reached && warn_about_unreachable) {
960 /* end-of-loop code not reached */ 961 /* end-of-loop code not reached */
961 warning(223); 962 warning(223);
962 set_reached(true); 963 set_reached(true);
963 } 964 }
964 965
965 if (tn3 != NULL) { 966 if (tn3 != NULL) {
966 expr(tn3, false, false, true, false); 967 expr(tn3, false, false, true, false);
967 } else { 968 } else {
968 expr_free_all(); 969 expr_free_all();
969 } 970 }
970 971
971 curr_pos = cpos; 972 curr_pos = cpos;
972 csrc_pos = cspos; 973 csrc_pos = cspos;
973 974
974 /* An endless loop without break will never terminate */ 975 /* An endless loop without break will never terminate */
975 /* TODO: What if the loop contains a 'return'? */ 976 /* TODO: What if the loop contains a 'return'? */
976 set_reached(cstmt->c_break || !cstmt->c_maybe_endless); 977 set_reached(cstmt->c_break || !cstmt->c_maybe_endless);
977 978
978 end_control_statement(CS_FOR); 979 end_control_statement(CS_FOR);
979} 980}
980 981
981/* 982/*
982 * T_GOTO identifier T_SEMI 983 * T_GOTO identifier T_SEMI
983 */ 984 */
984void 985void
985do_goto(sym_t *lab) 986do_goto(sym_t *lab)
986{ 987{
987 988
988 mark_as_used(lab, false, false); 989 mark_as_used(lab, false, false);
989 990
990 check_statement_reachable(); 991 check_statement_reachable();
991 992
992 set_reached(false); 993 set_reached(false);
993} 994}
994 995
995/* 996/*
996 * T_BREAK T_SEMI 997 * T_BREAK T_SEMI
997 */ 998 */
998void 999void
999do_break(void) 1000do_break(void)
1000{ 1001{
1001 control_statement *cs; 1002 control_statement *cs;
1002 1003
1003 cs = cstmt; 1004 cs = cstmt;
1004 while (cs != NULL && !cs->c_loop && !cs->c_switch) 1005 while (cs != NULL && !cs->c_loop && !cs->c_switch)
1005 cs = cs->c_surrounding; 1006 cs = cs->c_surrounding;
1006 1007
1007 if (cs == NULL) { 1008 if (cs == NULL) {
1008 /* break outside loop or switch */ 1009 /* break outside loop or switch */
1009 error(208); 1010 error(208);
1010 } else { 1011 } else {
1011 if (reached) 1012 if (reached)
1012 cs->c_break = true; 1013 cs->c_break = true;
1013 } 1014 }
1014 1015
1015 if (bflag) 1016 if (bflag)
1016 check_statement_reachable(); 1017 check_statement_reachable();
1017 1018
1018 set_reached(false); 1019 set_reached(false);
1019} 1020}
1020 1021
1021/* 1022/*
1022 * T_CONTINUE T_SEMI 1023 * T_CONTINUE T_SEMI
1023 */ 1024 */
1024void 1025void
1025do_continue(void) 1026do_continue(void)
1026{ 1027{
1027 control_statement *cs; 1028 control_statement *cs;
1028 1029
1029 for (cs = cstmt; cs != NULL && !cs->c_loop; cs = cs->c_surrounding) 1030 for (cs = cstmt; cs != NULL && !cs->c_loop; cs = cs->c_surrounding)
1030 continue; 1031 continue;
1031 1032
1032 if (cs == NULL) { 1033 if (cs == NULL) {
1033 /* continue outside loop */ 1034 /* continue outside loop */
1034 error(209); 1035 error(209);
1035 } else { 1036 } else {
1036 /* TODO: only if reachable, for symmetry with c_break */ 1037 /* TODO: only if reachable, for symmetry with c_break */
1037 cs->c_continue = true; 1038 cs->c_continue = true;
1038 } 1039 }
1039 1040
1040 check_statement_reachable(); 1041 check_statement_reachable();
1041 1042
1042 set_reached(false); 1043 set_reached(false);
1043} 1044}
1044 1045
1045/* 1046/*
1046 * T_RETURN T_SEMI 1047 * T_RETURN T_SEMI
1047 * T_RETURN expr T_SEMI 1048 * T_RETURN expr T_SEMI
1048 */ 1049 */
1049void 1050void
1050do_return(bool sys, tnode_t *tn) 1051do_return(bool sys, tnode_t *tn)
1051{ 1052{
1052 tnode_t *ln, *rn; 1053 tnode_t *ln, *rn;
1053 control_statement *cs; 1054 control_statement *cs;
1054 op_t op; 1055 op_t op;
1055 1056
1056 cs = cstmt; 1057 cs = cstmt;
1057 if (cs == NULL) { 1058 if (cs == NULL) {
1058 /* syntax error '%s' */ 1059 /* syntax error '%s' */
1059 error(249, "return outside function"); 1060 error(249, "return outside function");
1060 return; 1061 return;
1061 } 1062 }
1062 1063
1063 for (; cs->c_surrounding != NULL; cs = cs->c_surrounding) 1064 for (; cs->c_surrounding != NULL; cs = cs->c_surrounding)
1064 continue; 1065 continue;
1065 1066
1066 if (tn != NULL) 1067 if (tn != NULL)
1067 cs->c_had_return_value = true; 1068 cs->c_had_return_value = true;
1068 else 1069 else
1069 cs->c_had_return_noval = true; 1070 cs->c_had_return_noval = true;
1070 1071
1071 if (tn != NULL && funcsym->s_type->t_subt->t_tspec == VOID) { 1072 if (tn != NULL && funcsym->s_type->t_subt->t_tspec == VOID) {
1072 /* void function %s cannot return value */ 1073 /* void function %s cannot return value */
1073 error(213, funcsym->s_name); 1074 error(213, funcsym->s_name);
1074 expr_free_all(); 1075 expr_free_all();
1075 tn = NULL; 1076 tn = NULL;
1076 } else if (tn == NULL && funcsym->s_type->t_subt->t_tspec != VOID) { 1077 } else if (tn == NULL && funcsym->s_type->t_subt->t_tspec != VOID) {
1077 /* 1078 /*
1078 * Assume that the function has a return value only if it 1079 * Assume that the function has a return value only if it
1079 * is explicitly declared. 1080 * is explicitly declared.
1080 */ 1081 */
1081 if (!funcsym->s_return_type_implicit_int) 1082 if (!funcsym->s_return_type_implicit_int)
1082 /* function '%s' expects to return value */ 1083 /* function '%s' expects to return value */
1083 warning(214, funcsym->s_name); 1084 warning(214, funcsym->s_name);
1084 } 1085 }
1085 1086
1086 if (tn != NULL) { 1087 if (tn != NULL) {
1087 1088
1088 /* Create a temporary node for the left side */ 1089 /* Create a temporary node for the left side */
1089 ln = expr_zero_alloc(sizeof(*ln)); 1090 ln = expr_zero_alloc(sizeof(*ln));
1090 ln->tn_op = NAME; 1091 ln->tn_op = NAME;
1091 ln->tn_type = expr_unqualified_type(funcsym->s_type->t_subt); 1092 ln->tn_type = expr_unqualified_type(funcsym->s_type->t_subt);
1092 ln->tn_lvalue = true; 1093 ln->tn_lvalue = true;
1093 ln->tn_sym = funcsym; /* better than nothing */ 1094 ln->tn_sym = funcsym; /* better than nothing */
1094 1095
1095 tn = build_binary(ln, RETURN, sys, tn); 1096 tn = build_binary(ln, RETURN, sys, tn);
1096 1097
1097 if (tn != NULL) { 1098 if (tn != NULL) {
1098 rn = tn->tn_right; 1099 rn = tn->tn_right;
1099 while ((op = rn->tn_op) == CVT || op == PLUS) 1100 while ((op = rn->tn_op) == CVT || op == PLUS)
1100 rn = rn->tn_left; 1101 rn = rn->tn_left;
1101 if (rn->tn_op == ADDR && rn->tn_left->tn_op == NAME && 1102 if (rn->tn_op == ADDR && rn->tn_left->tn_op == NAME &&
1102 rn->tn_left->tn_sym->s_scl == AUTO) { 1103 rn->tn_left->tn_sym->s_scl == AUTO) {
1103 /* %s returns pointer to automatic object */ 1104 /* %s returns pointer to automatic object */
1104 warning(302, funcsym->s_name); 1105 warning(302, funcsym->s_name);
1105 } 1106 }
1106 } 1107 }
1107 1108
1108 expr(tn, true, false, true, false); 1109 expr(tn, true, false, true, false);
1109 1110
1110 } else { 1111 } else {
1111 1112
1112 check_statement_reachable(); 1113 check_statement_reachable();
1113 1114
1114 } 1115 }
1115 1116
1116 set_reached(false); 1117 set_reached(false);
1117} 1118}
1118 1119
1119/* 1120/*
1120 * Do some cleanup after a global declaration or definition. 1121 * Do some cleanup after a global declaration or definition.
1121 * Especially remove information about unused lint comments. 1122 * Especially remove information about unused lint comments.
1122 */ 1123 */
1123void 1124void
1124global_clean_up_decl(bool silent) 1125global_clean_up_decl(bool silent)
1125{ 1126{
1126 1127
1127 if (nargusg != -1) { 1128 if (nargusg != -1) {
1128 if (!silent) { 1129 if (!silent) {
1129 /* must precede function definition: ** %s ** */ 1130 /* must precede function definition: ** %s ** */
1130 warning_at(282, &argsused_pos, "ARGSUSED"); 1131 warning_at(282, &argsused_pos, "ARGSUSED");
1131 } 1132 }
1132 nargusg = -1; 1133 nargusg = -1;
1133 } 1134 }
1134 if (nvararg != -1) { 1135 if (nvararg != -1) {
1135 if (!silent) { 1136 if (!silent) {
1136 /* must precede function definition: ** %s ** */ 1137 /* must precede function definition: ** %s ** */
1137 warning_at(282, &vapos, "VARARGS"); 1138 warning_at(282, &vapos, "VARARGS");
1138 } 1139 }
1139 nvararg = -1; 1140 nvararg = -1;
1140 } 1141 }
1141 if (printflike_argnum != -1) { 1142 if (printflike_argnum != -1) {
1142 if (!silent) { 1143 if (!silent) {
1143 /* must precede function definition: ** %s ** */ 1144 /* must precede function definition: ** %s ** */
1144 warning_at(282, &printflike_pos, "PRINTFLIKE"); 1145 warning_at(282, &printflike_pos, "PRINTFLIKE");
1145 } 1146 }
1146 printflike_argnum = -1; 1147 printflike_argnum = -1;
1147 } 1148 }
1148 if (scanflike_argnum != -1) { 1149 if (scanflike_argnum != -1) {
1149 if (!silent) { 1150 if (!silent) {
1150 /* must precede function definition: ** %s ** */ 1151 /* must precede function definition: ** %s ** */
1151 warning_at(282, &scanflike_pos, "SCANFLIKE"); 1152 warning_at(282, &scanflike_pos, "SCANFLIKE");
1152 } 1153 }
1153 scanflike_argnum = -1; 1154 scanflike_argnum = -1;
1154 } 1155 }
1155 1156
1156 dcs->d_asm = false; 1157 dcs->d_asm = false;
1157 1158
1158 /* 1159 /*
1159 * Needed for BSD yacc in case of parse errors; GNU Bison 3.0.4 is 1160 * Needed for BSD yacc in case of parse errors; GNU Bison 3.0.4 is
1160 * fine. See test gcc_attribute.c, function_with_unknown_attribute. 1161 * fine. See test gcc_attribute.c, function_with_unknown_attribute.
1161 */ 1162 */
1162 in_gcc_attribute = false; 1163 in_gcc_attribute = false;
1163} 1164}
1164 1165
1165/* 1166/*
1166 * ARGSUSED comment 1167 * ARGSUSED comment
1167 * 1168 *
1168 * Only the first n arguments of the following function are checked 1169 * Only the first n arguments of the following function are checked
1169 * for usage. A missing argument is taken to be 0. 1170 * for usage. A missing argument is taken to be 0.
1170 */ 1171 */
1171void 1172void
1172argsused(int n) 1173argsused(int n)
1173{ 1174{
1174 1175
1175 if (n == -1) 1176 if (n == -1)
1176 n = 0; 1177 n = 0;
1177 1178
1178 if (dcs->d_ctx != EXTERN) { 1179 if (dcs->d_ctx != EXTERN) {
1179 /* must be outside function: ** %s ** */ 1180 /* must be outside function: ** %s ** */
1180 warning(280, "ARGSUSED"); 1181 warning(280, "ARGSUSED");
1181 return; 1182 return;
1182 } 1183 }
1183 if (nargusg != -1) { 1184 if (nargusg != -1) {
1184 /* duplicate use of ** %s ** */ 1185 /* duplicate use of ** %s ** */
1185 warning(281, "ARGSUSED"); 1186 warning(281, "ARGSUSED");
1186 } 1187 }
1187 nargusg = n; 1188 nargusg = n;
1188 argsused_pos = curr_pos; 1189 argsused_pos = curr_pos;
1189} 1190}
1190 1191
1191/* 1192/*
1192 * VARARGS comment 1193 * VARARGS comment
1193 * 1194 *
1194 * Causes lint2 to check only the first n arguments for compatibility 1195 * Causes lint2 to check only the first n arguments for compatibility
1195 * with the function definition. A missing argument is taken to be 0. 1196 * with the function definition. A missing argument is taken to be 0.
1196 */ 1197 */
1197void 1198void
1198varargs(int n) 1199varargs(int n)
1199{ 1200{
1200 1201
1201 if (n == -1) 1202 if (n == -1)
1202 n = 0; 1203 n = 0;
1203 1204
1204 if (dcs->d_ctx != EXTERN) { 1205 if (dcs->d_ctx != EXTERN) {
1205 /* must be outside function: ** %s ** */ 1206 /* must be outside function: ** %s ** */
1206 warning(280, "VARARGS"); 1207 warning(280, "VARARGS");
1207 return; 1208 return;
1208 } 1209 }
1209 if (nvararg != -1) { 1210 if (nvararg != -1) {
1210 /* duplicate use of ** %s ** */ 1211 /* duplicate use of ** %s ** */
1211 warning(281, "VARARGS"); 1212 warning(281, "VARARGS");
1212 } 1213 }
1213 nvararg = n; 1214 nvararg = n;
1214 vapos = curr_pos; 1215 vapos = curr_pos;
1215} 1216}
1216 1217
1217/* 1218/*
1218 * PRINTFLIKE comment 1219 * PRINTFLIKE comment
1219 * 1220 *
1220 * Check all arguments until the (n-1)-th as usual. The n-th argument is 1221 * Check all arguments until the (n-1)-th as usual. The n-th argument is
1221 * used the check the types of remaining arguments. 1222 * used the check the types of remaining arguments.
1222 */ 1223 */
1223void 1224void
1224printflike(int n) 1225printflike(int n)
1225{ 1226{
1226 1227
1227 if (n == -1) 1228 if (n == -1)
1228 n = 0; 1229 n = 0;
1229 1230
1230 if (dcs->d_ctx != EXTERN) { 1231 if (dcs->d_ctx != EXTERN) {
1231 /* must be outside function: ** %s ** */ 1232 /* must be outside function: ** %s ** */
1232 warning(280, "PRINTFLIKE"); 1233 warning(280, "PRINTFLIKE");
1233 return; 1234 return;
1234 } 1235 }
1235 if (printflike_argnum != -1) { 1236 if (printflike_argnum != -1) {
1236 /* duplicate use of ** %s ** */ 1237 /* duplicate use of ** %s ** */
1237 warning(281, "PRINTFLIKE"); 1238 warning(281, "PRINTFLIKE");

cvs diff -r1.101 -r1.102 src/usr.bin/xlint/lint1/lex.c (switch to unified diff)

--- src/usr.bin/xlint/lint1/lex.c 2022/02/27 08:31:26 1.101
+++ src/usr.bin/xlint/lint1/lex.c 2022/02/27 10:44:45 1.102
@@ -1,1542 +1,1542 @@ @@ -1,1542 +1,1542 @@
1/* $NetBSD: lex.c,v 1.101 2022/02/27 08:31:26 rillig Exp $ */ 1/* $NetBSD: lex.c,v 1.102 2022/02/27 10:44:45 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. 4 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
5 * Copyright (c) 1994, 1995 Jochen Pohl 5 * Copyright (c) 1994, 1995 Jochen Pohl
6 * All Rights Reserved. 6 * All Rights Reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement: 17 * must display the following acknowledgement:
18 * This product includes software developed by Jochen Pohl for 18 * This product includes software developed by Jochen Pohl for
19 * The NetBSD Project. 19 * The NetBSD Project.
20 * 4. The name of the author may not be used to endorse or promote products 20 * 4. The name of the author may not be used to endorse or promote products
21 * derived from this software without specific prior written permission. 21 * derived from this software without specific prior written permission.
22 * 22 *
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */ 33 */
34 34
35#if HAVE_NBTOOL_CONFIG_H 35#if HAVE_NBTOOL_CONFIG_H
36#include "nbtool_config.h" 36#include "nbtool_config.h"
37#endif 37#endif
38 38
39#include <sys/cdefs.h> 39#include <sys/cdefs.h>
40#if defined(__RCSID) && !defined(lint) 40#if defined(__RCSID) && !defined(lint)
41__RCSID("$NetBSD: lex.c,v 1.101 2022/02/27 08:31:26 rillig Exp $"); 41__RCSID("$NetBSD: lex.c,v 1.102 2022/02/27 10:44:45 rillig Exp $");
42#endif 42#endif
43 43
44#include <ctype.h> 44#include <ctype.h>
45#include <errno.h> 45#include <errno.h>
46#include <float.h> 46#include <float.h>
47#include <limits.h> 47#include <limits.h>
48#include <math.h> 48#include <math.h>
49#include <stdlib.h> 49#include <stdlib.h>
50#include <string.h> 50#include <string.h>
51 51
52#include "lint1.h" 52#include "lint1.h"
53#include "cgram.h" 53#include "cgram.h"
54 54
55#define CHAR_MASK ((1U << CHAR_SIZE) - 1) 55#define CHAR_MASK ((1U << CHAR_SIZE) - 1)
56 56
57 57
58/* Current position (it's also updated when an included file is parsed) */ 58/* Current position (it's also updated when an included file is parsed) */
59pos_t curr_pos = { "", 1, 0 }; 59pos_t curr_pos = { "", 1, 0 };
60 60
61/* 61/*
62 * Current position in C source (not updated when an included file is 62 * Current position in C source (not updated when an included file is
63 * parsed). 63 * parsed).
64 */ 64 */
65pos_t csrc_pos = { "", 1, 0 }; 65pos_t csrc_pos = { "", 1, 0 };
66 66
67bool in_gcc_attribute; 67bool in_gcc_attribute;
68bool in_system_header; 68bool in_system_header;
69 69
70static int inpc(void); 70static int inpc(void);
71static unsigned int hash(const char *); 71static unsigned int hash(const char *);
72static sym_t * search(sbuf_t *); 72static sym_t * search(sbuf_t *);
73static int keyw(sym_t *); 73static int keyw(sym_t *);
74static int get_escaped_char(int); 74static int get_escaped_char(int);
75 75
76void 76void
77lex_next_line(void) 77lex_next_line(void)
78{ 78{
79 curr_pos.p_line++; 79 curr_pos.p_line++;
80 curr_pos.p_uniq = 0; 80 curr_pos.p_uniq = 0;
81 debug_step("parsing %s:%d", curr_pos.p_file, curr_pos.p_line); 81 debug_step("parsing %s:%d", curr_pos.p_file, curr_pos.p_line);
82 if (curr_pos.p_file == csrc_pos.p_file) { 82 if (curr_pos.p_file == csrc_pos.p_file) {
83 csrc_pos.p_line++; 83 csrc_pos.p_line++;
84 csrc_pos.p_uniq = 0; 84 csrc_pos.p_uniq = 0;
85 } 85 }
86} 86}
87 87
88void 88void
89lex_unknown_character(int c) 89lex_unknown_character(int c)
90{ 90{
91 91
92 /* unknown character \%o */ 92 /* unknown character \%o */
93 error(250, c); 93 error(250, c);
94} 94}
95 95
96#define kwdef(name, token, scl, tspec, tqual, c90, c99, gcc, attr, deco) \ 96#define kwdef(name, token, scl, tspec, tqual, c90, c99, gcc, attr, deco) \
97 { \ 97 { \
98 name, token, scl, tspec, tqual, \ 98 name, token, scl, tspec, tqual, \
99 (c90) > 0, (c99) > 0, (gcc) > 0, (attr) > 0, \ 99 (c90) > 0, (c99) > 0, (gcc) > 0, (attr) > 0, \
100 ((deco) & 1) != 0, ((deco) & 2) != 0, ((deco) & 4) != 0, \ 100 ((deco) & 1) != 0, ((deco) & 2) != 0, ((deco) & 4) != 0, \
101 } 101 }
102#define kwdef_token(name, token, c90, c99, gcc, attr, deco) \ 102#define kwdef_token(name, token, c90, c99, gcc, attr, deco) \
103 kwdef(name, token, 0, 0, 0, c90, c99, gcc, attr, deco) 103 kwdef(name, token, 0, 0, 0, c90, c99, gcc, attr, deco)
104#define kwdef_sclass(name, sclass, c90, c99, gcc, attr, deco) \ 104#define kwdef_sclass(name, sclass, c90, c99, gcc, attr, deco) \
105 kwdef(name, T_SCLASS, sclass, 0, 0, c90, c99, gcc, attr, deco) 105 kwdef(name, T_SCLASS, sclass, 0, 0, c90, c99, gcc, attr, deco)
106#define kwdef_type(name, tspec, c90, c99, gcc, attr, deco) \ 106#define kwdef_type(name, tspec, c90, c99, gcc, attr, deco) \
107 kwdef(name, T_TYPE, 0, tspec, 0, c90, c99, gcc, attr, deco) 107 kwdef(name, T_TYPE, 0, tspec, 0, c90, c99, gcc, attr, deco)
108#define kwdef_tqual(name, tqual, c90, c99, gcc, attr, deco) \ 108#define kwdef_tqual(name, tqual, c90, c99, gcc, attr, deco) \
109 kwdef(name, T_QUAL, 0, 0, tqual, c90, c99, gcc, attr, deco) 109 kwdef(name, T_QUAL, 0, 0, tqual, c90, c99, gcc, attr, deco)
110#define kwdef_keyword(name, token) \ 110#define kwdef_keyword(name, token) \
111 kwdef(name, token, 0, 0, 0, 0, 0, 0, 0, 1) 111 kwdef(name, token, 0, 0, 0, 0, 0, 0, 0, 1)
112#define kwdef_gcc_attr(name, token) \ 112#define kwdef_gcc_attr(name, token) \
113 kwdef(name, token, 0, 0, 0, 0, 0, 1, 1, 5) 113 kwdef(name, token, 0, 0, 0, 0, 0, 1, 1, 5)
114 114
115/* During initialization, these keywords are written to the symbol table. */ 115/* During initialization, these keywords are written to the symbol table. */
116static struct keyword { 116static struct keyword {
117 const char *kw_name; /* keyword */ 117 const char *kw_name; /* keyword */
118 int kw_token; /* token returned by yylex() */ 118 int kw_token; /* token returned by yylex() */
119 scl_t kw_scl; /* storage class if kw_token T_SCLASS */ 119 scl_t kw_scl; /* storage class if kw_token T_SCLASS */
120 tspec_t kw_tspec; /* type spec. if kw_token 120 tspec_t kw_tspec; /* type spec. if kw_token
121 * T_TYPE or T_STRUCT_OR_UNION */ 121 * T_TYPE or T_STRUCT_OR_UNION */
122 tqual_t kw_tqual; /* type qual. if kw_token T_QUAL */ 122 tqual_t kw_tqual; /* type qual. if kw_token T_QUAL */
123 bool kw_c90:1; /* C90 keyword */ 123 bool kw_c90:1; /* C90 keyword */
124 bool kw_c99:1; /* C99 keyword */ 124 bool kw_c99:1; /* C99 keyword */
125 bool kw_gcc:1; /* GCC keyword */ 125 bool kw_gcc:1; /* GCC keyword */
126 bool kw_attr:1; /* GCC attribute, keyword */ 126 bool kw_attr:1; /* GCC attribute, keyword */
127 bool kw_plain:1; /* 'name' */ 127 bool kw_plain:1; /* 'name' */
128 bool kw_leading:1; /* '__name' */ 128 bool kw_leading:1; /* '__name' */
129 bool kw_both:1; /* '__name__' */ 129 bool kw_both:1; /* '__name__' */
130} keywords[] = { 130} keywords[] = {
131 kwdef_gcc_attr( "alias", T_AT_ALIAS), 131 kwdef_gcc_attr( "alias", T_AT_ALIAS),
132 kwdef_keyword( "_Alignas", T_ALIGNAS), 132 kwdef_keyword( "_Alignas", T_ALIGNAS),
133 kwdef_keyword( "_Alignof", T_ALIGNOF), 133 kwdef_keyword( "_Alignof", T_ALIGNOF),
134 kwdef_gcc_attr( "aligned", T_AT_ALIGNED), 134 kwdef_gcc_attr( "aligned", T_AT_ALIGNED),
135 kwdef_token( "__alignof__", T_ALIGNOF, 0,0,0,0,1), 135 kwdef_token( "__alignof__", T_ALIGNOF, 0,0,0,0,1),
136 kwdef_gcc_attr( "alloc_size", T_AT_ALLOC_SIZE), 136 kwdef_gcc_attr( "alloc_size", T_AT_ALLOC_SIZE),
137 kwdef_gcc_attr( "always_inline",T_AT_ALWAYS_INLINE), 137 kwdef_gcc_attr( "always_inline",T_AT_ALWAYS_INLINE),
138 kwdef_token( "asm", T_ASM, 0,0,1,0,7), 138 kwdef_token( "asm", T_ASM, 0,0,1,0,7),
139 kwdef_token( "attribute", T_ATTRIBUTE, 0,0,1,0,6), 139 kwdef_token( "attribute", T_ATTRIBUTE, 0,0,1,0,6),
140 kwdef_sclass( "auto", AUTO, 0,0,0,0,1), 140 kwdef_sclass( "auto", AUTO, 0,0,0,0,1),
141 kwdef_type( "_Bool", BOOL, 0,1,0,0,1), 141 kwdef_type( "_Bool", BOOL, 0,1,0,0,1),
142 kwdef_gcc_attr( "bounded", T_AT_BOUNDED), 142 kwdef_gcc_attr( "bounded", T_AT_BOUNDED),
143 kwdef_keyword( "break", T_BREAK), 143 kwdef_keyword( "break", T_BREAK),
144 kwdef_gcc_attr( "buffer", T_AT_BUFFER), 144 kwdef_gcc_attr( "buffer", T_AT_BUFFER),
145 kwdef_token( "__builtin_offsetof", T_BUILTIN_OFFSETOF, 0,0,1,0,1), 145 kwdef_token( "__builtin_offsetof", T_BUILTIN_OFFSETOF, 0,0,1,0,1),
146 kwdef_keyword( "case", T_CASE), 146 kwdef_keyword( "case", T_CASE),
147 kwdef_type( "char", CHAR, 0,0,0,0,1), 147 kwdef_type( "char", CHAR, 0,0,0,0,1),
148 kwdef_gcc_attr( "cold", T_AT_COLD), 148 kwdef_gcc_attr( "cold", T_AT_COLD),
149 kwdef_gcc_attr( "common", T_AT_COMMON), 149 kwdef_gcc_attr( "common", T_AT_COMMON),
150 kwdef_type( "_Complex", COMPLEX, 0,1,0,0,1), 150 kwdef_type( "_Complex", COMPLEX, 0,1,0,0,1),
151 kwdef_tqual( "const", CONST, 1,0,0,0,7), 151 kwdef_tqual( "const", CONST, 1,0,0,0,7),
152 kwdef_gcc_attr( "constructor", T_AT_CONSTRUCTOR), 152 kwdef_gcc_attr( "constructor", T_AT_CONSTRUCTOR),
153 kwdef_keyword( "continue", T_CONTINUE), 153 kwdef_keyword( "continue", T_CONTINUE),
154 kwdef_keyword( "default", T_DEFAULT), 154 kwdef_keyword( "default", T_DEFAULT),
155 kwdef_gcc_attr( "deprecated", T_AT_DEPRECATED), 155 kwdef_gcc_attr( "deprecated", T_AT_DEPRECATED),
156 kwdef_gcc_attr( "destructor", T_AT_DESTRUCTOR), 156 kwdef_gcc_attr( "destructor", T_AT_DESTRUCTOR),
157 kwdef_gcc_attr( "disable_sanitizer_instrumentation", 157 kwdef_gcc_attr( "disable_sanitizer_instrumentation",
158 T_AT_DISABLE_SANITIZER_INSTRUMENTATION), 158 T_AT_DISABLE_SANITIZER_INSTRUMENTATION),
159 kwdef_keyword( "do", T_DO), 159 kwdef_keyword( "do", T_DO),
160 kwdef_type( "double", DOUBLE, 0,0,0,0,1), 160 kwdef_type( "double", DOUBLE, 0,0,0,0,1),
161 kwdef_keyword( "else", T_ELSE), 161 kwdef_keyword( "else", T_ELSE),
162 kwdef_keyword( "enum", T_ENUM), 162 kwdef_keyword( "enum", T_ENUM),
163 kwdef_token( "__extension__",T_EXTENSION, 0,0,1,0,1), 163 kwdef_token( "__extension__",T_EXTENSION, 0,0,1,0,1),
164 kwdef_sclass( "extern", EXTERN, 0,0,0,0,1), 164 kwdef_sclass( "extern", EXTERN, 0,0,0,0,1),
165 kwdef_gcc_attr( "fallthrough", T_AT_FALLTHROUGH), 165 kwdef_gcc_attr( "fallthrough", T_AT_FALLTHROUGH),
166 kwdef_type( "float", FLOAT, 0,0,0,0,1), 166 kwdef_type( "float", FLOAT, 0,0,0,0,1),
167 kwdef_keyword( "for", T_FOR), 167 kwdef_keyword( "for", T_FOR),
168 kwdef_gcc_attr( "format", T_AT_FORMAT), 168 kwdef_gcc_attr( "format", T_AT_FORMAT),
169 kwdef_gcc_attr( "format_arg", T_AT_FORMAT_ARG), 169 kwdef_gcc_attr( "format_arg", T_AT_FORMAT_ARG),
170 kwdef_token( "_Generic", T_GENERIC, 0,1,0,0,1), 170 kwdef_token( "_Generic", T_GENERIC, 0,1,0,0,1),
171 kwdef_gcc_attr( "gnu_inline", T_AT_GNU_INLINE), 171 kwdef_gcc_attr( "gnu_inline", T_AT_GNU_INLINE),
172 kwdef_gcc_attr( "gnu_printf", T_AT_FORMAT_GNU_PRINTF), 172 kwdef_gcc_attr( "gnu_printf", T_AT_FORMAT_GNU_PRINTF),
173 kwdef_keyword( "goto", T_GOTO), 173 kwdef_keyword( "goto", T_GOTO),
174 kwdef_gcc_attr( "hot", T_AT_HOT), 174 kwdef_gcc_attr( "hot", T_AT_HOT),
175 kwdef_keyword( "if", T_IF), 175 kwdef_keyword( "if", T_IF),
176 kwdef_token( "__imag__", T_IMAG, 0,0,1,0,1), 176 kwdef_token( "__imag__", T_IMAG, 0,0,1,0,1),
177 kwdef_sclass( "inline", INLINE, 0,1,0,0,7), 177 kwdef_sclass( "inline", INLINE, 0,1,0,0,7),
178 kwdef_type( "int", INT, 0,0,0,0,1), 178 kwdef_type( "int", INT, 0,0,0,0,1),
179#ifdef INT128_SIZE 179#ifdef INT128_SIZE
180 kwdef_type( "__int128_t", INT128, 0,1,0,0,1), 180 kwdef_type( "__int128_t", INT128, 0,1,0,0,1),
181#endif 181#endif
182 kwdef_type( "long", LONG, 0,0,0,0,1), 182 kwdef_type( "long", LONG, 0,0,0,0,1),
183 kwdef_gcc_attr( "malloc", T_AT_MALLOC), 183 kwdef_gcc_attr( "malloc", T_AT_MALLOC),
184 kwdef_gcc_attr( "may_alias", T_AT_MAY_ALIAS), 184 kwdef_gcc_attr( "may_alias", T_AT_MAY_ALIAS),
185 kwdef_gcc_attr( "minbytes", T_AT_MINBYTES), 185 kwdef_gcc_attr( "minbytes", T_AT_MINBYTES),
186 kwdef_gcc_attr( "mode", T_AT_MODE), 186 kwdef_gcc_attr( "mode", T_AT_MODE),
187 kwdef_gcc_attr("no_instrument_function", 187 kwdef_gcc_attr("no_instrument_function",
188 T_AT_NO_INSTRUMENT_FUNCTION), 188 T_AT_NO_INSTRUMENT_FUNCTION),
189 kwdef_gcc_attr( "no_sanitize", T_AT_NO_SANITIZE), 189 kwdef_gcc_attr( "no_sanitize", T_AT_NO_SANITIZE),
190 kwdef_gcc_attr( "no_sanitize_thread", T_AT_NO_SANITIZE_THREAD), 190 kwdef_gcc_attr( "no_sanitize_thread", T_AT_NO_SANITIZE_THREAD),
191 kwdef_gcc_attr( "noinline", T_AT_NOINLINE), 191 kwdef_gcc_attr( "noinline", T_AT_NOINLINE),
192 kwdef_gcc_attr( "nonnull", T_AT_NONNULL), 192 kwdef_gcc_attr( "nonnull", T_AT_NONNULL),
193 kwdef_gcc_attr( "nonstring", T_AT_NONSTRING), 193 kwdef_gcc_attr( "nonstring", T_AT_NONSTRING),
194 kwdef_token( "_Noreturn", T_NORETURN, 0,1,0,0,1), 194 kwdef_token( "_Noreturn", T_NORETURN, 0,1,0,0,1),
195 kwdef_gcc_attr( "noreturn", T_AT_NORETURN), 195 kwdef_gcc_attr( "noreturn", T_AT_NORETURN),
196 kwdef_gcc_attr( "nothrow", T_AT_NOTHROW), 196 kwdef_gcc_attr( "nothrow", T_AT_NOTHROW),
197 kwdef_gcc_attr( "optimize", T_AT_OPTIMIZE), 197 kwdef_gcc_attr( "optimize", T_AT_OPTIMIZE),
198 kwdef_gcc_attr( "optnone", T_AT_OPTNONE), 198 kwdef_gcc_attr( "optnone", T_AT_OPTNONE),
199 kwdef_gcc_attr( "packed", T_AT_PACKED), 199 kwdef_gcc_attr( "packed", T_AT_PACKED),
200 kwdef_token( "__packed", T_PACKED, 0,0,0,0,1), 200 kwdef_token( "__packed", T_PACKED, 0,0,0,0,1),
201 kwdef_gcc_attr( "pcs", T_AT_PCS), 201 kwdef_gcc_attr( "pcs", T_AT_PCS),
202 kwdef_gcc_attr( "printf", T_AT_FORMAT_PRINTF), 202 kwdef_gcc_attr( "printf", T_AT_FORMAT_PRINTF),
203 kwdef_gcc_attr( "pure", T_AT_PURE), 203 kwdef_gcc_attr( "pure", T_AT_PURE),
204 kwdef_token( "__real__", T_REAL, 0,0,1,0,1), 204 kwdef_token( "__real__", T_REAL, 0,0,1,0,1),
205 kwdef_sclass( "register", REG, 0,0,0,0,1), 205 kwdef_sclass( "register", REG, 0,0,0,0,1),
206 kwdef_gcc_attr( "regparm", T_AT_REGPARM), 206 kwdef_gcc_attr( "regparm", T_AT_REGPARM),
207 kwdef_tqual( "restrict", RESTRICT, 0,1,0,0,7), 207 kwdef_tqual( "restrict", RESTRICT, 0,1,0,0,7),
208 kwdef_keyword( "return", T_RETURN), 208 kwdef_keyword( "return", T_RETURN),
209 kwdef_gcc_attr( "returns_nonnull",T_AT_RETURNS_NONNULL), 209 kwdef_gcc_attr( "returns_nonnull",T_AT_RETURNS_NONNULL),
210 kwdef_gcc_attr( "returns_twice",T_AT_RETURNS_TWICE), 210 kwdef_gcc_attr( "returns_twice",T_AT_RETURNS_TWICE),
211 kwdef_gcc_attr( "scanf", T_AT_FORMAT_SCANF), 211 kwdef_gcc_attr( "scanf", T_AT_FORMAT_SCANF),
212 kwdef_token( "section", T_AT_SECTION, 0,0,1,1,7), 212 kwdef_token( "section", T_AT_SECTION, 0,0,1,1,7),
213 kwdef_gcc_attr( "sentinel", T_AT_SENTINEL), 213 kwdef_gcc_attr( "sentinel", T_AT_SENTINEL),
214 kwdef_type( "short", SHORT, 0,0,0,0,1), 214 kwdef_type( "short", SHORT, 0,0,0,0,1),
215 kwdef_type( "signed", SIGNED, 1,0,0,0,3), 215 kwdef_type( "signed", SIGNED, 1,0,0,0,3),
216 kwdef_keyword( "sizeof", T_SIZEOF), 216 kwdef_keyword( "sizeof", T_SIZEOF),
217 kwdef_sclass( "static", STATIC, 0,0,0,0,1), 217 kwdef_sclass( "static", STATIC, 0,0,0,0,1),
218 kwdef_keyword( "_Static_assert", T_STATIC_ASSERT), 218 kwdef_keyword( "_Static_assert", T_STATIC_ASSERT),
219 kwdef_gcc_attr( "strfmon", T_AT_FORMAT_STRFMON), 219 kwdef_gcc_attr( "strfmon", T_AT_FORMAT_STRFMON),
220 kwdef_gcc_attr( "strftime", T_AT_FORMAT_STRFTIME), 220 kwdef_gcc_attr( "strftime", T_AT_FORMAT_STRFTIME),
221 kwdef_gcc_attr( "string", T_AT_STRING), 221 kwdef_gcc_attr( "string", T_AT_STRING),
222 kwdef("struct", T_STRUCT_OR_UNION, 0, STRUCT, 0, 0,0,0,0,1), 222 kwdef("struct", T_STRUCT_OR_UNION, 0, STRUCT, 0, 0,0,0,0,1),
223 kwdef_keyword( "switch", T_SWITCH), 223 kwdef_keyword( "switch", T_SWITCH),
224 kwdef_token( "__symbolrename", T_SYMBOLRENAME, 0,0,0,0,1), 224 kwdef_token( "__symbolrename", T_SYMBOLRENAME, 0,0,0,0,1),
225 kwdef_gcc_attr( "syslog", T_AT_FORMAT_SYSLOG), 225 kwdef_gcc_attr( "syslog", T_AT_FORMAT_SYSLOG),
226 kwdef_gcc_attr( "target", T_AT_TARGET), 226 kwdef_gcc_attr( "target", T_AT_TARGET),
227 kwdef_tqual( "__thread", THREAD, 0,0,1,0,1), 227 kwdef_tqual( "__thread", THREAD, 0,0,1,0,1),
228 kwdef_tqual( "_Thread_local", THREAD, 0,1,0,0,1), 228 kwdef_tqual( "_Thread_local", THREAD, 0,1,0,0,1),
229 kwdef_gcc_attr( "tls_model", T_AT_TLS_MODEL), 229 kwdef_gcc_attr( "tls_model", T_AT_TLS_MODEL),
230 kwdef_gcc_attr( "transparent_union", T_AT_TUNION), 230 kwdef_gcc_attr( "transparent_union", T_AT_TUNION),
231 kwdef_sclass( "typedef", TYPEDEF, 0,0,0,0,1), 231 kwdef_sclass( "typedef", TYPEDEF, 0,0,0,0,1),
232 kwdef_token( "typeof", T_TYPEOF, 0,0,1,0,7), 232 kwdef_token( "typeof", T_TYPEOF, 0,0,1,0,7),
233#ifdef INT128_SIZE 233#ifdef INT128_SIZE
234 kwdef_type( "__uint128_t", UINT128, 0,1,0,0,1), 234 kwdef_type( "__uint128_t", UINT128, 0,1,0,0,1),
235#endif 235#endif
236 kwdef("union", T_STRUCT_OR_UNION, 0, UNION, 0, 0,0,0,0,1), 236 kwdef("union", T_STRUCT_OR_UNION, 0, UNION, 0, 0,0,0,0,1),
237 kwdef_type( "unsigned", UNSIGN, 0,0,0,0,1), 237 kwdef_type( "unsigned", UNSIGN, 0,0,0,0,1),
238 kwdef_gcc_attr( "unused", T_AT_UNUSED), 238 kwdef_gcc_attr( "unused", T_AT_UNUSED),
239 kwdef_gcc_attr( "used", T_AT_USED), 239 kwdef_gcc_attr( "used", T_AT_USED),
240 kwdef_gcc_attr( "visibility", T_AT_VISIBILITY), 240 kwdef_gcc_attr( "visibility", T_AT_VISIBILITY),
241 kwdef_type( "void", VOID, 0,0,0,0,1), 241 kwdef_type( "void", VOID, 0,0,0,0,1),
242 kwdef_tqual( "volatile", VOLATILE, 1,0,0,0,7), 242 kwdef_tqual( "volatile", VOLATILE, 1,0,0,0,7),
243 kwdef_gcc_attr( "warn_unused_result", T_AT_WARN_UNUSED_RESULT), 243 kwdef_gcc_attr( "warn_unused_result", T_AT_WARN_UNUSED_RESULT),
244 kwdef_gcc_attr( "weak", T_AT_WEAK), 244 kwdef_gcc_attr( "weak", T_AT_WEAK),
245 kwdef_keyword( "while", T_WHILE), 245 kwdef_keyword( "while", T_WHILE),
246 kwdef(NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0), 246 kwdef(NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0),
247#undef kwdef 247#undef kwdef
248#undef kwdef_token 248#undef kwdef_token
249#undef kwdef_sclass 249#undef kwdef_sclass
250#undef kwdef_type 250#undef kwdef_type
251#undef kwdef_tqual 251#undef kwdef_tqual
252#undef kwdef_keyword 252#undef kwdef_keyword
253#undef kwdef_gcc_attr 253#undef kwdef_gcc_attr
254}; 254};
255 255
256/* Symbol table */ 256/* Symbol table */
257static sym_t *symtab[HSHSIZ1]; 257static sym_t *symtab[HSHSIZ1];
258 258
259/* type of next expected symbol */ 259/* type of next expected symbol */
260symt_t symtyp; 260symt_t symtyp;
261 261
262 262
263static void 263static void
264symtab_add(sym_t *sym) 264symtab_add(sym_t *sym)
265{ 265{
266 size_t h; 266 size_t h;
267 267
268 h = hash(sym->s_name); 268 h = hash(sym->s_name);
269 if ((sym->s_link = symtab[h]) != NULL) 269 if ((sym->s_symtab_next = symtab[h]) != NULL)
270 symtab[h]->s_rlink = &sym->s_link; 270 symtab[h]->s_symtab_ref = &sym->s_symtab_next;
271 sym->s_rlink = &symtab[h]; 271 sym->s_symtab_ref = &symtab[h];
272 symtab[h] = sym; 272 symtab[h] = sym;
273} 273}
274 274
275static void 275static void
276symtab_remove(sym_t *sym) 276symtab_remove(sym_t *sym)
277{ 277{
278 278
279 if ((*sym->s_rlink = sym->s_link) != NULL) 279 if ((*sym->s_symtab_ref = sym->s_symtab_next) != NULL)
280 sym->s_link->s_rlink = sym->s_rlink; 280 sym->s_symtab_next->s_symtab_ref = sym->s_symtab_ref;
281 sym->s_link = NULL; 281 sym->s_symtab_next = NULL;
282} 282}
283 283
284 284
285static void 285static void
286add_keyword(const struct keyword *kw, bool leading, bool trailing) 286add_keyword(const struct keyword *kw, bool leading, bool trailing)
287{ 287{
288 sym_t *sym; 288 sym_t *sym;
289 char buf[256]; 289 char buf[256];
290 const char *name; 290 const char *name;
291 291
292 if (!leading && !trailing) { 292 if (!leading && !trailing) {
293 name = kw->kw_name; 293 name = kw->kw_name;
294 } else { 294 } else {
295 (void)snprintf(buf, sizeof(buf), "%s%s%s", 295 (void)snprintf(buf, sizeof(buf), "%s%s%s",
296 leading ? "__" : "", kw->kw_name, trailing ? "__" : ""); 296 leading ? "__" : "", kw->kw_name, trailing ? "__" : "");
297 name = xstrdup(buf); 297 name = xstrdup(buf);
298 } 298 }
299 299
300 sym = block_zero_alloc(sizeof(*sym)); 300 sym = block_zero_alloc(sizeof(*sym));
301 sym->s_name = name; 301 sym->s_name = name;
302 sym->s_keyword = kw; 302 sym->s_keyword = kw;
303 sym->s_value.v_quad = kw->kw_token; 303 sym->s_value.v_quad = kw->kw_token;
304 if (kw->kw_token == T_TYPE || kw->kw_token == T_STRUCT_OR_UNION) { 304 if (kw->kw_token == T_TYPE || kw->kw_token == T_STRUCT_OR_UNION) {
305 sym->s_tspec = kw->kw_tspec; 305 sym->s_tspec = kw->kw_tspec;
306 } else if (kw->kw_token == T_SCLASS) { 306 } else if (kw->kw_token == T_SCLASS) {
307 sym->s_scl = kw->kw_scl; 307 sym->s_scl = kw->kw_scl;
308 } else if (kw->kw_token == T_QUAL) { 308 } else if (kw->kw_token == T_QUAL) {
309 sym->s_tqual = kw->kw_tqual; 309 sym->s_tqual = kw->kw_tqual;
310 } 310 }
311 311
312 symtab_add(sym); 312 symtab_add(sym);
313} 313}
314 314
315/* 315/*
316 * All keywords are written to the symbol table. This saves us looking 316 * All keywords are written to the symbol table. This saves us looking
317 * in an extra table for each name we found. 317 * in an extra table for each name we found.
318 */ 318 */
319void 319void
320initscan(void) 320initscan(void)
321{ 321{
322 struct keyword *kw; 322 struct keyword *kw;
323 323
324 for (kw = keywords; kw->kw_name != NULL; kw++) { 324 for (kw = keywords; kw->kw_name != NULL; kw++) {
325 if ((kw->kw_c90 || kw->kw_c99) && tflag) 325 if ((kw->kw_c90 || kw->kw_c99) && tflag)
326 continue; 326 continue;
327 if (kw->kw_c99 && !(Sflag || gflag)) 327 if (kw->kw_c99 && !(Sflag || gflag))
328 continue; 328 continue;
329 if (kw->kw_gcc && !gflag) 329 if (kw->kw_gcc && !gflag)
330 continue; 330 continue;
331 if (kw->kw_plain) 331 if (kw->kw_plain)
332 add_keyword(kw, false, false); 332 add_keyword(kw, false, false);
333 if (kw->kw_leading) 333 if (kw->kw_leading)
334 add_keyword(kw, true, false); 334 add_keyword(kw, true, false);
335 if (kw->kw_both) 335 if (kw->kw_both)
336 add_keyword(kw, true, true); 336 add_keyword(kw, true, true);
337 } 337 }
338} 338}
339 339
340/* 340/*
341 * Read a character and ensure that it is positive (except EOF). 341 * Read a character and ensure that it is positive (except EOF).
342 * Increment line count(s) if necessary. 342 * Increment line count(s) if necessary.
343 */ 343 */
344static int 344static int
345inpc(void) 345inpc(void)
346{ 346{
347 int c; 347 int c;
348 348
349 if ((c = lex_input()) == EOF) 349 if ((c = lex_input()) == EOF)
350 return c; 350 return c;
351 c &= CHAR_MASK; 351 c &= CHAR_MASK;
352 if (c == '\0') 352 if (c == '\0')
353 return EOF; /* lex returns 0 on EOF. */ 353 return EOF; /* lex returns 0 on EOF. */
354 if (c == '\n') 354 if (c == '\n')
355 lex_next_line(); 355 lex_next_line();
356 return c; 356 return c;
357} 357}
358 358
359static unsigned int 359static unsigned int
360hash(const char *s) 360hash(const char *s)
361{ 361{
362 unsigned int v; 362 unsigned int v;
363 const char *p; 363 const char *p;
364 364
365 v = 0; 365 v = 0;
366 for (p = s; *p != '\0'; p++) { 366 for (p = s; *p != '\0'; p++) {
367 v = (v << 4) + (unsigned char)*p; 367 v = (v << 4) + (unsigned char)*p;
368 v ^= v >> 28; 368 v ^= v >> 28;
369 } 369 }
370 return v % HSHSIZ1; 370 return v % HSHSIZ1;
371} 371}
372 372
373/* 373/*
374 * Lex has found a letter followed by zero or more letters or digits. 374 * Lex has found a letter followed by zero or more letters or digits.
375 * It looks for a symbol in the symbol table with the same name. This 375 * It looks for a symbol in the symbol table with the same name. This
376 * symbol must either be a keyword or a symbol of the type required by 376 * symbol must either be a keyword or a symbol of the type required by
377 * symtyp (label, member, tag, ...). 377 * symtyp (label, member, tag, ...).
378 * 378 *
379 * If it is a keyword, the token is returned. In some cases it is described 379 * If it is a keyword, the token is returned. In some cases it is described
380 * more deeply by data written to yylval. 380 * more deeply by data written to yylval.
381 * 381 *
382 * If it is a symbol, T_NAME is returned and the name is stored in yylval. 382 * If it is a symbol, T_NAME is returned and the name is stored in yylval.
383 * If there is already a symbol of the same name and type in the symbol 383 * If there is already a symbol of the same name and type in the symbol
384 * table, yylval.y_name->sb_sym points there. 384 * table, yylval.y_name->sb_sym points there.
385 */ 385 */
386extern int 386extern int
387lex_name(const char *yytext, size_t yyleng) 387lex_name(const char *yytext, size_t yyleng)
388{ 388{
389 char *s; 389 char *s;
390 sbuf_t *sb; 390 sbuf_t *sb;
391 sym_t *sym; 391 sym_t *sym;
392 int tok; 392 int tok;
393 393
394 sb = xmalloc(sizeof(*sb)); 394 sb = xmalloc(sizeof(*sb));
395 sb->sb_name = yytext; 395 sb->sb_name = yytext;
396 sb->sb_len = yyleng; 396 sb->sb_len = yyleng;
397 if ((sym = search(sb)) != NULL && sym->s_keyword != NULL) { 397 if ((sym = search(sb)) != NULL && sym->s_keyword != NULL) {
398 free(sb); 398 free(sb);
399 return keyw(sym); 399 return keyw(sym);
400 } 400 }
401 401
402 sb->sb_sym = sym; 402 sb->sb_sym = sym;
403 403
404 if (sym != NULL) { 404 if (sym != NULL) {
405 lint_assert(block_level >= sym->s_block_level); 405 lint_assert(block_level >= sym->s_block_level);
406 sb->sb_name = sym->s_name; 406 sb->sb_name = sym->s_name;
407 sb->sb_len = strlen(sym->s_name); 407 sb->sb_len = strlen(sym->s_name);
408 tok = sym->s_scl == TYPEDEF ? T_TYPENAME : T_NAME; 408 tok = sym->s_scl == TYPEDEF ? T_TYPENAME : T_NAME;
409 } else { 409 } else {
410 s = block_zero_alloc(yyleng + 1); 410 s = block_zero_alloc(yyleng + 1);
411 (void)memcpy(s, yytext, yyleng + 1); 411 (void)memcpy(s, yytext, yyleng + 1);
412 sb->sb_name = s; 412 sb->sb_name = s;
413 sb->sb_len = yyleng; 413 sb->sb_len = yyleng;
414 tok = T_NAME; 414 tok = T_NAME;
415 } 415 }
416 416
417 yylval.y_name = sb; 417 yylval.y_name = sb;
418 return tok; 418 return tok;
419} 419}
420 420
421static sym_t * 421static sym_t *
422search(sbuf_t *sb) 422search(sbuf_t *sb)
423{ 423{
424 unsigned int h; 424 unsigned int h;
425 sym_t *sym; 425 sym_t *sym;
426 const struct keyword *kw; 426 const struct keyword *kw;
427 427
428 h = hash(sb->sb_name); 428 h = hash(sb->sb_name);
429 for (sym = symtab[h]; sym != NULL; sym = sym->s_link) { 429 for (sym = symtab[h]; sym != NULL; sym = sym->s_symtab_next) {
430 if (strcmp(sym->s_name, sb->sb_name) != 0) 430 if (strcmp(sym->s_name, sb->sb_name) != 0)
431 continue; 431 continue;
432 kw = sym->s_keyword; 432 kw = sym->s_keyword;
433 433
434 if (kw != NULL && !kw->kw_attr) 434 if (kw != NULL && !kw->kw_attr)
435 return sym; 435 return sym;
436 if (kw != NULL && in_gcc_attribute) 436 if (kw != NULL && in_gcc_attribute)
437 return sym; 437 return sym;
438 if (kw == NULL && !in_gcc_attribute && sym->s_kind == symtyp) 438 if (kw == NULL && !in_gcc_attribute && sym->s_kind == symtyp)
439 return sym; 439 return sym;
440 } 440 }
441 441
442 return NULL; 442 return NULL;
443} 443}
444 444
445static int 445static int
446keyw(sym_t *sym) 446keyw(sym_t *sym)
447{ 447{
448 int t; 448 int t;
449 449
450 if ((t = (int)sym->s_value.v_quad) == T_SCLASS) { 450 if ((t = (int)sym->s_value.v_quad) == T_SCLASS) {
451 yylval.y_scl = sym->s_scl; 451 yylval.y_scl = sym->s_scl;
452 } else if (t == T_TYPE || t == T_STRUCT_OR_UNION) { 452 } else if (t == T_TYPE || t == T_STRUCT_OR_UNION) {
453 yylval.y_tspec = sym->s_tspec; 453 yylval.y_tspec = sym->s_tspec;
454 } else if (t == T_QUAL) { 454 } else if (t == T_QUAL) {
455 yylval.y_tqual = sym->s_tqual; 455 yylval.y_tqual = sym->s_tqual;
456 } 456 }
457 return t; 457 return t;
458} 458}
459 459
460/* 460/*
461 * Convert a string representing an integer into internal representation. 461 * Convert a string representing an integer into internal representation.
462 * Return T_CON, storing the numeric value in yylval, for yylex. 462 * Return T_CON, storing the numeric value in yylval, for yylex.
463 */ 463 */
464int 464int
465lex_integer_constant(const char *yytext, size_t yyleng, int base) 465lex_integer_constant(const char *yytext, size_t yyleng, int base)
466{ 466{
467 int l_suffix, u_suffix; 467 int l_suffix, u_suffix;
468 size_t len; 468 size_t len;
469 const char *cp; 469 const char *cp;
470 char c, *eptr; 470 char c, *eptr;
471 tspec_t typ; 471 tspec_t typ;
472 bool ansiu; 472 bool ansiu;
473 bool warned = false; 473 bool warned = false;
474 uint64_t uq = 0; 474 uint64_t uq = 0;
475 475
476 /* C11 6.4.4.1p5 */ 476 /* C11 6.4.4.1p5 */
477 static const tspec_t suffix_type[2][3] = { 477 static const tspec_t suffix_type[2][3] = {
478 { INT, LONG, QUAD, }, 478 { INT, LONG, QUAD, },
479 { UINT, ULONG, UQUAD, } 479 { UINT, ULONG, UQUAD, }
480 }; 480 };
481 481
482 cp = yytext; 482 cp = yytext;
483 len = yyleng; 483 len = yyleng;
484 484
485 /* skip 0[xX] or 0[bB] */ 485 /* skip 0[xX] or 0[bB] */
486 if (base == 16 || base == 2) { 486 if (base == 16 || base == 2) {
487 cp += 2; 487 cp += 2;
488 len -= 2; 488 len -= 2;
489 } 489 }
490 490
491 /* read suffixes */ 491 /* read suffixes */
492 l_suffix = u_suffix = 0; 492 l_suffix = u_suffix = 0;
493 for (;;) { 493 for (;;) {
494 if ((c = cp[len - 1]) == 'l' || c == 'L') { 494 if ((c = cp[len - 1]) == 'l' || c == 'L') {
495 l_suffix++; 495 l_suffix++;
496 } else if (c == 'u' || c == 'U') { 496 } else if (c == 'u' || c == 'U') {
497 u_suffix++; 497 u_suffix++;
498 } else { 498 } else {
499 break; 499 break;
500 } 500 }
501 len--; 501 len--;
502 } 502 }
503 if (l_suffix > 2 || u_suffix > 1) { 503 if (l_suffix > 2 || u_suffix > 1) {
504 /* malformed integer constant */ 504 /* malformed integer constant */
505 warning(251); 505 warning(251);
506 if (l_suffix > 2) 506 if (l_suffix > 2)
507 l_suffix = 2; 507 l_suffix = 2;
508 if (u_suffix > 1) 508 if (u_suffix > 1)
509 u_suffix = 1; 509 u_suffix = 1;
510 } 510 }
511 if (tflag && u_suffix != 0) { 511 if (tflag && u_suffix != 0) {
512 /* suffix U is illegal in traditional C */ 512 /* suffix U is illegal in traditional C */
513 warning(97); 513 warning(97);
514 } 514 }
515 typ = suffix_type[u_suffix][l_suffix]; 515 typ = suffix_type[u_suffix][l_suffix];
516 516
517 errno = 0; 517 errno = 0;
518 518
519 uq = (uint64_t)strtoull(cp, &eptr, base); 519 uq = (uint64_t)strtoull(cp, &eptr, base);
520 lint_assert(eptr == cp + len); 520 lint_assert(eptr == cp + len);
521 if (errno != 0) { 521 if (errno != 0) {
522 /* integer constant out of range */ 522 /* integer constant out of range */
523 warning(252); 523 warning(252);
524 warned = true; 524 warned = true;
525 } 525 }
526 526
527 /* 527 /*
528 * If the value is too big for the current type, we must choose 528 * If the value is too big for the current type, we must choose
529 * another type. 529 * another type.
530 */ 530 */
531 ansiu = false; 531 ansiu = false;
532 switch (typ) { 532 switch (typ) {
533 case INT: 533 case INT:
534 if (uq <= TARG_INT_MAX) { 534 if (uq <= TARG_INT_MAX) {
535 /* ok */ 535 /* ok */
536 } else if (uq <= TARG_UINT_MAX && base != 10) { 536 } else if (uq <= TARG_UINT_MAX && base != 10) {
537 typ = UINT; 537 typ = UINT;
538 } else if (uq <= TARG_LONG_MAX) { 538 } else if (uq <= TARG_LONG_MAX) {
539 typ = LONG; 539 typ = LONG;
540 } else { 540 } else {
541 typ = ULONG; 541 typ = ULONG;
542 if (uq > TARG_ULONG_MAX && !warned) { 542 if (uq > TARG_ULONG_MAX && !warned) {
543 /* integer constant out of range */ 543 /* integer constant out of range */
544 warning(252); 544 warning(252);
545 } 545 }
546 } 546 }
547 if (typ == UINT || typ == ULONG) { 547 if (typ == UINT || typ == ULONG) {
548 if (tflag) { 548 if (tflag) {
549 typ = LONG; 549 typ = LONG;
550 } else if (!sflag) { 550 } else if (!sflag) {
551 /* 551 /*
552 * Remember that the constant is unsigned 552 * Remember that the constant is unsigned
553 * only in ANSI C 553 * only in ANSI C
554 */ 554 */
555 ansiu = true; 555 ansiu = true;
556 } 556 }
557 } 557 }
558 break; 558 break;
559 case UINT: 559 case UINT:
560 if (uq > TARG_UINT_MAX) { 560 if (uq > TARG_UINT_MAX) {
561 typ = ULONG; 561 typ = ULONG;
562 if (uq > TARG_ULONG_MAX && !warned) { 562 if (uq > TARG_ULONG_MAX && !warned) {
563 /* integer constant out of range */ 563 /* integer constant out of range */
564 warning(252); 564 warning(252);
565 } 565 }
566 } 566 }
567 break; 567 break;
568 case LONG: 568 case LONG:
569 if (uq > TARG_LONG_MAX && !tflag) { 569 if (uq > TARG_LONG_MAX && !tflag) {
570 typ = ULONG; 570 typ = ULONG;
571 if (!sflag) 571 if (!sflag)
572 ansiu = true; 572 ansiu = true;
573 if (uq > TARG_ULONG_MAX && !warned) { 573 if (uq > TARG_ULONG_MAX && !warned) {
574 /* integer constant out of range */ 574 /* integer constant out of range */
575 warning(252); 575 warning(252);
576 } 576 }
577 } 577 }
578 break; 578 break;
579 case ULONG: 579 case ULONG:
580 if (uq > TARG_ULONG_MAX && !warned) { 580 if (uq > TARG_ULONG_MAX && !warned) {
581 /* integer constant out of range */ 581 /* integer constant out of range */
582 warning(252); 582 warning(252);
583 } 583 }
584 break; 584 break;
585 case QUAD: 585 case QUAD:
586 if (uq > TARG_QUAD_MAX && !tflag) { 586 if (uq > TARG_QUAD_MAX && !tflag) {
587 typ = UQUAD; 587 typ = UQUAD;
588 if (!sflag) 588 if (!sflag)
589 ansiu = true; 589 ansiu = true;
590 } 590 }
591 break; 591 break;
592 case UQUAD: 592 case UQUAD:
593 if (uq > TARG_UQUAD_MAX && !warned) { 593 if (uq > TARG_UQUAD_MAX && !warned) {
594 /* integer constant out of range */ 594 /* integer constant out of range */
595 warning(252); 595 warning(252);
596 } 596 }
597 break; 597 break;
598 default: 598 default:
599 break; 599 break;
600 } 600 }
601 601
602 uq = (uint64_t)convert_integer((int64_t)uq, typ, 0); 602 uq = (uint64_t)convert_integer((int64_t)uq, typ, 0);
603 603
604 yylval.y_val = xcalloc(1, sizeof(*yylval.y_val)); 604 yylval.y_val = xcalloc(1, sizeof(*yylval.y_val));
605 yylval.y_val->v_tspec = typ; 605 yylval.y_val->v_tspec = typ;
606 yylval.y_val->v_unsigned_since_c90 = ansiu; 606 yylval.y_val->v_unsigned_since_c90 = ansiu;
607 yylval.y_val->v_quad = (int64_t)uq; 607 yylval.y_val->v_quad = (int64_t)uq;
608 608
609 return T_CON; 609 return T_CON;
610} 610}
611 611
612/* 612/*
613 * Extend or truncate q to match t. If t is signed, sign-extend. 613 * Extend or truncate q to match t. If t is signed, sign-extend.
614 * 614 *
615 * len is the number of significant bits. If len is -1, len is set 615 * len is the number of significant bits. If len is -1, len is set
616 * to the width of type t. 616 * to the width of type t.
617 */ 617 */
618int64_t 618int64_t
619convert_integer(int64_t q, tspec_t t, unsigned int len) 619convert_integer(int64_t q, tspec_t t, unsigned int len)
620{ 620{
621 uint64_t vbits; 621 uint64_t vbits;
622 622
623 if (len == 0) 623 if (len == 0)
624 len = size_in_bits(t); 624 len = size_in_bits(t);
625 625
626 vbits = value_bits(len); 626 vbits = value_bits(len);
627 return t == PTR || is_uinteger(t) || ((q & bit(len - 1)) == 0) 627 return t == PTR || is_uinteger(t) || ((q & bit(len - 1)) == 0)
628 ? (int64_t)(q & vbits) 628 ? (int64_t)(q & vbits)
629 : (int64_t)(q | ~vbits); 629 : (int64_t)(q | ~vbits);
630} 630}
631 631
632/* 632/*
633 * Convert a string representing a floating point value into its numerical 633 * Convert a string representing a floating point value into its numerical
634 * representation. Type and value are returned in yylval. 634 * representation. Type and value are returned in yylval.
635 * 635 *
636 * XXX Currently it is not possible to convert constants of type 636 * XXX Currently it is not possible to convert constants of type
637 * long double which are greater than DBL_MAX. 637 * long double which are greater than DBL_MAX.
638 */ 638 */
639int 639int
640lex_floating_constant(const char *yytext, size_t yyleng) 640lex_floating_constant(const char *yytext, size_t yyleng)
641{ 641{
642 const char *cp; 642 const char *cp;
643 size_t len; 643 size_t len;
644 tspec_t typ; 644 tspec_t typ;
645 char c, *eptr; 645 char c, *eptr;
646 double d; 646 double d;
647 float f = 0; 647 float f = 0;
648 648
649 cp = yytext; 649 cp = yytext;
650 len = yyleng; 650 len = yyleng;
651 651
652 if (cp[len - 1] == 'i') 652 if (cp[len - 1] == 'i')
653 len--; /* imaginary, do nothing for now */ 653 len--; /* imaginary, do nothing for now */
654 654
655 if ((c = cp[len - 1]) == 'f' || c == 'F') { 655 if ((c = cp[len - 1]) == 'f' || c == 'F') {
656 typ = FLOAT; 656 typ = FLOAT;
657 len--; 657 len--;
658 } else if (c == 'l' || c == 'L') { 658 } else if (c == 'l' || c == 'L') {
659 typ = LDOUBLE; 659 typ = LDOUBLE;
660 len--; 660 len--;
661 } else { 661 } else {
662 if (c == 'd' || c == 'D') 662 if (c == 'd' || c == 'D')
663 len--; 663 len--;
664 typ = DOUBLE; 664 typ = DOUBLE;
665 } 665 }
666 666
667 if (tflag && typ != DOUBLE) { 667 if (tflag && typ != DOUBLE) {
668 /* suffixes F and L are illegal in traditional C */ 668 /* suffixes F and L are illegal in traditional C */
669 warning(98); 669 warning(98);
670 } 670 }
671 671
672 errno = 0; 672 errno = 0;
673 d = strtod(cp, &eptr); 673 d = strtod(cp, &eptr);
674 if (eptr != cp + len) { 674 if (eptr != cp + len) {
675 switch (*eptr) { 675 switch (*eptr) {
676 /* 676 /*
677 * XXX: non-native non-current strtod() may not handle hex 677 * XXX: non-native non-current strtod() may not handle hex
678 * floats, ignore the rest if we find traces of hex float 678 * floats, ignore the rest if we find traces of hex float
679 * syntax... 679 * syntax...
680 */ 680 */
681 case 'p': 681 case 'p':
682 case 'P': 682 case 'P':
683 case 'x': 683 case 'x':
684 case 'X': 684 case 'X':
685 d = 0; 685 d = 0;
686 errno = 0; 686 errno = 0;
687 break; 687 break;
688 default: 688 default:
689 INTERNAL_ERROR("lex_floating_constant(%s->%s)", 689 INTERNAL_ERROR("lex_floating_constant(%s->%s)",
690 cp, eptr); 690 cp, eptr);
691 } 691 }
692 } 692 }
693 if (errno != 0) 693 if (errno != 0)
694 /* floating-point constant out of range */ 694 /* floating-point constant out of range */
695 warning(248); 695 warning(248);
696 696
697 if (typ == FLOAT) { 697 if (typ == FLOAT) {
698 f = (float)d; 698 f = (float)d;
699 if (isfinite(f) == 0) { 699 if (isfinite(f) == 0) {
700 /* floating-point constant out of range */ 700 /* floating-point constant out of range */
701 warning(248); 701 warning(248);
702 f = f > 0 ? FLT_MAX : -FLT_MAX; 702 f = f > 0 ? FLT_MAX : -FLT_MAX;
703 } 703 }
704 } 704 }
705 705
706 yylval.y_val = xcalloc(1, sizeof(*yylval.y_val)); 706 yylval.y_val = xcalloc(1, sizeof(*yylval.y_val));
707 yylval.y_val->v_tspec = typ; 707 yylval.y_val->v_tspec = typ;
708 if (typ == FLOAT) { 708 if (typ == FLOAT) {
709 yylval.y_val->v_ldbl = f; 709 yylval.y_val->v_ldbl = f;
710 } else { 710 } else {
711 yylval.y_val->v_ldbl = d; 711 yylval.y_val->v_ldbl = d;
712 } 712 }
713 713
714 return T_CON; 714 return T_CON;
715} 715}
716 716
717int 717int
718lex_operator(int t, op_t o) 718lex_operator(int t, op_t o)
719{ 719{
720 720
721 yylval.y_op = o; 721 yylval.y_op = o;
722 return t; 722 return t;
723} 723}
724 724
725/* 725/*
726 * Called if lex found a leading \'. 726 * Called if lex found a leading \'.
727 */ 727 */
728int 728int
729lex_character_constant(void) 729lex_character_constant(void)
730{ 730{
731 size_t n; 731 size_t n;
732 int val, c; 732 int val, c;
733 733
734 n = 0; 734 n = 0;
735 val = 0; 735 val = 0;
736 while ((c = get_escaped_char('\'')) >= 0) { 736 while ((c = get_escaped_char('\'')) >= 0) {
737 val = (val << CHAR_SIZE) + c; 737 val = (val << CHAR_SIZE) + c;
738 n++; 738 n++;
739 } 739 }
740 if (c == -2) { 740 if (c == -2) {
741 /* unterminated character constant */ 741 /* unterminated character constant */
742 error(253); 742 error(253);
743 } else if (n > sizeof(int) || (n > 1 && (pflag || hflag))) { 743 } else if (n > sizeof(int) || (n > 1 && (pflag || hflag))) {
744 /* XXX: should rather be sizeof(TARG_INT) */ 744 /* XXX: should rather be sizeof(TARG_INT) */
745 745
746 /* too many characters in character constant */ 746 /* too many characters in character constant */
747 error(71); 747 error(71);
748 } else if (n > 1) { 748 } else if (n > 1) {
749 /* multi-character character constant */ 749 /* multi-character character constant */
750 warning(294); 750 warning(294);
751 } else if (n == 0) { 751 } else if (n == 0) {
752 /* empty character constant */ 752 /* empty character constant */
753 error(73); 753 error(73);
754 } 754 }
755 if (n == 1) 755 if (n == 1)
756 val = (int)convert_integer(val, CHAR, CHAR_SIZE); 756 val = (int)convert_integer(val, CHAR, CHAR_SIZE);
757 757
758 yylval.y_val = xcalloc(1, sizeof(*yylval.y_val)); 758 yylval.y_val = xcalloc(1, sizeof(*yylval.y_val));
759 yylval.y_val->v_tspec = INT; 759 yylval.y_val->v_tspec = INT;
760 yylval.y_val->v_quad = val; 760 yylval.y_val->v_quad = val;
761 761
762 return T_CON; 762 return T_CON;
763} 763}
764 764
765/* 765/*
766 * Called if lex found a leading L\' 766 * Called if lex found a leading L\'
767 */ 767 */
768int 768int
769lex_wide_character_constant(void) 769lex_wide_character_constant(void)
770{ 770{
771 static char buf[MB_LEN_MAX + 1]; 771 static char buf[MB_LEN_MAX + 1];
772 size_t n, nmax; 772 size_t n, nmax;
773 int c; 773 int c;
774 wchar_t wc; 774 wchar_t wc;
775 775
776 nmax = MB_CUR_MAX; 776 nmax = MB_CUR_MAX;
777 777
778 n = 0; 778 n = 0;
779 while ((c = get_escaped_char('\'')) >= 0) { 779 while ((c = get_escaped_char('\'')) >= 0) {
780 if (n < nmax) 780 if (n < nmax)
781 buf[n] = (char)c; 781 buf[n] = (char)c;
782 n++; 782 n++;
783 } 783 }
784 784
785 wc = 0; 785 wc = 0;
786 786
787 if (c == -2) { 787 if (c == -2) {
788 /* unterminated character constant */ 788 /* unterminated character constant */
789 error(253); 789 error(253);
790 } else if (n == 0) { 790 } else if (n == 0) {
791 /* empty character constant */ 791 /* empty character constant */
792 error(73); 792 error(73);
793 } else if (n > nmax) { 793 } else if (n > nmax) {
794 n = nmax; 794 n = nmax;
795 /* too many characters in character constant */ 795 /* too many characters in character constant */
796 error(71); 796 error(71);
797 } else { 797 } else {
798 buf[n] = '\0'; 798 buf[n] = '\0';
799 (void)mbtowc(NULL, NULL, 0); 799 (void)mbtowc(NULL, NULL, 0);
800 if (mbtowc(&wc, buf, nmax) < 0) 800 if (mbtowc(&wc, buf, nmax) < 0)
801 /* invalid multibyte character */ 801 /* invalid multibyte character */
802 error(291); 802 error(291);
803 } 803 }
804 804
805 yylval.y_val = xcalloc(1, sizeof(*yylval.y_val)); 805 yylval.y_val = xcalloc(1, sizeof(*yylval.y_val));
806 yylval.y_val->v_tspec = WCHAR; 806 yylval.y_val->v_tspec = WCHAR;
807 yylval.y_val->v_quad = wc; 807 yylval.y_val->v_quad = wc;
808 808
809 return T_CON; 809 return T_CON;
810} 810}
811 811
812/* 812/*
813 * Read a character which is part of a character constant or of a string 813 * Read a character which is part of a character constant or of a string
814 * and handle escapes. 814 * and handle escapes.
815 * 815 *
816 * The argument is the character which delimits the character constant or 816 * The argument is the character which delimits the character constant or
817 * string. 817 * string.
818 * 818 *
819 * Returns -1 if the end of the character constant or string is reached, 819 * Returns -1 if the end of the character constant or string is reached,
820 * -2 if the EOF is reached, and the character otherwise. 820 * -2 if the EOF is reached, and the character otherwise.
821 */ 821 */
822static int 822static int
823get_escaped_char(int delim) 823get_escaped_char(int delim)
824{ 824{
825 static int pbc = -1; 825 static int pbc = -1;
826 int n, c, v; 826 int n, c, v;
827 827
828 if (pbc == -1) { 828 if (pbc == -1) {
829 c = inpc(); 829 c = inpc();
830 } else { 830 } else {
831 c = pbc; 831 c = pbc;
832 pbc = -1; 832 pbc = -1;
833 } 833 }
834 if (c == delim) 834 if (c == delim)
835 return -1; 835 return -1;
836 switch (c) { 836 switch (c) {
837 case '\n': 837 case '\n':
838 if (tflag) { 838 if (tflag) {
839 /* newline in string or char constant */ 839 /* newline in string or char constant */
840 error(254); 840 error(254);
841 return -2; 841 return -2;
842 } 842 }
843 return c; 843 return c;
844 case 0: 844 case 0:
845 /* syntax error '%s' */ 845 /* syntax error '%s' */
846 error(249, "EOF or null byte in literal"); 846 error(249, "EOF or null byte in literal");
847 return -2; 847 return -2;
848 case EOF: 848 case EOF:
849 return -2; 849 return -2;
850 case '\\': 850 case '\\':
851 switch (c = inpc()) { 851 switch (c = inpc()) {
852 case '"': 852 case '"':
853 if (tflag && delim == '\'') 853 if (tflag && delim == '\'')
854 /* \" inside character constants undef... */ 854 /* \" inside character constants undef... */
855 warning(262); 855 warning(262);
856 return '"'; 856 return '"';
857 case '\'': 857 case '\'':
858 return '\''; 858 return '\'';
859 case '?': 859 case '?':
860 if (tflag) 860 if (tflag)
861 /* \? undefined in traditional C */ 861 /* \? undefined in traditional C */
862 warning(263); 862 warning(263);
863 return '?'; 863 return '?';
864 case '\\': 864 case '\\':
865 return '\\'; 865 return '\\';
866 case 'a': 866 case 'a':
867 if (tflag) 867 if (tflag)
868 /* \a undefined in traditional C */ 868 /* \a undefined in traditional C */
869 warning(81); 869 warning(81);
870 return '\a'; 870 return '\a';
871 case 'b': 871 case 'b':
872 return '\b'; 872 return '\b';
873 case 'f': 873 case 'f':
874 return '\f'; 874 return '\f';
875 case 'n': 875 case 'n':
876 return '\n'; 876 return '\n';
877 case 'r': 877 case 'r':
878 return '\r'; 878 return '\r';
879 case 't': 879 case 't':
880 return '\t'; 880 return '\t';
881 case 'v': 881 case 'v':
882 if (tflag) 882 if (tflag)
883 /* \v undefined in traditional C */ 883 /* \v undefined in traditional C */
884 warning(264); 884 warning(264);
885 return '\v'; 885 return '\v';
886 case '8': case '9': 886 case '8': case '9':
887 /* bad octal digit %c */ 887 /* bad octal digit %c */
888 warning(77, c); 888 warning(77, c);
889 /* FALLTHROUGH */ 889 /* FALLTHROUGH */
890 case '0': case '1': case '2': case '3': 890 case '0': case '1': case '2': case '3':
891 case '4': case '5': case '6': case '7': 891 case '4': case '5': case '6': case '7':
892 n = 3; 892 n = 3;
893 v = 0; 893 v = 0;
894 do { 894 do {
895 v = (v << 3) + (c - '0'); 895 v = (v << 3) + (c - '0');
896 c = inpc(); 896 c = inpc();
897 } while (--n > 0 && '0' <= c && c <= '7'); 897 } while (--n > 0 && '0' <= c && c <= '7');
898 pbc = c; 898 pbc = c;
899 if (v > TARG_UCHAR_MAX) { 899 if (v > TARG_UCHAR_MAX) {
900 /* character escape does not fit in character */ 900 /* character escape does not fit in character */
901 warning(76); 901 warning(76);
902 v &= CHAR_MASK; 902 v &= CHAR_MASK;
903 } 903 }
904 return v; 904 return v;
905 case 'x': 905 case 'x':
906 if (tflag) 906 if (tflag)
907 /* \x undefined in traditional C */ 907 /* \x undefined in traditional C */
908 warning(82); 908 warning(82);
909 v = 0; 909 v = 0;
910 n = 0; 910 n = 0;
911 while (c = inpc(), isxdigit(c)) { 911 while (c = inpc(), isxdigit(c)) {
912 c = isdigit(c) ? 912 c = isdigit(c) ?
913 c - '0' : toupper(c) - 'A' + 10; 913 c - '0' : toupper(c) - 'A' + 10;
914 v = (v << 4) + c; 914 v = (v << 4) + c;
915 if (n >= 0) { 915 if (n >= 0) {
916 if ((v & ~CHAR_MASK) != 0) { 916 if ((v & ~CHAR_MASK) != 0) {
917 /* overflow in hex escape */ 917 /* overflow in hex escape */
918 warning(75); 918 warning(75);
919 n = -1; 919 n = -1;
920 } else { 920 } else {
921 n++; 921 n++;
922 } 922 }
923 } 923 }
924 } 924 }
925 pbc = c; 925 pbc = c;
926 if (n == 0) { 926 if (n == 0) {
927 /* no hex digits follow \x */ 927 /* no hex digits follow \x */
928 error(74); 928 error(74);
929 } if (n == -1) { 929 } if (n == -1) {
930 v &= CHAR_MASK; 930 v &= CHAR_MASK;
931 } 931 }
932 return v; 932 return v;
933 case '\n': 933 case '\n':
934 return get_escaped_char(delim); 934 return get_escaped_char(delim);
935 case EOF: 935 case EOF:
936 return -2; 936 return -2;
937 default: 937 default:
938 if (isprint(c)) { 938 if (isprint(c)) {
939 /* dubious escape \%c */ 939 /* dubious escape \%c */
940 warning(79, c); 940 warning(79, c);
941 } else { 941 } else {
942 /* dubious escape \%o */ 942 /* dubious escape \%o */
943 warning(80, c); 943 warning(80, c);
944 } 944 }
945 } 945 }
946 } 946 }
947 return c; 947 return c;
948} 948}
949 949
950/* See https://gcc.gnu.org/onlinedocs/cpp/Preprocessor-Output.html */ 950/* See https://gcc.gnu.org/onlinedocs/cpp/Preprocessor-Output.html */
951static void 951static void
952parse_line_directive_flags(const char *p, 952parse_line_directive_flags(const char *p,
953 bool *is_begin, bool *is_end, bool *is_system) 953 bool *is_begin, bool *is_end, bool *is_system)
954{ 954{
955 955
956 *is_begin = false; 956 *is_begin = false;
957 *is_end = false; 957 *is_end = false;
958 *is_system = false; 958 *is_system = false;
959 959
960 while (*p != '\0') { 960 while (*p != '\0') {
961 const char *word_start, *word_end; 961 const char *word_start, *word_end;
962 962
963 while (ch_isspace(*p)) 963 while (ch_isspace(*p))
964 p++; 964 p++;
965 965
966 word_start = p; 966 word_start = p;
967 while (*p != '\0' && !ch_isspace(*p)) 967 while (*p != '\0' && !ch_isspace(*p))
968 p++; 968 p++;
969 word_end = p; 969 word_end = p;
970 970
971 if (word_end - word_start == 1 && word_start[0] == '1') 971 if (word_end - word_start == 1 && word_start[0] == '1')
972 *is_begin = true; 972 *is_begin = true;
973 if (word_end - word_start == 1 && word_start[0] == '2') 973 if (word_end - word_start == 1 && word_start[0] == '2')
974 *is_end = true; 974 *is_end = true;
975 if (word_end - word_start == 1 && word_start[0] == '3') 975 if (word_end - word_start == 1 && word_start[0] == '3')
976 *is_system = true; 976 *is_system = true;
977 /* Flag '4' is only interesting for C++. */ 977 /* Flag '4' is only interesting for C++. */
978 } 978 }
979} 979}
980 980
981/* 981/*
982 * Called for preprocessor directives. Currently implemented are: 982 * Called for preprocessor directives. Currently implemented are:
983 * # pragma [argument...] 983 * # pragma [argument...]
984 * # lineno 984 * # lineno
985 * # lineno "filename" 985 * # lineno "filename"
986 * # lineno "filename" GCC-flag... 986 * # lineno "filename" GCC-flag...
987 */ 987 */
988void 988void
989lex_directive(const char *yytext) 989lex_directive(const char *yytext)
990{ 990{
991 const char *cp, *fn; 991 const char *cp, *fn;
992 char c, *eptr; 992 char c, *eptr;
993 size_t fnl; 993 size_t fnl;
994 long ln; 994 long ln;
995 bool is_begin, is_end, is_system; 995 bool is_begin, is_end, is_system;
996 996
997 static bool first = true; 997 static bool first = true;
998 998
999 /* Go to first non-whitespace after # */ 999 /* Go to first non-whitespace after # */
1000 for (cp = yytext + 1; (c = *cp) == ' ' || c == '\t'; cp++) 1000 for (cp = yytext + 1; (c = *cp) == ' ' || c == '\t'; cp++)
1001 continue; 1001 continue;
1002 1002
1003 if (!ch_isdigit(c)) { 1003 if (!ch_isdigit(c)) {
1004 if (strncmp(cp, "pragma", 6) == 0 && ch_isspace(cp[6])) 1004 if (strncmp(cp, "pragma", 6) == 0 && ch_isspace(cp[6]))
1005 return; 1005 return;
1006 error: 1006 error:
1007 /* undefined or invalid # directive */ 1007 /* undefined or invalid # directive */
1008 warning(255); 1008 warning(255);
1009 return; 1009 return;
1010 } 1010 }
1011 ln = strtol(--cp, &eptr, 10); 1011 ln = strtol(--cp, &eptr, 10);
1012 if (eptr == cp) 1012 if (eptr == cp)
1013 goto error; 1013 goto error;
1014 if ((c = *(cp = eptr)) != ' ' && c != '\t' && c != '\0') 1014 if ((c = *(cp = eptr)) != ' ' && c != '\t' && c != '\0')
1015 goto error; 1015 goto error;
1016 while ((c = *cp++) == ' ' || c == '\t') 1016 while ((c = *cp++) == ' ' || c == '\t')
1017 continue; 1017 continue;
1018 if (c != '\0') { 1018 if (c != '\0') {
1019 if (c != '"') 1019 if (c != '"')
1020 goto error; 1020 goto error;
1021 fn = cp; 1021 fn = cp;
1022 while ((c = *cp) != '"' && c != '\0') 1022 while ((c = *cp) != '"' && c != '\0')
1023 cp++; 1023 cp++;
1024 if (c != '"') 1024 if (c != '"')
1025 goto error; 1025 goto error;
1026 if ((fnl = cp++ - fn) > PATH_MAX) 1026 if ((fnl = cp++ - fn) > PATH_MAX)
1027 goto error; 1027 goto error;
1028 /* empty string means stdin */ 1028 /* empty string means stdin */
1029 if (fnl == 0) { 1029 if (fnl == 0) {
1030 fn = "{standard input}"; 1030 fn = "{standard input}";
1031 fnl = 16; /* strlen (fn) */ 1031 fnl = 16; /* strlen (fn) */
1032 } 1032 }
1033 curr_pos.p_file = record_filename(fn, fnl); 1033 curr_pos.p_file = record_filename(fn, fnl);
1034 /* 1034 /*
1035 * If this is the first directive, the name is the name 1035 * If this is the first directive, the name is the name
1036 * of the C source file as specified at the command line. 1036 * of the C source file as specified at the command line.
1037 * It is written to the output file. 1037 * It is written to the output file.
1038 */ 1038 */
1039 if (first) { 1039 if (first) {
1040 csrc_pos.p_file = curr_pos.p_file; 1040 csrc_pos.p_file = curr_pos.p_file;
1041 outsrc(transform_filename(curr_pos.p_file, 1041 outsrc(transform_filename(curr_pos.p_file,
1042 strlen(curr_pos.p_file))); 1042 strlen(curr_pos.p_file)));
1043 first = false; 1043 first = false;
1044 } 1044 }
1045 1045
1046 parse_line_directive_flags(cp, &is_begin, &is_end, &is_system); 1046 parse_line_directive_flags(cp, &is_begin, &is_end, &is_system);
1047 update_location(curr_pos.p_file, (int)ln, is_begin, is_end); 1047 update_location(curr_pos.p_file, (int)ln, is_begin, is_end);
1048 in_system_header = is_system; 1048 in_system_header = is_system;
1049 } 1049 }
1050 curr_pos.p_line = (int)ln - 1; 1050 curr_pos.p_line = (int)ln - 1;
1051 curr_pos.p_uniq = 0; 1051 curr_pos.p_uniq = 0;
1052 if (curr_pos.p_file == csrc_pos.p_file) { 1052 if (curr_pos.p_file == csrc_pos.p_file) {
1053 csrc_pos.p_line = (int)ln - 1; 1053 csrc_pos.p_line = (int)ln - 1;
1054 csrc_pos.p_uniq = 0; 1054 csrc_pos.p_uniq = 0;
1055 } 1055 }
1056} 1056}
1057 1057
1058/* 1058/*
1059 * Handle lint comments such as ARGSUSED. 1059 * Handle lint comments such as ARGSUSED.
1060 * 1060 *
1061 * If one of these comments is recognized, the argument, if any, is 1061 * If one of these comments is recognized, the argument, if any, is
1062 * parsed and a function which handles this comment is called. 1062 * parsed and a function which handles this comment is called.
1063 */ 1063 */
1064void 1064void
1065lex_comment(void) 1065lex_comment(void)
1066{ 1066{
1067 int c, lc; 1067 int c, lc;
1068 static const struct { 1068 static const struct {
1069 const char *keywd; 1069 const char *keywd;
1070 bool arg; 1070 bool arg;
1071 void (*func)(int); 1071 void (*func)(int);
1072 } keywtab[] = { 1072 } keywtab[] = {
1073 { "ARGSUSED", true, argsused }, 1073 { "ARGSUSED", true, argsused },
1074 { "BITFIELDTYPE", false, bitfieldtype }, 1074 { "BITFIELDTYPE", false, bitfieldtype },
1075 { "CONSTCOND", false, constcond }, 1075 { "CONSTCOND", false, constcond },
1076 { "CONSTANTCOND", false, constcond }, 1076 { "CONSTANTCOND", false, constcond },
1077 { "CONSTANTCONDITION", false, constcond }, 1077 { "CONSTANTCONDITION", false, constcond },
1078 { "FALLTHRU", false, fallthru }, 1078 { "FALLTHRU", false, fallthru },
1079 { "FALLTHROUGH", false, fallthru }, 1079 { "FALLTHROUGH", false, fallthru },
1080 { "FALL THROUGH", false, fallthru }, 1080 { "FALL THROUGH", false, fallthru },
1081 { "fallthrough", false, fallthru }, 1081 { "fallthrough", false, fallthru },
1082 { "LINTLIBRARY", false, lintlib }, 1082 { "LINTLIBRARY", false, lintlib },
1083 { "LINTED", true, linted }, 1083 { "LINTED", true, linted },
1084 { "LONGLONG", false, longlong }, 1084 { "LONGLONG", false, longlong },
1085 { "NOSTRICT", true, linted }, 1085 { "NOSTRICT", true, linted },
1086 { "NOTREACHED", false, not_reached }, 1086 { "NOTREACHED", false, not_reached },
1087 { "PRINTFLIKE", true, printflike }, 1087 { "PRINTFLIKE", true, printflike },
1088 { "PROTOLIB", true, protolib }, 1088 { "PROTOLIB", true, protolib },
1089 { "SCANFLIKE", true, scanflike }, 1089 { "SCANFLIKE", true, scanflike },
1090 { "VARARGS", true, varargs }, 1090 { "VARARGS", true, varargs },
1091 }; 1091 };
1092 char keywd[32]; 1092 char keywd[32];
1093 char arg[32]; 1093 char arg[32];
1094 size_t l, i; 1094 size_t l, i;
1095 int a; 1095 int a;
1096 bool eoc; 1096 bool eoc;
1097 1097
1098 eoc = false; 1098 eoc = false;
1099 1099
1100 /* Skip whitespace after the start of the comment */ 1100 /* Skip whitespace after the start of the comment */
1101 while (c = inpc(), isspace(c)) 1101 while (c = inpc(), isspace(c))
1102 continue; 1102 continue;
1103 1103
1104 /* Read the potential keyword to keywd */ 1104 /* Read the potential keyword to keywd */
1105 l = 0; 1105 l = 0;
1106 while (c != EOF && l < sizeof(keywd) - 1 && 1106 while (c != EOF && l < sizeof(keywd) - 1 &&
1107 (isalpha(c) || isspace(c))) { 1107 (isalpha(c) || isspace(c))) {
1108 if (islower(c) && l > 0 && ch_isupper(keywd[0])) 1108 if (islower(c) && l > 0 && ch_isupper(keywd[0]))
1109 break; 1109 break;
1110 keywd[l++] = (char)c; 1110 keywd[l++] = (char)c;
1111 c = inpc(); 1111 c = inpc();
1112 } 1112 }
1113 while (l > 0 && ch_isspace(keywd[l - 1])) 1113 while (l > 0 && ch_isspace(keywd[l - 1]))
1114 l--; 1114 l--;
1115 keywd[l] = '\0'; 1115 keywd[l] = '\0';
1116 1116
1117 /* look for the keyword */ 1117 /* look for the keyword */
1118 for (i = 0; i < sizeof(keywtab) / sizeof(keywtab[0]); i++) { 1118 for (i = 0; i < sizeof(keywtab) / sizeof(keywtab[0]); i++) {
1119 if (strcmp(keywtab[i].keywd, keywd) == 0) 1119 if (strcmp(keywtab[i].keywd, keywd) == 0)
1120 break; 1120 break;
1121 } 1121 }
1122 if (i == sizeof(keywtab) / sizeof(keywtab[0])) 1122 if (i == sizeof(keywtab) / sizeof(keywtab[0]))
1123 goto skip_rest; 1123 goto skip_rest;
1124 1124
1125 /* skip whitespace after the keyword */ 1125 /* skip whitespace after the keyword */
1126 while (isspace(c)) 1126 while (isspace(c))
1127 c = inpc(); 1127 c = inpc();
1128 1128
1129 /* read the argument, if the keyword accepts one and there is one */ 1129 /* read the argument, if the keyword accepts one and there is one */
1130 l = 0; 1130 l = 0;
1131 if (keywtab[i].arg) { 1131 if (keywtab[i].arg) {
1132 while (isdigit(c) && l < sizeof(arg) - 1) { 1132 while (isdigit(c) && l < sizeof(arg) - 1) {
1133 arg[l++] = (char)c; 1133 arg[l++] = (char)c;
1134 c = inpc(); 1134 c = inpc();
1135 } 1135 }
1136 } 1136 }
1137 arg[l] = '\0'; 1137 arg[l] = '\0';
1138 a = l != 0 ? atoi(arg) : -1; 1138 a = l != 0 ? atoi(arg) : -1;
1139 1139
1140 /* skip whitespace after the argument */ 1140 /* skip whitespace after the argument */
1141 while (isspace(c)) 1141 while (isspace(c))
1142 c = inpc(); 1142 c = inpc();
1143 1143
1144 if (c != '*' || (c = inpc()) != '/') { 1144 if (c != '*' || (c = inpc()) != '/') {
1145 if (keywtab[i].func != linted) 1145 if (keywtab[i].func != linted)
1146 /* extra characters in lint comment */ 1146 /* extra characters in lint comment */
1147 warning(257); 1147 warning(257);
1148 } else { 1148 } else {
1149 /* 1149 /*
1150 * remember that we have already found the end of the 1150 * remember that we have already found the end of the
1151 * comment 1151 * comment
1152 */ 1152 */
1153 eoc = true; 1153 eoc = true;
1154 } 1154 }
1155 1155
1156 if (keywtab[i].func != NULL) 1156 if (keywtab[i].func != NULL)
1157 (*keywtab[i].func)(a); 1157 (*keywtab[i].func)(a);
1158 1158
1159skip_rest: 1159skip_rest:
1160 while (!eoc) { 1160 while (!eoc) {
1161 lc = c; 1161 lc = c;
1162 if ((c = inpc()) == EOF) { 1162 if ((c = inpc()) == EOF) {
1163 /* unterminated comment */ 1163 /* unterminated comment */
1164 error(256); 1164 error(256);
1165 break; 1165 break;
1166 } 1166 }
1167 if (lc == '*' && c == '/') 1167 if (lc == '*' && c == '/')
1168 eoc = true; 1168 eoc = true;
1169 } 1169 }
1170} 1170}
1171 1171
1172/* 1172/*
1173 * Handle // style comments 1173 * Handle // style comments
1174 */ 1174 */
1175void 1175void
1176lex_slash_slash_comment(void) 1176lex_slash_slash_comment(void)
1177{ 1177{
1178 int c; 1178 int c;
1179 1179
1180 if (!Sflag && !gflag) 1180 if (!Sflag && !gflag)
1181 /* %s does not support // comments */ 1181 /* %s does not support // comments */
1182 gnuism(312, tflag ? "traditional C" : "C90"); 1182 gnuism(312, tflag ? "traditional C" : "C90");
1183 1183
1184 while ((c = inpc()) != EOF && c != '\n') 1184 while ((c = inpc()) != EOF && c != '\n')
1185 continue; 1185 continue;
1186} 1186}
1187 1187
1188/* 1188/*
1189 * Clear flags for lint comments LINTED, LONGLONG and CONSTCOND. 1189 * Clear flags for lint comments LINTED, LONGLONG and CONSTCOND.
1190 * clear_warn_flags is called after function definitions and global and 1190 * clear_warn_flags is called after function definitions and global and
1191 * local declarations and definitions. It is also called between 1191 * local declarations and definitions. It is also called between
1192 * the controlling expression and the body of control statements 1192 * the controlling expression and the body of control statements
1193 * (if, switch, for, while). 1193 * (if, switch, for, while).
1194 */ 1194 */
1195void 1195void
1196clear_warn_flags(void) 1196clear_warn_flags(void)
1197{ 1197{
1198 1198
1199 lwarn = LWARN_ALL; 1199 lwarn = LWARN_ALL;
1200 quadflg = false; 1200 quadflg = false;
1201 constcond_flag = false; 1201 constcond_flag = false;
1202} 1202}
1203 1203
1204/* 1204/*
1205 * Strings are stored in a dynamically allocated buffer and passed 1205 * Strings are stored in a dynamically allocated buffer and passed
1206 * in yylval.y_string to the parser. The parser or the routines called 1206 * in yylval.y_string to the parser. The parser or the routines called
1207 * by the parser are responsible for freeing this buffer. 1207 * by the parser are responsible for freeing this buffer.
1208 */ 1208 */
1209int 1209int
1210lex_string(void) 1210lex_string(void)
1211{ 1211{
1212 unsigned char *s; 1212 unsigned char *s;
1213 int c; 1213 int c;
1214 size_t len, max; 1214 size_t len, max;
1215 strg_t *strg; 1215 strg_t *strg;
1216 1216
1217 s = xmalloc(max = 64); 1217 s = xmalloc(max = 64);
1218 1218
1219 len = 0; 1219 len = 0;
1220 while ((c = get_escaped_char('"')) >= 0) { 1220 while ((c = get_escaped_char('"')) >= 0) {
1221 /* +1 to reserve space for a trailing NUL character */ 1221 /* +1 to reserve space for a trailing NUL character */
1222 if (len + 1 == max) 1222 if (len + 1 == max)
1223 s = xrealloc(s, max *= 2); 1223 s = xrealloc(s, max *= 2);
1224 s[len++] = (char)c; 1224 s[len++] = (char)c;
1225 } 1225 }
1226 s[len] = '\0'; 1226 s[len] = '\0';
1227 if (c == -2) 1227 if (c == -2)
1228 /* unterminated string constant */ 1228 /* unterminated string constant */
1229 error(258); 1229 error(258);
1230 1230
1231 strg = xcalloc(1, sizeof(*strg)); 1231 strg = xcalloc(1, sizeof(*strg));
1232 strg->st_tspec = CHAR; 1232 strg->st_tspec = CHAR;
1233 strg->st_len = len; 1233 strg->st_len = len;
1234 strg->st_cp = s; 1234 strg->st_cp = s;
1235 1235
1236 yylval.y_string = strg; 1236 yylval.y_string = strg;
1237 return T_STRING; 1237 return T_STRING;
1238} 1238}
1239 1239
1240int 1240int
1241lex_wide_string(void) 1241lex_wide_string(void)
1242{ 1242{
1243 char *s; 1243 char *s;
1244 int c, n; 1244 int c, n;
1245 size_t i, wi; 1245 size_t i, wi;
1246 size_t len, max, wlen; 1246 size_t len, max, wlen;
1247 wchar_t *ws; 1247 wchar_t *ws;
1248 strg_t *strg; 1248 strg_t *strg;
1249 1249
1250 s = xmalloc(max = 64); 1250 s = xmalloc(max = 64);
1251 len = 0; 1251 len = 0;
1252 while ((c = get_escaped_char('"')) >= 0) { 1252 while ((c = get_escaped_char('"')) >= 0) {
1253 /* +1 to save space for a trailing NUL character */ 1253 /* +1 to save space for a trailing NUL character */
1254 if (len + 1 >= max) 1254 if (len + 1 >= max)
1255 s = xrealloc(s, max *= 2); 1255 s = xrealloc(s, max *= 2);
1256 s[len++] = (char)c; 1256 s[len++] = (char)c;
1257 } 1257 }
1258 s[len] = '\0'; 1258 s[len] = '\0';
1259 if (c == -2) 1259 if (c == -2)
1260 /* unterminated string constant */ 1260 /* unterminated string constant */
1261 error(258); 1261 error(258);
1262 1262
1263 /* get length of wide-character string */ 1263 /* get length of wide-character string */
1264 (void)mblen(NULL, 0); 1264 (void)mblen(NULL, 0);
1265 for (i = 0, wlen = 0; i < len; i += n, wlen++) { 1265 for (i = 0, wlen = 0; i < len; i += n, wlen++) {
1266 if ((n = mblen(&s[i], MB_CUR_MAX)) == -1) { 1266 if ((n = mblen(&s[i], MB_CUR_MAX)) == -1) {
1267 /* invalid multibyte character */ 1267 /* invalid multibyte character */
1268 error(291); 1268 error(291);
1269 break; 1269 break;
1270 } 1270 }
1271 if (n == 0) 1271 if (n == 0)
1272 n = 1; 1272 n = 1;
1273 } 1273 }
1274 1274
1275 ws = xmalloc((wlen + 1) * sizeof(*ws)); 1275 ws = xmalloc((wlen + 1) * sizeof(*ws));
1276 1276
1277 /* convert from multibyte to wide char */ 1277 /* convert from multibyte to wide char */
1278 (void)mbtowc(NULL, NULL, 0); 1278 (void)mbtowc(NULL, NULL, 0);
1279 for (i = 0, wi = 0; i < len; i += n, wi++) { 1279 for (i = 0, wi = 0; i < len; i += n, wi++) {
1280 if ((n = mbtowc(&ws[wi], &s[i], MB_CUR_MAX)) == -1) 1280 if ((n = mbtowc(&ws[wi], &s[i], MB_CUR_MAX)) == -1)
1281 break; 1281 break;
1282 if (n == 0) 1282 if (n == 0)
1283 n = 1; 1283 n = 1;
1284 } 1284 }
1285 ws[wi] = 0; 1285 ws[wi] = 0;
1286 free(s); 1286 free(s);
1287 1287
1288 strg = xcalloc(1, sizeof(*strg)); 1288 strg = xcalloc(1, sizeof(*strg));
1289 strg->st_tspec = WCHAR; 1289 strg->st_tspec = WCHAR;
1290 strg->st_len = wlen; 1290 strg->st_len = wlen;
1291 strg->st_wcp = ws; 1291 strg->st_wcp = ws;
1292 1292
1293 yylval.y_string = strg; 1293 yylval.y_string = strg;
1294 return T_STRING; 1294 return T_STRING;
1295} 1295}
1296 1296
1297#ifdef DEBUG 1297#ifdef DEBUG
1298static const char * 1298static const char *
1299symt_name(symt_t kind) 1299symt_name(symt_t kind)
1300{ 1300{
1301 static const char *name[] = { 1301 static const char *name[] = {
1302 "var-func-type", 1302 "var-func-type",
1303 "member", 1303 "member",
1304 "tag", 1304 "tag",
1305 "label", 1305 "label",
1306 }; 1306 };
1307 return name[kind]; 1307 return name[kind];
1308} 1308}
1309#endif 1309#endif
1310 1310
1311/* 1311/*
1312 * As noted above, the scanner does not create new symbol table entries 1312 * As noted above, the scanner does not create new symbol table entries
1313 * for symbols it cannot find in the symbol table. This is to avoid 1313 * for symbols it cannot find in the symbol table. This is to avoid
1314 * putting undeclared symbols into the symbol table if a syntax error 1314 * putting undeclared symbols into the symbol table if a syntax error
1315 * occurs. 1315 * occurs.
1316 * 1316 *
1317 * getsym() is called as soon as it is probably ok to put the symbol in the 1317 * getsym() is called as soon as it is probably ok to put the symbol in the
1318 * symbol table. It is still possible that symbols are put in the symbol 1318 * symbol table. It is still possible that symbols are put in the symbol
1319 * table that are not completely declared due to syntax errors. To avoid too 1319 * table that are not completely declared due to syntax errors. To avoid too
1320 * many problems in this case, symbols get type 'int' in getsym(). 1320 * many problems in this case, symbols get type 'int' in getsym().
1321 * 1321 *
1322 * XXX calls to getsym() should be delayed until decl1*() is called. 1322 * XXX calls to getsym() should be delayed until decl1*() is called.
1323 */ 1323 */
1324sym_t * 1324sym_t *
1325getsym(sbuf_t *sb) 1325getsym(sbuf_t *sb)
1326{ 1326{
1327 dinfo_t *di; 1327 dinfo_t *di;
1328 char *s; 1328 char *s;
1329 sym_t *sym; 1329 sym_t *sym;
1330 1330
1331 sym = sb->sb_sym; 1331 sym = sb->sb_sym;
1332 1332
1333 /* 1333 /*
1334 * During member declaration it is possible that name() looked 1334 * During member declaration it is possible that name() looked
1335 * for symbols of type FVFT, although it should have looked for 1335 * for symbols of type FVFT, although it should have looked for
1336 * symbols of type FTAG. Same can happen for labels. Both cases 1336 * symbols of type FTAG. Same can happen for labels. Both cases
1337 * are compensated here. 1337 * are compensated here.
1338 */ 1338 */
1339 if (symtyp == FMEMBER || symtyp == FLABEL) { 1339 if (symtyp == FMEMBER || symtyp == FLABEL) {
1340 if (sym == NULL || sym->s_kind == FVFT) 1340 if (sym == NULL || sym->s_kind == FVFT)
1341 sym = search(sb); 1341 sym = search(sb);
1342 } 1342 }
1343 1343
1344 if (sym != NULL) { 1344 if (sym != NULL) {
1345 lint_assert(sym->s_kind == symtyp); 1345 lint_assert(sym->s_kind == symtyp);
1346 symtyp = FVFT; 1346 symtyp = FVFT;
1347 free(sb); 1347 free(sb);
1348 return sym; 1348 return sym;
1349 } 1349 }
1350 1350
1351 /* create a new symbol table entry */ 1351 /* create a new symbol table entry */
1352 1352
1353 /* labels must always be allocated at level 1 (outermost block) */ 1353 /* labels must always be allocated at level 1 (outermost block) */
1354 if (symtyp == FLABEL) { 1354 if (symtyp == FLABEL) {
1355 sym = level_zero_alloc(1, sizeof(*sym)); 1355 sym = level_zero_alloc(1, sizeof(*sym));
1356 s = level_zero_alloc(1, sb->sb_len + 1); 1356 s = level_zero_alloc(1, sb->sb_len + 1);
1357 (void)memcpy(s, sb->sb_name, sb->sb_len + 1); 1357 (void)memcpy(s, sb->sb_name, sb->sb_len + 1);
1358 sym->s_name = s; 1358 sym->s_name = s;
1359 sym->s_block_level = 1; 1359 sym->s_block_level = 1;
1360 di = dcs; 1360 di = dcs;
1361 while (di->d_next != NULL && di->d_next->d_next != NULL) 1361 while (di->d_next != NULL && di->d_next->d_next != NULL)
1362 di = di->d_next; 1362 di = di->d_next;
1363 lint_assert(di->d_ctx == AUTO); 1363 lint_assert(di->d_ctx == AUTO);
1364 } else { 1364 } else {
1365 sym = block_zero_alloc(sizeof(*sym)); 1365 sym = block_zero_alloc(sizeof(*sym));
1366 sym->s_name = sb->sb_name; 1366 sym->s_name = sb->sb_name;
1367 sym->s_block_level = block_level; 1367 sym->s_block_level = block_level;
1368 di = dcs; 1368 di = dcs;
1369 } 1369 }
1370 1370
1371 UNIQUE_CURR_POS(sym->s_def_pos); 1371 UNIQUE_CURR_POS(sym->s_def_pos);
1372 if ((sym->s_kind = symtyp) != FLABEL) 1372 if ((sym->s_kind = symtyp) != FLABEL)
1373 sym->s_type = gettyp(INT); 1373 sym->s_type = gettyp(INT);
1374 1374
1375 symtyp = FVFT; 1375 symtyp = FVFT;
1376 1376
1377 symtab_add(sym); 1377 symtab_add(sym);
1378 1378
1379 *di->d_ldlsym = sym; 1379 *di->d_ldlsym = sym;
1380 di->d_ldlsym = &sym->s_dlnxt; 1380 di->d_ldlsym = &sym->s_level_next;
1381 1381
1382 free(sb); 1382 free(sb);
1383 return sym; 1383 return sym;
1384} 1384}
1385 1385
1386/* 1386/*
1387 * Construct a temporary symbol. The symbol name starts with a digit, making 1387 * Construct a temporary symbol. The symbol name starts with a digit, making
1388 * the name illegal. 1388 * the name illegal.
1389 */ 1389 */
1390sym_t * 1390sym_t *
1391mktempsym(type_t *t) 1391mktempsym(type_t *t)
1392{ 1392{
1393 static int n = 0; 1393 static int n = 0;
1394 char *s = level_zero_alloc(block_level, 64); 1394 char *s = level_zero_alloc(block_level, 64);
1395 sym_t *sym = block_zero_alloc(sizeof(*sym)); 1395 sym_t *sym = block_zero_alloc(sizeof(*sym));
1396 scl_t scl; 1396 scl_t scl;
1397 1397
1398 (void)snprintf(s, 64, "%.8d_tmp", n++); 1398 (void)snprintf(s, 64, "%.8d_tmp", n++);
1399 1399
1400 scl = dcs->d_scl; 1400 scl = dcs->d_scl;
1401 if (scl == NOSCL) 1401 if (scl == NOSCL)
1402 scl = block_level > 0 ? AUTO : EXTERN; 1402 scl = block_level > 0 ? AUTO : EXTERN;
1403 1403
1404 sym->s_name = s; 1404 sym->s_name = s;
1405 sym->s_type = t; 1405 sym->s_type = t;
1406 sym->s_block_level = block_level; 1406 sym->s_block_level = block_level;
1407 sym->s_scl = scl; 1407 sym->s_scl = scl;
1408 sym->s_kind = FVFT; 1408 sym->s_kind = FVFT;
1409 sym->s_used = true; 1409 sym->s_used = true;
1410 sym->s_set = true; 1410 sym->s_set = true;
1411 1411
1412 symtab_add(sym); 1412 symtab_add(sym);
1413 1413
1414 *dcs->d_ldlsym = sym; 1414 *dcs->d_ldlsym = sym;
1415 dcs->d_ldlsym = &sym->s_dlnxt; 1415 dcs->d_ldlsym = &sym->s_level_next;
1416 1416
1417 return sym; 1417 return sym;
1418} 1418}
1419 1419
1420/* Remove a symbol forever from the symbol table. */ 1420/* Remove a symbol forever from the symbol table. */
1421void 1421void
1422rmsym(sym_t *sym) 1422rmsym(sym_t *sym)
1423{ 1423{
1424 1424
1425 debug_step("rmsym '%s' %s '%s'", 1425 debug_step("rmsym '%s' %s '%s'",
1426 sym->s_name, symt_name(sym->s_kind), type_name(sym->s_type)); 1426 sym->s_name, symt_name(sym->s_kind), type_name(sym->s_type));
1427 symtab_remove(sym); 1427 symtab_remove(sym);
1428 1428
1429 /* avoid that the symbol will later be put back to the symbol table */ 1429 /* avoid that the symbol will later be put back to the symbol table */
1430 sym->s_block_level = -1; 1430 sym->s_block_level = -1;
1431} 1431}
1432 1432
1433/* 1433/*
1434 * Remove a list of symbols declared at one level from the symbol 1434 * Remove a list of symbols declared at one level from the symbol
1435 * table. 1435 * table.
1436 */ 1436 */
1437void 1437void
1438rmsyms(sym_t *syms) 1438rmsyms(sym_t *syms)
1439{ 1439{
1440 sym_t *sym; 1440 sym_t *sym;
1441 1441
1442 for (sym = syms; sym != NULL; sym = sym->s_dlnxt) { 1442 for (sym = syms; sym != NULL; sym = sym->s_level_next) {
1443 if (sym->s_block_level != -1) { 1443 if (sym->s_block_level != -1) {
1444 debug_step("rmsyms '%s' %s '%s'", 1444 debug_step("rmsyms '%s' %s '%s'",
1445 sym->s_name, symt_name(sym->s_kind), 1445 sym->s_name, symt_name(sym->s_kind),
1446 type_name(sym->s_type)); 1446 type_name(sym->s_type));
1447 symtab_remove(sym); 1447 symtab_remove(sym);
1448 sym->s_rlink = NULL; 1448 sym->s_symtab_ref = NULL;
1449 } 1449 }
1450 } 1450 }
1451} 1451}
1452 1452
1453/* 1453/*
1454 * Put a symbol into the symbol table. 1454 * Put a symbol into the symbol table.
1455 */ 1455 */
1456void 1456void
1457inssym(int bl, sym_t *sym) 1457inssym(int bl, sym_t *sym)
1458{ 1458{
1459 1459
1460 debug_step("inssym '%s' %s '%s'", 1460 debug_step("inssym '%s' %s '%s'",
1461 sym->s_name, symt_name(sym->s_kind), type_name(sym->s_type)); 1461 sym->s_name, symt_name(sym->s_kind), type_name(sym->s_type));
1462 symtab_add(sym); 1462 symtab_add(sym);
1463 sym->s_block_level = bl; 1463 sym->s_block_level = bl;
1464 lint_assert(sym->s_link == NULL || 1464 lint_assert(sym->s_symtab_next == NULL ||
1465 sym->s_block_level >= sym->s_link->s_block_level); 1465 sym->s_block_level >= sym->s_symtab_next->s_block_level);
1466} 1466}
1467 1467
1468/* 1468/*
1469 * Called at level 0 after syntax errors. 1469 * Called at level 0 after syntax errors.
1470 * 1470 *
1471 * Removes all symbols which are not declared at level 0 from the 1471 * Removes all symbols which are not declared at level 0 from the
1472 * symbol table. Also frees all memory which is not associated with 1472 * symbol table. Also frees all memory which is not associated with
1473 * level 0. 1473 * level 0.
1474 */ 1474 */
1475void 1475void
1476cleanup(void) 1476cleanup(void)
1477{ 1477{
1478 sym_t *sym, *nsym; 1478 sym_t *sym, *nsym;
1479 size_t i; 1479 size_t i;
1480 1480
1481 for (i = 0; i < HSHSIZ1; i++) { 1481 for (i = 0; i < HSHSIZ1; i++) {
1482 for (sym = symtab[i]; sym != NULL; sym = nsym) { 1482 for (sym = symtab[i]; sym != NULL; sym = nsym) {
1483 nsym = sym->s_link; 1483 nsym = sym->s_symtab_next;
1484 if (sym->s_block_level >= 1) 1484 if (sym->s_block_level >= 1)
1485 symtab_remove(sym); 1485 symtab_remove(sym);
1486 } 1486 }
1487 } 1487 }
1488 1488
1489 for (i = mem_block_level; i > 0; i--) 1489 for (i = mem_block_level; i > 0; i--)
1490 level_free_all(i); 1490 level_free_all(i);
1491} 1491}
1492 1492
1493/* 1493/*
1494 * Create a new symbol with the name of an existing symbol. 1494 * Create a new symbol with the name of an existing symbol.
1495 */ 1495 */
1496sym_t * 1496sym_t *
1497pushdown(const sym_t *sym) 1497pushdown(const sym_t *sym)
1498{ 1498{
1499 sym_t *nsym; 1499 sym_t *nsym;
1500 1500
1501 debug_step("pushdown '%s' %s '%s'", 1501 debug_step("pushdown '%s' %s '%s'",
1502 sym->s_name, symt_name(sym->s_kind), type_name(sym->s_type)); 1502 sym->s_name, symt_name(sym->s_kind), type_name(sym->s_type));
1503 nsym = block_zero_alloc(sizeof(*nsym)); 1503 nsym = block_zero_alloc(sizeof(*nsym));
1504 lint_assert(sym->s_block_level <= block_level); 1504 lint_assert(sym->s_block_level <= block_level);
1505 nsym->s_name = sym->s_name; 1505 nsym->s_name = sym->s_name;
1506 UNIQUE_CURR_POS(nsym->s_def_pos); 1506 UNIQUE_CURR_POS(nsym->s_def_pos);
1507 nsym->s_kind = sym->s_kind; 1507 nsym->s_kind = sym->s_kind;
1508 nsym->s_block_level = block_level; 1508 nsym->s_block_level = block_level;
1509 1509
1510 symtab_add(nsym); 1510 symtab_add(nsym);
1511 1511
1512 *dcs->d_ldlsym = nsym; 1512 *dcs->d_ldlsym = nsym;
1513 dcs->d_ldlsym = &nsym->s_dlnxt; 1513 dcs->d_ldlsym = &nsym->s_level_next;
1514 1514
1515 return nsym; 1515 return nsym;
1516} 1516}
1517 1517
1518/* 1518/*
1519 * Free any dynamically allocated memory referenced by 1519 * Free any dynamically allocated memory referenced by
1520 * the value stack or yylval. 1520 * the value stack or yylval.
1521 * The type of information in yylval is described by tok. 1521 * The type of information in yylval is described by tok.
1522 */ 1522 */
1523void 1523void
1524freeyyv(void *sp, int tok) 1524freeyyv(void *sp, int tok)
1525{ 1525{
1526 if (tok == T_NAME || tok == T_TYPENAME) { 1526 if (tok == T_NAME || tok == T_TYPENAME) {
1527 sbuf_t *sb = *(sbuf_t **)sp; 1527 sbuf_t *sb = *(sbuf_t **)sp;
1528 free(sb); 1528 free(sb);
1529 } else if (tok == T_CON) { 1529 } else if (tok == T_CON) {
1530 val_t *val = *(val_t **)sp; 1530 val_t *val = *(val_t **)sp;
1531 free(val); 1531 free(val);
1532 } else if (tok == T_STRING) { 1532 } else if (tok == T_STRING) {
1533 strg_t *strg = *(strg_t **)sp; 1533 strg_t *strg = *(strg_t **)sp;
1534 if (strg->st_tspec == CHAR) { 1534 if (strg->st_tspec == CHAR) {
1535 free(strg->st_cp); 1535 free(strg->st_cp);
1536 } else { 1536 } else {
1537 lint_assert(strg->st_tspec == WCHAR); 1537 lint_assert(strg->st_tspec == WCHAR);
1538 free(strg->st_wcp); 1538 free(strg->st_wcp);
1539 } 1539 }
1540 free(strg); 1540 free(strg);
1541 } 1541 }
1542} 1542}

cvs diff -r1.138 -r1.139 src/usr.bin/xlint/lint1/lint1.h (switch to unified diff)

--- src/usr.bin/xlint/lint1/lint1.h 2022/02/27 07:50:09 1.138
+++ src/usr.bin/xlint/lint1/lint1.h 2022/02/27 10:44:45 1.139
@@ -1,601 +1,603 @@ @@ -1,601 +1,603 @@
1/* $NetBSD: lint1.h,v 1.138 2022/02/27 07:50:09 rillig Exp $ */ 1/* $NetBSD: lint1.h,v 1.139 2022/02/27 10:44:45 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. 4 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
5 * Copyright (c) 1994, 1995 Jochen Pohl 5 * Copyright (c) 1994, 1995 Jochen Pohl
6 * All Rights Reserved. 6 * All Rights Reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement: 17 * must display the following acknowledgement:
18 * This product includes software developed by Jochen Pohl for 18 * This product includes software developed by Jochen Pohl for
19 * The NetBSD Project. 19 * The NetBSD Project.
20 * 4. The name of the author may not be used to endorse or promote products 20 * 4. The name of the author may not be used to endorse or promote products
21 * derived from this software without specific prior written permission. 21 * derived from this software without specific prior written permission.
22 * 22 *
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */ 33 */
34 34
35#include "lint.h" 35#include "lint.h"
36#include "err-msgs.h" 36#include "err-msgs.h"
37#include "op.h" 37#include "op.h"
38 38
39/* 39/*
40 * XXX - Super conservative so that works for most systems, but we should 40 * XXX - Super conservative so that works for most systems, but we should
41 * not depend on the host settings but the target settings in determining 41 * not depend on the host settings but the target settings in determining
42 * the alignment. The only valid use for this is in mem1.c; uses in decl.c 42 * the alignment. The only valid use for this is in mem1.c; uses in decl.c
43 * are bogus. 43 * are bogus.
44 */ 44 */
45#ifndef WORST_ALIGN 45#ifndef WORST_ALIGN
46#ifdef _LP64 46#ifdef _LP64
47# define AVAL 15 47# define AVAL 15
48#else 48#else
49# define AVAL 7 49# define AVAL 7
50#endif 50#endif
51#define WORST_ALIGN(x) (((x) + AVAL) & ~AVAL) 51#define WORST_ALIGN(x) (((x) + AVAL) & ~AVAL)
52#endif 52#endif
53 53
54#define LWARN_BAD (-3) 54#define LWARN_BAD (-3)
55#define LWARN_ALL (-2) 55#define LWARN_ALL (-2)
56#define LWARN_NONE (-1) 56#define LWARN_NONE (-1)
57 57
58/* 58/*
59 * Describes the position of a declaration or anything else. 59 * Describes the position of a declaration or anything else.
60 * 60 *
61 * FIXME: Just a single file:lineno pair is not enough to accurately describe 61 * FIXME: Just a single file:lineno pair is not enough to accurately describe
62 * the position of a symbol. The whole inclusion path at that point must be 62 * the position of a symbol. The whole inclusion path at that point must be
63 * stored as well. This makes a difference for symbols from included 63 * stored as well. This makes a difference for symbols from included
64 * headers, see print_stack_trace. 64 * headers, see print_stack_trace.
65 */ 65 */
66typedef struct { 66typedef struct {
67 const char *p_file; 67 const char *p_file;
68 int p_line; 68 int p_line;
69 int p_uniq; /* uniquifier */ 69 int p_uniq; /* uniquifier */
70} pos_t; 70} pos_t;
71 71
72/* Copies curr_pos, keeping things unique. */ 72/* Copies curr_pos, keeping things unique. */
73#define UNIQUE_CURR_POS(pos) \ 73#define UNIQUE_CURR_POS(pos) \
74 do { \ 74 do { \
75 (pos) = curr_pos; \ 75 (pos) = curr_pos; \
76 curr_pos.p_uniq++; \ 76 curr_pos.p_uniq++; \
77 if (curr_pos.p_file == csrc_pos.p_file) \ 77 if (curr_pos.p_file == csrc_pos.p_file) \
78 csrc_pos.p_uniq++; \ 78 csrc_pos.p_uniq++; \
79 } while (false) 79 } while (false)
80 80
81/* 81/*
82 * Strings cannot be referenced simply by a pointer to their first 82 * Strings cannot be referenced simply by a pointer to their first
83 * char. This is because strings can contain NUL characters other than the 83 * char. This is because strings can contain NUL characters other than the
84 * trailing NUL. 84 * trailing NUL.
85 * 85 *
86 * Strings are stored with a trailing NUL. 86 * Strings are stored with a trailing NUL.
87 */ 87 */
88typedef struct strg { 88typedef struct strg {
89 tspec_t st_tspec; /* CHAR or WCHAR */ 89 tspec_t st_tspec; /* CHAR or WCHAR */
90 size_t st_len; /* length without trailing NUL */ 90 size_t st_len; /* length without trailing NUL */
91 union { 91 union {
92 unsigned char *_st_cp; 92 unsigned char *_st_cp;
93 wchar_t *_st_wcp; 93 wchar_t *_st_wcp;
94 } st_u; 94 } st_u;
95} strg_t; 95} strg_t;
96 96
97#define st_cp st_u._st_cp 97#define st_cp st_u._st_cp
98#define st_wcp st_u._st_wcp 98#define st_wcp st_u._st_wcp
99 99
100/* 100/*
101 * qualifiers (only for lex/yacc interface) 101 * qualifiers (only for lex/yacc interface)
102 */ 102 */
103typedef enum { 103typedef enum {
104 CONST, VOLATILE, RESTRICT, THREAD 104 CONST, VOLATILE, RESTRICT, THREAD
105} tqual_t; 105} tqual_t;
106 106
107/* An integer or floating-point value. */ 107/* An integer or floating-point value. */
108typedef struct { 108typedef struct {
109 tspec_t v_tspec; 109 tspec_t v_tspec;
110 /* 110 /*
111 * Set if an integer constant is unsigned only in C90 and later, but 111 * Set if an integer constant is unsigned only in C90 and later, but
112 * not in traditional C. 112 * not in traditional C.
113 * 113 *
114 * See the operators table in ops.def, columns "l r". 114 * See the operators table in ops.def, columns "l r".
115 */ 115 */
116 bool v_unsigned_since_c90; 116 bool v_unsigned_since_c90;
117 union { 117 union {
118 int64_t _v_quad; /* integers */ 118 int64_t _v_quad; /* integers */
119 ldbl_t _v_ldbl; /* floats */ 119 ldbl_t _v_ldbl; /* floats */
120 } v_u; 120 } v_u;
121} val_t; 121} val_t;
122 122
123#define v_quad v_u._v_quad 123#define v_quad v_u._v_quad
124#define v_ldbl v_u._v_ldbl 124#define v_ldbl v_u._v_ldbl
125 125
126/* 126/*
127 * Structures of type struct_or_union uniquely identify structures. This can't 127 * Structures of type struct_or_union uniquely identify structures. This can't
128 * be done in structures of type type_t, because these are copied 128 * be done in structures of type type_t, because these are copied
129 * if they must be modified. So it would not be possible to check 129 * if they must be modified. So it would not be possible to check
130 * if two structures are identical by comparing the pointers to 130 * if two structures are identical by comparing the pointers to
131 * the type structures. 131 * the type structures.
132 * 132 *
133 * The typename is used if the structure is unnamed to identify 133 * The typename is used if the structure is unnamed to identify
134 * the structure type in pass 2. 134 * the structure type in pass 2.
135 */ 135 */
136typedef struct { 136typedef struct {
137 unsigned int sou_size_in_bits; 137 unsigned int sou_size_in_bits;
138 unsigned short sou_align_in_bits; 138 unsigned short sou_align_in_bits;
139 bool sou_incomplete:1; 139 bool sou_incomplete:1;
140 struct sym *sou_first_member; 140 struct sym *sou_first_member;
141 struct sym *sou_tag; 141 struct sym *sou_tag;
142 struct sym *sou_first_typedef; 142 struct sym *sou_first_typedef;
143} struct_or_union; 143} struct_or_union;
144 144
145/* 145/*
146 * same as above for enums 146 * same as above for enums
147 */ 147 */
148typedef struct { 148typedef struct {
149 bool en_incomplete:1; 149 bool en_incomplete:1;
150 struct sym *en_first_enumerator; 150 struct sym *en_first_enumerator;
151 struct sym *en_tag; 151 struct sym *en_tag;
152 struct sym *en_first_typedef; 152 struct sym *en_first_typedef;
153} enumeration; 153} enumeration;
154 154
155/* 155/*
156 * The type of an expression or object. Complex types are formed via t_subt 156 * The type of an expression or object. Complex types are formed via t_subt
157 * (for arrays, pointers and functions), as well as t_str. 157 * (for arrays, pointers and functions), as well as t_str.
158 */ 158 */
159struct lint1_type { 159struct lint1_type {
160 tspec_t t_tspec; /* type specifier */ 160 tspec_t t_tspec; /* type specifier */
161 bool t_incomplete_array:1; 161 bool t_incomplete_array:1;
162 bool t_const:1; /* const modifier */ 162 bool t_const:1; /* const modifier */
163 bool t_volatile:1; /* volatile modifier */ 163 bool t_volatile:1; /* volatile modifier */
164 bool t_proto:1; /* function prototype (t_args valid) */ 164 bool t_proto:1; /* function prototype (t_args valid) */
165 bool t_vararg:1; /* prototype with '...' */ 165 bool t_vararg:1; /* prototype with '...' */
166 bool t_typedef:1; /* type defined with typedef */ 166 bool t_typedef:1; /* type defined with typedef */
167 bool t_bitfield:1; 167 bool t_bitfield:1;
168 /* 168 /*
169 * Either the type is currently an enum (having t_tspec ENUM), or 169 * Either the type is currently an enum (having t_tspec ENUM), or
170 * it is an integer type (typically INT) that has been implicitly 170 * it is an integer type (typically INT) that has been implicitly
171 * converted from an enum type. In both cases, t_enum is valid. 171 * converted from an enum type. In both cases, t_enum is valid.
172 * 172 *
173 * The information about a former enum type is retained to allow 173 * The information about a former enum type is retained to allow
174 * type checks in expressions such as ((var1 & 0x0001) == var2), to 174 * type checks in expressions such as ((var1 & 0x0001) == var2), to
175 * detect when var1 and var2 are from incompatible enum types. 175 * detect when var1 and var2 are from incompatible enum types.
176 */ 176 */
177 bool t_is_enum:1; 177 bool t_is_enum:1;
178 bool t_packed:1; 178 bool t_packed:1;
179 union { 179 union {
180 int _t_dim; /* dimension (if ARRAY) */ 180 int _t_dim; /* dimension (if ARRAY) */
181 struct_or_union *_t_str; 181 struct_or_union *_t_str;
182 enumeration *_t_enum; 182 enumeration *_t_enum;
183 struct sym *_t_args; /* arguments (if t_proto) */ 183 struct sym *_t_args; /* arguments (if t_proto) */
184 } t_u; 184 } t_u;
185 struct { 185 struct {
186 unsigned int _t_flen:8; /* length of bit-field */ 186 unsigned int _t_flen:8; /* length of bit-field */
187 unsigned int _t_foffs:24; /* offset of bit-field */ 187 unsigned int _t_foffs:24; /* offset of bit-field */
188 } t_b; 188 } t_b;
189 struct lint1_type *t_subt; /* element type (if ARRAY), 189 struct lint1_type *t_subt; /* element type (if ARRAY),
190 * return value (if FUNC), 190 * return value (if FUNC),
191 * target type (if PTR) */ 191 * target type (if PTR) */
192}; 192};
193 193
194#define t_dim t_u._t_dim 194#define t_dim t_u._t_dim
195/* TODO: rename t_str to t_sou, to avoid confusing it with strings. */ 195/* TODO: rename t_str to t_sou, to avoid confusing it with strings. */
196#define t_str t_u._t_str 196#define t_str t_u._t_str
197#define t_enum t_u._t_enum 197#define t_enum t_u._t_enum
198#define t_args t_u._t_args 198#define t_args t_u._t_args
199#define t_flen t_b._t_flen 199#define t_flen t_b._t_flen
200#define t_foffs t_b._t_foffs 200#define t_foffs t_b._t_foffs
201 201
202/* 202/*
203 * types of symbols 203 * types of symbols
204 */ 204 */
205typedef enum { 205typedef enum {
206 FVFT, /* variables, functions, type names, enums */ 206 FVFT, /* variables, functions, type names, enums */
207 FMEMBER, /* members of structs or unions */ 207 FMEMBER, /* members of structs or unions */
208 FTAG, /* tags */ 208 FTAG, /* tags */
209 FLABEL /* labels */ 209 FLABEL /* labels */
210} symt_t; 210} symt_t;
211 211
212/* 212/*
213 * storage classes and related things 213 * storage classes and related things
214 */ 214 */
215typedef enum { 215typedef enum {
216 NOSCL, 216 NOSCL,
217 EXTERN, /* external symbols (independent of decl_t) */ 217 EXTERN, /* external symbols (independent of decl_t) */
218 STATIC, /* static symbols (local and global) */ 218 STATIC, /* static symbols (local and global) */
219 AUTO, /* automatic symbols (except register) */ 219 AUTO, /* automatic symbols (except register) */
220 REG, /* register */ 220 REG, /* register */
221 TYPEDEF, /* typedef */ 221 TYPEDEF, /* typedef */
222 STRUCT_TAG, 222 STRUCT_TAG,
223 UNION_TAG, 223 UNION_TAG,
224 ENUM_TAG, 224 ENUM_TAG,
225 MOS, /* member of struct */ 225 MOS, /* member of struct */
226 MOU, /* member of union */ 226 MOU, /* member of union */
227 CTCONST, /* enumerator, enum constant or bool constant */ 227 CTCONST, /* enumerator, enum constant or bool constant */
228 ABSTRACT, /* abstract symbol (sizeof, casts, unnamed argument) */ 228 ABSTRACT, /* abstract symbol (sizeof, casts, unnamed argument) */
229 OLD_STYLE_ARG, /* old-style function argument declarations */ 229 OLD_STYLE_ARG, /* old-style function argument declarations */
230 PROTO_ARG, /* used in declaration stack during prototype 230 PROTO_ARG, /* used in declaration stack during prototype
231 declaration */ 231 declaration */
232 INLINE /* only used by the parser */ 232 INLINE /* only used by the parser */
233} scl_t; 233} scl_t;
234 234
235/* 235/*
236 * symbol table entry 236 * symbol table entry
237 */ 237 */
238typedef struct sym { 238typedef struct sym {
239 const char *s_name; 239 const char *s_name;
240 const char *s_rename; /* renamed symbol's given name */ 240 const char *s_rename; /* renamed symbol's given name */
241 pos_t s_def_pos; /* position of last (prototype) definition, 241 pos_t s_def_pos; /* position of last (prototype) definition,
242 prototype declaration, no-prototype-def., 242 prototype declaration, no-prototype-def.,
243 tentative definition or declaration, 243 tentative definition or declaration,
244 in this order */ 244 in this order */
245 pos_t s_set_pos; /* position of first initialization */ 245 pos_t s_set_pos; /* position of first initialization */
246 pos_t s_use_pos; /* position of first use */ 246 pos_t s_use_pos; /* position of first use */
247 symt_t s_kind; /* type of symbol */ 247 symt_t s_kind; /* type of symbol */
248 const struct keyword *s_keyword; 248 const struct keyword *s_keyword;
249 bool s_bitfield:1; 249 bool s_bitfield:1;
250 bool s_set:1; /* variable set, label defined */ 250 bool s_set:1; /* variable set, label defined */
251 bool s_used:1; /* variable/label used */ 251 bool s_used:1; /* variable/label used */
252 bool s_arg:1; /* symbol is function argument */ 252 bool s_arg:1; /* symbol is function argument */
253 bool s_reg:1; /* symbol is register variable */ 253 bool s_reg:1; /* symbol is register variable */
254 bool s_defarg:1; /* undefined symbol in old style function 254 bool s_defarg:1; /* undefined symbol in old style function
255 definition */ 255 definition */
256 bool s_return_type_implicit_int:1; 256 bool s_return_type_implicit_int:1;
257 bool s_osdef:1; /* symbol stems from old style function def. */ 257 bool s_osdef:1; /* symbol stems from old style function def. */
258 bool s_inline:1; /* true if this is an inline function */ 258 bool s_inline:1; /* true if this is an inline function */
259 struct sym *s_ext_sym; /* for local declared external symbols pointer 259 struct sym *s_ext_sym; /* for local declared external symbols pointer
260 to external symbol with same name */ 260 to external symbol with same name */
261 def_t s_def; /* declared, tentative defined, defined */ 261 def_t s_def; /* declared, tentative defined, defined */
262 scl_t s_scl; /* storage class */ 262 scl_t s_scl; /* storage class */
263 int s_block_level; /* level of declaration, -1 if not in symbol 263 int s_block_level; /* level of declaration, -1 if not in symbol
264 table */ 264 table */
265 type_t *s_type; 265 type_t *s_type;
266 val_t s_value; /* value (if enum or bool constant) */ 266 val_t s_value; /* value (if enum or bool constant) */
267 union { 267 union {
268 /* XXX: what is the difference to s_type->t_str? */ 268 /* XXX: what is the difference to s_type->t_str? */
269 struct_or_union *_s_st; 269 struct_or_union *_s_st;
270 enumeration *_s_et; 270 enumeration *_s_et;
271 tspec_t _s_tsp; /* type (only for keywords) */ 271 tspec_t _s_tsp; /* type (only for keywords) */
272 tqual_t _s_tqu; /* qualifier (only for keywords) */ 272 tqual_t _s_tqu; /* qualifier (only for keywords) */
273 struct sym *_s_args; /* arguments in old style function 273 struct sym *_s_args; /* arguments in old style function
274 definitions */ 274 definitions */
275 } u; 275 } u;
276 struct sym *s_link; /* next symbol with same hash value */ 276 struct sym *s_symtab_next; /* next symbol with same hash value */
277 struct sym **s_rlink; /* pointer to s_link of prev. symbol */ 277 struct sym **s_symtab_ref; /* pointer to s_symtab_next of the
 278 * previous symbol */
278 struct sym *s_next; /* next struct/union member, enumerator, 279 struct sym *s_next; /* next struct/union member, enumerator,
279 argument */ 280 argument */
280 struct sym *s_dlnxt; /* next symbol declared on same level */ 281 struct sym *s_level_next; /* next symbol declared on the same
 282 * level */
281} sym_t; 283} sym_t;
282 284
283#define s_styp u._s_st 285#define s_styp u._s_st
284#define s_etyp u._s_et 286#define s_etyp u._s_et
285#define s_tspec u._s_tsp 287#define s_tspec u._s_tsp
286#define s_tqual u._s_tqu 288#define s_tqual u._s_tqu
287#define s_args u._s_args 289#define s_args u._s_args
288 290
289/* 291/*
290 * Used to keep some information about symbols before they are entered 292 * Used to keep some information about symbols before they are entered
291 * into the symbol table. 293 * into the symbol table.
292 */ 294 */
293typedef struct sbuf { 295typedef struct sbuf {
294 const char *sb_name; /* name of symbol */ 296 const char *sb_name; /* name of symbol */
295 size_t sb_len; /* length (without '\0') */ 297 size_t sb_len; /* length (without '\0') */
296 sym_t *sb_sym; /* symbol table entry */ 298 sym_t *sb_sym; /* symbol table entry */
297} sbuf_t; 299} sbuf_t;
298 300
299 301
300/* 302/*
301 * tree node 303 * tree node
302 */ 304 */
303typedef struct tnode { 305typedef struct tnode {
304 op_t tn_op; /* operator */ 306 op_t tn_op; /* operator */
305 type_t *tn_type; /* type */ 307 type_t *tn_type; /* type */
306 bool tn_lvalue:1; /* node is lvalue */ 308 bool tn_lvalue:1; /* node is lvalue */
307 bool tn_cast:1; /* if tn_op == CVT, it's an explicit cast */ 309 bool tn_cast:1; /* if tn_op == CVT, it's an explicit cast */
308 bool tn_parenthesized:1; 310 bool tn_parenthesized:1;
309 bool tn_sys:1; /* in strict bool mode, allow mixture between 311 bool tn_sys:1; /* in strict bool mode, allow mixture between
310 * bool and scalar, for code from system 312 * bool and scalar, for code from system
311 * headers that may be a mixture between 313 * headers that may be a mixture between
312 * scalar types and bool 314 * scalar types and bool
313 */ 315 */
314 bool tn_system_dependent:1; /* depends on sizeof or offsetof */ 316 bool tn_system_dependent:1; /* depends on sizeof or offsetof */
315 union { 317 union {
316 struct { 318 struct {
317 struct tnode *_tn_left; /* (left) operand */ 319 struct tnode *_tn_left; /* (left) operand */
318 struct tnode *_tn_right; /* right operand */ 320 struct tnode *_tn_right; /* right operand */
319 } tn_s; 321 } tn_s;
320 sym_t *_tn_sym; /* symbol if op == NAME */ 322 sym_t *_tn_sym; /* symbol if op == NAME */
321 val_t *_tn_val; /* value if op == CON */ 323 val_t *_tn_val; /* value if op == CON */
322 strg_t *_tn_string; /* string if op == STRING */ 324 strg_t *_tn_string; /* string if op == STRING */
323 } tn_u; 325 } tn_u;
324} tnode_t; 326} tnode_t;
325 327
326#define tn_left tn_u.tn_s._tn_left 328#define tn_left tn_u.tn_s._tn_left
327#define tn_right tn_u.tn_s._tn_right 329#define tn_right tn_u.tn_s._tn_right
328#define tn_sym tn_u._tn_sym 330#define tn_sym tn_u._tn_sym
329#define tn_val tn_u._tn_val 331#define tn_val tn_u._tn_val
330#define tn_string tn_u._tn_string 332#define tn_string tn_u._tn_string
331 333
332struct generic_association { 334struct generic_association {
333 type_t *ga_arg; /* NULL means default or error */ 335 type_t *ga_arg; /* NULL means default or error */
334 tnode_t *ga_result; /* NULL means error */ 336 tnode_t *ga_result; /* NULL means error */
335 struct generic_association *ga_prev; 337 struct generic_association *ga_prev;
336}; 338};
337 339
338struct array_size { 340struct array_size {
339 bool has_dim; 341 bool has_dim;
340 int dim; 342 int dim;
341}; 343};
342 344
343/* 345/*
344 * For nested declarations there is a stack that holds all information 346 * For nested declarations there is a stack that holds all information
345 * needed for the current level. dcs points to the innermost element of this 347 * needed for the current level. dcs points to the innermost element of this
346 * stack. 348 * stack.
347 * 349 *
348 * d_ctx describes the context of the current declaration. Its value is 350 * d_ctx describes the context of the current declaration. Its value is
349 * one of 351 * one of
350 * EXTERN global declarations 352 * EXTERN global declarations
351 * MOS or MOU declarations of struct or union members 353 * MOS or MOU declarations of struct or union members
352 * CTCONST declarations of enums or boolean constants 354 * CTCONST declarations of enums or boolean constants
353 * OLD_STYLE_ARG declaration of arguments in old-style function 355 * OLD_STYLE_ARG declaration of arguments in old-style function
354 * definitions 356 * definitions
355 * PROTO_ARG declaration of arguments in function prototypes 357 * PROTO_ARG declaration of arguments in function prototypes
356 * AUTO declaration of local symbols 358 * AUTO declaration of local symbols
357 * ABSTRACT abstract declarations (sizeof, casts) 359 * ABSTRACT abstract declarations (sizeof, casts)
358 * 360 *
359 */ 361 */
360typedef struct dinfo { 362typedef struct dinfo {
361 tspec_t d_abstract_type;/* VOID, BOOL, CHAR, INT or COMPLEX */ 363 tspec_t d_abstract_type;/* VOID, BOOL, CHAR, INT or COMPLEX */
362 tspec_t d_complex_mod; /* FLOAT or DOUBLE */ 364 tspec_t d_complex_mod; /* FLOAT or DOUBLE */
363 tspec_t d_sign_mod; /* SIGNED or UNSIGN */ 365 tspec_t d_sign_mod; /* SIGNED or UNSIGN */
364 tspec_t d_rank_mod; /* SHORT, LONG or QUAD */ 366 tspec_t d_rank_mod; /* SHORT, LONG or QUAD */
365 scl_t d_scl; /* storage class */ 367 scl_t d_scl; /* storage class */
366 type_t *d_type; /* after end_type() pointer to the type used 368 type_t *d_type; /* after end_type() pointer to the type used
367 for all declarators */ 369 for all declarators */
368 sym_t *d_redeclared_symbol; 370 sym_t *d_redeclared_symbol;
369 unsigned int d_offset; /* offset of next structure member */ 371 unsigned int d_offset; /* offset of next structure member */
370 unsigned short d_sou_align_in_bits; /* alignment required for current 372 unsigned short d_sou_align_in_bits; /* alignment required for current
371 * structure */ 373 * structure */
372 scl_t d_ctx; /* context of declaration */ 374 scl_t d_ctx; /* context of declaration */
373 bool d_const:1; /* const in declaration specifiers */ 375 bool d_const:1; /* const in declaration specifiers */
374 bool d_volatile:1; /* volatile in declaration specifiers */ 376 bool d_volatile:1; /* volatile in declaration specifiers */
375 bool d_inline:1; /* inline in declaration specifiers */ 377 bool d_inline:1; /* inline in declaration specifiers */
376 bool d_multiple_storage_classes:1; /* reported in end_type */ 378 bool d_multiple_storage_classes:1; /* reported in end_type */
377 bool d_invalid_type_combination:1; 379 bool d_invalid_type_combination:1;
378 bool d_nonempty_decl:1; /* if at least one tag is declared 380 bool d_nonempty_decl:1; /* if at least one tag is declared
379 * ... in the current function decl. */ 381 * ... in the current function decl. */
380 bool d_vararg:1; 382 bool d_vararg:1;
381 bool d_proto:1; /* current function decl. is prototype */ 383 bool d_proto:1; /* current function decl. is prototype */
382 bool d_notyp:1; /* set if no type specifier was present */ 384 bool d_notyp:1; /* set if no type specifier was present */
383 bool d_asm:1; /* set if d_ctx == AUTO and asm() present */ 385 bool d_asm:1; /* set if d_ctx == AUTO and asm() present */
384 bool d_packed:1; 386 bool d_packed:1;
385 bool d_used:1; 387 bool d_used:1;
386 type_t *d_tagtyp; /* tag during member declaration */ 388 type_t *d_tagtyp; /* tag during member declaration */
387 sym_t *d_func_args; /* list of arguments during function def. */ 389 sym_t *d_func_args; /* list of arguments during function def. */
388 pos_t d_func_def_pos; /* position of function definition */ 390 pos_t d_func_def_pos; /* position of function definition */
389 sym_t *d_dlsyms; /* first symbol declared at this level */ 391 sym_t *d_dlsyms; /* first symbol declared at this level */
390 sym_t **d_ldlsym; /* points to s_dlnxt in last symbol decl. 392 sym_t **d_ldlsym; /* points to s_level_next in the last symbol
391 at this level */ 393 declaration at this level */
392 sym_t *d_func_proto_syms; /* symbols defined in prototype */ 394 sym_t *d_func_proto_syms; /* symbols defined in prototype */
393 struct dinfo *d_next; /* next level */ 395 struct dinfo *d_next; /* next level */
394} dinfo_t; 396} dinfo_t;
395 397
396/* One level of pointer indirection in declarators, including qualifiers. */ 398/* One level of pointer indirection in declarators, including qualifiers. */
397typedef struct qual_ptr { 399typedef struct qual_ptr {
398 bool p_const: 1; 400 bool p_const: 1;
399 bool p_volatile: 1; 401 bool p_volatile: 1;
400 bool p_pointer: 1; 402 bool p_pointer: 1;
401 struct qual_ptr *p_next; 403 struct qual_ptr *p_next;
402} qual_ptr; 404} qual_ptr;
403 405
404/* 406/*
405 * The values of the 'case' labels, linked via cl_next in reverse order of 407 * The values of the 'case' labels, linked via cl_next in reverse order of
406 * appearance in the code, that is from bottom to top. 408 * appearance in the code, that is from bottom to top.
407 */ 409 */
408typedef struct case_label { 410typedef struct case_label {
409 val_t cl_val; 411 val_t cl_val;
410 struct case_label *cl_next; 412 struct case_label *cl_next;
411} case_label_t; 413} case_label_t;
412 414
413typedef enum { 415typedef enum {
414 CS_DO_WHILE, 416 CS_DO_WHILE,
415 CS_FOR, 417 CS_FOR,
416 CS_FUNCTION_BODY, 418 CS_FUNCTION_BODY,
417 CS_IF, 419 CS_IF,
418 CS_SWITCH, 420 CS_SWITCH,
419 CS_WHILE 421 CS_WHILE
420} control_statement_kind; 422} control_statement_kind;
421 423
422/* 424/*
423 * Used to keep information about nested control statements. 425 * Used to keep information about nested control statements.
424 */ 426 */
425typedef struct control_statement { 427typedef struct control_statement {
426 control_statement_kind c_kind; /* to ensure proper nesting */ 428 control_statement_kind c_kind; /* to ensure proper nesting */
427 bool c_loop:1; /* 'continue' and 'break' are valid */ 429 bool c_loop:1; /* 'continue' and 'break' are valid */
428 bool c_switch:1; /* 'case' and 'break' are valid */ 430 bool c_switch:1; /* 'case' and 'break' are valid */
429 bool c_break:1; /* the loop/switch has a reachable 431 bool c_break:1; /* the loop/switch has a reachable
430 * 'break' statement */ 432 * 'break' statement */
431 bool c_continue:1; /* the loop has a reachable 'continue' 433 bool c_continue:1; /* the loop has a reachable 'continue'
432 * statement */ 434 * statement */
433 bool c_default:1; /* the switch has a 'default' label */ 435 bool c_default:1; /* the switch has a 'default' label */
434 bool c_maybe_endless:1; /* the controlling expression is 436 bool c_maybe_endless:1; /* the controlling expression is
435 * always true (as in 'for (;;)' or 437 * always true (as in 'for (;;)' or
436 * 'while (1)'), there may be break 438 * 'while (1)'), there may be break
437 * statements though */ 439 * statements though */
438 bool c_always_then:1; 440 bool c_always_then:1;
439 bool c_reached_end_of_then:1; 441 bool c_reached_end_of_then:1;
440 bool c_had_return_noval:1; /* had "return;" */ 442 bool c_had_return_noval:1; /* had "return;" */
441 bool c_had_return_value:1; /* had "return expr;" */ 443 bool c_had_return_value:1; /* had "return expr;" */
442 444
443 type_t *c_switch_type; /* type of switch expression */ 445 type_t *c_switch_type; /* type of switch expression */
444 tnode_t *c_switch_expr; 446 tnode_t *c_switch_expr;
445 case_label_t *c_case_labels; /* list of case values */ 447 case_label_t *c_case_labels; /* list of case values */
446 448
447 struct memory_block *c_for_expr3_mem; /* saved memory for end of loop 449 struct memory_block *c_for_expr3_mem; /* saved memory for end of loop
448 * expression in for() */ 450 * expression in for() */
449 tnode_t *c_for_expr3; /* end of loop expr in for() */ 451 tnode_t *c_for_expr3; /* end of loop expr in for() */
450 pos_t c_for_expr3_pos; /* position of end of loop expr */ 452 pos_t c_for_expr3_pos; /* position of end of loop expr */
451 pos_t c_for_expr3_csrc_pos; /* same for csrc_pos */ 453 pos_t c_for_expr3_csrc_pos; /* same for csrc_pos */
452 454
453 struct control_statement *c_surrounding; 455 struct control_statement *c_surrounding;
454} control_statement; 456} control_statement;
455 457
456typedef struct { 458typedef struct {
457 size_t lo; /* inclusive */ 459 size_t lo; /* inclusive */
458 size_t hi; /* inclusive */ 460 size_t hi; /* inclusive */
459} range_t; 461} range_t;
460 462
461#include "externs1.h" 463#include "externs1.h"
462 464
463#define ERR_SETSIZE 1024 465#define ERR_SETSIZE 1024
464#define __NERRBITS (sizeof(unsigned int)) 466#define __NERRBITS (sizeof(unsigned int))
465 467
466typedef struct err_set { 468typedef struct err_set {
467 unsigned int errs_bits[(ERR_SETSIZE + __NERRBITS-1) / __NERRBITS]; 469 unsigned int errs_bits[(ERR_SETSIZE + __NERRBITS-1) / __NERRBITS];
468} err_set; 470} err_set;
469 471
470#define ERR_SET(n, p) \ 472#define ERR_SET(n, p) \
471 ((p)->errs_bits[(n)/__NERRBITS] |= (1 << ((n) % __NERRBITS))) 473 ((p)->errs_bits[(n)/__NERRBITS] |= (1 << ((n) % __NERRBITS)))
472#define ERR_CLR(n, p) \ 474#define ERR_CLR(n, p) \
473 ((p)->errs_bits[(n)/__NERRBITS] &= ~(1 << ((n) % __NERRBITS))) 475 ((p)->errs_bits[(n)/__NERRBITS] &= ~(1 << ((n) % __NERRBITS)))
474#define ERR_ISSET(n, p) \ 476#define ERR_ISSET(n, p) \
475 (((p)->errs_bits[(n)/__NERRBITS] & (1 << ((n) % __NERRBITS))) != 0) 477 (((p)->errs_bits[(n)/__NERRBITS] & (1 << ((n) % __NERRBITS))) != 0)
476#define ERR_ZERO(p) (void)memset((p), 0, sizeof(*(p))) 478#define ERR_ZERO(p) (void)memset((p), 0, sizeof(*(p)))
477 479
478#define INTERNAL_ERROR(fmt, args...) \ 480#define INTERNAL_ERROR(fmt, args...) \
479 internal_error(__FILE__, __LINE__, fmt, ##args) 481 internal_error(__FILE__, __LINE__, fmt, ##args)
480 482
481#define lint_assert(cond) \ 483#define lint_assert(cond) \
482 do { \ 484 do { \
483 if (!(cond)) \ 485 if (!(cond)) \
484 assert_failed(__FILE__, __LINE__, __func__, #cond); \ 486 assert_failed(__FILE__, __LINE__, __func__, #cond); \
485 } while (false) 487 } while (false)
486 488
487extern err_set msgset; 489extern err_set msgset;
488 490
489 491
490#ifdef DEBUG 492#ifdef DEBUG
491# include "err-msgs.h" 493# include "err-msgs.h"
492 494
493/* ARGSUSED */ 495/* ARGSUSED */
494static inline void __attribute__((format(printf, 1, 2))) 496static inline void __attribute__((format(printf, 1, 2)))
495check_printf(const char *fmt, ...) 497check_printf(const char *fmt, ...)
496{ 498{
497} 499}
498 500
499# define wrap_check_printf_at(func, msgid, pos, args...) \ 501# define wrap_check_printf_at(func, msgid, pos, args...) \
500 do { \ 502 do { \
501 check_printf(__CONCAT(MSG_, msgid), ##args); \ 503 check_printf(__CONCAT(MSG_, msgid), ##args); \
502 (func)(msgid, pos, ##args); \ 504 (func)(msgid, pos, ##args); \
503 } while (false) 505 } while (false)
504 506
505# define error_at(msgid, pos, args...) \ 507# define error_at(msgid, pos, args...) \
506 wrap_check_printf_at(error_at, msgid, pos, ##args) 508 wrap_check_printf_at(error_at, msgid, pos, ##args)
507# define warning_at(msgid, pos, args...) \ 509# define warning_at(msgid, pos, args...) \
508 wrap_check_printf_at(warning_at, msgid, pos, ##args) 510 wrap_check_printf_at(warning_at, msgid, pos, ##args)
509# define message_at(msgid, pos, args...) \ 511# define message_at(msgid, pos, args...) \
510 wrap_check_printf_at(message_at, msgid, pos, ##args) 512 wrap_check_printf_at(message_at, msgid, pos, ##args)
511 513
512# define wrap_check_printf(func, msgid, args...) \ 514# define wrap_check_printf(func, msgid, args...) \
513 do { \ 515 do { \
514 check_printf(__CONCAT(MSG_, msgid), ##args); \ 516 check_printf(__CONCAT(MSG_, msgid), ##args); \
515 (func)(msgid, ##args); \ 517 (func)(msgid, ##args); \
516 } while (false) 518 } while (false)
517 519
518# define error(msgid, args...) wrap_check_printf(error, msgid, ##args) 520# define error(msgid, args...) wrap_check_printf(error, msgid, ##args)
519# define warning(msgid, args...) wrap_check_printf(warning, msgid, ##args) 521# define warning(msgid, args...) wrap_check_printf(warning, msgid, ##args)
520# define gnuism(msgid, args...) wrap_check_printf(gnuism, msgid, ##args) 522# define gnuism(msgid, args...) wrap_check_printf(gnuism, msgid, ##args)
521# define c99ism(msgid, args...) wrap_check_printf(c99ism, msgid, ##args) 523# define c99ism(msgid, args...) wrap_check_printf(c99ism, msgid, ##args)
522# define c11ism(msgid, args...) wrap_check_printf(c11ism, msgid, ##args) 524# define c11ism(msgid, args...) wrap_check_printf(c11ism, msgid, ##args)
523#endif 525#endif
524 526
525static inline bool 527static inline bool
526is_nonzero_val(const val_t *val) 528is_nonzero_val(const val_t *val)
527{ 529{
528 return is_floating(val->v_tspec) 530 return is_floating(val->v_tspec)
529 ? val->v_ldbl != 0.0 531 ? val->v_ldbl != 0.0
530 : val->v_quad != 0; 532 : val->v_quad != 0;
531} 533}
532 534
533static inline bool 535static inline bool
534constant_is_nonzero(const tnode_t *tn) 536constant_is_nonzero(const tnode_t *tn)
535{ 537{
536 lint_assert(tn->tn_op == CON); 538 lint_assert(tn->tn_op == CON);
537 lint_assert(tn->tn_type->t_tspec == tn->tn_val->v_tspec); 539 lint_assert(tn->tn_type->t_tspec == tn->tn_val->v_tspec);
538 return is_nonzero_val(tn->tn_val); 540 return is_nonzero_val(tn->tn_val);
539} 541}
540 542
541static inline bool 543static inline bool
542is_zero(const tnode_t *tn) 544is_zero(const tnode_t *tn)
543{ 545{
544 return tn != NULL && tn->tn_op == CON && !is_nonzero_val(tn->tn_val); 546 return tn != NULL && tn->tn_op == CON && !is_nonzero_val(tn->tn_val);
545} 547}
546 548
547static inline bool 549static inline bool
548is_nonzero(const tnode_t *tn) 550is_nonzero(const tnode_t *tn)
549{ 551{
550 return tn != NULL && tn->tn_op == CON && is_nonzero_val(tn->tn_val); 552 return tn != NULL && tn->tn_op == CON && is_nonzero_val(tn->tn_val);
551} 553}
552 554
553static inline bool 555static inline bool
554is_binary(const tnode_t *tn) 556is_binary(const tnode_t *tn)
555{ 557{
556 return modtab[tn->tn_op].m_binary; 558 return modtab[tn->tn_op].m_binary;
557} 559}
558 560
559static inline uint64_t 561static inline uint64_t
560bit(unsigned i) 562bit(unsigned i)
561{ 563{
562 /* 564 /*
563 * TODO: Add proper support for INT128. 565 * TODO: Add proper support for INT128.
564 * This involves changing val_t to 128 bits. 566 * This involves changing val_t to 128 bits.
565 */ 567 */
566 if (i >= 64) 568 if (i >= 64)
567 return 0; /* XXX: not correct for INT128 and UINT128 */ 569 return 0; /* XXX: not correct for INT128 and UINT128 */
568 570
569 lint_assert(i < 64); 571 lint_assert(i < 64);
570 return (uint64_t)1 << i; 572 return (uint64_t)1 << i;
571} 573}
572 574
573static inline bool 575static inline bool
574msb(int64_t q, tspec_t t) 576msb(int64_t q, tspec_t t)
575{ 577{
576 return (q & bit((unsigned int)size_in_bits(t) - 1)) != 0; 578 return (q & bit((unsigned int)size_in_bits(t) - 1)) != 0;
577} 579}
578 580
579static inline uint64_t 581static inline uint64_t
580value_bits(unsigned bitsize) 582value_bits(unsigned bitsize)
581{ 583{
582 lint_assert(bitsize > 0); 584 lint_assert(bitsize > 0);
583 585
584 /* for long double (80 or 128), double _Complex (128) */ 586 /* for long double (80 or 128), double _Complex (128) */
585 /* 587 /*
586 * XXX: double _Complex does not have 128 bits of precision, 588 * XXX: double _Complex does not have 128 bits of precision,
587 * therefore it should never be necessary to query the value bits 589 * therefore it should never be necessary to query the value bits
588 * of such a type; see d_c99_complex_split.c to trigger this case. 590 * of such a type; see d_c99_complex_split.c to trigger this case.
589 */ 591 */
590 if (bitsize >= 64) 592 if (bitsize >= 64)
591 return ~((uint64_t)0); 593 return ~((uint64_t)0);
592 594
593 return ~(~(uint64_t)0 << bitsize); 595 return ~(~(uint64_t)0 << bitsize);
594} 596}
595 597
596/* C99 6.7.8p7 */ 598/* C99 6.7.8p7 */
597static inline bool 599static inline bool
598is_struct_or_union(tspec_t t) 600is_struct_or_union(tspec_t t)
599{ 601{
600 return t == STRUCT || t == UNION; 602 return t == STRUCT || t == UNION;
601} 603}

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

--- src/usr.bin/xlint/lint1/tree.c 2022/02/27 10:31:58 1.406
+++ src/usr.bin/xlint/lint1/tree.c 2022/02/27 10:44:45 1.407
@@ -1,1402 +1,1403 @@ @@ -1,1402 +1,1403 @@
1/* $NetBSD: tree.c,v 1.406 2022/02/27 10:31:58 rillig Exp $ */ 1/* $NetBSD: tree.c,v 1.407 2022/02/27 10:44:45 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.406 2022/02/27 10:31:58 rillig Exp $"); 40__RCSID("$NetBSD: tree.c,v 1.407 2022/02/27 10:44:45 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 *build_integer_constant(tspec_t, int64_t); 53static tnode_t *build_integer_constant(tspec_t, int64_t);
54static void check_pointer_comparison(op_t, 54static void check_pointer_comparison(op_t,
55 const tnode_t *, const tnode_t *); 55 const tnode_t *, const tnode_t *);
56static bool check_assign_types_compatible(op_t, int, 56static bool check_assign_types_compatible(op_t, int,
57 const tnode_t *, const tnode_t *); 57 const tnode_t *, const tnode_t *);
58static void check_bad_enum_operation(op_t, 58static void check_bad_enum_operation(op_t,
59 const tnode_t *, const tnode_t *); 59 const tnode_t *, const tnode_t *);
60static void check_enum_type_mismatch(op_t, int, 60static void check_enum_type_mismatch(op_t, int,
61 const tnode_t *, const tnode_t *); 61 const tnode_t *, const tnode_t *);
62static void check_enum_int_mismatch(op_t, int, 62static void check_enum_int_mismatch(op_t, int,
63 const tnode_t *, const tnode_t *); 63 const tnode_t *, const tnode_t *);
64static tnode_t *new_tnode(op_t, bool, type_t *, tnode_t *, tnode_t *); 64static tnode_t *new_tnode(op_t, bool, type_t *, tnode_t *, tnode_t *);
65static void balance(op_t, tnode_t **, tnode_t **); 65static void balance(op_t, tnode_t **, tnode_t **);
66static void warn_incompatible_types(op_t, const type_t *, tspec_t, 66static void warn_incompatible_types(op_t, const type_t *, tspec_t,
67 const type_t *, tspec_t); 67 const type_t *, tspec_t);
68static void warn_incompatible_pointers(const mod_t *, 68static void warn_incompatible_pointers(const mod_t *,
69 const type_t *, const type_t *); 69 const type_t *, const type_t *);
70static bool has_constant_member(const type_t *); 70static bool has_constant_member(const type_t *);
71static void check_prototype_conversion(int, tspec_t, tspec_t, type_t *, 71static void check_prototype_conversion(int, tspec_t, tspec_t, type_t *,
72 tnode_t *); 72 tnode_t *);
73static void check_integer_conversion(op_t, int, tspec_t, tspec_t, type_t *, 73static void check_integer_conversion(op_t, int, tspec_t, tspec_t, type_t *,
74 tnode_t *); 74 tnode_t *);
75static void check_pointer_integer_conversion(op_t, tspec_t, type_t *, 75static void check_pointer_integer_conversion(op_t, tspec_t, type_t *,
76 tnode_t *); 76 tnode_t *);
77static void check_pointer_conversion(tnode_t *, type_t *); 77static void check_pointer_conversion(tnode_t *, type_t *);
78static tnode_t *build_struct_access(op_t, bool, tnode_t *, tnode_t *); 78static tnode_t *build_struct_access(op_t, bool, tnode_t *, tnode_t *);
79static tnode_t *build_prepost_incdec(op_t, bool, tnode_t *); 79static tnode_t *build_prepost_incdec(op_t, bool, tnode_t *);
80static tnode_t *build_real_imag(op_t, bool, tnode_t *); 80static tnode_t *build_real_imag(op_t, bool, tnode_t *);
81static tnode_t *build_address(bool, tnode_t *, bool); 81static tnode_t *build_address(bool, tnode_t *, bool);
82static tnode_t *build_plus_minus(op_t, bool, tnode_t *, tnode_t *); 82static tnode_t *build_plus_minus(op_t, bool, tnode_t *, tnode_t *);
83static tnode_t *build_bit_shift(op_t, bool, tnode_t *, tnode_t *); 83static tnode_t *build_bit_shift(op_t, bool, tnode_t *, tnode_t *);
84static tnode_t *build_colon(bool, tnode_t *, tnode_t *); 84static tnode_t *build_colon(bool, tnode_t *, tnode_t *);
85static tnode_t *build_assignment(op_t, bool, tnode_t *, tnode_t *); 85static tnode_t *build_assignment(op_t, bool, tnode_t *, tnode_t *);
86static tnode_t *plength(type_t *); 86static tnode_t *plength(type_t *);
87static tnode_t *fold(tnode_t *); 87static tnode_t *fold(tnode_t *);
88static tnode_t *fold_test(tnode_t *); 88static tnode_t *fold_test(tnode_t *);
89static tnode_t *fold_float(tnode_t *); 89static tnode_t *fold_float(tnode_t *);
90static tnode_t *check_function_arguments(type_t *, tnode_t *); 90static tnode_t *check_function_arguments(type_t *, tnode_t *);
91static tnode_t *check_prototype_argument(int, type_t *, tnode_t *); 91static tnode_t *check_prototype_argument(int, type_t *, tnode_t *);
92static void check_null_effect(const tnode_t *); 92static void check_null_effect(const tnode_t *);
93static void check_array_index(tnode_t *, bool); 93static void check_array_index(tnode_t *, bool);
94static void check_integer_comparison(op_t, tnode_t *, tnode_t *); 94static void check_integer_comparison(op_t, tnode_t *, tnode_t *);
95static void check_precedence_confusion(tnode_t *); 95static void check_precedence_confusion(tnode_t *);
96 96
97extern sig_atomic_t fpe; 97extern sig_atomic_t fpe;
98 98
99static const char * 99static const char *
100op_name(op_t op) 100op_name(op_t op)
101{ 101{
102 return modtab[op].m_name; 102 return modtab[op].m_name;
103} 103}
104 104
105/* Build 'pointer to tp', 'array of tp' or 'function returning tp'. */ 105/* Build 'pointer to tp', 'array of tp' or 'function returning tp'. */
106type_t * 106type_t *
107block_derive_type(type_t *tp, tspec_t t) 107block_derive_type(type_t *tp, tspec_t t)
108{ 108{
109 type_t *tp2; 109 type_t *tp2;
110 110
111 tp2 = block_zero_alloc(sizeof(*tp2)); 111 tp2 = block_zero_alloc(sizeof(*tp2));
112 tp2->t_tspec = t; 112 tp2->t_tspec = t;
113 tp2->t_subt = tp; 113 tp2->t_subt = tp;
114 return tp2; 114 return tp2;
115} 115}
116 116
117/* 117/*
118 * Derive 'pointer to tp' or 'function returning tp'. 118 * Derive 'pointer to tp' or 'function returning tp'.
119 * The memory is freed at the end of the current expression. 119 * The memory is freed at the end of the current expression.
120 */ 120 */
121type_t * 121type_t *
122expr_derive_type(type_t *tp, tspec_t t) 122expr_derive_type(type_t *tp, tspec_t t)
123{ 123{
124 type_t *tp2; 124 type_t *tp2;
125 125
126 tp2 = expr_zero_alloc(sizeof(*tp2)); 126 tp2 = expr_zero_alloc(sizeof(*tp2));
127 tp2->t_tspec = t; 127 tp2->t_tspec = t;
128 tp2->t_subt = tp; 128 tp2->t_subt = tp;
129 return tp2; 129 return tp2;
130} 130}
131 131
132/* 132/*
133 * Create a node for a constant. 133 * Create a node for a constant.
134 */ 134 */
135tnode_t * 135tnode_t *
136build_constant(type_t *tp, val_t *v) 136build_constant(type_t *tp, val_t *v)
137{ 137{
138 tnode_t *n; 138 tnode_t *n;
139 139
140 n = expr_alloc_tnode(); 140 n = expr_alloc_tnode();
141 n->tn_op = CON; 141 n->tn_op = CON;
142 n->tn_type = tp; 142 n->tn_type = tp;
143 n->tn_val = expr_zero_alloc(sizeof(*n->tn_val)); 143 n->tn_val = expr_zero_alloc(sizeof(*n->tn_val));
144 n->tn_val->v_tspec = tp->t_tspec; 144 n->tn_val->v_tspec = tp->t_tspec;
145 n->tn_val->v_unsigned_since_c90 = v->v_unsigned_since_c90; 145 n->tn_val->v_unsigned_since_c90 = v->v_unsigned_since_c90;
146 n->tn_val->v_u = v->v_u; 146 n->tn_val->v_u = v->v_u;
147 free(v); 147 free(v);
148 return n; 148 return n;
149} 149}
150 150
151static tnode_t * 151static tnode_t *
152build_integer_constant(tspec_t t, int64_t q) 152build_integer_constant(tspec_t t, int64_t q)
153{ 153{
154 tnode_t *n; 154 tnode_t *n;
155 155
156 n = expr_alloc_tnode(); 156 n = expr_alloc_tnode();
157 n->tn_op = CON; 157 n->tn_op = CON;
158 n->tn_type = gettyp(t); 158 n->tn_type = gettyp(t);
159 n->tn_val = expr_zero_alloc(sizeof(*n->tn_val)); 159 n->tn_val = expr_zero_alloc(sizeof(*n->tn_val));
160 n->tn_val->v_tspec = t; 160 n->tn_val->v_tspec = t;
161 n->tn_val->v_quad = q; 161 n->tn_val->v_quad = q;
162 return n; 162 return n;
163} 163}
164 164
165static void 165static void
166fallback_symbol(sym_t *sym) 166fallback_symbol(sym_t *sym)
167{ 167{
168 168
169 if (fallback_symbol_strict_bool(sym)) 169 if (fallback_symbol_strict_bool(sym))
170 return; 170 return;
171 171
172 if (block_level > 0 && (strcmp(sym->s_name, "__FUNCTION__") == 0 || 172 if (block_level > 0 && (strcmp(sym->s_name, "__FUNCTION__") == 0 ||
173 strcmp(sym->s_name, "__PRETTY_FUNCTION__") == 0)) { 173 strcmp(sym->s_name, "__PRETTY_FUNCTION__") == 0)) {
174 /* __FUNCTION__/__PRETTY_FUNCTION__ is a GCC extension */ 174 /* __FUNCTION__/__PRETTY_FUNCTION__ is a GCC extension */
175 gnuism(316); 175 gnuism(316);
176 sym->s_type = block_derive_type(gettyp(CHAR), PTR); 176 sym->s_type = block_derive_type(gettyp(CHAR), PTR);
177 sym->s_type->t_const = true; 177 sym->s_type->t_const = true;
178 return; 178 return;
179 } 179 }
180 180
181 if (block_level > 0 && strcmp(sym->s_name, "__func__") == 0) { 181 if (block_level > 0 && strcmp(sym->s_name, "__func__") == 0) {
182 if (!Sflag) 182 if (!Sflag)
183 /* __func__ is a C9X feature */ 183 /* __func__ is a C9X feature */
184 warning(317); 184 warning(317);
185 sym->s_type = block_derive_type(gettyp(CHAR), PTR); 185 sym->s_type = block_derive_type(gettyp(CHAR), PTR);
186 sym->s_type->t_const = true; 186 sym->s_type->t_const = true;
187 return; 187 return;
188 } 188 }
189 189
190 /* '%s' undefined */ 190 /* '%s' undefined */
191 error(99, sym->s_name); 191 error(99, sym->s_name);
192} 192}
193 193
194/* 194/*
195 * Functions that are predeclared by GCC or other compilers can be called 195 * Functions that are predeclared by GCC or other compilers can be called
196 * with arbitrary arguments. Since lint usually runs after a successful 196 * with arbitrary arguments. Since lint usually runs after a successful
197 * compilation, it's the compiler's job to catch any errors. 197 * compilation, it's the compiler's job to catch any errors.
198 */ 198 */
199bool 199bool
200is_compiler_builtin(const char *name) 200is_compiler_builtin(const char *name)
201{ 201{
202 /* https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html */ 202 /* https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html */
203 if (gflag) { 203 if (gflag) {
204 if (strncmp(name, "__atomic_", 9) == 0 || 204 if (strncmp(name, "__atomic_", 9) == 0 ||
205 strncmp(name, "__builtin_", 10) == 0 || 205 strncmp(name, "__builtin_", 10) == 0 ||
206 strcmp(name, "alloca") == 0 || 206 strcmp(name, "alloca") == 0 ||
207 /* obsolete but still in use, as of 2021 */ 207 /* obsolete but still in use, as of 2021 */
208 strncmp(name, "__sync_", 7) == 0) 208 strncmp(name, "__sync_", 7) == 0)
209 return true; 209 return true;
210 } 210 }
211 211
212 /* https://software.intel.com/sites/landingpage/IntrinsicsGuide/ */ 212 /* https://software.intel.com/sites/landingpage/IntrinsicsGuide/ */
213 if (strncmp(name, "_mm_", 4) == 0) 213 if (strncmp(name, "_mm_", 4) == 0)
214 return true; 214 return true;
215 215
216 return false; 216 return false;
217} 217}
218 218
219static bool 219static bool
220str_endswith(const char *haystack, const char *needle) 220str_endswith(const char *haystack, const char *needle)
221{ 221{
222 size_t hlen = strlen(haystack); 222 size_t hlen = strlen(haystack);
223 size_t nlen = strlen(needle); 223 size_t nlen = strlen(needle);
224 224
225 return nlen <= hlen && 225 return nlen <= hlen &&
226 memcmp(haystack + hlen - nlen, needle, nlen) == 0; 226 memcmp(haystack + hlen - nlen, needle, nlen) == 0;
227} 227}
228 228
229/* https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html */ 229/* https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html */
230static bool 230static bool
231is_gcc_bool_builtin(const char *name) 231is_gcc_bool_builtin(const char *name)
232{ 232{
233 return strncmp(name, "__builtin_", 10) == 0 && 233 return strncmp(name, "__builtin_", 10) == 0 &&
234 (str_endswith(name, "_overflow") || 234 (str_endswith(name, "_overflow") ||
235 str_endswith(name, "_overflow_p")); 235 str_endswith(name, "_overflow_p"));
236} 236}
237 237
238static void 238static void
239build_name_call(sym_t *sym) 239build_name_call(sym_t *sym)
240{ 240{
241 241
242 if (is_compiler_builtin(sym->s_name)) { 242 if (is_compiler_builtin(sym->s_name)) {
243 /* 243 /*
244 * Do not warn about these, just assume that 244 * Do not warn about these, just assume that
245 * they are regular functions compatible with 245 * they are regular functions compatible with
246 * non-prototype calling conventions. 246 * non-prototype calling conventions.
247 */ 247 */
248 if (gflag && is_gcc_bool_builtin(sym->s_name)) 248 if (gflag && is_gcc_bool_builtin(sym->s_name))
249 sym->s_type = gettyp(BOOL); 249 sym->s_type = gettyp(BOOL);
250 250
251 } else if (Sflag) { 251 } else if (Sflag) {
252 /* function '%s' implicitly declared to return int */ 252 /* function '%s' implicitly declared to return int */
253 error(215, sym->s_name); 253 error(215, sym->s_name);
254 } else if (sflag) { 254 } else if (sflag) {
255 /* function '%s' implicitly declared to return int */ 255 /* function '%s' implicitly declared to return int */
256 warning(215, sym->s_name); 256 warning(215, sym->s_name);
257 } 257 }
258 258
259 /* XXX if tflag is set, the symbol should be exported to level 0 */ 259 /* XXX if tflag is set, the symbol should be exported to level 0 */
260 sym->s_type = block_derive_type(sym->s_type, FUNC); 260 sym->s_type = block_derive_type(sym->s_type, FUNC);
261} 261}
262 262
263/* Create a node for a name (symbol table entry). */ 263/* Create a node for a name (symbol table entry). */
264tnode_t * 264tnode_t *
265build_name(sym_t *sym, bool is_funcname) 265build_name(sym_t *sym, bool is_funcname)
266{ 266{
267 tnode_t *n; 267 tnode_t *n;
268 268
269 if (sym->s_scl == NOSCL) { 269 if (sym->s_scl == NOSCL) {
270 sym->s_scl = EXTERN; 270 sym->s_scl = EXTERN;
271 sym->s_def = DECL; 271 sym->s_def = DECL;
272 if (is_funcname) 272 if (is_funcname)
273 build_name_call(sym); 273 build_name_call(sym);
274 else 274 else
275 fallback_symbol(sym); 275 fallback_symbol(sym);
276 } 276 }
277 277
278 lint_assert(sym->s_kind == FVFT || sym->s_kind == FMEMBER); 278 lint_assert(sym->s_kind == FVFT || sym->s_kind == FMEMBER);
279 279
280 n = expr_alloc_tnode(); 280 n = expr_alloc_tnode();
281 n->tn_type = sym->s_type; 281 n->tn_type = sym->s_type;
282 if (sym->s_scl == CTCONST) { 282 if (sym->s_scl == CTCONST) {
283 n->tn_op = CON; 283 n->tn_op = CON;
284 n->tn_val = expr_zero_alloc(sizeof(*n->tn_val)); 284 n->tn_val = expr_zero_alloc(sizeof(*n->tn_val));
285 *n->tn_val = sym->s_value; 285 *n->tn_val = sym->s_value;
286 } else { 286 } else {
287 n->tn_op = NAME; 287 n->tn_op = NAME;
288 n->tn_sym = sym; 288 n->tn_sym = sym;
289 if (sym->s_kind == FVFT && sym->s_type->t_tspec != FUNC) 289 if (sym->s_kind == FVFT && sym->s_type->t_tspec != FUNC)
290 n->tn_lvalue = true; 290 n->tn_lvalue = true;
291 } 291 }
292 292
293 return n; 293 return n;
294} 294}
295 295
296tnode_t * 296tnode_t *
297build_string(strg_t *strg) 297build_string(strg_t *strg)
298{ 298{
299 size_t len; 299 size_t len;
300 tnode_t *n; 300 tnode_t *n;
301 type_t *tp; 301 type_t *tp;
302 302
303 len = strg->st_len; 303 len = strg->st_len;
304 304
305 n = expr_alloc_tnode(); 305 n = expr_alloc_tnode();
306 306
307 tp = expr_zero_alloc(sizeof(*tp)); 307 tp = expr_zero_alloc(sizeof(*tp));
308 tp->t_tspec = ARRAY; 308 tp->t_tspec = ARRAY;
309 tp->t_subt = gettyp(strg->st_tspec); 309 tp->t_subt = gettyp(strg->st_tspec);
310 tp->t_dim = (int)(len + 1); 310 tp->t_dim = (int)(len + 1);
311 311
312 n->tn_op = STRING; 312 n->tn_op = STRING;
313 n->tn_type = tp; 313 n->tn_type = tp;
314 n->tn_lvalue = true; 314 n->tn_lvalue = true;
315 315
316 n->tn_string = expr_zero_alloc(sizeof(*n->tn_string)); 316 n->tn_string = expr_zero_alloc(sizeof(*n->tn_string));
317 n->tn_string->st_tspec = strg->st_tspec; 317 n->tn_string->st_tspec = strg->st_tspec;
318 n->tn_string->st_len = len; 318 n->tn_string->st_len = len;
319 319
320 if (strg->st_tspec == CHAR) { 320 if (strg->st_tspec == CHAR) {
321 n->tn_string->st_cp = expr_zero_alloc(len + 1); 321 n->tn_string->st_cp = expr_zero_alloc(len + 1);
322 (void)memcpy(n->tn_string->st_cp, strg->st_cp, len + 1); 322 (void)memcpy(n->tn_string->st_cp, strg->st_cp, len + 1);
323 free(strg->st_cp); 323 free(strg->st_cp);
324 } else { 324 } else {
325 size_t size = (len + 1) * sizeof(*n->tn_string->st_wcp); 325 size_t size = (len + 1) * sizeof(*n->tn_string->st_wcp);
326 n->tn_string->st_wcp = expr_zero_alloc(size); 326 n->tn_string->st_wcp = expr_zero_alloc(size);
327 (void)memcpy(n->tn_string->st_wcp, strg->st_wcp, size); 327 (void)memcpy(n->tn_string->st_wcp, strg->st_wcp, size);
328 free(strg->st_wcp); 328 free(strg->st_wcp);
329 } 329 }
330 free(strg); 330 free(strg);
331 331
332 return n; 332 return n;
333} 333}
334 334
335/* 335/*
336 * Returns a symbol which has the same name as the msym argument and is a 336 * Returns a symbol which has the same name as the msym argument and is a
337 * member of the struct or union specified by the tn argument. 337 * member of the struct or union specified by the tn argument.
338 */ 338 */
339static sym_t * 339static sym_t *
340struct_or_union_member(tnode_t *tn, op_t op, sym_t *msym) 340struct_or_union_member(tnode_t *tn, op_t op, sym_t *msym)
341{ 341{
342 struct_or_union *str; 342 struct_or_union *str;
343 type_t *tp; 343 type_t *tp;
344 sym_t *sym, *csym; 344 sym_t *sym, *csym;
345 bool eq; 345 bool eq;
346 tspec_t t; 346 tspec_t t;
347 347
348 /* 348 /*
349 * Remove the member if it was unknown until now, which means 349 * Remove the member if it was unknown until now, which means
350 * that no defined struct or union has a member with the same name. 350 * that no defined struct or union has a member with the same name.
351 */ 351 */
352 if (msym->s_scl == NOSCL) { 352 if (msym->s_scl == NOSCL) {
353 /* type '%s' does not have member '%s' */ 353 /* type '%s' does not have member '%s' */
354 error(101, type_name(tn->tn_type), msym->s_name); 354 error(101, type_name(tn->tn_type), msym->s_name);
355 rmsym(msym); 355 rmsym(msym);
356 msym->s_kind = FMEMBER; 356 msym->s_kind = FMEMBER;
357 msym->s_scl = MOS; 357 msym->s_scl = MOS;
358 msym->s_styp = expr_zero_alloc(sizeof(*msym->s_styp)); 358 msym->s_styp = expr_zero_alloc(sizeof(*msym->s_styp));
359 msym->s_styp->sou_tag = expr_zero_alloc( 359 msym->s_styp->sou_tag = expr_zero_alloc(
360 sizeof(*msym->s_styp->sou_tag)); 360 sizeof(*msym->s_styp->sou_tag));
361 msym->s_styp->sou_tag->s_name = unnamed; 361 msym->s_styp->sou_tag->s_name = unnamed;
362 msym->s_value.v_tspec = INT; 362 msym->s_value.v_tspec = INT;
363 return msym; 363 return msym;
364 } 364 }
365 365
366 /* Set str to the tag of which msym is expected to be a member. */ 366 /* Set str to the tag of which msym is expected to be a member. */
367 str = NULL; 367 str = NULL;
368 t = (tp = tn->tn_type)->t_tspec; 368 t = (tp = tn->tn_type)->t_tspec;
369 if (op == POINT) { 369 if (op == POINT) {
370 if (t == STRUCT || t == UNION) 370 if (t == STRUCT || t == UNION)
371 str = tp->t_str; 371 str = tp->t_str;
372 } else if (op == ARROW && t == PTR) { 372 } else if (op == ARROW && t == PTR) {
373 t = (tp = tp->t_subt)->t_tspec; 373 t = (tp = tp->t_subt)->t_tspec;
374 if (t == STRUCT || t == UNION) 374 if (t == STRUCT || t == UNION)
375 str = tp->t_str; 375 str = tp->t_str;
376 } 376 }
377 377
378 /* 378 /*
379 * If this struct/union has a member with the name of msym, return it. 379 * If this struct/union has a member with the name of msym, return it.
380 */ 380 */
381 if (str != NULL) { 381 if (str != NULL) {
382 for (sym = msym; sym != NULL; sym = sym->s_link) { 382 for (sym = msym; sym != NULL; sym = sym->s_symtab_next) {
383 if (sym->s_scl != MOS && sym->s_scl != MOU) 383 if (sym->s_scl != MOS && sym->s_scl != MOU)
384 continue; 384 continue;
385 if (sym->s_styp != str) 385 if (sym->s_styp != str)
386 continue; 386 continue;
387 if (strcmp(sym->s_name, msym->s_name) != 0) 387 if (strcmp(sym->s_name, msym->s_name) != 0)
388 continue; 388 continue;
389 return sym; 389 return sym;
390 } 390 }
391 } 391 }
392 392
393 /* 393 /*
394 * Set eq to false if there are struct/union members with the same 394 * Set eq to false if there are struct/union members with the same
395 * name and different types and/or offsets. 395 * name and different types and/or offsets.
396 */ 396 */
397 eq = true; 397 eq = true;
398 for (csym = msym; csym != NULL; csym = csym->s_link) { 398 for (csym = msym; csym != NULL; csym = csym->s_symtab_next) {
399 if (csym->s_scl != MOS && csym->s_scl != MOU) 399 if (csym->s_scl != MOS && csym->s_scl != MOU)
400 continue; 400 continue;
401 if (strcmp(msym->s_name, csym->s_name) != 0) 401 if (strcmp(msym->s_name, csym->s_name) != 0)
402 continue; 402 continue;
403 for (sym = csym->s_link; sym != NULL; sym = sym->s_link) { 403 for (sym = csym->s_symtab_next; sym != NULL;
 404 sym = sym->s_symtab_next) {
404 bool w; 405 bool w;
405 406
406 if (sym->s_scl != MOS && sym->s_scl != MOU) 407 if (sym->s_scl != MOS && sym->s_scl != MOU)
407 continue; 408 continue;
408 if (strcmp(csym->s_name, sym->s_name) != 0) 409 if (strcmp(csym->s_name, sym->s_name) != 0)
409 continue; 410 continue;
410 if (csym->s_value.v_quad != sym->s_value.v_quad) { 411 if (csym->s_value.v_quad != sym->s_value.v_quad) {
411 eq = false; 412 eq = false;
412 break; 413 break;
413 } 414 }
414 w = false; 415 w = false;
415 eq = eqtype(csym->s_type, sym->s_type, 416 eq = eqtype(csym->s_type, sym->s_type,
416 false, false, &w) && !w; 417 false, false, &w) && !w;
417 if (!eq) 418 if (!eq)
418 break; 419 break;
419 if (csym->s_bitfield != sym->s_bitfield) { 420 if (csym->s_bitfield != sym->s_bitfield) {
420 eq = false; 421 eq = false;
421 break; 422 break;
422 } 423 }
423 if (csym->s_bitfield) { 424 if (csym->s_bitfield) {
424 type_t *tp1, *tp2; 425 type_t *tp1, *tp2;
425 426
426 tp1 = csym->s_type; 427 tp1 = csym->s_type;
427 tp2 = sym->s_type; 428 tp2 = sym->s_type;
428 if (tp1->t_flen != tp2->t_flen) { 429 if (tp1->t_flen != tp2->t_flen) {
429 eq = false; 430 eq = false;
430 break; 431 break;
431 } 432 }
432 if (tp1->t_foffs != tp2->t_foffs) { 433 if (tp1->t_foffs != tp2->t_foffs) {
433 eq = false; 434 eq = false;
434 break; 435 break;
435 } 436 }
436 } 437 }
437 } 438 }
438 if (!eq) 439 if (!eq)
439 break; 440 break;
440 } 441 }
441 442
442 /* 443 /*
443 * Now handle the case in which the left operand refers really 444 * Now handle the case in which the left operand refers really
444 * to a struct/union, but the right operand is not member of it. 445 * to a struct/union, but the right operand is not member of it.
445 */ 446 */
446 if (str != NULL) { 447 if (str != NULL) {
447 if (eq && tflag) { 448 if (eq && tflag) {
448 /* illegal member use: %s */ 449 /* illegal member use: %s */
449 warning(102, msym->s_name); 450 warning(102, msym->s_name);
450 } else { 451 } else {
451 /* illegal member use: %s */ 452 /* illegal member use: %s */
452 error(102, msym->s_name); 453 error(102, msym->s_name);
453 } 454 }
454 return msym; 455 return msym;
455 } 456 }
456 457
457 /* 458 /*
458 * Now the left operand of ARROW does not point to a struct/union 459 * Now the left operand of ARROW does not point to a struct/union
459 * or the left operand of POINT is no struct/union. 460 * or the left operand of POINT is no struct/union.
460 */ 461 */
461 if (eq) { 462 if (eq) {
462 if (op == POINT) { 463 if (op == POINT) {
463 if (tflag) { 464 if (tflag) {
464 /* left operand of '.' must be struct ... */ 465 /* left operand of '.' must be struct ... */
465 warning(103, type_name(tn->tn_type)); 466 warning(103, type_name(tn->tn_type));
466 } else { 467 } else {
467 /* left operand of '.' must be struct ... */ 468 /* left operand of '.' must be struct ... */
468 error(103, type_name(tn->tn_type)); 469 error(103, type_name(tn->tn_type));
469 } 470 }
470 } else { 471 } else {
471 if (tflag && tn->tn_type->t_tspec == PTR) { 472 if (tflag && tn->tn_type->t_tspec == PTR) {
472 /* left operand of '->' must be pointer ... */ 473 /* left operand of '->' must be pointer ... */
473 warning(104, type_name(tn->tn_type)); 474 warning(104, type_name(tn->tn_type));
474 } else { 475 } else {
475 /* left operand of '->' must be pointer ... */ 476 /* left operand of '->' must be pointer ... */
476 error(104, type_name(tn->tn_type)); 477 error(104, type_name(tn->tn_type));
477 } 478 }
478 } 479 }
479 } else { 480 } else {
480 if (tflag) { 481 if (tflag) {
481 /* non-unique member requires struct/union %s */ 482 /* non-unique member requires struct/union %s */
482 error(105, op == POINT ? "object" : "pointer"); 483 error(105, op == POINT ? "object" : "pointer");
483 } else { 484 } else {
484 /* unacceptable operand of '%s' */ 485 /* unacceptable operand of '%s' */
485 error(111, op_name(op)); 486 error(111, op_name(op));
486 } 487 }
487 } 488 }
488 489
489 return msym; 490 return msym;
490} 491}
491 492
492tnode_t * 493tnode_t *
493build_generic_selection(const tnode_t *expr, 494build_generic_selection(const tnode_t *expr,
494 struct generic_association *sel) 495 struct generic_association *sel)
495{ 496{
496 tnode_t *default_result = NULL; 497 tnode_t *default_result = NULL;
497 498
498 for (; sel != NULL; sel = sel->ga_prev) 499 for (; sel != NULL; sel = sel->ga_prev)
499 if (expr != NULL && 500 if (expr != NULL &&
500 eqtype(sel->ga_arg, expr->tn_type, false, false, NULL)) 501 eqtype(sel->ga_arg, expr->tn_type, false, false, NULL))
501 return sel->ga_result; 502 return sel->ga_result;
502 else if (sel->ga_arg == NULL) 503 else if (sel->ga_arg == NULL)
503 default_result = sel->ga_result; 504 default_result = sel->ga_result;
504 return default_result; 505 return default_result;
505} 506}
506 507
507/* 508/*
508 * Create a tree node for a binary operator and its two operands. Also called 509 * Create a tree node for a binary operator and its two operands. Also called
509 * for unary operators; in that case rn is NULL. 510 * for unary operators; in that case rn is NULL.
510 * 511 *
511 * Function calls, sizeof and casts are handled elsewhere. 512 * Function calls, sizeof and casts are handled elsewhere.
512 */ 513 */
513tnode_t * 514tnode_t *
514build_binary(tnode_t *ln, op_t op, bool sys, tnode_t *rn) 515build_binary(tnode_t *ln, op_t op, bool sys, tnode_t *rn)
515{ 516{
516 const mod_t *mp; 517 const mod_t *mp;
517 tnode_t *ntn; 518 tnode_t *ntn;
518 type_t *rettp; 519 type_t *rettp;
519 520
520 mp = &modtab[op]; 521 mp = &modtab[op];
521 522
522 /* If there was an error in one of the operands, return. */ 523 /* If there was an error in one of the operands, return. */
523 if (ln == NULL || (mp->m_binary && rn == NULL)) 524 if (ln == NULL || (mp->m_binary && rn == NULL))
524 return NULL; 525 return NULL;
525 526
526 /* 527 /*
527 * Apply class conversions to the left operand, but only if its 528 * Apply class conversions to the left operand, but only if its
528 * value is needed or it is compared with null. 529 * value is needed or it is compared with null.
529 */ 530 */
530 if (mp->m_left_value_context || mp->m_left_test_context) 531 if (mp->m_left_value_context || mp->m_left_test_context)
531 ln = cconv(ln); 532 ln = cconv(ln);
532 /* 533 /*
533 * The right operand is almost always in a test or value context, 534 * The right operand is almost always in a test or value context,
534 * except if it is a struct or union member. 535 * except if it is a struct or union member.
535 */ 536 */
536 if (mp->m_binary && op != ARROW && op != POINT) 537 if (mp->m_binary && op != ARROW && op != POINT)
537 rn = cconv(rn); 538 rn = cconv(rn);
538 539
539 /* 540 /*
540 * Print some warnings for comparisons of unsigned values with 541 * Print some warnings for comparisons of unsigned values with
541 * constants lower than or equal to null. This must be done 542 * constants lower than or equal to null. This must be done
542 * before promote() because otherwise unsigned char and unsigned 543 * before promote() because otherwise unsigned char and unsigned
543 * short would be promoted to int. Also types are tested to be 544 * short would be promoted to int. Also types are tested to be
544 * CHAR, which would also become int. 545 * CHAR, which would also become int.
545 */ 546 */
546 if (mp->m_comparison) 547 if (mp->m_comparison)
547 check_integer_comparison(op, ln, rn); 548 check_integer_comparison(op, ln, rn);
548 549
549 /* 550 /*
550 * Promote the left operand if it is in a test or value context 551 * Promote the left operand if it is in a test or value context
551 */ 552 */
552 if (mp->m_left_value_context || mp->m_left_test_context) 553 if (mp->m_left_value_context || mp->m_left_test_context)
553 ln = promote(op, false, ln); 554 ln = promote(op, false, ln);
554 /* 555 /*
555 * Promote the right operand, but only if it is no struct or 556 * Promote the right operand, but only if it is no struct or
556 * union member, or if it is not to be assigned to the left operand 557 * union member, or if it is not to be assigned to the left operand
557 */ 558 */
558 if (mp->m_binary && op != ARROW && op != POINT && 559 if (mp->m_binary && op != ARROW && op != POINT &&
559 op != ASSIGN && op != RETURN && op != INIT) { 560 op != ASSIGN && op != RETURN && op != INIT) {
560 rn = promote(op, false, rn); 561 rn = promote(op, false, rn);
561 } 562 }
562 563
563 /* 564 /*
564 * If the result of the operation is different for signed or 565 * If the result of the operation is different for signed or
565 * unsigned operands and one of the operands is signed only in 566 * unsigned operands and one of the operands is signed only in
566 * ANSI C, print a warning. 567 * ANSI C, print a warning.
567 */ 568 */
568 if (mp->m_warn_if_left_unsigned_in_c90 && 569 if (mp->m_warn_if_left_unsigned_in_c90 &&
569 ln->tn_op == CON && ln->tn_val->v_unsigned_since_c90) { 570 ln->tn_op == CON && ln->tn_val->v_unsigned_since_c90) {
570 /* ANSI C treats constant as unsigned, op %s */ 571 /* ANSI C treats constant as unsigned, op %s */
571 warning(218, mp->m_name); 572 warning(218, mp->m_name);
572 ln->tn_val->v_unsigned_since_c90 = false; 573 ln->tn_val->v_unsigned_since_c90 = false;
573 } 574 }
574 if (mp->m_warn_if_right_unsigned_in_c90 && 575 if (mp->m_warn_if_right_unsigned_in_c90 &&
575 rn->tn_op == CON && rn->tn_val->v_unsigned_since_c90) { 576 rn->tn_op == CON && rn->tn_val->v_unsigned_since_c90) {
576 /* ANSI C treats constant as unsigned, op %s */ 577 /* ANSI C treats constant as unsigned, op %s */
577 warning(218, mp->m_name); 578 warning(218, mp->m_name);
578 rn->tn_val->v_unsigned_since_c90 = false; 579 rn->tn_val->v_unsigned_since_c90 = false;
579 } 580 }
580 581
581 /* Make sure both operands are of the same type */ 582 /* Make sure both operands are of the same type */
582 if (mp->m_balance_operands || (tflag && (op == SHL || op == SHR))) 583 if (mp->m_balance_operands || (tflag && (op == SHL || op == SHR)))
583 balance(op, &ln, &rn); 584 balance(op, &ln, &rn);
584 585
585 /* 586 /*
586 * Check types for compatibility with the operation and mutual 587 * Check types for compatibility with the operation and mutual
587 * compatibility. Return if there are serious problems. 588 * compatibility. Return if there are serious problems.
588 */ 589 */
589 if (!typeok(op, 0, ln, rn)) 590 if (!typeok(op, 0, ln, rn))
590 return NULL; 591 return NULL;
591 592
592 /* And now create the node. */ 593 /* And now create the node. */
593 switch (op) { 594 switch (op) {
594 case POINT: 595 case POINT:
595 case ARROW: 596 case ARROW:
596 ntn = build_struct_access(op, sys, ln, rn); 597 ntn = build_struct_access(op, sys, ln, rn);
597 break; 598 break;
598 case INCAFT: 599 case INCAFT:
599 case DECAFT: 600 case DECAFT:
600 case INCBEF: 601 case INCBEF:
601 case DECBEF: 602 case DECBEF:
602 ntn = build_prepost_incdec(op, sys, ln); 603 ntn = build_prepost_incdec(op, sys, ln);
603 break; 604 break;
604 case ADDR: 605 case ADDR:
605 ntn = build_address(sys, ln, false); 606 ntn = build_address(sys, ln, false);
606 break; 607 break;
607 case INDIR: 608 case INDIR:
608 ntn = new_tnode(INDIR, sys, ln->tn_type->t_subt, ln, NULL); 609 ntn = new_tnode(INDIR, sys, ln->tn_type->t_subt, ln, NULL);
609 break; 610 break;
610 case PLUS: 611 case PLUS:
611 case MINUS: 612 case MINUS:
612 ntn = build_plus_minus(op, sys, ln, rn); 613 ntn = build_plus_minus(op, sys, ln, rn);
613 break; 614 break;
614 case SHL: 615 case SHL:
615 case SHR: 616 case SHR:
616 ntn = build_bit_shift(op, sys, ln, rn); 617 ntn = build_bit_shift(op, sys, ln, rn);
617 break; 618 break;
618 case COLON: 619 case COLON:
619 ntn = build_colon(sys, ln, rn); 620 ntn = build_colon(sys, ln, rn);
620 break; 621 break;
621 case ASSIGN: 622 case ASSIGN:
622 case MULASS: 623 case MULASS:
623 case DIVASS: 624 case DIVASS:
624 case MODASS: 625 case MODASS:
625 case ADDASS: 626 case ADDASS:
626 case SUBASS: 627 case SUBASS:
627 case SHLASS: 628 case SHLASS:
628 case SHRASS: 629 case SHRASS:
629 case ANDASS: 630 case ANDASS:
630 case XORASS: 631 case XORASS:
631 case ORASS: 632 case ORASS:
632 case RETURN: 633 case RETURN:
633 case INIT: 634 case INIT:
634 ntn = build_assignment(op, sys, ln, rn); 635 ntn = build_assignment(op, sys, ln, rn);
635 break; 636 break;
636 case COMMA: 637 case COMMA:
637 case QUEST: 638 case QUEST:
638 ntn = new_tnode(op, sys, rn->tn_type, ln, rn); 639 ntn = new_tnode(op, sys, rn->tn_type, ln, rn);
639 break; 640 break;
640 case REAL: 641 case REAL:
641 case IMAG: 642 case IMAG:
642 ntn = build_real_imag(op, sys, ln); 643 ntn = build_real_imag(op, sys, ln);
643 break; 644 break;
644 default: 645 default:
645 rettp = mp->m_returns_bool 646 rettp = mp->m_returns_bool
646 ? gettyp(Tflag ? BOOL : INT) : ln->tn_type; 647 ? gettyp(Tflag ? BOOL : INT) : ln->tn_type;
647 lint_assert(mp->m_binary || rn == NULL); 648 lint_assert(mp->m_binary || rn == NULL);
648 ntn = new_tnode(op, sys, rettp, ln, rn); 649 ntn = new_tnode(op, sys, rettp, ln, rn);
649 break; 650 break;
650 } 651 }
651 652
652 /* Return if an error occurred. */ 653 /* Return if an error occurred. */
653 if (ntn == NULL) 654 if (ntn == NULL)
654 return NULL; 655 return NULL;
655 656
656 /* Print a warning if precedence confusion is possible */ 657 /* Print a warning if precedence confusion is possible */
657 if (mp->m_possible_precedence_confusion) 658 if (mp->m_possible_precedence_confusion)
658 check_precedence_confusion(ntn); 659 check_precedence_confusion(ntn);
659 660
660 /* 661 /*
661 * Print a warning if one of the operands is in a context where 662 * Print a warning if one of the operands is in a context where
662 * it is compared with null and if this operand is a constant. 663 * it is compared with null and if this operand is a constant.
663 */ 664 */
664 if (mp->m_left_test_context) { 665 if (mp->m_left_test_context) {
665 if (ln->tn_op == CON || 666 if (ln->tn_op == CON ||
666 ((mp->m_binary && op != QUEST) && rn->tn_op == CON)) { 667 ((mp->m_binary && op != QUEST) && rn->tn_op == CON)) {
667 if (hflag && !constcond_flag && 668 if (hflag && !constcond_flag &&
668 !ln->tn_system_dependent) 669 !ln->tn_system_dependent)
669 /* constant in conditional context */ 670 /* constant in conditional context */
670 warning(161); 671 warning(161);
671 } 672 }
672 } 673 }
673 674
674 /* Fold if the operator requires it */ 675 /* Fold if the operator requires it */
675 if (mp->m_fold_constant_operands) { 676 if (mp->m_fold_constant_operands) {
676 if (ln->tn_op == CON && (!mp->m_binary || rn->tn_op == CON)) { 677 if (ln->tn_op == CON && (!mp->m_binary || rn->tn_op == CON)) {
677 if (mp->m_left_test_context) { 678 if (mp->m_left_test_context) {
678 ntn = fold_test(ntn); 679 ntn = fold_test(ntn);
679 } else if (is_floating(ntn->tn_type->t_tspec)) { 680 } else if (is_floating(ntn->tn_type->t_tspec)) {
680 ntn = fold_float(ntn); 681 ntn = fold_float(ntn);
681 } else { 682 } else {
682 ntn = fold(ntn); 683 ntn = fold(ntn);
683 } 684 }
684 } else if (op == QUEST && ln->tn_op == CON) { 685 } else if (op == QUEST && ln->tn_op == CON) {
685 ntn = ln->tn_val->v_quad != 0 686 ntn = ln->tn_val->v_quad != 0
686 ? rn->tn_left : rn->tn_right; 687 ? rn->tn_left : rn->tn_right;
687 } 688 }
688 } 689 }
689 690
690 return ntn; 691 return ntn;
691} 692}
692 693
693tnode_t * 694tnode_t *
694build_unary(op_t op, bool sys, tnode_t *tn) 695build_unary(op_t op, bool sys, tnode_t *tn)
695{ 696{
696 return build_binary(tn, op, sys, NULL); 697 return build_binary(tn, op, sys, NULL);
697} 698}
698 699
699tnode_t * 700tnode_t *
700build_member_access(tnode_t *ln, op_t op, bool sys, sbuf_t *member) 701build_member_access(tnode_t *ln, op_t op, bool sys, sbuf_t *member)
701{ 702{
702 sym_t *msym; 703 sym_t *msym;
703 704
704 if (ln == NULL) 705 if (ln == NULL)
705 return NULL; 706 return NULL;
706 707
707 if (op == ARROW) { 708 if (op == ARROW) {
708 /* must do this before struct_or_union_member is called */ 709 /* must do this before struct_or_union_member is called */
709 ln = cconv(ln); 710 ln = cconv(ln);
710 } 711 }
711 msym = struct_or_union_member(ln, op, getsym(member)); 712 msym = struct_or_union_member(ln, op, getsym(member));
712 return build_binary(ln, op, sys, build_name(msym, false)); 713 return build_binary(ln, op, sys, build_name(msym, false));
713} 714}
714 715
715/* 716/*
716 * Perform class conversions. 717 * Perform class conversions.
717 * 718 *
718 * Arrays of type T are converted into pointers to type T. 719 * Arrays of type T are converted into pointers to type T.
719 * Functions are converted to pointers to functions. 720 * Functions are converted to pointers to functions.
720 * Lvalues are converted to rvalues. 721 * Lvalues are converted to rvalues.
721 * 722 *
722 * C99 6.3 "Conversions" 723 * C99 6.3 "Conversions"
723 * C99 6.3.2 "Other operands" 724 * C99 6.3.2 "Other operands"
724 * C99 6.3.2.1 "Lvalues, arrays, and function designators" 725 * C99 6.3.2.1 "Lvalues, arrays, and function designators"
725 */ 726 */
726tnode_t * 727tnode_t *
727cconv(tnode_t *tn) 728cconv(tnode_t *tn)
728{ 729{
729 type_t *tp; 730 type_t *tp;
730 731
731 /* 732 /*
732 * Array-lvalue (array of type T) is converted into rvalue 733 * Array-lvalue (array of type T) is converted into rvalue
733 * (pointer to type T) 734 * (pointer to type T)
734 */ 735 */
735 if (tn->tn_type->t_tspec == ARRAY) { 736 if (tn->tn_type->t_tspec == ARRAY) {
736 if (!tn->tn_lvalue) { 737 if (!tn->tn_lvalue) {
737 /* XXX print correct operator */ 738 /* XXX print correct operator */
738 /* %soperand of '%s' must be lvalue */ 739 /* %soperand of '%s' must be lvalue */
739 gnuism(114, "", op_name(ADDR)); 740 gnuism(114, "", op_name(ADDR));
740 } 741 }
741 tn = new_tnode(ADDR, tn->tn_sys, 742 tn = new_tnode(ADDR, tn->tn_sys,
742 expr_derive_type(tn->tn_type->t_subt, PTR), tn, NULL); 743 expr_derive_type(tn->tn_type->t_subt, PTR), tn, NULL);
743 } 744 }
744 745
745 /* 746 /*
746 * Expression of type function (function with return value of type T) 747 * Expression of type function (function with return value of type T)
747 * in rvalue-expression (pointer to function with return value 748 * in rvalue-expression (pointer to function with return value
748 * of type T) 749 * of type T)
749 */ 750 */
750 if (tn->tn_type->t_tspec == FUNC) 751 if (tn->tn_type->t_tspec == FUNC)
751 tn = build_address(tn->tn_sys, tn, true); 752 tn = build_address(tn->tn_sys, tn, true);
752 753
753 /* lvalue to rvalue */ 754 /* lvalue to rvalue */
754 if (tn->tn_lvalue) { 755 if (tn->tn_lvalue) {
755 tp = expr_dup_type(tn->tn_type); 756 tp = expr_dup_type(tn->tn_type);
756 /* C99 6.3.2.1p2 sentence 2 says to remove the qualifiers. */ 757 /* C99 6.3.2.1p2 sentence 2 says to remove the qualifiers. */
757 tp->t_const = tp->t_volatile = false; 758 tp->t_const = tp->t_volatile = false;
758 tn = new_tnode(LOAD, tn->tn_sys, tp, tn, NULL); 759 tn = new_tnode(LOAD, tn->tn_sys, tp, tn, NULL);
759 } 760 }
760 761
761 return tn; 762 return tn;
762} 763}
763 764
764const tnode_t * 765const tnode_t *
765before_conversion(const tnode_t *tn) 766before_conversion(const tnode_t *tn)
766{ 767{
767 while (tn->tn_op == CVT && !tn->tn_cast) 768 while (tn->tn_op == CVT && !tn->tn_cast)
768 tn = tn->tn_left; 769 tn = tn->tn_left;
769 return tn; 770 return tn;
770} 771}
771 772
772static bool 773static bool
773is_null_pointer(const tnode_t *tn) 774is_null_pointer(const tnode_t *tn)
774{ 775{
775 tspec_t t = tn->tn_type->t_tspec; 776 tspec_t t = tn->tn_type->t_tspec;
776 777
777 return ((t == PTR && tn->tn_type->t_subt->t_tspec == VOID) || 778 return ((t == PTR && tn->tn_type->t_subt->t_tspec == VOID) ||
778 is_integer(t)) 779 is_integer(t))
779 && (tn->tn_op == CON && tn->tn_val->v_quad == 0); 780 && (tn->tn_op == CON && tn->tn_val->v_quad == 0);
780} 781}
781 782
782/* 783/*
783 * Most errors required by ANSI C are reported in struct_or_union_member(). 784 * Most errors required by ANSI C are reported in struct_or_union_member().
784 * Here we only check for totally wrong things. 785 * Here we only check for totally wrong things.
785 */ 786 */
786static bool 787static bool
787typeok_point(const tnode_t *ln, const type_t *ltp, tspec_t lt) 788typeok_point(const tnode_t *ln, const type_t *ltp, tspec_t lt)
788{ 789{
789 if (lt == FUNC || lt == VOID || ltp->t_bitfield || 790 if (lt == FUNC || lt == VOID || ltp->t_bitfield ||
790 ((lt != STRUCT && lt != UNION) && !ln->tn_lvalue)) { 791 ((lt != STRUCT && lt != UNION) && !ln->tn_lvalue)) {
791 /* Without tflag we got already an error */ 792 /* Without tflag we got already an error */
792 if (tflag) 793 if (tflag)
793 /* unacceptable operand of '%s' */ 794 /* unacceptable operand of '%s' */
794 error(111, op_name(POINT)); 795 error(111, op_name(POINT));
795 return false; 796 return false;
796 } 797 }
797 return true; 798 return true;
798} 799}
799 800
800static bool 801static bool
801typeok_arrow(tspec_t lt) 802typeok_arrow(tspec_t lt)
802{ 803{
803 if (lt == PTR || (tflag && is_integer(lt))) 804 if (lt == PTR || (tflag && is_integer(lt)))
804 return true; 805 return true;
805 806
806 /* Without tflag we got already an error */ 807 /* Without tflag we got already an error */
807 if (tflag) 808 if (tflag)
808 /* unacceptable operand of '%s' */ 809 /* unacceptable operand of '%s' */
809 error(111, op_name(ARROW)); 810 error(111, op_name(ARROW));
810 return false; 811 return false;
811} 812}
812 813
813static bool 814static bool
814typeok_incdec(op_t op, const tnode_t *tn, const type_t *tp) 815typeok_incdec(op_t op, const tnode_t *tn, const type_t *tp)
815{ 816{
816 /* operand has scalar type (checked in typeok) */ 817 /* operand has scalar type (checked in typeok) */
817 if (!tn->tn_lvalue) { 818 if (!tn->tn_lvalue) {
818 if (tn->tn_op == CVT && tn->tn_cast && 819 if (tn->tn_op == CVT && tn->tn_cast &&
819 tn->tn_left->tn_op == LOAD) { 820 tn->tn_left->tn_op == LOAD) {
820 /* a cast does not yield an lvalue */ 821 /* a cast does not yield an lvalue */
821 error(163); 822 error(163);
822 } 823 }
823 /* %soperand of '%s' must be lvalue */ 824 /* %soperand of '%s' must be lvalue */
824 error(114, "", op_name(op)); 825 error(114, "", op_name(op));
825 return false; 826 return false;
826 } else if (tp->t_const) { 827 } else if (tp->t_const) {
827 if (!tflag) 828 if (!tflag)
828 /* %soperand of '%s' must be modifiable lvalue */ 829 /* %soperand of '%s' must be modifiable lvalue */
829 warning(115, "", op_name(op)); 830 warning(115, "", op_name(op));
830 } 831 }
831 return true; 832 return true;
832} 833}
833 834
834static bool 835static bool
835typeok_address(const mod_t *mp, 836typeok_address(const mod_t *mp,
836 const tnode_t *tn, const type_t *tp, tspec_t t) 837 const tnode_t *tn, const type_t *tp, tspec_t t)
837{ 838{
838 if (t == ARRAY || t == FUNC) { 839 if (t == ARRAY || t == FUNC) {
839 /* ok, a warning comes later (in build_address()) */ 840 /* ok, a warning comes later (in build_address()) */
840 } else if (!tn->tn_lvalue) { 841 } else if (!tn->tn_lvalue) {
841 if (tn->tn_op == CVT && tn->tn_cast && 842 if (tn->tn_op == CVT && tn->tn_cast &&
842 tn->tn_left->tn_op == LOAD) { 843 tn->tn_left->tn_op == LOAD) {
843 /* a cast does not yield an lvalue */ 844 /* a cast does not yield an lvalue */
844 error(163); 845 error(163);
845 } 846 }
846 /* %soperand of '%s' must be lvalue */ 847 /* %soperand of '%s' must be lvalue */
847 error(114, "", mp->m_name); 848 error(114, "", mp->m_name);
848 return false; 849 return false;
849 } else if (is_scalar(t)) { 850 } else if (is_scalar(t)) {
850 if (tp->t_bitfield) { 851 if (tp->t_bitfield) {
851 /* cannot take address of bit-field */ 852 /* cannot take address of bit-field */
852 error(112); 853 error(112);
853 return false; 854 return false;
854 } 855 }
855 } else if (t != STRUCT && t != UNION) { 856 } else if (t != STRUCT && t != UNION) {
856 /* unacceptable operand of '%s' */ 857 /* unacceptable operand of '%s' */
857 error(111, mp->m_name); 858 error(111, mp->m_name);
858 return false; 859 return false;
859 } 860 }
860 if (tn->tn_op == NAME && tn->tn_sym->s_reg) { 861 if (tn->tn_op == NAME && tn->tn_sym->s_reg) {
861 /* cannot take address of register %s */ 862 /* cannot take address of register %s */
862 error(113, tn->tn_sym->s_name); 863 error(113, tn->tn_sym->s_name);
863 return false; 864 return false;
864 } 865 }
865 return true; 866 return true;
866} 867}
867 868
868static bool 869static bool
869typeok_indir(tspec_t t) 870typeok_indir(tspec_t t)
870{ 871{
871 /* until now there were no type checks for this operator */ 872 /* until now there were no type checks for this operator */
872 if (t != PTR) { 873 if (t != PTR) {
873 /* cannot dereference non-pointer type */ 874 /* cannot dereference non-pointer type */
874 error(96); 875 error(96);
875 return false; 876 return false;
876 } 877 }
877 return true; 878 return true;
878} 879}
879 880
880static bool 881static bool
881typeok_plus(op_t op, 882typeok_plus(op_t op,
882 const type_t *ltp, tspec_t lt, 883 const type_t *ltp, tspec_t lt,
883 const type_t *rtp, tspec_t rt) 884 const type_t *rtp, tspec_t rt)
884{ 885{
885 /* operands have scalar types (checked above) */ 886 /* operands have scalar types (checked above) */
886 if ((lt == PTR && !is_integer(rt)) || (rt == PTR && !is_integer(lt))) { 887 if ((lt == PTR && !is_integer(rt)) || (rt == PTR && !is_integer(lt))) {
887 warn_incompatible_types(op, ltp, lt, rtp, rt); 888 warn_incompatible_types(op, ltp, lt, rtp, rt);
888 return false; 889 return false;
889 } 890 }
890 return true; 891 return true;
891} 892}
892 893
893static bool 894static bool
894typeok_minus(op_t op, 895typeok_minus(op_t op,
895 const type_t *ltp, tspec_t lt, 896 const type_t *ltp, tspec_t lt,
896 const type_t *rtp, tspec_t rt) 897 const type_t *rtp, tspec_t rt)
897{ 898{
898 /* operands have scalar types (checked above) */ 899 /* operands have scalar types (checked above) */
899 if (lt == PTR && (!is_integer(rt) && rt != PTR)) { 900 if (lt == PTR && (!is_integer(rt) && rt != PTR)) {
900 warn_incompatible_types(op, ltp, lt, rtp, rt); 901 warn_incompatible_types(op, ltp, lt, rtp, rt);
901 return false; 902 return false;
902 } else if (rt == PTR && lt != PTR) { 903 } else if (rt == PTR && lt != PTR) {
903 warn_incompatible_types(op, ltp, lt, rtp, rt); 904 warn_incompatible_types(op, ltp, lt, rtp, rt);
904 return false; 905 return false;
905 } 906 }
906 if (lt == PTR && rt == PTR) { 907 if (lt == PTR && rt == PTR) {
907 if (!eqtype(ltp->t_subt, rtp->t_subt, true, false, NULL)) { 908 if (!eqtype(ltp->t_subt, rtp->t_subt, true, false, NULL)) {
908 /* illegal pointer subtraction */ 909 /* illegal pointer subtraction */
909 error(116); 910 error(116);
910 } 911 }
911 } 912 }
912 return true; 913 return true;
913} 914}
914 915
915static void 916static void
916typeok_shr(const mod_t *mp, 917typeok_shr(const mod_t *mp,
917 const tnode_t *ln, tspec_t lt, 918 const tnode_t *ln, tspec_t lt,
918 const tnode_t *rn, tspec_t rt) 919 const tnode_t *rn, tspec_t rt)
919{ 920{
920 tspec_t olt, ort; 921 tspec_t olt, ort;
921 922
922 olt = before_conversion(ln)->tn_type->t_tspec; 923 olt = before_conversion(ln)->tn_type->t_tspec;
923 ort = before_conversion(rn)->tn_type->t_tspec; 924 ort = before_conversion(rn)->tn_type->t_tspec;
924 925
925 /* operands have integer types (checked above) */ 926 /* operands have integer types (checked above) */
926 if (pflag && !is_uinteger(olt)) { 927 if (pflag && !is_uinteger(olt)) {
927 /* 928 /*
928 * The left operand is signed. This means that 929 * The left operand is signed. This means that
929 * the operation is (possibly) nonportable. 930 * the operation is (possibly) nonportable.
930 */ 931 */
931 if (ln->tn_op != CON) { 932 if (ln->tn_op != CON) {
932 /* bitwise '%s' on signed value possibly nonportable */ 933 /* bitwise '%s' on signed value possibly nonportable */
933 warning(117, mp->m_name); 934 warning(117, mp->m_name);
934 } else if (ln->tn_val->v_quad < 0) { 935 } else if (ln->tn_val->v_quad < 0) {
935 /* bitwise '%s' on signed value nonportable */ 936 /* bitwise '%s' on signed value nonportable */
936 warning(120, mp->m_name); 937 warning(120, mp->m_name);
937 } 938 }
938 } else if (!tflag && !sflag && !is_uinteger(olt) && is_uinteger(ort)) { 939 } else if (!tflag && !sflag && !is_uinteger(olt) && is_uinteger(ort)) {
939 /* 940 /*
940 * The left operand would become unsigned in 941 * The left operand would become unsigned in
941 * traditional C. 942 * traditional C.
942 */ 943 */
943 if (hflag && !Sflag && 944 if (hflag && !Sflag &&
944 (ln->tn_op != CON || ln->tn_val->v_quad < 0)) { 945 (ln->tn_op != CON || ln->tn_val->v_quad < 0)) {
945 /* semantics of '%s' change in ANSI C; use ... */ 946 /* semantics of '%s' change in ANSI C; use ... */
946 warning(118, mp->m_name); 947 warning(118, mp->m_name);
947 } 948 }
948 } else if (!tflag && !sflag && !is_uinteger(olt) && !is_uinteger(ort) && 949 } else if (!tflag && !sflag && !is_uinteger(olt) && !is_uinteger(ort) &&
949 portable_size_in_bits(lt) < portable_size_in_bits(rt)) { 950 portable_size_in_bits(lt) < portable_size_in_bits(rt)) {
950 /* 951 /*
951 * In traditional C the left operand would be extended, 952 * In traditional C the left operand would be extended,
952 * possibly with 1, and then shifted. 953 * possibly with 1, and then shifted.
953 */ 954 */
954 if (hflag && !Sflag && 955 if (hflag && !Sflag &&
955 (ln->tn_op != CON || ln->tn_val->v_quad < 0)) { 956 (ln->tn_op != CON || ln->tn_val->v_quad < 0)) {
956 /* semantics of '%s' change in ANSI C; use ... */ 957 /* semantics of '%s' change in ANSI C; use ... */
957 warning(118, mp->m_name); 958 warning(118, mp->m_name);
958 } 959 }
959 } 960 }
960} 961}
961 962
962static void 963static void
963typeok_shl(const mod_t *mp, tspec_t lt, tspec_t rt) 964typeok_shl(const mod_t *mp, tspec_t lt, tspec_t rt)
964{ 965{
965 /* 966 /*
966 * C90 does not perform balancing for shift operations, 967 * C90 does not perform balancing for shift operations,
967 * but traditional C does. If the width of the right operand 968 * but traditional C does. If the width of the right operand
968 * is greater than the width of the left operand, then in 969 * is greater than the width of the left operand, then in
969 * traditional C the left operand would be extended to the 970 * traditional C the left operand would be extended to the
970 * width of the right operand. For SHL this may result in 971 * width of the right operand. For SHL this may result in
971 * different results. 972 * different results.
972 */ 973 */
973 if (portable_size_in_bits(lt) < portable_size_in_bits(rt)) { 974 if (portable_size_in_bits(lt) < portable_size_in_bits(rt)) {
974 /* 975 /*
975 * XXX If both operands are constant, make sure 976 * XXX If both operands are constant, make sure
976 * that there is really a difference between 977 * that there is really a difference between
977 * ANSI C and traditional C. 978 * ANSI C and traditional C.
978 */ 979 */
979 if (hflag && !Sflag) 980 if (hflag && !Sflag)
980 /* semantics of '%s' change in ANSI C; use ... */ 981 /* semantics of '%s' change in ANSI C; use ... */
981 warning(118, mp->m_name); 982 warning(118, mp->m_name);
982 } 983 }
983} 984}
984 985
985static void 986static void
986typeok_shift(tspec_t lt, const tnode_t *rn, tspec_t rt) 987typeok_shift(tspec_t lt, const tnode_t *rn, tspec_t rt)
987{ 988{
988 if (rn->tn_op != CON) 989 if (rn->tn_op != CON)
989 return; 990 return;
990 991
991 if (!is_uinteger(rt) && rn->tn_val->v_quad < 0) { 992 if (!is_uinteger(rt) && rn->tn_val->v_quad < 0) {
992 /* negative shift */ 993 /* negative shift */
993 warning(121); 994 warning(121);
994 } else if ((uint64_t)rn->tn_val->v_quad == 995 } else if ((uint64_t)rn->tn_val->v_quad ==
995 (uint64_t)size_in_bits(lt)) { 996 (uint64_t)size_in_bits(lt)) {
996 /* shift equal to size of object */ 997 /* shift equal to size of object */
997 warning(267); 998 warning(267);
998 } else if ((uint64_t)rn->tn_val->v_quad > (uint64_t)size_in_bits(lt)) { 999 } else if ((uint64_t)rn->tn_val->v_quad > (uint64_t)size_in_bits(lt)) {
999 /* shift amount %llu is greater than bit-size %llu of '%s' */ 1000 /* shift amount %llu is greater than bit-size %llu of '%s' */
1000 warning(122, (unsigned long long)rn->tn_val->v_quad, 1001 warning(122, (unsigned long long)rn->tn_val->v_quad,
1001 (unsigned long long)size_in_bits(lt), 1002 (unsigned long long)size_in_bits(lt),
1002 tspec_name(lt)); 1003 tspec_name(lt));
1003 } 1004 }
1004} 1005}
1005 1006
1006static bool 1007static bool
1007is_typeok_eq(const tnode_t *ln, tspec_t lt, const tnode_t *rn, tspec_t rt) 1008is_typeok_eq(const tnode_t *ln, tspec_t lt, const tnode_t *rn, tspec_t rt)
1008{ 1009{
1009 if (lt == PTR && is_null_pointer(rn)) 1010 if (lt == PTR && is_null_pointer(rn))
1010 return true; 1011 return true;
1011 if (rt == PTR && is_null_pointer(ln)) 1012 if (rt == PTR && is_null_pointer(ln))
1012 return true; 1013 return true;
1013 return false; 1014 return false;
1014} 1015}
1015 1016
1016static bool 1017static bool
1017typeok_compare(op_t op, 1018typeok_compare(op_t op,
1018 const tnode_t *ln, const type_t *ltp, tspec_t lt, 1019 const tnode_t *ln, const type_t *ltp, tspec_t lt,
1019 const tnode_t *rn, const type_t *rtp, tspec_t rt) 1020 const tnode_t *rn, const type_t *rtp, tspec_t rt)
1020{ 1021{
1021 const char *lx, *rx; 1022 const char *lx, *rx;
1022 1023
1023 if (lt == PTR && rt == PTR) { 1024 if (lt == PTR && rt == PTR) {
1024 check_pointer_comparison(op, ln, rn); 1025 check_pointer_comparison(op, ln, rn);
1025 return true; 1026 return true;
1026 } 1027 }
1027 1028
1028 if (lt != PTR && rt != PTR) 1029 if (lt != PTR && rt != PTR)
1029 return true; 1030 return true;
1030 1031
1031 if (!is_integer(lt) && !is_integer(rt)) { 1032 if (!is_integer(lt) && !is_integer(rt)) {
1032 warn_incompatible_types(op, ltp, lt, rtp, rt); 1033 warn_incompatible_types(op, ltp, lt, rtp, rt);
1033 return false; 1034 return false;
1034 } 1035 }
1035 1036
1036 lx = lt == PTR ? "pointer" : "integer"; 1037 lx = lt == PTR ? "pointer" : "integer";
1037 rx = rt == PTR ? "pointer" : "integer"; 1038 rx = rt == PTR ? "pointer" : "integer";
1038 /* illegal combination of %s '%s' and %s '%s', op '%s' */ 1039 /* illegal combination of %s '%s' and %s '%s', op '%s' */
1039 warning(123, lx, type_name(ltp), rx, type_name(rtp), op_name(op)); 1040 warning(123, lx, type_name(ltp), rx, type_name(rtp), op_name(op));
1040 return true; 1041 return true;
1041} 1042}
1042 1043
1043static bool 1044static bool
1044typeok_quest(tspec_t lt, const tnode_t *rn) 1045typeok_quest(tspec_t lt, const tnode_t *rn)
1045{ 1046{
1046 if (!is_scalar(lt)) { 1047 if (!is_scalar(lt)) {
1047 /* first operand must have scalar type, op ? : */ 1048 /* first operand must have scalar type, op ? : */
1048 error(170); 1049 error(170);
1049 return false; 1050 return false;
1050 } 1051 }
1051 lint_assert(before_conversion(rn)->tn_op == COLON); 1052 lint_assert(before_conversion(rn)->tn_op == COLON);
1052 return true; 1053 return true;
1053} 1054}
1054 1055
1055static void 1056static void
1056typeok_colon_pointer(const mod_t *mp, const type_t *ltp, const type_t *rtp) 1057typeok_colon_pointer(const mod_t *mp, const type_t *ltp, const type_t *rtp)
1057{ 1058{
1058 type_t *lstp = ltp->t_subt; 1059 type_t *lstp = ltp->t_subt;
1059 type_t *rstp = rtp->t_subt; 1060 type_t *rstp = rtp->t_subt;
1060 tspec_t lst = lstp->t_tspec; 1061 tspec_t lst = lstp->t_tspec;
1061 tspec_t rst = rstp->t_tspec; 1062 tspec_t rst = rstp->t_tspec;
1062 1063
1063 if ((lst == VOID && rst == FUNC) || (lst == FUNC && rst == VOID)) { 1064 if ((lst == VOID && rst == FUNC) || (lst == FUNC && rst == VOID)) {
1064 /* (void *)0 handled above */ 1065 /* (void *)0 handled above */
1065 if (sflag) 1066 if (sflag)
1066 /* ANSI C forbids conversion of %s to %s, op %s */ 1067 /* ANSI C forbids conversion of %s to %s, op %s */
1067 warning(305, "function pointer", "'void *'", 1068 warning(305, "function pointer", "'void *'",
1068 mp->m_name); 1069 mp->m_name);
1069 return; 1070 return;
1070 } 1071 }
1071 1072
1072 if (eqptrtype(lstp, rstp, true)) 1073 if (eqptrtype(lstp, rstp, true))
1073 return; 1074 return;
1074 if (!eqtype(lstp, rstp, true, false, NULL)) 1075 if (!eqtype(lstp, rstp, true, false, NULL))
1075 warn_incompatible_pointers(mp, ltp, rtp); 1076 warn_incompatible_pointers(mp, ltp, rtp);
1076} 1077}
1077 1078
1078static bool 1079static bool
1079typeok_colon(const mod_t *mp, 1080typeok_colon(const mod_t *mp,
1080 const tnode_t *ln, const type_t *ltp, tspec_t lt, 1081 const tnode_t *ln, const type_t *ltp, tspec_t lt,
1081 const tnode_t *rn, const type_t *rtp, tspec_t rt) 1082 const tnode_t *rn, const type_t *rtp, tspec_t rt)
1082{ 1083{
1083 1084
1084 if (is_arithmetic(lt) && is_arithmetic(rt)) 1085 if (is_arithmetic(lt) && is_arithmetic(rt))
1085 return true; 1086 return true;
1086 if (lt == BOOL && rt == BOOL) 1087 if (lt == BOOL && rt == BOOL)
1087 return true; 1088 return true;
1088 1089
1089 if (lt == STRUCT && rt == STRUCT && ltp->t_str == rtp->t_str) 1090 if (lt == STRUCT && rt == STRUCT && ltp->t_str == rtp->t_str)
1090 return true; 1091 return true;
1091 if (lt == UNION && rt == UNION && ltp->t_str == rtp->t_str) 1092 if (lt == UNION && rt == UNION && ltp->t_str == rtp->t_str)
1092 return true; 1093 return true;
1093 1094
1094 if (lt == PTR && is_null_pointer(rn)) 1095 if (lt == PTR && is_null_pointer(rn))
1095 return true; 1096 return true;
1096 if (rt == PTR && is_null_pointer(ln)) 1097 if (rt == PTR && is_null_pointer(ln))
1097 return true; 1098 return true;
1098 1099
1099 if ((lt == PTR && is_integer(rt)) || (is_integer(lt) && rt == PTR)) { 1100 if ((lt == PTR && is_integer(rt)) || (is_integer(lt) && rt == PTR)) {
1100 const char *lx = lt == PTR ? "pointer" : "integer"; 1101 const char *lx = lt == PTR ? "pointer" : "integer";
1101 const char *rx = rt == PTR ? "pointer" : "integer"; 1102 const char *rx = rt == PTR ? "pointer" : "integer";
1102 /* illegal combination of %s '%s' and %s '%s', op '%s' */ 1103 /* illegal combination of %s '%s' and %s '%s', op '%s' */
1103 warning(123, lx, type_name(ltp), 1104 warning(123, lx, type_name(ltp),
1104 rx, type_name(rtp), mp->m_name); 1105 rx, type_name(rtp), mp->m_name);
1105 return true; 1106 return true;
1106 } 1107 }
1107 1108
1108 if (lt == VOID || rt == VOID) { 1109 if (lt == VOID || rt == VOID) {
1109 if (lt != VOID || rt != VOID) 1110 if (lt != VOID || rt != VOID)
1110 /* incompatible types '%s' and '%s' in conditional */ 1111 /* incompatible types '%s' and '%s' in conditional */
1111 warning(126, type_name(ltp), type_name(rtp)); 1112 warning(126, type_name(ltp), type_name(rtp));
1112 return true; 1113 return true;
1113 } 1114 }
1114 1115
1115 if (lt == PTR && rt == PTR) { 1116 if (lt == PTR && rt == PTR) {
1116 typeok_colon_pointer(mp, ltp, rtp); 1117 typeok_colon_pointer(mp, ltp, rtp);
1117 return true; 1118 return true;
1118 } 1119 }
1119 1120
1120 /* incompatible types '%s' and '%s' in conditional */ 1121 /* incompatible types '%s' and '%s' in conditional */
1121 error(126, type_name(ltp), type_name(rtp)); 1122 error(126, type_name(ltp), type_name(rtp));
1122 return false; 1123 return false;
1123} 1124}
1124 1125
1125static bool 1126static bool
1126typeok_assign(op_t op, const tnode_t *ln, const type_t *ltp, tspec_t lt) 1127typeok_assign(op_t op, const tnode_t *ln, const type_t *ltp, tspec_t lt)
1127{ 1128{
1128 if (op == RETURN || op == INIT || op == FARG) 1129 if (op == RETURN || op == INIT || op == FARG)
1129 return true; 1130 return true;
1130 1131
1131 if (!ln->tn_lvalue) { 1132 if (!ln->tn_lvalue) {
1132 if (ln->tn_op == CVT && ln->tn_cast && 1133 if (ln->tn_op == CVT && ln->tn_cast &&
1133 ln->tn_left->tn_op == LOAD) { 1134 ln->tn_left->tn_op == LOAD) {
1134 /* a cast does not yield an lvalue */ 1135 /* a cast does not yield an lvalue */
1135 error(163); 1136 error(163);
1136 } 1137 }
1137 /* %soperand of '%s' must be lvalue */ 1138 /* %soperand of '%s' must be lvalue */
1138 error(114, "left ", op_name(op)); 1139 error(114, "left ", op_name(op));
1139 return false; 1140 return false;
1140 } else if (ltp->t_const || ((lt == STRUCT || lt == UNION) && 1141 } else if (ltp->t_const || ((lt == STRUCT || lt == UNION) &&
1141 has_constant_member(ltp))) { 1142 has_constant_member(ltp))) {
1142 if (!tflag) 1143 if (!tflag)
1143 /* %soperand of '%s' must be modifiable lvalue */ 1144 /* %soperand of '%s' must be modifiable lvalue */
1144 warning(115, "left ", op_name(op)); 1145 warning(115, "left ", op_name(op));
1145 } 1146 }
1146 return true; 1147 return true;
1147} 1148}
1148 1149
1149/* Check the types using the information from modtab[]. */ 1150/* Check the types using the information from modtab[]. */
1150static bool 1151static bool
1151typeok_scalar(op_t op, const mod_t *mp, 1152typeok_scalar(op_t op, const mod_t *mp,
1152 const type_t *ltp, tspec_t lt, 1153 const type_t *ltp, tspec_t lt,
1153 const type_t *rtp, tspec_t rt) 1154 const type_t *rtp, tspec_t rt)
1154{ 1155{
1155 if (mp->m_takes_bool && lt == BOOL && rt == BOOL) 1156 if (mp->m_takes_bool && lt == BOOL && rt == BOOL)
1156 return true; 1157 return true;
1157 if (mp->m_requires_integer) { 1158 if (mp->m_requires_integer) {
1158 if (!is_integer(lt) || (mp->m_binary && !is_integer(rt))) { 1159 if (!is_integer(lt) || (mp->m_binary && !is_integer(rt))) {
1159 warn_incompatible_types(op, ltp, lt, rtp, rt); 1160 warn_incompatible_types(op, ltp, lt, rtp, rt);
1160 return false; 1161 return false;
1161 } 1162 }
1162 } else if (mp->m_requires_integer_or_complex) { 1163 } else if (mp->m_requires_integer_or_complex) {
1163 if ((!is_integer(lt) && !is_complex(lt)) || 1164 if ((!is_integer(lt) && !is_complex(lt)) ||
1164 (mp->m_binary && (!is_integer(rt) && !is_complex(rt)))) { 1165 (mp->m_binary && (!is_integer(rt) && !is_complex(rt)))) {
1165 warn_incompatible_types(op, ltp, lt, rtp, rt); 1166 warn_incompatible_types(op, ltp, lt, rtp, rt);
1166 return false; 1167 return false;
1167 } 1168 }
1168 } else if (mp->m_requires_scalar) { 1169 } else if (mp->m_requires_scalar) {
1169 if (!is_scalar(lt) || (mp->m_binary && !is_scalar(rt))) { 1170 if (!is_scalar(lt) || (mp->m_binary && !is_scalar(rt))) {
1170 warn_incompatible_types(op, ltp, lt, rtp, rt); 1171 warn_incompatible_types(op, ltp, lt, rtp, rt);
1171 return false; 1172 return false;
1172 } 1173 }
1173 } else if (mp->m_requires_arith) { 1174 } else if (mp->m_requires_arith) {
1174 if (!is_arithmetic(lt) || 1175 if (!is_arithmetic(lt) ||
1175 (mp->m_binary && !is_arithmetic(rt))) { 1176 (mp->m_binary && !is_arithmetic(rt))) {
1176 warn_incompatible_types(op, ltp, lt, rtp, rt); 1177 warn_incompatible_types(op, ltp, lt, rtp, rt);
1177 return false; 1178 return false;
1178 } 1179 }
1179 } 1180 }
1180 return true; 1181 return true;
1181} 1182}
1182 1183
1183/* 1184/*
1184 * Check the types for specific operators and type combinations. 1185 * Check the types for specific operators and type combinations.
1185 * 1186 *
1186 * At this point, the operands already conform to the type requirements of 1187 * At this point, the operands already conform to the type requirements of
1187 * the operator, such as being integer, floating or scalar. 1188 * the operator, such as being integer, floating or scalar.
1188 */ 1189 */
1189static bool 1190static bool
1190typeok_op(op_t op, const mod_t *mp, int arg, 1191typeok_op(op_t op, const mod_t *mp, int arg,
1191 const tnode_t *ln, const type_t *ltp, tspec_t lt, 1192 const tnode_t *ln, const type_t *ltp, tspec_t lt,
1192 const tnode_t *rn, const type_t *rtp, tspec_t rt) 1193 const tnode_t *rn, const type_t *rtp, tspec_t rt)
1193{ 1194{
1194 switch (op) { 1195 switch (op) {
1195 case ARROW: 1196 case ARROW:
1196 return typeok_arrow(lt); 1197 return typeok_arrow(lt);
1197 case POINT: 1198 case POINT:
1198 return typeok_point(ln, ltp, lt); 1199 return typeok_point(ln, ltp, lt);
1199 case INCBEF: 1200 case INCBEF:
1200 case DECBEF: 1201 case DECBEF:
1201 case INCAFT: 1202 case INCAFT:
1202 case DECAFT: 1203 case DECAFT:
1203 return typeok_incdec(op, ln, ltp); 1204 return typeok_incdec(op, ln, ltp);
1204 case INDIR: 1205 case INDIR:
1205 return typeok_indir(lt); 1206 return typeok_indir(lt);
1206 case ADDR: 1207 case ADDR:
1207 return typeok_address(mp, ln, ltp, lt); 1208 return typeok_address(mp, ln, ltp, lt);
1208 case PLUS: 1209 case PLUS:
1209 return typeok_plus(op, ltp, lt, rtp, rt); 1210 return typeok_plus(op, ltp, lt, rtp, rt);
1210 case MINUS: 1211 case MINUS:
1211 return typeok_minus(op, ltp, lt, rtp, rt); 1212 return typeok_minus(op, ltp, lt, rtp, rt);
1212 case SHL: 1213 case SHL:
1213 typeok_shl(mp, lt, rt); 1214 typeok_shl(mp, lt, rt);
1214 goto shift; 1215 goto shift;
1215 case SHR: 1216 case SHR:
1216 typeok_shr(mp, ln, lt, rn, rt); 1217 typeok_shr(mp, ln, lt, rn, rt);
1217 shift: 1218 shift:
1218 typeok_shift(lt, rn, rt); 1219 typeok_shift(lt, rn, rt);
1219 break; 1220 break;
1220 case LT: 1221 case LT:
1221 case LE: 1222 case LE:
1222 case GT: 1223 case GT:
1223 case GE: 1224 case GE:
1224 compare: 1225 compare:
1225 return typeok_compare(op, ln, ltp, lt, rn, rtp, rt); 1226 return typeok_compare(op, ln, ltp, lt, rn, rtp, rt);
1226 case EQ: 1227 case EQ:
1227 case NE: 1228 case NE:
1228 if (is_typeok_eq(ln, lt, rn, rt)) 1229 if (is_typeok_eq(ln, lt, rn, rt))
1229 break; 1230 break;
1230 goto compare; 1231 goto compare;
1231 case QUEST: 1232 case QUEST:
1232 return typeok_quest(lt, rn); 1233 return typeok_quest(lt, rn);
1233 case COLON: 1234 case COLON:
1234 return typeok_colon(mp, ln, ltp, lt, rn, rtp, rt); 1235 return typeok_colon(mp, ln, ltp, lt, rn, rtp, rt);
1235 case ASSIGN: 1236 case ASSIGN:
1236 case INIT: 1237 case INIT:
1237 case FARG: 1238 case FARG:
1238 case RETURN: 1239 case RETURN:
1239 if (!check_assign_types_compatible(op, arg, ln, rn)) 1240 if (!check_assign_types_compatible(op, arg, ln, rn))
1240 return false; 1241 return false;
1241 goto assign; 1242 goto assign;
1242 case MULASS: 1243 case MULASS:
1243 case DIVASS: 1244 case DIVASS:
1244 case MODASS: 1245 case MODASS:
1245 goto assign; 1246 goto assign;
1246 case ADDASS: 1247 case ADDASS:
1247 case SUBASS: 1248 case SUBASS:
1248 if ((lt == PTR && !is_integer(rt)) || rt == PTR) { 1249 if ((lt == PTR && !is_integer(rt)) || rt == PTR) {
1249 warn_incompatible_types(op, ltp, lt, rtp, rt); 1250 warn_incompatible_types(op, ltp, lt, rtp, rt);
1250 return false; 1251 return false;
1251 } 1252 }
1252 goto assign; 1253 goto assign;
1253 case SHLASS: 1254 case SHLASS:
1254 goto assign; 1255 goto assign;
1255 case SHRASS: 1256 case SHRASS:
1256 if (pflag && !is_uinteger(lt) && !(tflag && is_uinteger(rt))) { 1257 if (pflag && !is_uinteger(lt) && !(tflag && is_uinteger(rt))) {
1257 /* bitwise '%s' on signed value possibly nonportable */ 1258 /* bitwise '%s' on signed value possibly nonportable */
1258 warning(117, mp->m_name); 1259 warning(117, mp->m_name);
1259 } 1260 }
1260 goto assign; 1261 goto assign;
1261 case ANDASS: 1262 case ANDASS:
1262 case XORASS: 1263 case XORASS:
1263 case ORASS: 1264 case ORASS:
1264 assign: 1265 assign:
1265 return typeok_assign(op, ln, ltp, lt); 1266 return typeok_assign(op, ln, ltp, lt);
1266 case COMMA: 1267 case COMMA:
1267 if (!modtab[ln->tn_op].m_has_side_effect) 1268 if (!modtab[ln->tn_op].m_has_side_effect)
1268 check_null_effect(ln); 1269 check_null_effect(ln);
1269 break; 1270 break;
1270 default: 1271 default:
1271 break; 1272 break;
1272 } 1273 }
1273 return true; 1274 return true;
1274} 1275}
1275 1276
1276static void 1277static void
1277typeok_enum(op_t op, const mod_t *mp, int arg, 1278typeok_enum(op_t op, const mod_t *mp, int arg,
1278 const tnode_t *ln, const type_t *ltp, 1279 const tnode_t *ln, const type_t *ltp,
1279 const tnode_t *rn, const type_t *rtp) 1280 const tnode_t *rn, const type_t *rtp)
1280{ 1281{
1281 if (mp->m_bad_on_enum && 1282 if (mp->m_bad_on_enum &&
1282 (ltp->t_is_enum || (mp->m_binary && rtp->t_is_enum))) { 1283 (ltp->t_is_enum || (mp->m_binary && rtp->t_is_enum))) {
1283 check_bad_enum_operation(op, ln, rn); 1284 check_bad_enum_operation(op, ln, rn);
1284 } else if (mp->m_valid_on_enum && 1285 } else if (mp->m_valid_on_enum &&
1285 (ltp->t_is_enum && rtp != NULL && rtp->t_is_enum)) { 1286 (ltp->t_is_enum && rtp != NULL && rtp->t_is_enum)) {
1286 check_enum_type_mismatch(op, arg, ln, rn); 1287 check_enum_type_mismatch(op, arg, ln, rn);
1287 } else if (mp->m_valid_on_enum && 1288 } else if (mp->m_valid_on_enum &&
1288 (ltp->t_is_enum || (rtp != NULL && rtp->t_is_enum))) { 1289 (ltp->t_is_enum || (rtp != NULL && rtp->t_is_enum))) {
1289 check_enum_int_mismatch(op, arg, ln, rn); 1290 check_enum_int_mismatch(op, arg, ln, rn);
1290 } 1291 }
1291} 1292}
1292 1293
1293/* Perform most type checks. Return whether the types are ok. */ 1294/* Perform most type checks. Return whether the types are ok. */
1294bool 1295bool
1295typeok(op_t op, int arg, const tnode_t *ln, const tnode_t *rn) 1296typeok(op_t op, int arg, const tnode_t *ln, const tnode_t *rn)
1296{ 1297{
1297 const mod_t *mp; 1298 const mod_t *mp;
1298 tspec_t lt, rt; 1299 tspec_t lt, rt;
1299 type_t *ltp, *rtp; 1300 type_t *ltp, *rtp;
1300 1301
1301 mp = &modtab[op]; 1302 mp = &modtab[op];
1302 1303
1303 lint_assert((ltp = ln->tn_type) != NULL); 1304 lint_assert((ltp = ln->tn_type) != NULL);
1304 lt = ltp->t_tspec; 1305 lt = ltp->t_tspec;
1305 1306
1306 if (mp->m_binary) { 1307 if (mp->m_binary) {
1307 lint_assert((rtp = rn->tn_type) != NULL); 1308 lint_assert((rtp = rn->tn_type) != NULL);
1308 rt = rtp->t_tspec; 1309 rt = rtp->t_tspec;
1309 } else { 1310 } else {
1310 rtp = NULL; 1311 rtp = NULL;
1311 rt = NOTSPEC; 1312 rt = NOTSPEC;
1312 } 1313 }
1313 1314
1314 if (Tflag && !typeok_scalar_strict_bool(op, mp, arg, ln, rn)) 1315 if (Tflag && !typeok_scalar_strict_bool(op, mp, arg, ln, rn))
1315 return false; 1316 return false;
1316 if (!typeok_scalar(op, mp, ltp, lt, rtp, rt)) 1317 if (!typeok_scalar(op, mp, ltp, lt, rtp, rt))
1317 return false; 1318 return false;
1318 1319
1319 if (!typeok_op(op, mp, arg, ln, ltp, lt, rn, rtp, rt)) 1320 if (!typeok_op(op, mp, arg, ln, ltp, lt, rn, rtp, rt))
1320 return false; 1321 return false;
1321 1322
1322 typeok_enum(op, mp, arg, ln, ltp, rn, rtp); 1323 typeok_enum(op, mp, arg, ln, ltp, rn, rtp);
1323 return true; 1324 return true;
1324} 1325}
1325 1326
1326static void 1327static void
1327check_pointer_comparison(op_t op, const tnode_t *ln, const tnode_t *rn) 1328check_pointer_comparison(op_t op, const tnode_t *ln, const tnode_t *rn)
1328{ 1329{
1329 type_t *ltp, *rtp; 1330 type_t *ltp, *rtp;
1330 tspec_t lst, rst; 1331 tspec_t lst, rst;
1331 const char *lsts, *rsts; 1332 const char *lsts, *rsts;
1332 1333
1333 lst = (ltp = ln->tn_type)->t_subt->t_tspec; 1334 lst = (ltp = ln->tn_type)->t_subt->t_tspec;
1334 rst = (rtp = rn->tn_type)->t_subt->t_tspec; 1335 rst = (rtp = rn->tn_type)->t_subt->t_tspec;
1335 1336
1336 if (lst == VOID || rst == VOID) { 1337 if (lst == VOID || rst == VOID) {
1337 if (sflag && (lst == FUNC || rst == FUNC)) { 1338 if (sflag && (lst == FUNC || rst == FUNC)) {
1338 /* (void *)0 already handled in typeok() */ 1339 /* (void *)0 already handled in typeok() */
1339 *(lst == FUNC ? &lsts : &rsts) = "function pointer"; 1340 *(lst == FUNC ? &lsts : &rsts) = "function pointer";
1340 *(lst == VOID ? &lsts : &rsts) = "'void *'"; 1341 *(lst == VOID ? &lsts : &rsts) = "'void *'";
1341 /* ANSI C forbids comparison of %s with %s */ 1342 /* ANSI C forbids comparison of %s with %s */
1342 warning(274, lsts, rsts); 1343 warning(274, lsts, rsts);
1343 } 1344 }
1344 return; 1345 return;
1345 } 1346 }
1346 1347
1347 if (!eqtype(ltp->t_subt, rtp->t_subt, true, false, NULL)) { 1348 if (!eqtype(ltp->t_subt, rtp->t_subt, true, false, NULL)) {
1348 warn_incompatible_pointers(&modtab[op], ltp, rtp); 1349 warn_incompatible_pointers(&modtab[op], ltp, rtp);
1349 return; 1350 return;
1350 } 1351 }
1351 1352
1352 if (lst == FUNC && rst == FUNC) { 1353 if (lst == FUNC && rst == FUNC) {
1353 if (sflag && op != EQ && op != NE) 1354 if (sflag && op != EQ && op != NE)
1354 /* ANSI C forbids ordered comparisons of ... */ 1355 /* ANSI C forbids ordered comparisons of ... */
1355 warning(125); 1356 warning(125);
1356 } 1357 }
1357} 1358}
1358 1359
1359static bool 1360static bool
1360is_direct_function_call(const tnode_t *tn, const char **out_name) 1361is_direct_function_call(const tnode_t *tn, const char **out_name)
1361{ 1362{
1362 1363
1363 if (!(tn->tn_op == CALL && 1364 if (!(tn->tn_op == CALL &&
1364 tn->tn_left->tn_op == ADDR && 1365 tn->tn_left->tn_op == ADDR &&
1365 tn->tn_left->tn_left->tn_op == NAME)) 1366 tn->tn_left->tn_left->tn_op == NAME))
1366 return false; 1367 return false;
1367 1368
1368 *out_name = tn->tn_left->tn_left->tn_sym->s_name; 1369 *out_name = tn->tn_left->tn_left->tn_sym->s_name;
1369 return true; 1370 return true;
1370} 1371}
1371 1372
1372static bool 1373static bool
1373is_unconst_function(const char *name) 1374is_unconst_function(const char *name)
1374{ 1375{
1375 1376
1376 return strcmp(name, "memchr") == 0 || 1377 return strcmp(name, "memchr") == 0 ||
1377 strcmp(name, "strchr") == 0 || 1378 strcmp(name, "strchr") == 0 ||
1378 strcmp(name, "strpbrk") == 0 || 1379 strcmp(name, "strpbrk") == 0 ||
1379 strcmp(name, "strrchr") == 0 || 1380 strcmp(name, "strrchr") == 0 ||
1380 strcmp(name, "strstr") == 0; 1381 strcmp(name, "strstr") == 0;
1381} 1382}
1382 1383
1383static bool 1384static bool
1384is_const_char_pointer(const tnode_t *tn) 1385is_const_char_pointer(const tnode_t *tn)
1385{ 1386{
1386 const type_t *tp; 1387 const type_t *tp;
1387 1388
1388 /* 1389 /*
1389 * For traditional reasons, C99 6.4.5p5 defines that string literals 1390 * For traditional reasons, C99 6.4.5p5 defines that string literals
1390 * have type 'char[]'. They are often implicitly converted to 1391 * have type 'char[]'. They are often implicitly converted to
1391 * 'char *', for example when they are passed as function arguments. 1392 * 'char *', for example when they are passed as function arguments.
1392 * 1393 *
1393 * C99 6.4.5p6 further defines that modifying a string that is 1394 * C99 6.4.5p6 further defines that modifying a string that is
1394 * constructed from a string literal invokes undefined behavior. 1395 * constructed from a string literal invokes undefined behavior.
1395 * 1396 *
1396 * Out of these reasons, string literals are treated as 'effectively 1397 * Out of these reasons, string literals are treated as 'effectively
1397 * const' here. 1398 * const' here.
1398 */ 1399 */
1399 if (tn->tn_op == CVT && 1400 if (tn->tn_op == CVT &&
1400 tn->tn_left->tn_op == ADDR && 1401 tn->tn_left->tn_op == ADDR &&
1401 tn->tn_left->tn_left->tn_op == STRING) 1402 tn->tn_left->tn_left->tn_op == STRING)
1402 return true; 1403 return true;