Sat Jul 29 07:03:19 2023 UTC ()
lint: remove forward declarations for functions

No functional change.


(rillig)
diff -r1.363 -r1.364 src/usr.bin/xlint/lint1/decl.c

cvs diff -r1.363 -r1.364 src/usr.bin/xlint/lint1/decl.c (expand / switch to unified diff)

--- src/usr.bin/xlint/lint1/decl.c 2023/07/28 21:50:03 1.363
+++ src/usr.bin/xlint/lint1/decl.c 2023/07/29 07:03:19 1.364
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: decl.c,v 1.363 2023/07/28 21:50:03 rillig Exp $ */ 1/* $NetBSD: decl.c,v 1.364 2023/07/29 07:03:19 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
@@ -28,69 +28,51 @@ @@ -28,69 +28,51 @@
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) 40#if defined(__RCSID)
41__RCSID("$NetBSD: decl.c,v 1.363 2023/07/28 21:50:03 rillig Exp $"); 41__RCSID("$NetBSD: decl.c,v 1.364 2023/07/29 07:03:19 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[NTSPEC]; 54static type_t typetab[NTSPEC];
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 * Points to the innermost element of a stack that contains information about 60 * Points to the innermost element of a stack that contains information about
61 * nested declarations, such as struct declarations, function prototypes, 61 * nested declarations, such as struct declarations, function prototypes,
62 * local variables. 62 * local variables.
63 */ 63 */
64decl_level *dcs; 64decl_level *dcs;
65 65
66static type_t *typedef_error(type_t *, tspec_t); 
67static void set_first_typedef(type_t *, sym_t *); 
68static void dcs_align(unsigned int, unsigned int); 
69static sym_t *new_tag(sym_t *, scl_t, bool, bool); 
70static bool prototypes_compatible(const type_t *, const type_t *, bool *); 
71static bool matches_no_arg_function(const type_t *, bool *); 
72static bool check_old_style_definition(sym_t *, sym_t *); 
73static bool check_prototype_declaration(sym_t *, sym_t *); 
74static void check_prototype_parameters(sym_t *); 
75static void old_style_function(sym_t *, sym_t *); 
76static void declare_external_in_block(sym_t *); 
77static bool check_init(sym_t *); 
78static void check_argument_usage(bool, sym_t *); 
79static void check_variable_usage(bool, sym_t *); 
80static void check_label_usage(sym_t *); 
81static void check_tag_usage(sym_t *); 
82static void check_global_variable(const sym_t *); 
83static void check_global_variable_size(const sym_t *); 
84 66
85/* 67/*
86 * initializes all global vars used in declarations 68 * initializes all global vars used in declarations
87 */ 69 */
88void 70void
89initdecl(void) 71initdecl(void)
90{ 72{
91 73
92 /* declaration stack */ 74 /* declaration stack */
93 dcs = xcalloc(1, sizeof(*dcs)); 75 dcs = xcalloc(1, sizeof(*dcs));
94 dcs->d_kind = DLK_EXTERN; 76 dcs->d_kind = DLK_EXTERN;
95 dcs->d_last_dlsym = &dcs->d_first_dlsym; 77 dcs->d_last_dlsym = &dcs->d_first_dlsym;
96 78
@@ -223,26 +205,104 @@ dcs_add_storage_class(scl_t sc) @@ -223,26 +205,104 @@ dcs_add_storage_class(scl_t sc)
223 205
224 if (dcs->d_scl == NOSCL) 206 if (dcs->d_scl == NOSCL)
225 dcs->d_scl = sc; 207 dcs->d_scl = sc;
226 else if ((dcs->d_scl == EXTERN && sc == THREAD_LOCAL) 208 else if ((dcs->d_scl == EXTERN && sc == THREAD_LOCAL)
227 || (dcs->d_scl == THREAD_LOCAL && sc == EXTERN)) 209 || (dcs->d_scl == THREAD_LOCAL && sc == EXTERN))
228 dcs->d_scl = EXTERN; /* ignore thread_local */ 210 dcs->d_scl = EXTERN; /* ignore thread_local */
229 else if ((dcs->d_scl == STATIC && sc == THREAD_LOCAL) 211 else if ((dcs->d_scl == STATIC && sc == THREAD_LOCAL)
230 || (dcs->d_scl == THREAD_LOCAL && sc == STATIC)) 212 || (dcs->d_scl == THREAD_LOCAL && sc == STATIC))
231 dcs->d_scl = STATIC; /* ignore thread_local */ 213 dcs->d_scl = STATIC; /* ignore thread_local */
232 else 214 else
233 dcs->d_multiple_storage_classes = true; 215 dcs->d_multiple_storage_classes = true;
234} 216}
235 217
 218/* Merge the signedness into the abstract type. */
 219static tspec_t
 220merge_signedness(tspec_t t, tspec_t s)
 221{
 222
 223 if (s == SIGNED)
 224 return t == CHAR ? SCHAR : t;
 225 if (s != UNSIGN)
 226 return t;
 227 return t == CHAR ? UCHAR
 228 : t == SHORT ? USHORT
 229 : t == INT ? UINT
 230 : t == LONG ? ULONG
 231 : t == LLONG ? ULLONG
 232 : t;
 233}
 234
 235/*
 236 * Called if a list of declaration specifiers contains a typedef name
 237 * and other specifiers (except struct, union, enum, typedef name).
 238 */
 239static type_t *
 240typedef_error(type_t *td, tspec_t t)
 241{
 242
 243 tspec_t t2 = td->t_tspec;
 244
 245 if ((t == SIGNED || t == UNSIGN) &&
 246 (t2 == CHAR || t2 == SHORT || t2 == INT ||
 247 t2 == LONG || t2 == LLONG)) {
 248 if (allow_c90)
 249 /* modifying typedef with '%s'; only qualifiers... */
 250 warning(5, tspec_name(t));
 251 td = block_dup_type(gettyp(merge_signedness(t2, t)));
 252 td->t_typedef = true;
 253 return td;
 254 }
 255
 256 if (t == SHORT && (t2 == INT || t2 == UINT)) {
 257 /* modifying typedef with '%s'; only qualifiers allowed */
 258 warning(5, "short");
 259 td = block_dup_type(gettyp(t2 == INT ? SHORT : USHORT));
 260 td->t_typedef = true;
 261 return td;
 262 }
 263
 264 if (t != LONG)
 265 goto invalid;
 266
 267 if (t2 == INT)
 268 td = gettyp(LONG);
 269 else if (t2 == UINT)
 270 td = gettyp(ULONG);
 271 else if (t2 == LONG)
 272 td = gettyp(LLONG);
 273 else if (t2 == ULONG)
 274 td = gettyp(ULLONG);
 275 else if (t2 == FLOAT)
 276 td = gettyp(DOUBLE);
 277 else if (t2 == DOUBLE)
 278 td = gettyp(LDOUBLE);
 279 else if (t2 == DCOMPLEX)
 280 td = gettyp(LCOMPLEX);
 281 else
 282 goto invalid;
 283
 284 /* modifying typedef with '%s'; only qualifiers allowed */
 285 warning(5, "long");
 286 td = block_dup_type(td);
 287 td->t_typedef = true;
 288 return td;
 289
 290invalid:
 291 /* Anything else is not accepted. */
 292 dcs->d_invalid_type_combination = true;
 293 return td;
 294}
 295
236/* 296/*
237 * Remember the type, modifier or typedef name returned by the parser in the 297 * Remember the type, modifier or typedef name returned by the parser in the
238 * top element of the declaration stack. This information is used in 298 * top element of the declaration stack. This information is used in
239 * dcs_end_type to build the type used for all declarators in this declaration. 299 * dcs_end_type to build the type used for all declarators in this declaration.
240 * 300 *
241 * If tp->t_typedef is true, the type comes from a previously defined typename. 301 * If tp->t_typedef is true, the type comes from a previously defined typename.
242 * Otherwise, it comes from a type specifier (int, long, ...) or a 302 * Otherwise, it comes from a type specifier (int, long, ...) or a
243 * struct/union/enum tag. 303 * struct/union/enum tag.
244 */ 304 */
245void 305void
246dcs_add_type(type_t *tp) 306dcs_add_type(type_t *tp)
247{ 307{
248 308
@@ -334,104 +394,26 @@ dcs_add_type(type_t *tp) @@ -334,104 +394,26 @@ dcs_add_type(type_t *tp)
334 if (dcs->d_abstract_type != NO_TSPEC) 394 if (dcs->d_abstract_type != NO_TSPEC)
335 dcs->d_invalid_type_combination = true; 395 dcs->d_invalid_type_combination = true;
336 dcs->d_abstract_type = t; 396 dcs->d_abstract_type = t;
337 } 397 }
338 } else if (t == PTR) { 398 } else if (t == PTR) {
339 dcs->d_type = tp; 399 dcs->d_type = tp;
340 } else { 400 } else {
341 if (dcs->d_abstract_type != NO_TSPEC) 401 if (dcs->d_abstract_type != NO_TSPEC)
342 dcs->d_invalid_type_combination = true; 402 dcs->d_invalid_type_combination = true;
343 dcs->d_abstract_type = t; 403 dcs->d_abstract_type = t;
344 } 404 }
345} 405}
346 406
347/* Merge the signedness into the abstract type. */ 
348static tspec_t 
349merge_signedness(tspec_t t, tspec_t s) 
350{ 
351 
352 if (s == SIGNED) 
353 return t == CHAR ? SCHAR : t; 
354 if (s != UNSIGN) 
355 return t; 
356 return t == CHAR ? UCHAR 
357 : t == SHORT ? USHORT 
358 : t == INT ? UINT 
359 : t == LONG ? ULONG 
360 : t == LLONG ? ULLONG 
361 : t; 
362} 
363 
364/* 
365 * Called if a list of declaration specifiers contains a typedef name 
366 * and other specifiers (except struct, union, enum, typedef name). 
367 */ 
368static type_t * 
369typedef_error(type_t *td, tspec_t t) 
370{ 
371 
372 tspec_t t2 = td->t_tspec; 
373 
374 if ((t == SIGNED || t == UNSIGN) && 
375 (t2 == CHAR || t2 == SHORT || t2 == INT || 
376 t2 == LONG || t2 == LLONG)) { 
377 if (allow_c90) 
378 /* modifying typedef with '%s'; only qualifiers... */ 
379 warning(5, tspec_name(t)); 
380 td = block_dup_type(gettyp(merge_signedness(t2, t))); 
381 td->t_typedef = true; 
382 return td; 
383 } 
384 
385 if (t == SHORT && (t2 == INT || t2 == UINT)) { 
386 /* modifying typedef with '%s'; only qualifiers allowed */ 
387 warning(5, "short"); 
388 td = block_dup_type(gettyp(t2 == INT ? SHORT : USHORT)); 
389 td->t_typedef = true; 
390 return td; 
391 } 
392 
393 if (t != LONG) 
394 goto invalid; 
395 
396 if (t2 == INT) 
397 td = gettyp(LONG); 
398 else if (t2 == UINT) 
399 td = gettyp(ULONG); 
400 else if (t2 == LONG) 
401 td = gettyp(LLONG); 
402 else if (t2 == ULONG) 
403 td = gettyp(ULLONG); 
404 else if (t2 == FLOAT) 
405 td = gettyp(DOUBLE); 
406 else if (t2 == DOUBLE) 
407 td = gettyp(LDOUBLE); 
408 else if (t2 == DCOMPLEX) 
409 td = gettyp(LCOMPLEX); 
410 else 
411 goto invalid; 
412 
413 /* modifying typedef with '%s'; only qualifiers allowed */ 
414 warning(5, "long"); 
415 td = block_dup_type(td); 
416 td->t_typedef = true; 
417 return td; 
418 
419invalid: 
420 /* Anything else is not accepted. */ 
421 dcs->d_invalid_type_combination = true; 
422 return td; 
423} 
424 
425static void 407static void
426set_first_typedef(type_t *tp, sym_t *sym) 408set_first_typedef(type_t *tp, sym_t *sym)
427{ 409{
428 410
429 tspec_t t = tp->t_tspec; 411 tspec_t t = tp->t_tspec;
430 if (is_struct_or_union(t) && tp->t_sou->sou_first_typedef == NULL) 412 if (is_struct_or_union(t) && tp->t_sou->sou_first_typedef == NULL)
431 tp->t_sou->sou_first_typedef = sym; 413 tp->t_sou->sou_first_typedef = sym;
432 if (t == ENUM && tp->t_enum->en_first_typedef == NULL) 414 if (t == ENUM && tp->t_enum->en_first_typedef == NULL)
433 tp->t_enum->en_first_typedef = sym; 415 tp->t_enum->en_first_typedef = sym;
434} 416}
435 417
436static unsigned int 418static unsigned int
437bit_fields_width(const sym_t **mem, bool *named) 419bit_fields_width(const sym_t **mem, bool *named)
@@ -1000,26 +982,41 @@ check_bit_field(sym_t *dsym, tspec_t *in @@ -1000,26 +982,41 @@ check_bit_field(sym_t *dsym, tspec_t *in
1000 } else if (tp->t_bit_field_width == 0 && dsym->s_name != unnamed) { 982 } else if (tp->t_bit_field_width == 0 && dsym->s_name != unnamed) {
1001 /* zero size bit-field */ 983 /* zero size bit-field */
1002 error(37); 984 error(37);
1003 tp->t_bit_field_width = t_width; 985 tp->t_bit_field_width = t_width;
1004 } 986 }
1005 if (dsym->s_scl == UNION_MEMBER) { 987 if (dsym->s_scl == UNION_MEMBER) {
1006 /* bit-field in union is very unusual */ 988 /* bit-field in union is very unusual */
1007 warning(41); 989 warning(41);
1008 dsym->s_type->t_bitfield = false; 990 dsym->s_type->t_bitfield = false;
1009 dsym->s_bitfield = false; 991 dsym->s_bitfield = false;
1010 } 992 }
1011} 993}
1012 994
 995/* Aligns the next structure element as required. */
 996static void
 997dcs_align(unsigned int member_alignment, unsigned int bit_field_width)
 998{
 999
 1000 if (member_alignment > dcs->d_sou_align_in_bits)
 1001 dcs->d_sou_align_in_bits = member_alignment;
 1002
 1003 unsigned int offset = (dcs->d_sou_size_in_bits + member_alignment - 1)
 1004 & ~(member_alignment - 1);
 1005 if (bit_field_width == 0
 1006 || dcs->d_sou_size_in_bits + bit_field_width > offset)
 1007 dcs->d_sou_size_in_bits = offset;
 1008}
 1009
1013/* Add a member to the struct or union type that is being built in 'dcs'. */ 1010/* Add a member to the struct or union type that is being built in 'dcs'. */
1014static void 1011static void
1015dcs_add_member(sym_t *mem) 1012dcs_add_member(sym_t *mem)
1016{ 1013{
1017 type_t *tp = mem->s_type; 1014 type_t *tp = mem->s_type;
1018 1015
1019 unsigned int union_size = 0; 1016 unsigned int union_size = 0;
1020 if (dcs->d_kind == DLK_UNION) { 1017 if (dcs->d_kind == DLK_UNION) {
1021 union_size = dcs->d_sou_size_in_bits; 1018 union_size = dcs->d_sou_size_in_bits;
1022 dcs->d_sou_size_in_bits = 0; 1019 dcs->d_sou_size_in_bits = 0;
1023 } 1020 }
1024 1021
1025 if (mem->s_bitfield) { 1022 if (mem->s_bitfield) {
@@ -1096,41 +1093,26 @@ declare_member(sym_t *dsym) @@ -1096,41 +1093,26 @@ declare_member(sym_t *dsym)
1096 /* zero-sized array '%s' in struct is a C99 extension */ 1093 /* zero-sized array '%s' in struct is a C99 extension */
1097 c99ism(39, dsym->s_name); 1094 c99ism(39, dsym->s_name);
1098 } 1095 }
1099 1096
1100 dcs_add_member(dsym); 1097 dcs_add_member(dsym);
1101 1098
1102 check_function_definition(dsym, false); 1099 check_function_definition(dsym, false);
1103 1100
1104 suppress_bitfieldtype = false; 1101 suppress_bitfieldtype = false;
1105 1102
1106 return dsym; 1103 return dsym;
1107} 1104}
1108 1105
1109/* Aligns the next structure element as required. */ 
1110static void 
1111dcs_align(unsigned int member_alignment, unsigned int bit_field_width) 
1112{ 
1113 
1114 if (member_alignment > dcs->d_sou_align_in_bits) 
1115 dcs->d_sou_align_in_bits = member_alignment; 
1116 
1117 unsigned int offset = (dcs->d_sou_size_in_bits + member_alignment - 1) 
1118 & ~(member_alignment - 1); 
1119 if (bit_field_width == 0 
1120 || dcs->d_sou_size_in_bits + bit_field_width > offset) 
1121 dcs->d_sou_size_in_bits = offset; 
1122} 
1123 
1124sym_t * 1106sym_t *
1125set_bit_field_width(sym_t *dsym, int bit_field_width) 1107set_bit_field_width(sym_t *dsym, int bit_field_width)
1126{ 1108{
1127 1109
1128 if (dsym == NULL) { 1110 if (dsym == NULL) {
1129 dsym = block_zero_alloc(sizeof(*dsym), "sym"); 1111 dsym = block_zero_alloc(sizeof(*dsym), "sym");
1130 dsym->s_name = unnamed; 1112 dsym->s_name = unnamed;
1131 dsym->s_kind = FMEMBER; 1113 dsym->s_kind = FMEMBER;
1132 dsym->s_scl = STRUCT_MEMBER; 1114 dsym->s_scl = STRUCT_MEMBER;
1133 dsym->s_type = gettyp(UINT); 1115 dsym->s_type = gettyp(UINT);
1134 dsym->s_block_level = -1; 1116 dsym->s_block_level = -1;
1135 } 1117 }
1136 dsym->s_type = block_dup_type(dsym->s_type); 1118 dsym->s_type = block_dup_type(dsym->s_type);
@@ -1279,26 +1261,74 @@ add_array(sym_t *decl, bool dim, int n) @@ -1279,26 +1261,74 @@ add_array(sym_t *decl, bool dim, int n)
1279 1261
1280static type_t * 1262static type_t *
1281block_derive_function(type_t *ret, bool proto, sym_t *args, bool vararg) 1263block_derive_function(type_t *ret, bool proto, sym_t *args, bool vararg)
1282{ 1264{
1283 1265
1284 type_t *tp = block_derive_type(ret, FUNC); 1266 type_t *tp = block_derive_type(ret, FUNC);
1285 tp->t_proto = proto; 1267 tp->t_proto = proto;
1286 if (proto) 1268 if (proto)
1287 tp->t_args = args; 1269 tp->t_args = args;
1288 tp->t_vararg = vararg; 1270 tp->t_vararg = vararg;
1289 return tp; 1271 return tp;
1290} 1272}
1291 1273
 1274static void
 1275check_prototype_parameters(sym_t *args)
 1276{
 1277
 1278 for (sym_t *sym = dcs->d_first_dlsym;
 1279 sym != NULL; sym = sym->s_level_next) {
 1280 scl_t sc = sym->s_scl;
 1281 if (sc == STRUCT_TAG || sc == UNION_TAG || sc == ENUM_TAG) {
 1282 /* dubious tag declaration '%s %s' */
 1283 warning(85, storage_class_name(sc), sym->s_name);
 1284 }
 1285 }
 1286
 1287 for (sym_t *arg = args; arg != NULL; arg = arg->s_next) {
 1288 if (arg->s_type->t_tspec == VOID &&
 1289 !(arg == args && arg->s_next == NULL)) {
 1290 /* void must be sole parameter */
 1291 error(60);
 1292 arg->s_type = gettyp(INT);
 1293 }
 1294 }
 1295}
 1296
 1297static void
 1298old_style_function(sym_t *decl, sym_t *args)
 1299{
 1300
 1301 /*
 1302 * Remember the list of parameters only if this really seems to be a
 1303 * function definition.
 1304 */
 1305 if (dcs->d_enclosing->d_kind == DLK_EXTERN &&
 1306 decl->s_type == dcs->d_enclosing->d_type) {
 1307 /*
 1308 * Assume that this becomes a function definition. If not, it
 1309 * will be corrected in check_function_definition.
 1310 */
 1311 if (args != NULL) {
 1312 decl->s_osdef = true;
 1313 decl->u.s_old_style_args = args;
 1314 }
 1315 } else {
 1316 if (args != NULL)
 1317 /* function prototype parameters must have types */
 1318 warning(62);
 1319 }
 1320}
 1321
1292sym_t * 1322sym_t *
1293add_function(sym_t *decl, struct parameter_list params) 1323add_function(sym_t *decl, struct parameter_list params)
1294{ 1324{
1295 1325
1296 debug_enter(); 1326 debug_enter();
1297 debug_dcs(true); 1327 debug_dcs(true);
1298 debug_sym("decl: ", decl, "\n"); 1328 debug_sym("decl: ", decl, "\n");
1299#ifdef DEBUG 1329#ifdef DEBUG
1300 for (const sym_t *arg = params.first; arg != NULL; arg = arg->s_next) 1330 for (const sym_t *arg = params.first; arg != NULL; arg = arg->s_next)
1301 debug_sym("arg: ", arg, "\n"); 1331 debug_sym("arg: ", arg, "\n");
1302#endif 1332#endif
1303 1333
1304 if (params.prototype) { 1334 if (params.prototype) {
@@ -1347,91 +1377,43 @@ add_function(sym_t *decl, struct paramet @@ -1347,91 +1377,43 @@ add_function(sym_t *decl, struct paramet
1347 debug_leave(); 1377 debug_leave();
1348 return decl; /* see msg_347 */ 1378 return decl; /* see msg_347 */
1349 } 1379 }
1350 1380
1351 *tpp = block_derive_function(dcs->d_enclosing->d_type, 1381 *tpp = block_derive_function(dcs->d_enclosing->d_type,
1352 params.prototype, params.first, params.vararg); 1382 params.prototype, params.first, params.vararg);
1353 1383
1354 debug_step("add_function: '%s'", type_name(decl->s_type)); 1384 debug_step("add_function: '%s'", type_name(decl->s_type));
1355 debug_dcs(true); 1385 debug_dcs(true);
1356 debug_leave(); 1386 debug_leave();
1357 return decl; 1387 return decl;
1358} 1388}
1359 1389
1360static void 1390/*
1361check_prototype_parameters(sym_t *args) 1391 * In a function declaration, a list of identifiers (as opposed to a list of
 1392 * types) is allowed only if it's also a function definition.
 1393 */
 1394void
 1395check_function_definition(sym_t *sym, bool msg)
1362{ 1396{
1363 1397
1364 for (sym_t *sym = dcs->d_first_dlsym; 1398 if (sym->s_osdef) {
1365 sym != NULL; sym = sym->s_level_next) { 1399 if (msg) {
1366 scl_t sc = sym->s_scl; 1400 /* incomplete or misplaced function definition */
1367 if (sc == STRUCT_TAG || sc == UNION_TAG || sc == ENUM_TAG) { 1401 error(22);
1368 /* dubious tag declaration '%s %s' */ 
1369 warning(85, storage_class_name(sc), sym->s_name); 
1370 } 1402 }
 1403 sym->s_osdef = false;
 1404 sym->u.s_old_style_args = NULL;
1371 } 1405 }
1372 1406}
1373 for (sym_t *arg = args; arg != NULL; arg = arg->s_next) { 
1374 if (arg->s_type->t_tspec == VOID && 
1375 !(arg == args && arg->s_next == NULL)) { 
1376 /* void must be sole parameter */ 
1377 error(60); 
1378 arg->s_type = gettyp(INT); 
1379 } 
1380 } 
1381} 
1382 
1383static void 
1384old_style_function(sym_t *decl, sym_t *args) 
1385{ 
1386 
1387 /* 
1388 * Remember the list of parameters only if this really seems to be a 
1389 * function definition. 
1390 */ 
1391 if (dcs->d_enclosing->d_kind == DLK_EXTERN && 
1392 decl->s_type == dcs->d_enclosing->d_type) { 
1393 /* 
1394 * Assume that this becomes a function definition. If not, it 
1395 * will be corrected in check_function_definition. 
1396 */ 
1397 if (args != NULL) { 
1398 decl->s_osdef = true; 
1399 decl->u.s_old_style_args = args; 
1400 } 
1401 } else { 
1402 if (args != NULL) 
1403 /* function prototype parameters must have types */ 
1404 warning(62); 
1405 } 
1406} 
1407 
1408/* 
1409 * In a function declaration, a list of identifiers (as opposed to a list of 
1410 * types) is allowed only if it's also a function definition. 
1411 */ 
1412void 
1413check_function_definition(sym_t *sym, bool msg) 
1414{ 
1415 
1416 if (sym->s_osdef) { 
1417 if (msg) { 
1418 /* incomplete or misplaced function definition */ 
1419 error(22); 
1420 } 
1421 sym->s_osdef = false; 
1422 sym->u.s_old_style_args = NULL; 
1423 } 
1424} 
1425 1407
1426/* The symbol gets a storage class and a definedness. */ 1408/* The symbol gets a storage class and a definedness. */
1427sym_t * 1409sym_t *
1428declarator_name(sym_t *sym) 1410declarator_name(sym_t *sym)
1429{ 1411{
1430 scl_t sc = NOSCL; 1412 scl_t sc = NOSCL;
1431 1413
1432 if (sym->s_scl == NOSCL) 1414 if (sym->s_scl == NOSCL)
1433 dcs->d_redeclared_symbol = NULL; 1415 dcs->d_redeclared_symbol = NULL;
1434 else if (sym->s_defarg) { 1416 else if (sym->s_defarg) {
1435 sym->s_defarg = false; 1417 sym->s_defarg = false;
1436 dcs->d_redeclared_symbol = NULL; 1418 dcs->d_redeclared_symbol = NULL;
1437 } else { 1419 } else {
@@ -1525,26 +1507,87 @@ old_style_function_parameter_name(sym_t  @@ -1525,26 +1507,87 @@ old_style_function_parameter_name(sym_t
1525 error(21, sym->s_name); 1507 error(21, sym->s_name);
1526 lint_assert(sym->s_defarg); 1508 lint_assert(sym->s_defarg);
1527 } 1509 }
1528 sym = pushdown(sym); 1510 sym = pushdown(sym);
1529 } 1511 }
1530 sym->s_type = gettyp(INT); 1512 sym->s_type = gettyp(INT);
1531 sym->s_scl = AUTO; 1513 sym->s_scl = AUTO;
1532 sym->s_def = DEF; 1514 sym->s_def = DEF;
1533 sym->s_defarg = sym->s_arg = true; 1515 sym->s_defarg = sym->s_arg = true;
1534 return sym; 1516 return sym;
1535} 1517}
1536 1518
1537/*- 1519/*-
 1520 * Checks all possible cases of tag redeclarations.
 1521 *
 1522 * decl whether T_LBRACE follows
 1523 * semi whether T_SEMI follows
 1524 */
 1525static sym_t *
 1526new_tag(sym_t *tag, scl_t scl, bool decl, bool semi)
 1527{
 1528
 1529 if (tag->s_block_level < block_level) {
 1530 if (semi) {
 1531 /* "struct a;" */
 1532 if (allow_c90) {
 1533 /* XXX: Why is this warning suppressed in C90 mode? */
 1534 if (allow_trad || allow_c99)
 1535 /* declaration of '%s %s' intro... */
 1536 warning(44, storage_class_name(scl),
 1537 tag->s_name);
 1538 tag = pushdown(tag);
 1539 } else if (tag->s_scl != scl) {
 1540 /* base type is really '%s %s' */
 1541 warning(45, storage_class_name(tag->s_scl),
 1542 tag->s_name);
 1543 }
 1544 dcs->d_enclosing->d_nonempty_decl = true;
 1545 } else if (decl) {
 1546 /* "struct a { ... } " */
 1547 if (hflag)
 1548 /* redefinition of '%s' hides earlier one */
 1549 warning(43, tag->s_name);
 1550 tag = pushdown(tag);
 1551 dcs->d_enclosing->d_nonempty_decl = true;
 1552 } else if (tag->s_scl != scl) {
 1553 /* base type is really '%s %s' */
 1554 warning(45, storage_class_name(tag->s_scl),
 1555 tag->s_name);
 1556 /* XXX: Why is this warning suppressed in C90 mode? */
 1557 if (allow_trad || allow_c99) {
 1558 /* declaration of '%s %s' introduces ... */
 1559 warning(44, storage_class_name(scl),
 1560 tag->s_name);
 1561 }
 1562 tag = pushdown(tag);
 1563 dcs->d_enclosing->d_nonempty_decl = true;
 1564 }
 1565 } else {
 1566 if (tag->s_scl != scl ||
 1567 (decl && !is_incomplete(tag->s_type))) {
 1568 /* %s tag '%s' redeclared as %s */
 1569 error(46, storage_class_name(tag->s_scl),
 1570 tag->s_name, storage_class_name(scl));
 1571 print_previous_declaration(tag);
 1572 tag = pushdown(tag);
 1573 dcs->d_enclosing->d_nonempty_decl = true;
 1574 } else if (semi || decl)
 1575 dcs->d_enclosing->d_nonempty_decl = true;
 1576 }
 1577 return tag;
 1578}
 1579
 1580/*-
1538 * tag the symbol table entry of the tag 1581 * tag the symbol table entry of the tag
1539 * kind the kind of the tag (STRUCT/UNION/ENUM) 1582 * kind the kind of the tag (STRUCT/UNION/ENUM)
1540 * decl whether the tag type will be completed in this declaration 1583 * decl whether the tag type will be completed in this declaration
1541 * (when the following token is T_LBRACE) 1584 * (when the following token is T_LBRACE)
1542 * semi whether the following token is T_SEMI 1585 * semi whether the following token is T_SEMI
1543 */ 1586 */
1544type_t * 1587type_t *
1545make_tag_type(sym_t *tag, tspec_t kind, bool decl, bool semi) 1588make_tag_type(sym_t *tag, tspec_t kind, bool decl, bool semi)
1546{ 1589{
1547 scl_t scl; 1590 scl_t scl;
1548 type_t *tp; 1591 type_t *tp;
1549 1592
1550 if (kind == STRUCT) 1593 if (kind == STRUCT)
@@ -1599,87 +1642,26 @@ make_tag_type(sym_t *tag, tspec_t kind,  @@ -1599,87 +1642,26 @@ make_tag_type(sym_t *tag, tspec_t kind,
1599 tp->t_sou->sou_tag = tag; 1642 tp->t_sou->sou_tag = tag;
1600 tp->t_sou->sou_incomplete = true; 1643 tp->t_sou->sou_incomplete = true;
1601 } else { 1644 } else {
1602 tp->t_is_enum = true; 1645 tp->t_is_enum = true;
1603 tp->t_enum = block_zero_alloc(sizeof(*tp->t_enum), 1646 tp->t_enum = block_zero_alloc(sizeof(*tp->t_enum),
1604 "enumeration"); 1647 "enumeration");
1605 tp->t_enum->en_tag = tag; 1648 tp->t_enum->en_tag = tag;
1606 tp->t_enum->en_incomplete = true; 1649 tp->t_enum->en_incomplete = true;
1607 } 1650 }
1608 } 1651 }
1609 return tp; 1652 return tp;
1610} 1653}
1611 1654
1612/*- 
1613 * Checks all possible cases of tag redeclarations. 
1614 * 
1615 * decl whether T_LBRACE follows 
1616 * semi whether T_SEMI follows 
1617 */ 
1618static sym_t * 
1619new_tag(sym_t *tag, scl_t scl, bool decl, bool semi) 
1620{ 
1621 
1622 if (tag->s_block_level < block_level) { 
1623 if (semi) { 
1624 /* "struct a;" */ 
1625 if (allow_c90) { 
1626 /* XXX: Why is this warning suppressed in C90 mode? */ 
1627 if (allow_trad || allow_c99) 
1628 /* declaration of '%s %s' intro... */ 
1629 warning(44, storage_class_name(scl), 
1630 tag->s_name); 
1631 tag = pushdown(tag); 
1632 } else if (tag->s_scl != scl) { 
1633 /* base type is really '%s %s' */ 
1634 warning(45, storage_class_name(tag->s_scl), 
1635 tag->s_name); 
1636 } 
1637 dcs->d_enclosing->d_nonempty_decl = true; 
1638 } else if (decl) { 
1639 /* "struct a { ... } " */ 
1640 if (hflag) 
1641 /* redefinition of '%s' hides earlier one */ 
1642 warning(43, tag->s_name); 
1643 tag = pushdown(tag); 
1644 dcs->d_enclosing->d_nonempty_decl = true; 
1645 } else if (tag->s_scl != scl) { 
1646 /* base type is really '%s %s' */ 
1647 warning(45, storage_class_name(tag->s_scl), 
1648 tag->s_name); 
1649 /* XXX: Why is this warning suppressed in C90 mode? */ 
1650 if (allow_trad || allow_c99) { 
1651 /* declaration of '%s %s' introduces ... */ 
1652 warning(44, storage_class_name(scl), 
1653 tag->s_name); 
1654 } 
1655 tag = pushdown(tag); 
1656 dcs->d_enclosing->d_nonempty_decl = true; 
1657 } 
1658 } else { 
1659 if (tag->s_scl != scl || 
1660 (decl && !is_incomplete(tag->s_type))) { 
1661 /* %s tag '%s' redeclared as %s */ 
1662 error(46, storage_class_name(tag->s_scl), 
1663 tag->s_name, storage_class_name(scl)); 
1664 print_previous_declaration(tag); 
1665 tag = pushdown(tag); 
1666 dcs->d_enclosing->d_nonempty_decl = true; 
1667 } else if (semi || decl) 
1668 dcs->d_enclosing->d_nonempty_decl = true; 
1669 } 
1670 return tag; 
1671} 
1672 
1673const char * 1655const char *
1674storage_class_name(scl_t sc) 1656storage_class_name(scl_t sc)
1675{ 1657{
1676 switch (sc) { 1658 switch (sc) {
1677 case EXTERN: return "extern"; 1659 case EXTERN: return "extern";
1678 case STATIC: return "static"; 1660 case STATIC: return "static";
1679 case AUTO: return "auto"; 1661 case AUTO: return "auto";
1680 case REG: return "register"; 1662 case REG: return "register";
1681 case TYPEDEF: return "typedef"; 1663 case TYPEDEF: return "typedef";
1682 case STRUCT_TAG:return "struct"; 1664 case STRUCT_TAG:return "struct";
1683 case UNION_TAG: return "union"; 1665 case UNION_TAG: return "union";
1684 case ENUM_TAG: return "enum"; 1666 case ENUM_TAG: return "enum";
1685 default: lint_assert(/*CONSTCOND*/false); 1667 default: lint_assert(/*CONSTCOND*/false);
@@ -1812,26 +1794,116 @@ check_extern_declaration(const sym_t *sy @@ -1812,26 +1794,116 @@ check_extern_declaration(const sym_t *sy
1812 warning(351, sym->s_type->t_tspec == FUNC ? "" : " 'extern'", 1794 warning(351, sym->s_type->t_tspec == FUNC ? "" : " 'extern'",
1813 sym->s_name); 1795 sym->s_name);
1814 } 1796 }
1815 if (any_query_enabled && 1797 if (any_query_enabled &&
1816 sym->s_type->t_tspec == FUNC && 1798 sym->s_type->t_tspec == FUNC &&
1817 sym->s_scl == EXTERN && 1799 sym->s_scl == EXTERN &&
1818 sym->s_def == DECL && 1800 sym->s_def == DECL &&
1819 !in_system_header) { 1801 !in_system_header) {
1820 /* redundant 'extern' in function declaration of '%s' */ 1802 /* redundant 'extern' in function declaration of '%s' */
1821 query_message(13, sym->s_name); 1803 query_message(13, sym->s_name);
1822 } 1804 }
1823} 1805}
1824 1806
 1807/*
 1808 * Check whether the symbol cannot be initialized due to type/storage class.
 1809 * Return whether an error has been detected.
 1810 */
 1811static bool
 1812check_init(sym_t *sym)
 1813{
 1814
 1815 if (sym->s_type->t_tspec == FUNC) {
 1816 /* cannot initialize function '%s' */
 1817 error(24, sym->s_name);
 1818 return true;
 1819 }
 1820 if (sym->s_scl == TYPEDEF) {
 1821 /* cannot initialize typedef '%s' */
 1822 error(25, sym->s_name);
 1823 return true;
 1824 }
 1825 if (sym->s_scl == EXTERN && sym->s_def == DECL) {
 1826 if (dcs->d_kind == DLK_EXTERN) {
 1827 /* cannot initialize extern declaration '%s' */
 1828 warning(26, sym->s_name);
 1829 } else {
 1830 /* cannot initialize extern declaration '%s' */
 1831 error(26, sym->s_name);
 1832 return true;
 1833 }
 1834 }
 1835
 1836 return false;
 1837}
 1838
 1839/*
 1840 * Compares a prototype declaration with the remembered arguments of a previous
 1841 * old-style function definition.
 1842 */
 1843static bool
 1844check_old_style_definition(sym_t *rdsym, sym_t *dsym)
 1845{
 1846
 1847 sym_t *args = rdsym->u.s_old_style_args;
 1848 sym_t *pargs = dsym->s_type->t_args;
 1849
 1850 bool msg = false;
 1851
 1852 int narg = 0;
 1853 for (sym_t *arg = args; arg != NULL; arg = arg->s_next)
 1854 narg++;
 1855 int nparg = 0;
 1856 for (sym_t *parg = pargs; parg != NULL; parg = parg->s_next)
 1857 nparg++;
 1858 if (narg != nparg) {
 1859 /* prototype does not match old-style definition */
 1860 error(63);
 1861 msg = true;
 1862 goto end;
 1863 }
 1864
 1865 sym_t *arg = args;
 1866 sym_t *parg = pargs;
 1867 int n = 1;
 1868 while (narg-- > 0) {
 1869 bool dowarn = false;
 1870 /*
 1871 * If it does not match due to promotion and lint runs in
 1872 * "traditional to C90" migration mode, print only a warning.
 1873 *
 1874 * XXX: Where is this "only a warning"?
 1875 */
 1876 if (!types_compatible(arg->s_type, parg->s_type,
 1877 true, true, &dowarn) ||
 1878 dowarn) {
 1879 /* prototype does not match old-style ... */
 1880 error(299, n);
 1881 msg = true;
 1882 }
 1883 arg = arg->s_next;
 1884 parg = parg->s_next;
 1885 n++;
 1886 }
 1887
 1888end:
 1889 if (msg && rflag) {
 1890 /* old-style definition */
 1891 message_at(300, &rdsym->s_def_pos);
 1892 }
 1893
 1894 return msg;
 1895}
 1896
1825/* Process a single external or 'static' declarator. */ 1897/* Process a single external or 'static' declarator. */
1826static void 1898static void
1827declare_extern(sym_t *dsym, bool has_initializer, sbuf_t *renaming) 1899declare_extern(sym_t *dsym, bool has_initializer, sbuf_t *renaming)
1828{ 1900{
1829 1901
1830 if (renaming != NULL) { 1902 if (renaming != NULL) {
1831 lint_assert(dsym->s_rename == NULL); 1903 lint_assert(dsym->s_rename == NULL);
1832 1904
1833 char *s = level_zero_alloc(1, renaming->sb_len + 1, "string"); 1905 char *s = level_zero_alloc(1, renaming->sb_len + 1, "string");
1834 (void)memcpy(s, renaming->sb_name, renaming->sb_len + 1); 1906 (void)memcpy(s, renaming->sb_name, renaming->sb_len + 1);
1835 dsym->s_rename = s; 1907 dsym->s_rename = s;
1836 } 1908 }
1837 1909
@@ -2063,26 +2135,73 @@ qualifiers_correspond(const type_t *tp1, @@ -2063,26 +2135,73 @@ qualifiers_correspond(const type_t *tp1,
2063 if (tp1->t_volatile != tp2->t_volatile && !ignqual && allow_c90) 2135 if (tp1->t_volatile != tp2->t_volatile && !ignqual && allow_c90)
2064 return false; 2136 return false;
2065 return true; 2137 return true;
2066} 2138}
2067 2139
2068bool 2140bool
2069pointer_types_are_compatible(const type_t *tp1, const type_t *tp2, bool ignqual) 2141pointer_types_are_compatible(const type_t *tp1, const type_t *tp2, bool ignqual)
2070{ 2142{
2071 2143
2072 return tp1->t_tspec == VOID || tp2->t_tspec == VOID || 2144 return tp1->t_tspec == VOID || tp2->t_tspec == VOID ||
2073 qualifiers_correspond(tp1, tp2, ignqual); 2145 qualifiers_correspond(tp1, tp2, ignqual);
2074} 2146}
2075 2147
 2148static bool
 2149prototypes_compatible(const type_t *tp1, const type_t *tp2, bool *dowarn)
 2150{
 2151
 2152 if (tp1->t_vararg != tp2->t_vararg)
 2153 return false;
 2154
 2155 sym_t *a1 = tp1->t_args;
 2156 sym_t *a2 = tp2->t_args;
 2157
 2158 for (; a1 != NULL && a2 != NULL; a1 = a1->s_next, a2 = a2->s_next) {
 2159 if (!types_compatible(a1->s_type, a2->s_type,
 2160 true, false, dowarn))
 2161 return false;
 2162 }
 2163 return a1 == a2;
 2164}
 2165
 2166/*
 2167 * Returns whether all parameters of a prototype are compatible with an
 2168 * old-style function declaration.
 2169 *
 2170 * This is the case if the following conditions are met:
 2171 * 1. the prototype has a fixed number of parameters
 2172 * 2. no parameter is of type float
 2173 * 3. no parameter is converted to another type if integer promotion
 2174 * is applied on it
 2175 */
 2176static bool
 2177matches_no_arg_function(const type_t *tp, bool *dowarn)
 2178{
 2179
 2180 if (tp->t_vararg && dowarn != NULL)
 2181 *dowarn = true;
 2182 for (sym_t *arg = tp->t_args; arg != NULL; arg = arg->s_next) {
 2183 tspec_t t = arg->s_type->t_tspec;
 2184 if (t == FLOAT ||
 2185 t == CHAR || t == SCHAR || t == UCHAR ||
 2186 t == SHORT || t == USHORT) {
 2187 if (dowarn != NULL)
 2188 *dowarn = true;
 2189 }
 2190 }
 2191 /* FIXME: Always returning true cannot be correct. */
 2192 return true;
 2193}
 2194
2076/*- 2195/*-
2077 * ignqual ignore type qualifiers; used for function parameters 2196 * ignqual ignore type qualifiers; used for function parameters
2078 * promot promote the left type; used for comparison of parameters of 2197 * promot promote the left type; used for comparison of parameters of
2079 * old-style function definitions with parameters of prototypes. 2198 * old-style function definitions with parameters of prototypes.
2080 * *dowarn is set to true if an old-style function declaration is not 2199 * *dowarn is set to true if an old-style function declaration is not
2081 * compatible with a prototype 2200 * compatible with a prototype
2082 */ 2201 */
2083bool 2202bool
2084types_compatible(const type_t *tp1, const type_t *tp2, 2203types_compatible(const type_t *tp1, const type_t *tp2,
2085 bool ignqual, bool promot, bool *dowarn) 2204 bool ignqual, bool promot, bool *dowarn)
2086{ 2205{
2087 2206
2088 while (tp1 != NULL && tp2 != NULL) { 2207 while (tp1 != NULL && tp2 != NULL) {
@@ -2132,131 +2251,26 @@ types_compatible(const type_t *tp1, cons @@ -2132,131 +2251,26 @@ types_compatible(const type_t *tp1, cons
2132 if (!matches_no_arg_function(tp2, dowarn)) 2251 if (!matches_no_arg_function(tp2, dowarn))
2133 return false; 2252 return false;
2134 } 2253 }
2135 } 2254 }
2136 2255
2137 tp1 = tp1->t_subt; 2256 tp1 = tp1->t_subt;
2138 tp2 = tp2->t_subt; 2257 tp2 = tp2->t_subt;
2139 ignqual = promot = false; 2258 ignqual = promot = false;
2140 } 2259 }
2141 2260
2142 return tp1 == tp2; 2261 return tp1 == tp2;
2143} 2262}
2144 2263
2145static bool 
2146prototypes_compatible(const type_t *tp1, const type_t *tp2, bool *dowarn) 
2147{ 
2148 
2149 if (tp1->t_vararg != tp2->t_vararg) 
2150 return false; 
2151 
2152 sym_t *a1 = tp1->t_args; 
2153 sym_t *a2 = tp2->t_args; 
2154 
2155 for (; a1 != NULL && a2 != NULL; a1 = a1->s_next, a2 = a2->s_next) { 
2156 if (!types_compatible(a1->s_type, a2->s_type, 
2157 true, false, dowarn)) 
2158 return false; 
2159 } 
2160 return a1 == a2; 
2161} 
2162 
2163/* 
2164 * Returns whether all parameters of a prototype are compatible with an 
2165 * old-style function declaration. 
2166 * 
2167 * This is the case if the following conditions are met: 
2168 * 1. the prototype has a fixed number of parameters 
2169 * 2. no parameter is of type float 
2170 * 3. no parameter is converted to another type if integer promotion 
2171 * is applied on it 
2172 */ 
2173static bool 
2174matches_no_arg_function(const type_t *tp, bool *dowarn) 
2175{ 
2176 
2177 if (tp->t_vararg && dowarn != NULL) 
2178 *dowarn = true; 
2179 for (sym_t *arg = tp->t_args; arg != NULL; arg = arg->s_next) { 
2180 tspec_t t = arg->s_type->t_tspec; 
2181 if (t == FLOAT || 
2182 t == CHAR || t == SCHAR || t == UCHAR || 
2183 t == SHORT || t == USHORT) { 
2184 if (dowarn != NULL) 
2185 *dowarn = true; 
2186 } 
2187 } 
2188 /* FIXME: Always returning true cannot be correct. */ 
2189 return true; 
2190} 
2191 
2192/* 
2193 * Compares a prototype declaration with the remembered arguments of a previous 
2194 * old-style function definition. 
2195 */ 
2196static bool 
2197check_old_style_definition(sym_t *rdsym, sym_t *dsym) 
2198{ 
2199 
2200 sym_t *args = rdsym->u.s_old_style_args; 
2201 sym_t *pargs = dsym->s_type->t_args; 
2202 
2203 bool msg = false; 
2204 
2205 int narg = 0; 
2206 for (sym_t *arg = args; arg != NULL; arg = arg->s_next) 
2207 narg++; 
2208 int nparg = 0; 
2209 for (sym_t *parg = pargs; parg != NULL; parg = parg->s_next) 
2210 nparg++; 
2211 if (narg != nparg) { 
2212 /* prototype does not match old-style definition */ 
2213 error(63); 
2214 msg = true; 
2215 goto end; 
2216 } 
2217 
2218 sym_t *arg = args; 
2219 sym_t *parg = pargs; 
2220 int n = 1; 
2221 while (narg-- > 0) { 
2222 bool dowarn = false; 
2223 /* 
2224 * If it does not match due to promotion and lint runs in 
2225 * "traditional to C90" migration mode, print only a warning. 
2226 * 
2227 * XXX: Where is this "only a warning"? 
2228 */ 
2229 if (!types_compatible(arg->s_type, parg->s_type, 
2230 true, true, &dowarn) || 
2231 dowarn) { 
2232 /* prototype does not match old-style ... */ 
2233 error(299, n); 
2234 msg = true; 
2235 } 
2236 arg = arg->s_next; 
2237 parg = parg->s_next; 
2238 n++; 
2239 } 
2240 
2241end: 
2242 if (msg && rflag) { 
2243 /* old-style definition */ 
2244 message_at(300, &rdsym->s_def_pos); 
2245 } 
2246 
2247 return msg; 
2248} 
2249 
2250/* 2264/*
2251 * Completes a type by copying the dimension and prototype information from a 2265 * Completes a type by copying the dimension and prototype information from a
2252 * second compatible type. 2266 * second compatible type.
2253 * 2267 *
2254 * Following lines are legal: 2268 * Following lines are legal:
2255 * "typedef a[]; a b; a b[10]; a c; a c[20];" 2269 * "typedef a[]; a b; a b[10]; a c; a c[20];"
2256 * "typedef ft(); ft f; f(int); ft g; g(long);" 2270 * "typedef ft(); ft f; f(int); ft g; g(long);"
2257 * This means that, if a type is completed, the type structure must be 2271 * This means that, if a type is completed, the type structure must be
2258 * duplicated. 2272 * duplicated.
2259 */ 2273 */
2260void 2274void
2261complete_type(sym_t *dsym, sym_t *ssym) 2275complete_type(sym_t *dsym, sym_t *ssym)
2262{ 2276{
@@ -2412,26 +2426,62 @@ check_func_lint_directives(void) @@ -2412,26 +2426,62 @@ check_func_lint_directives(void)
2412 ? printflike_argnum : scanflike_argnum; 2426 ? printflike_argnum : scanflike_argnum;
2413 sym_t *arg = dcs->d_func_args; 2427 sym_t *arg = dcs->d_func_args;
2414 for (int n = 1; n < narg; n++) 2428 for (int n = 1; n < narg; n++)
2415 arg = arg->s_next; 2429 arg = arg->s_next;
2416 if (!is_character_pointer(arg->s_type)) { 2430 if (!is_character_pointer(arg->s_type)) {
2417 /* argument %d must be 'char *' for PRINTFLIKE/... */ 2431 /* argument %d must be 'char *' for PRINTFLIKE/... */
2418 warning(293, narg); 2432 warning(293, narg);
2419 printflike_argnum = scanflike_argnum = -1; 2433 printflike_argnum = scanflike_argnum = -1;
2420 } 2434 }
2421 } 2435 }
2422} 2436}
2423 2437
2424/* 2438/*
 2439 * Checks compatibility of an old-style function definition with a previous
 2440 * prototype declaration.
 2441 * Returns true if the position of the previous declaration should be reported.
 2442 */
 2443static bool
 2444check_prototype_declaration(sym_t *arg, sym_t *parg)
 2445{
 2446 type_t *tp = arg->s_type;
 2447 type_t *ptp = parg->s_type;
 2448 bool dowarn = false;
 2449
 2450 if (!types_compatible(tp, ptp, true, true, &dowarn)) {
 2451 if (types_compatible(tp, ptp, true, false, &dowarn)) {
 2452 /* type of '%s' does not match prototype */
 2453 return gnuism(58, arg->s_name);
 2454 } else {
 2455 /* type of '%s' does not match prototype */
 2456 error(58, arg->s_name);
 2457 return true;
 2458 }
 2459 }
 2460 if (dowarn) {
 2461 /* TODO: Make this an error in C99 mode as well. */
 2462 if (!allow_trad && !allow_c99)
 2463 /* type of '%s' does not match prototype */
 2464 error(58, arg->s_name);
 2465 else
 2466 /* type of '%s' does not match prototype */
 2467 warning(58, arg->s_name);
 2468 return true;
 2469 }
 2470
 2471 return false;
 2472}
 2473
 2474/*
2425 * Warn about arguments in old-style function definitions that default to int. 2475 * Warn about arguments in old-style function definitions that default to int.
2426 * Check that an old-style function definition is compatible to a previous 2476 * Check that an old-style function definition is compatible to a previous
2427 * prototype. 2477 * prototype.
2428 */ 2478 */
2429void 2479void
2430check_func_old_style_arguments(void) 2480check_func_old_style_arguments(void)
2431{ 2481{
2432 int narg; 2482 int narg;
2433 int nparg; 2483 int nparg;
2434 bool msg; 2484 bool msg;
2435 2485
2436 sym_t *args = funcsym->u.s_old_style_args; 2486 sym_t *args = funcsym->u.s_old_style_args;
2437 sym_t *pargs = funcsym->s_type->t_args; 2487 sym_t *pargs = funcsym->s_type->t_args;
@@ -2478,62 +2528,26 @@ check_func_old_style_arguments(void) @@ -2478,62 +2528,26 @@ check_func_old_style_arguments(void)
2478 } 2528 }
2479 } 2529 }
2480 if (msg && rflag) { 2530 if (msg && rflag) {
2481 /* prototype declaration */ 2531 /* prototype declaration */
2482 message_at(285, &dcs->d_redeclared_symbol->s_def_pos); 2532 message_at(285, &dcs->d_redeclared_symbol->s_def_pos);
2483 } 2533 }
2484 2534
2485 /* from now on the prototype is valid */ 2535 /* from now on the prototype is valid */
2486 funcsym->s_osdef = false; 2536 funcsym->s_osdef = false;
2487 funcsym->u.s_old_style_args = NULL; 2537 funcsym->u.s_old_style_args = NULL;
2488 } 2538 }
2489} 2539}
2490 2540
2491/* 
2492 * Checks compatibility of an old-style function definition with a previous 
2493 * prototype declaration. 
2494 * Returns true if the position of the previous declaration should be reported. 
2495 */ 
2496static bool 
2497check_prototype_declaration(sym_t *arg, sym_t *parg) 
2498{ 
2499 type_t *tp = arg->s_type; 
2500 type_t *ptp = parg->s_type; 
2501 bool dowarn = false; 
2502 
2503 if (!types_compatible(tp, ptp, true, true, &dowarn)) { 
2504 if (types_compatible(tp, ptp, true, false, &dowarn)) { 
2505 /* type of '%s' does not match prototype */ 
2506 return gnuism(58, arg->s_name); 
2507 } else { 
2508 /* type of '%s' does not match prototype */ 
2509 error(58, arg->s_name); 
2510 return true; 
2511 } 
2512 } 
2513 if (dowarn) { 
2514 /* TODO: Make this an error in C99 mode as well. */ 
2515 if (!allow_trad && !allow_c99) 
2516 /* type of '%s' does not match prototype */ 
2517 error(58, arg->s_name); 
2518 else 
2519 /* type of '%s' does not match prototype */ 
2520 warning(58, arg->s_name); 
2521 return true; 
2522 } 
2523 
2524 return false; 
2525} 
2526 
2527static void 2541static void
2528check_local_hiding(const sym_t *dsym) 2542check_local_hiding(const sym_t *dsym)
2529{ 2543{
2530 switch (dsym->s_scl) { 2544 switch (dsym->s_scl) {
2531 case AUTO: 2545 case AUTO:
2532 /* automatic '%s' hides external declaration */ 2546 /* automatic '%s' hides external declaration */
2533 warning(86, dsym->s_name); 2547 warning(86, dsym->s_name);
2534 break; 2548 break;
2535 case STATIC: 2549 case STATIC:
2536 /* static '%s' hides external declaration */ 2550 /* static '%s' hides external declaration */
2537 warning(87, dsym->s_name); 2551 warning(87, dsym->s_name);
2538 break; 2552 break;
2539 case TYPEDEF: 2553 case TYPEDEF:
@@ -2562,37 +2576,87 @@ check_local_redeclaration(const sym_t *d @@ -2562,37 +2576,87 @@ check_local_redeclaration(const sym_t *d
2562 /* 2576 /*
2563 * if allow_c90, a "redeclaration of '%s'" error 2577 * if allow_c90, a "redeclaration of '%s'" error
2564 * is produced below 2578 * is produced below
2565 */ 2579 */
2566 if (!allow_c90) { 2580 if (!allow_c90) {
2567 if (hflag) { 2581 if (hflag) {
2568 /* declaration of '%s' hides ... */ 2582 /* declaration of '%s' hides ... */
2569 warning(91, dsym->s_name); 2583 warning(91, dsym->s_name);
2570 } 2584 }
2571 rmsym(rdsym); 2585 rmsym(rdsym);
2572 } 2586 }
2573 } 2587 }
2574 2588
2575 } else if (rdsym->s_block_level < block_level) { 2589 } else if (rdsym->s_block_level < block_level) {
2576 if (hflag) { 2590 if (hflag) {
2577 /* declaration of '%s' hides earlier one */ 2591 /* declaration of '%s' hides earlier one */
2578 warning(95, dsym->s_name); 2592 warning(95, dsym->s_name);
 2593 }
 2594 }
 2595
 2596 if (rdsym->s_block_level == block_level) {
 2597 /* redeclaration of '%s' */
 2598 error(27, dsym->s_name);
 2599 rmsym(rdsym);
 2600 }
 2601}
 2602
 2603/* Processes (re)declarations of external symbols inside blocks. */
 2604static void
 2605declare_external_in_block(sym_t *dsym)
 2606{
 2607
 2608 /* look for a symbol with the same name */
 2609 sym_t *esym = dcs->d_redeclared_symbol;
 2610 while (esym != NULL && esym->s_block_level != 0) {
 2611 while ((esym = esym->s_symtab_next) != NULL) {
 2612 if (esym->s_kind != FVFT)
 2613 continue;
 2614 if (strcmp(dsym->s_name, esym->s_name) == 0)
 2615 break;
 2616 }
 2617 }
 2618 if (esym == NULL)
 2619 return;
 2620 if (esym->s_scl != EXTERN && esym->s_scl != STATIC) {
 2621 /* gcc accepts this without a warning, pcc prints an error. */
 2622 /* redeclaration of '%s' */
 2623 warning(27, dsym->s_name);
 2624 print_previous_declaration(esym);
 2625 return;
 2626 }
 2627
 2628 bool dowarn = false;
 2629 bool compatible = types_compatible(esym->s_type, dsym->s_type,
 2630 false, false, &dowarn);
 2631
 2632 if (!compatible || dowarn) {
 2633 if (esym->s_scl == EXTERN) {
 2634 /* inconsistent redeclaration of extern '%s' */
 2635 warning(90, dsym->s_name);
 2636 print_previous_declaration(esym);
 2637 } else {
 2638 /* inconsistent redeclaration of static '%s' */
 2639 warning(92, dsym->s_name);
 2640 print_previous_declaration(esym);
2579 } 2641 }
2580 } 2642 }
2581 2643
2582 if (rdsym->s_block_level == block_level) { 2644 if (compatible) {
2583 /* redeclaration of '%s' */ 2645 /*
2584 error(27, dsym->s_name); 2646 * Remember the external symbol, so we can update usage
2585 rmsym(rdsym); 2647 * information at the end of the block.
 2648 */
 2649 dsym->s_ext_sym = esym;
2586 } 2650 }
2587} 2651}
2588 2652
2589/* 2653/*
2590 * Completes a single local declaration/definition. 2654 * Completes a single local declaration/definition.
2591 */ 2655 */
2592void 2656void
2593declare_local(sym_t *dsym, bool has_initializer) 2657declare_local(sym_t *dsym, bool has_initializer)
2594{ 2658{
2595 2659
2596 /* Correct a mistake done in declarator_name(). */ 2660 /* Correct a mistake done in declarator_name(). */
2597 if (dsym->s_type->t_tspec == FUNC) { 2661 if (dsym->s_type->t_tspec == FUNC) {
2598 dsym->s_def = DECL; 2662 dsym->s_def = DECL;
@@ -2661,108 +2725,26 @@ declare_local(sym_t *dsym, bool has_init @@ -2661,108 +2725,26 @@ declare_local(sym_t *dsym, bool has_init
2661 2725
2662 if (dsym->s_scl == TYPEDEF) { 2726 if (dsym->s_scl == TYPEDEF) {
2663 dsym->s_type = block_dup_type(dsym->s_type); 2727 dsym->s_type = block_dup_type(dsym->s_type);
2664 dsym->s_type->t_typedef = true; 2728 dsym->s_type->t_typedef = true;
2665 set_first_typedef(dsym->s_type, dsym); 2729 set_first_typedef(dsym->s_type, dsym);
2666 } 2730 }
2667 2731
2668 if (dsym->s_scl == STATIC && any_query_enabled) { 2732 if (dsym->s_scl == STATIC && any_query_enabled) {
2669 /* static variable '%s' in function */ 2733 /* static variable '%s' in function */
2670 query_message(11, dsym->s_name); 2734 query_message(11, dsym->s_name);
2671 } 2735 }
2672} 2736}
2673 2737
2674/* Processes (re)declarations of external symbols inside blocks. */ 
2675static void 
2676declare_external_in_block(sym_t *dsym) 
2677{ 
2678 
2679 /* look for a symbol with the same name */ 
2680 sym_t *esym = dcs->d_redeclared_symbol; 
2681 while (esym != NULL && esym->s_block_level != 0) { 
2682 while ((esym = esym->s_symtab_next) != NULL) { 
2683 if (esym->s_kind != FVFT) 
2684 continue; 
2685 if (strcmp(dsym->s_name, esym->s_name) == 0) 
2686 break; 
2687 } 
2688 } 
2689 if (esym == NULL) 
2690 return; 
2691 if (esym->s_scl != EXTERN && esym->s_scl != STATIC) { 
2692 /* gcc accepts this without a warning, pcc prints an error. */ 
2693 /* redeclaration of '%s' */ 
2694 warning(27, dsym->s_name); 
2695 print_previous_declaration(esym); 
2696 return; 
2697 } 
2698 
2699 bool dowarn = false; 
2700 bool compatible = types_compatible(esym->s_type, dsym->s_type, 
2701 false, false, &dowarn); 
2702 
2703 if (!compatible || dowarn) { 
2704 if (esym->s_scl == EXTERN) { 
2705 /* inconsistent redeclaration of extern '%s' */ 
2706 warning(90, dsym->s_name); 
2707 print_previous_declaration(esym); 
2708 } else { 
2709 /* inconsistent redeclaration of static '%s' */ 
2710 warning(92, dsym->s_name); 
2711 print_previous_declaration(esym); 
2712 } 
2713 } 
2714 
2715 if (compatible) { 
2716 /* 
2717 * Remember the external symbol, so we can update usage 
2718 * information at the end of the block. 
2719 */ 
2720 dsym->s_ext_sym = esym; 
2721 } 
2722} 
2723 
2724/* 
2725 * Check whether the symbol cannot be initialized due to type/storage class. 
2726 * Return whether an error has been detected. 
2727 */ 
2728static bool 
2729check_init(sym_t *sym) 
2730{ 
2731 
2732 if (sym->s_type->t_tspec == FUNC) { 
2733 /* cannot initialize function '%s' */ 
2734 error(24, sym->s_name); 
2735 return true; 
2736 } 
2737 if (sym->s_scl == TYPEDEF) { 
2738 /* cannot initialize typedef '%s' */ 
2739 error(25, sym->s_name); 
2740 return true; 
2741 } 
2742 if (sym->s_scl == EXTERN && sym->s_def == DECL) { 
2743 if (dcs->d_kind == DLK_EXTERN) { 
2744 /* cannot initialize extern declaration '%s' */ 
2745 warning(26, sym->s_name); 
2746 } else { 
2747 /* cannot initialize extern declaration '%s' */ 
2748 error(26, sym->s_name); 
2749 return true; 
2750 } 
2751 } 
2752 
2753 return false; 
2754} 
2755 
2756/* Create a symbol for an abstract declaration. */ 2738/* Create a symbol for an abstract declaration. */
2757sym_t * 2739sym_t *
2758abstract_name(void) 2740abstract_name(void)
2759{ 2741{
2760 2742
2761 lint_assert(dcs->d_kind == DLK_ABSTRACT 2743 lint_assert(dcs->d_kind == DLK_ABSTRACT
2762 || dcs->d_kind == DLK_PROTO_PARAMS); 2744 || dcs->d_kind == DLK_PROTO_PARAMS);
2763 2745
2764 sym_t *sym = block_zero_alloc(sizeof(*sym), "sym"); 2746 sym_t *sym = block_zero_alloc(sizeof(*sym), "sym");
2765 sym->s_name = unnamed; 2747 sym->s_name = unnamed;
2766 sym->s_def = DEF; 2748 sym->s_def = DEF;
2767 sym->s_scl = ABSTRACT; 2749 sym->s_scl = ABSTRACT;
2768 sym->s_block_level = -1; 2750 sym->s_block_level = -1;
@@ -2865,44 +2847,26 @@ check_usage(decl_level *dl) @@ -2865,44 +2847,26 @@ check_usage(decl_level *dl)
2865{ 2847{
2866 /* for this warning LINTED has no effect */ 2848 /* for this warning LINTED has no effect */
2867 int saved_lwarn = lwarn; 2849 int saved_lwarn = lwarn;
2868 lwarn = LWARN_ALL; 2850 lwarn = LWARN_ALL;
2869 2851
2870 debug_step("begin lwarn %d", lwarn); 2852 debug_step("begin lwarn %d", lwarn);
2871 for (sym_t *sym = dl->d_first_dlsym; 2853 for (sym_t *sym = dl->d_first_dlsym;
2872 sym != NULL; sym = sym->s_level_next) 2854 sym != NULL; sym = sym->s_level_next)
2873 check_usage_sym(dl->d_asm, sym); 2855 check_usage_sym(dl->d_asm, sym);
2874 lwarn = saved_lwarn; 2856 lwarn = saved_lwarn;
2875 debug_step("end lwarn %d", lwarn); 2857 debug_step("end lwarn %d", lwarn);
2876} 2858}
2877 2859
2878/* Warns about a variable or a label that is not used or only set. */ 
2879void 
2880check_usage_sym(bool novar, sym_t *sym) 
2881{ 
2882 
2883 if (sym->s_block_level == -1) 
2884 return; 
2885 
2886 if (sym->s_kind == FVFT && sym->s_arg) 
2887 check_argument_usage(novar, sym); 
2888 else if (sym->s_kind == FVFT) 
2889 check_variable_usage(novar, sym); 
2890 else if (sym->s_kind == FLABEL) 
2891 check_label_usage(sym); 
2892 else if (sym->s_kind == FTAG) 
2893 check_tag_usage(sym); 
2894} 
2895 
2896static void 2860static void
2897check_argument_usage(bool novar, sym_t *arg) 2861check_argument_usage(bool novar, sym_t *arg)
2898{ 2862{
2899 2863
2900 lint_assert(arg->s_set); 2864 lint_assert(arg->s_set);
2901 2865
2902 if (novar) 2866 if (novar)
2903 return; 2867 return;
2904 2868
2905 if (!arg->s_used && !vflag) { 2869 if (!arg->s_used && !vflag) {
2906 /* parameter '%s' unused in function '%s' */ 2870 /* parameter '%s' unused in function '%s' */
2907 warning_at(231, &arg->s_def_pos, arg->s_name, funcsym->s_name); 2871 warning_at(231, &arg->s_def_pos, arg->s_name, funcsym->s_name);
2908 } 2872 }
@@ -3012,51 +2976,75 @@ check_tag_usage(sym_t *sym) @@ -3012,51 +2976,75 @@ check_tag_usage(sym_t *sym)
3012 break; 2976 break;
3013 case UNION: 2977 case UNION:
3014 /* union '%s' never defined */ 2978 /* union '%s' never defined */
3015 warning_at(234, &sym->s_def_pos, sym->s_name); 2979 warning_at(234, &sym->s_def_pos, sym->s_name);
3016 break; 2980 break;
3017 default: 2981 default:
3018 lint_assert(sym->s_type->t_tspec == ENUM); 2982 lint_assert(sym->s_type->t_tspec == ENUM);
3019 /* enum '%s' never defined */ 2983 /* enum '%s' never defined */
3020 warning_at(235, &sym->s_def_pos, sym->s_name); 2984 warning_at(235, &sym->s_def_pos, sym->s_name);
3021 break; 2985 break;
3022 } 2986 }
3023} 2987}
3024 2988
3025/* 2989/* Warns about a variable or a label that is not used or only set. */
3026 * Called after the entire translation unit has been parsed. 
3027 * Changes tentative definitions into definitions. 
3028 * Performs some tests on global symbols. Detected problems are: 
3029 * - defined variables of incomplete type 
3030 * - constant variables which are not initialized 
3031 * - static symbols which are never used 
3032 */ 
3033void 2990void
3034check_global_symbols(void) 2991check_usage_sym(bool novar, sym_t *sym)
3035{ 2992{
3036 sym_t *sym; 
3037 2993
3038 if (block_level != 0 || dcs->d_enclosing != NULL) 2994 if (sym->s_block_level == -1)
3039 norecover(); 2995 return;
3040 2996
3041 for (sym = dcs->d_first_dlsym; sym != NULL; sym = sym->s_level_next) { 2997 if (sym->s_kind == FVFT && sym->s_arg)
3042 if (sym->s_block_level == -1) 2998 check_argument_usage(novar, sym);
3043 continue; 2999 else if (sym->s_kind == FVFT)
3044 if (sym->s_kind == FVFT) 3000 check_variable_usage(novar, sym);
3045 check_global_variable(sym); 3001 else if (sym->s_kind == FLABEL)
3046 else if (sym->s_kind == FTAG) 3002 check_label_usage(sym);
3047 check_tag_usage(sym); 3003 else if (sym->s_kind == FTAG)
3048 else 3004 check_tag_usage(sym);
3049 lint_assert(sym->s_kind == FMEMBER); 3005}
 3006
 3007static void
 3008check_global_variable_size(const sym_t *sym)
 3009{
 3010
 3011 if (sym->s_def != TDEF)
 3012 return;
 3013 if (sym->s_type->t_tspec == FUNC) {
 3014 /* Maybe a syntax error after a function declaration. */
 3015 return;
 3016 }
 3017 if (sym->s_def == TDEF && sym->s_type->t_tspec == VOID) {
 3018 /* Prevent an internal error in length_in_bits below. */
 3019 return;
 3020 }
 3021
 3022 pos_t cpos = curr_pos;
 3023 curr_pos = sym->s_def_pos;
 3024 int len_in_bits = length_in_bits(sym->s_type, sym->s_name);
 3025 curr_pos = cpos;
 3026
 3027 if (len_in_bits == 0 &&
 3028 sym->s_type->t_tspec == ARRAY && sym->s_type->t_dim == 0) {
 3029 /* TODO: C99 6.7.5.2p1 defines this as an error as well. */
 3030 if (!allow_c90 ||
 3031 (sym->s_scl == EXTERN && (allow_trad || allow_c99))) {
 3032 /* empty array declaration for '%s' */
 3033 warning_at(190, &sym->s_def_pos, sym->s_name);
 3034 } else {
 3035 /* empty array declaration for '%s' */
 3036 error_at(190, &sym->s_def_pos, sym->s_name);
 3037 }
3050 } 3038 }
3051} 3039}
3052 3040
3053static void 3041static void
3054check_unused_static_global_variable(const sym_t *sym) 3042check_unused_static_global_variable(const sym_t *sym)
3055{ 3043{
3056 if (sym->s_type->t_tspec == FUNC) { 3044 if (sym->s_type->t_tspec == FUNC) {
3057 if (sym->s_def == DEF) { 3045 if (sym->s_def == DEF) {
3058 if (!sym->s_inline) 3046 if (!sym->s_inline)
3059 /* static function '%s' unused */ 3047 /* static function '%s' unused */
3060 warning_at(236, &sym->s_def_pos, sym->s_name); 3048 warning_at(236, &sym->s_def_pos, sym->s_name);
3061 } else { 3049 } else {
3062 /* static function '%s' declared but not defined */ 3050 /* static function '%s' declared but not defined */
@@ -3097,57 +3085,51 @@ check_global_variable(const sym_t *sym) @@ -3097,57 +3085,51 @@ check_global_variable(const sym_t *sym)
3097 return; 3085 return;
3098 3086
3099 if (scl == NOSCL) 3087 if (scl == NOSCL)
3100 return; /* May be caused by a syntax error. */ 3088 return; /* May be caused by a syntax error. */
3101 3089
3102 lint_assert(scl == EXTERN || scl == STATIC); 3090 lint_assert(scl == EXTERN || scl == STATIC);
3103 3091
3104 check_global_variable_size(sym); 3092 check_global_variable_size(sym);
3105 3093
3106 if (scl == STATIC) 3094 if (scl == STATIC)
3107 check_static_global_variable(sym); 3095 check_static_global_variable(sym);
3108} 3096}
3109 3097
3110static void 3098/*
3111check_global_variable_size(const sym_t *sym) 3099 * Called after the entire translation unit has been parsed.
 3100 * Changes tentative definitions into definitions.
 3101 * Performs some tests on global symbols. Detected problems are:
 3102 * - defined variables of incomplete type
 3103 * - constant variables which are not initialized
 3104 * - static symbols which are never used
 3105 */
 3106void
 3107check_global_symbols(void)
3112{ 3108{
 3109 sym_t *sym;
3113 3110
3114 if (sym->s_def != TDEF) 3111 if (block_level != 0 || dcs->d_enclosing != NULL)
3115 return; 3112 norecover();
3116 if (sym->s_type->t_tspec == FUNC) { 
3117 /* Maybe a syntax error after a function declaration. */ 
3118 return; 
3119 } 
3120 if (sym->s_def == TDEF && sym->s_type->t_tspec == VOID) { 
3121 /* Prevent an internal error in length_in_bits below. */ 
3122 return; 
3123 } 
3124 
3125 pos_t cpos = curr_pos; 
3126 curr_pos = sym->s_def_pos; 
3127 int len_in_bits = length_in_bits(sym->s_type, sym->s_name); 
3128 curr_pos = cpos; 
3129 3113
3130 if (len_in_bits == 0 && 3114 for (sym = dcs->d_first_dlsym; sym != NULL; sym = sym->s_level_next) {
3131 sym->s_type->t_tspec == ARRAY && sym->s_type->t_dim == 0) { 3115 if (sym->s_block_level == -1)
3132 /* TODO: C99 6.7.5.2p1 defines this as an error as well. */ 3116 continue;
3133 if (!allow_c90 || 3117 if (sym->s_kind == FVFT)
3134 (sym->s_scl == EXTERN && (allow_trad || allow_c99))) { 3118 check_global_variable(sym);
3135 /* empty array declaration for '%s' */ 3119 else if (sym->s_kind == FTAG)
3136 warning_at(190, &sym->s_def_pos, sym->s_name); 3120 check_tag_usage(sym);
3137 } else { 3121 else
3138 /* empty array declaration for '%s' */ 3122 lint_assert(sym->s_kind == FMEMBER);
3139 error_at(190, &sym->s_def_pos, sym->s_name); 
3140 } 
3141 } 3123 }
3142} 3124}
3143 3125
3144/* 3126/*
3145 * Prints information about location of previous definition/declaration. 3127 * Prints information about location of previous definition/declaration.
3146 */ 3128 */
3147void 3129void
3148print_previous_declaration(const sym_t *psym) 3130print_previous_declaration(const sym_t *psym)
3149{ 3131{
3150 3132
3151 if (!rflag) 3133 if (!rflag)
3152 return; 3134 return;
3153 3135