Module Name: src Committed By: rillig Date: Sat May 4 06:52:17 UTC 2024
Modified Files: src/tests/usr.bin/xlint/lint1: msg_004.c msg_005.c src/usr.bin/xlint/lint1: decl.c Log Message: lint: increase debug logging for declarations All changes to the global variable 'dcs' are tracked now, to help identify the cause of the failing tests in expr_sizeof and gcc_attribute_aligned. While here, test more invalid type combinations in typedefs. To generate a diff of this commit: cvs rdiff -u -r1.7 -r1.8 src/tests/usr.bin/xlint/lint1/msg_004.c cvs rdiff -u -r1.5 -r1.6 src/tests/usr.bin/xlint/lint1/msg_005.c cvs rdiff -u -r1.401 -r1.402 src/usr.bin/xlint/lint1/decl.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/tests/usr.bin/xlint/lint1/msg_004.c diff -u src/tests/usr.bin/xlint/lint1/msg_004.c:1.7 src/tests/usr.bin/xlint/lint1/msg_004.c:1.8 --- src/tests/usr.bin/xlint/lint1/msg_004.c:1.7 Tue Mar 28 14:44:34 2023 +++ src/tests/usr.bin/xlint/lint1/msg_004.c Sat May 4 06:52:17 2024 @@ -1,7 +1,10 @@ -/* $NetBSD: msg_004.c,v 1.7 2023/03/28 14:44:34 rillig Exp $ */ +/* $NetBSD: msg_004.c,v 1.8 2024/05/04 06:52:17 rillig Exp $ */ # 3 "msg_004.c" // Test for message: illegal type combination [4] +// +// See also: +// msg_005.c /* lint1-extra-flags: -X 351 */ Index: src/tests/usr.bin/xlint/lint1/msg_005.c diff -u src/tests/usr.bin/xlint/lint1/msg_005.c:1.5 src/tests/usr.bin/xlint/lint1/msg_005.c:1.6 --- src/tests/usr.bin/xlint/lint1/msg_005.c:1.5 Fri Jun 17 18:54:53 2022 +++ src/tests/usr.bin/xlint/lint1/msg_005.c Sat May 4 06:52:17 2024 @@ -1,29 +1,146 @@ -/* $NetBSD: msg_005.c,v 1.5 2022/06/17 18:54:53 rillig Exp $ */ +/* $NetBSD: msg_005.c,v 1.6 2024/05/04 06:52:17 rillig Exp $ */ # 3 "msg_005.c" // Test for message: modifying typedef with '%s'; only qualifiers allowed [5] -typedef int number; +typedef char char_alias; +typedef signed char schar_alias; +typedef unsigned char uchar_alias; +typedef short short_alias; +typedef unsigned short ushort_alias; +typedef int int_alias; +typedef unsigned int uint_alias; +typedef long long_alias; +typedef unsigned long ulong_alias; +typedef long long llong_alias; +typedef unsigned long long ullong_alias; +typedef float float_alias; +typedef double double_alias; +typedef long double ldouble_alias; +typedef float _Complex fcomplex_alias; +typedef double _Complex dcomplex_alias; +typedef long double _Complex lcomplex_alias; /* expect+1: warning: modifying typedef with 'signed'; only qualifiers allowed [5] */ -typedef number signed signed_number; - +typedef char_alias signed err_s_char; +/* expect+1: warning: modifying typedef with 'unsigned'; only qualifiers allowed [5] */ +typedef char_alias unsigned err_u_char; +/* expect+1: error: illegal type combination [4] */ +typedef schar_alias signed err_s_schar; +/* expect+1: error: illegal type combination [4] */ +typedef schar_alias unsigned err_u_schar; +/* expect+1: error: illegal type combination [4] */ +typedef uchar_alias signed err_s_uchar; +/* expect+1: error: illegal type combination [4] */ +typedef uchar_alias unsigned err_u_uchar; +/* expect+1: warning: modifying typedef with 'signed'; only qualifiers allowed [5] */ +typedef short_alias signed err_s_short; +/* expect+1: warning: modifying typedef with 'unsigned'; only qualifiers allowed [5] */ +typedef short_alias unsigned err_u_short; +/* expect+1: error: illegal type combination [4] */ +typedef ushort_alias signed err_s_ushort; +/* expect+1: error: illegal type combination [4] */ +typedef ushort_alias unsigned err_u_ushort; +/* expect+1: warning: modifying typedef with 'signed'; only qualifiers allowed [5] */ +typedef int_alias signed err_s_int; +/* expect+1: warning: modifying typedef with 'unsigned'; only qualifiers allowed [5] */ +typedef int_alias unsigned err_u_int; +/* expect+1: error: illegal type combination [4] */ +typedef uint_alias signed err_s_uint; +/* expect+1: error: illegal type combination [4] */ +typedef uint_alias unsigned err_u_uint; +/* expect+1: warning: modifying typedef with 'signed'; only qualifiers allowed [5] */ +typedef long_alias signed err_s_long; +/* expect+1: warning: modifying typedef with 'unsigned'; only qualifiers allowed [5] */ +typedef long_alias unsigned err_u_long; +/* expect+1: error: illegal type combination [4] */ +typedef ulong_alias signed err_s_ulong; +/* expect+1: error: illegal type combination [4] */ +typedef ulong_alias unsigned err_u_ulong; +/* expect+1: warning: modifying typedef with 'signed'; only qualifiers allowed [5] */ +typedef llong_alias signed err_s_llong; /* expect+1: warning: modifying typedef with 'unsigned'; only qualifiers allowed [5] */ -typedef number unsigned unsigned_number; +typedef llong_alias unsigned err_u_llong; +/* expect+1: error: illegal type combination [4] */ +typedef ullong_alias signed err_s_ullong; +/* expect+1: error: illegal type combination [4] */ +typedef ullong_alias unsigned err_u_ullong; +/* expect+1: error: illegal type combination [4] */ +typedef float_alias signed err_s_float; +/* expect+1: error: illegal type combination [4] */ +typedef float_alias unsigned err_u_float; +/* expect+1: error: illegal type combination [4] */ +typedef double_alias signed err_s_double; +/* expect+1: error: illegal type combination [4] */ +typedef double_alias unsigned err_u_double; +/* expect+1: error: illegal type combination [4] */ +typedef ldouble_alias signed err_s_ldouble; +/* expect+1: error: illegal type combination [4] */ +typedef ldouble_alias unsigned err_u_ldouble; +/* expect+1: error: illegal type combination [4] */ +typedef fcomplex_alias signed err_s_fcomplex; +/* expect+1: error: illegal type combination [4] */ +typedef fcomplex_alias unsigned err_u_fcomplex; +/* expect+1: error: illegal type combination [4] */ +typedef dcomplex_alias signed err_s_dcomplex; +/* expect+1: error: illegal type combination [4] */ +typedef dcomplex_alias unsigned err_u_dcomplex; +/* expect+1: error: illegal type combination [4] */ +typedef lcomplex_alias signed err_s_lcomplex; +/* expect+1: error: illegal type combination [4] */ +typedef lcomplex_alias unsigned err_u_lcomplex; /* expect+1: warning: modifying typedef with 'short'; only qualifiers allowed [5] */ -typedef number short short_number; - +typedef int_alias short err_short_int; +/* expect+1: error: illegal type combination [4] */ +typedef long_alias short err_short_long; +/* expect+1: error: illegal type combination [4] */ +typedef float_alias short err_short_float; + +/* expect+1: error: illegal type combination [4] */ +typedef char_alias long err_l_char; +/* expect+1: error: illegal type combination [4] */ +typedef schar_alias long err_l_schar; +/* expect+1: error: illegal type combination [4] */ +typedef uchar_alias long err_l_uchar; +/* expect+1: error: illegal type combination [4] */ +typedef short_alias long err_l_short; +/* expect+1: error: illegal type combination [4] */ +typedef ushort_alias long err_l_ushort; +/* expect+1: warning: modifying typedef with 'long'; only qualifiers allowed [5] */ +typedef int_alias long err_l_int; +/* expect+1: warning: modifying typedef with 'long'; only qualifiers allowed [5] */ +typedef uint_alias long err_l_uint; +/* expect+1: warning: modifying typedef with 'long'; only qualifiers allowed [5] */ +typedef long_alias long err_l_long; /* expect+1: warning: modifying typedef with 'long'; only qualifiers allowed [5] */ -typedef number long long_number; +typedef ulong_alias long err_l_ulong; +/* expect+1: error: illegal type combination [4] */ +typedef llong_alias long err_l_llong; +/* expect+1: error: illegal type combination [4] */ +typedef ullong_alias long err_l_ullong; +/* expect+1: warning: modifying typedef with 'long'; only qualifiers allowed [5] */ +typedef float_alias long err_l_float; +/* expect+1: warning: modifying typedef with 'long'; only qualifiers allowed [5] */ +typedef double_alias long err_l_double; +/* expect+1: error: illegal type combination [4] */ +typedef ldouble_alias long err_l_ldouble; +/* expect+1: error: illegal type combination [4] */ +typedef fcomplex_alias long err_l_fcomplex; +/* expect+1: warning: modifying typedef with 'long'; only qualifiers allowed [5] */ +typedef dcomplex_alias long err_l_dcomplex; +/* expect+1: error: illegal type combination [4] */ +typedef lcomplex_alias long err_l_lcomplex; + /* - * If the type qualifier comes first, the following name is interpreted as a - * new name, not as the one referring to the typedef. This makes the above - * type modifications even more obscure. + * If the type qualifier comes before the type name, which would be the + * natural order, the type name is interpreted as a new name, not as the one + * referring to the typedef. This makes the above type modifications even + * more unlikely to be accidentally seen in practice. */ /* expect+1: error: syntax error 'prefix_long_number' [249] */ -typedef long number prefix_long_number; +typedef long int_alias prefix_long_number; /* Type qualifiers are OK. */ -typedef number const const_number; +typedef int_alias const const_int; Index: src/usr.bin/xlint/lint1/decl.c diff -u src/usr.bin/xlint/lint1/decl.c:1.401 src/usr.bin/xlint/lint1/decl.c:1.402 --- src/usr.bin/xlint/lint1/decl.c:1.401 Fri May 3 04:04:17 2024 +++ src/usr.bin/xlint/lint1/decl.c Sat May 4 06:52:16 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: decl.c,v 1.401 2024/05/03 04:04:17 rillig Exp $ */ +/* $NetBSD: decl.c,v 1.402 2024/05/04 06:52:16 rillig Exp $ */ /* * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. @@ -38,7 +38,7 @@ #include <sys/cdefs.h> #if defined(__RCSID) -__RCSID("$NetBSD: decl.c,v 1.401 2024/05/03 04:04:17 rillig Exp $"); +__RCSID("$NetBSD: decl.c,v 1.402 2024/05/04 06:52:16 rillig Exp $"); #endif #include <sys/param.h> @@ -63,12 +63,20 @@ int enumval; */ decl_level *dcs; +#ifdef DEBUG +static inline void +debug_func_dcs(const char *func) +{ + debug_printf("%s: ", func); + debug_dcs(); +} +#else +#define debug_func_dcs(func) debug_noop() +#endif void init_decl(void) { - - /* declaration stack */ dcs = xcalloc(1, sizeof(*dcs)); dcs->d_kind = DLK_EXTERN; dcs->d_last_dlsym = &dcs->d_first_dlsym; @@ -109,10 +117,10 @@ gettyp(tspec_t t) type_t * block_dup_type(const type_t *tp) { - - debug_step("%s '%s'", __func__, type_name(tp)); type_t *ntp = block_zero_alloc(sizeof(*ntp), "type"); + // Keep referring to the same subtype, struct, union, enum, params. *ntp = *tp; + debug_step("%s '%s'", __func__, type_name(ntp)); return ntp; } @@ -120,10 +128,10 @@ block_dup_type(const type_t *tp) type_t * expr_dup_type(const type_t *tp) { - - debug_step("%s '%s'", __func__, type_name(tp)); type_t *ntp = expr_zero_alloc(sizeof(*ntp), "type"); + // Keep referring to the same subtype, struct, union, enum, params. *ntp = *tp; + debug_step("%s: '%s'", __func__, type_name(ntp)); return ntp; } @@ -136,8 +144,8 @@ expr_dup_type(const type_t *tp) type_t * expr_unqualified_type(const type_t *tp) { - type_t *ntp = expr_zero_alloc(sizeof(*ntp), "type"); + // Keep referring to the same subtype, struct, union, enum, params. *ntp = *tp; ntp->t_const = false; ntp->t_volatile = false; @@ -146,11 +154,11 @@ expr_unqualified_type(const type_t *tp) * In case of a struct or union type, the members should lose their * qualifiers as well, but that would require a deep copy of the struct * or union type. This in turn would defeat the type comparison in - * types_compatible, which simply tests whether tp1->u.sou == - * tp2->u.sou. + * types_compatible, which simply tests whether 'tp1->u.sou == + * tp2->u.sou'. */ - debug_step("%s '%s'", __func__, type_name(ntp)); + debug_step("%s: '%s'", __func__, type_name(ntp)); return ntp; } @@ -177,19 +185,15 @@ is_incomplete(const type_t *tp) void dcs_add_function_specifier(function_specifier fs) { - debug_step("%s: %s", __func__, function_specifier_name(fs)); if (fs == FS_INLINE) { if (dcs->d_inline) /* duplicate '%s' */ warning(10, "inline"); dcs->d_inline = true; } + debug_func_dcs(__func__); } -/* - * Remember the storage class of the current declaration and detect multiple - * storage classes. - */ void dcs_add_storage_class(scl_t sc) { @@ -209,8 +213,7 @@ dcs_add_storage_class(scl_t sc) dcs->d_scl = STATIC; /* ignore thread_local */ else dcs->d_multiple_storage_classes = true; - debug_printf("%s: ", __func__); - debug_dcs(); + debug_func_dcs(__func__); } /* Merge the signedness into the abstract type. */ @@ -237,9 +240,6 @@ merge_signedness(tspec_t t, tspec_t s) static type_t * typedef_error(type_t *td, tspec_t t) { - - debug_step("%s: '%s' %s", __func__, type_name(td), tspec_name(t)); - tspec_t t2 = td->t_tspec; if ((t == SIGNED || t == UNSIGN) && @@ -290,6 +290,7 @@ typedef_error(type_t *td, tspec_t t) invalid: dcs->d_invalid_type_combination = true; + debug_func_dcs(__func__); return td; } @@ -306,8 +307,6 @@ void dcs_add_type(type_t *tp) { - debug_step("%s: %s", __func__, type_name(tp)); - debug_dcs(); if (tp->t_typedef) { /*- * something like "typedef int a; int a b;" @@ -319,11 +318,12 @@ dcs_add_type(type_t *tp) lint_assert(dcs->d_rank_mod == NO_TSPEC); dcs->d_type = tp; + debug_func_dcs(__func__); return; } tspec_t t = tp->t_tspec; - if (is_struct_or_union(t) || t == ENUM) { + if (t == STRUCT || t == UNION || t == ENUM) { /* something like "int struct a ..." */ if (dcs->d_type != NULL || dcs->d_abstract_type != NO_TSPEC || dcs->d_rank_mod != NO_TSPEC || dcs->d_sign_mod != NO_TSPEC) { @@ -333,13 +333,14 @@ dcs_add_type(type_t *tp) dcs->d_rank_mod = NO_TSPEC; } dcs->d_type = tp; - debug_dcs(); + debug_func_dcs(__func__); return; } if (dcs->d_type != NULL && !dcs->d_type->t_typedef) { /* something like "struct a int" */ dcs->d_invalid_type_combination = true; + debug_func_dcs(__func__); return; } @@ -398,7 +399,7 @@ dcs_add_type(type_t *tp) dcs->d_invalid_type_combination = true; dcs->d_abstract_type = t; } - debug_dcs(); + debug_func_dcs(__func__); } static void @@ -410,6 +411,8 @@ set_first_typedef(type_t *tp, sym_t *sym tp->u.sou->sou_first_typedef = sym; if (t == ENUM && tp->u.enumer->en_first_typedef == NULL) tp->u.enumer->en_first_typedef = sym; + debug_printf("%s: ", __func__); + debug_type(tp); } static unsigned int @@ -457,7 +460,6 @@ pack_struct_or_union(type_t *tp) bits = mem_bits; } tp->u.sou->sou_size_in_bits = bits; - debug_dcs(); } void @@ -465,7 +467,9 @@ dcs_add_alignas(tnode_t *tn) { dcs->d_mem_align = to_int_constant(tn, true); if (dcs->d_type != NULL && is_struct_or_union(dcs->d_type->t_tspec)) + // FIXME: The type must not be modified. dcs->d_type->u.sou->sou_align = dcs->d_mem_align; + debug_func_dcs(__func__); } void @@ -475,12 +479,14 @@ dcs_add_packed(void) dcs->d_packed = true; else pack_struct_or_union(dcs->d_type); + debug_func_dcs(__func__); } void dcs_set_used(void) { dcs->d_used = true; + debug_func_dcs(__func__); } /* @@ -492,6 +498,7 @@ void dcs_add_qualifiers(type_qualifiers qs) { add_type_qualifiers(&dcs->d_qual, qs); + debug_func_dcs(__func__); } void @@ -591,6 +598,8 @@ dcs_set_asm(void) for (decl_level *dl = dcs; dl != NULL; dl = dl->d_enclosing) dl->d_asm = true; + debug_step("%s", __func__); + debug_dcs_all(); } void @@ -626,6 +635,8 @@ dcs_begin_type(void) // keep d_last_dlsym dcs->d_func_proto_syms = NULL; // keep d_enclosing + + debug_func_dcs(__func__); } static void @@ -707,8 +718,7 @@ dcs_merge_declaration_specifiers(void) if (l != NO_TSPEC) t = l; dcs->d_type = gettyp(merge_signedness(t, s)); - debug_printf("%s: ", __func__); - debug_dcs(); + debug_func_dcs(__func__); } static void dcs_align(unsigned int, unsigned int); @@ -1036,6 +1046,7 @@ dcs_align(unsigned int member_alignment, if (bit_field_width == 0 || dcs->d_sou_size_in_bits + bit_field_width > offset) dcs->d_sou_size_in_bits = offset; + debug_func_dcs(__func__); } /* Add a member to the struct or union type that is being built in 'dcs'. */ @@ -1069,7 +1080,7 @@ dcs_add_member(sym_t *mem) if (union_size > dcs->d_sou_size_in_bits) dcs->d_sou_size_in_bits = union_size; - debug_dcs(); + debug_func_dcs(__func__); } sym_t * @@ -1224,7 +1235,7 @@ add_pointer(sym_t *decl, qual_ptr *p) free(p); p = next; } - debug_step("add_pointer: '%s'", type_name(decl->s_type)); + debug_step("%s: '%s'", __func__, type_name(decl->s_type)); return decl; } @@ -1514,6 +1525,7 @@ declarator_name(sym_t *sym) dcs->d_func_proto_syms = NULL; debug_sym("declarator_name: ", sym, "\n"); + debug_func_dcs(__func__); return sym; } @@ -1592,6 +1604,7 @@ new_tag(sym_t *tag, scl_t scl, bool decl dcs->d_enclosing->d_nonempty_decl = true; } debug_sym("new_tag: ", tag, "\n"); + debug_dcs_all(); return tag; } @@ -1669,6 +1682,7 @@ make_tag_type(sym_t *tag, tspec_t kind, } debug_printf("%s: '%s'", __func__, type_name(tp)); debug_sym(" ", tag, "\n"); + debug_dcs_all(); return tp; } @@ -1712,6 +1726,7 @@ complete_struct_or_union(sym_t *first_me /* '%s' has no named members */ warning(65, type_name(tp)); debug_step("%s: '%s'", __func__, type_name(tp)); + debug_dcs_all(); return tp; } @@ -1723,6 +1738,7 @@ complete_enum(sym_t *first_enumerator) tp->u.enumer->en_incomplete = false; tp->u.enumer->en_first_enumerator = first_enumerator; debug_step("%s: '%s'", __func__, type_name(tp)); + debug_func_dcs(__func__); return tp; } @@ -2762,6 +2778,7 @@ abstract_name_level(bool enclosing) debug_printf("%s: ", __func__); debug_sym("", sym, "\n"); + debug_func_dcs(__func__); return sym; }