Module Name: src Committed By: rillig Date: Thu Aug 25 19:03:48 UTC 2022
Modified Files: src/tests/usr.bin/xlint/lint1: expr_precedence.c gcc_attribute.c gcc_attribute_type.c gcc_attribute_var.c src/usr.bin/xlint/lint1: cgram.y lex.c tree.c Log Message: lint: remove explicit list of known GCC attributes Most GCC attributes consist of a single identifier. Up to now, it was necessary to list each of these identifiers in the grammar, even those that only apply to a single target architecture. Instead, parse the general form of attributes, matching the few attributes that lint handles by name instead. While here, rename the grammar rules to use the GCC terms. To avoid conflicts between the global function 'printf' and the GCC attribute of the same name, do not add GCC attributes to the symbol table, and don't make these symbols 'extern' either. ok christos@. To generate a diff of this commit: cvs rdiff -u -r1.9 -r1.10 src/tests/usr.bin/xlint/lint1/expr_precedence.c cvs rdiff -u -r1.11 -r1.12 src/tests/usr.bin/xlint/lint1/gcc_attribute.c cvs rdiff -u -r1.2 -r1.3 src/tests/usr.bin/xlint/lint1/gcc_attribute_type.c cvs rdiff -u -r1.5 -r1.6 src/tests/usr.bin/xlint/lint1/gcc_attribute_var.c cvs rdiff -u -r1.420 -r1.421 src/usr.bin/xlint/lint1/cgram.y cvs rdiff -u -r1.132 -r1.133 src/usr.bin/xlint/lint1/lex.c cvs rdiff -u -r1.476 -r1.477 src/usr.bin/xlint/lint1/tree.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/expr_precedence.c diff -u src/tests/usr.bin/xlint/lint1/expr_precedence.c:1.9 src/tests/usr.bin/xlint/lint1/expr_precedence.c:1.10 --- src/tests/usr.bin/xlint/lint1/expr_precedence.c:1.9 Fri Jun 17 18:54:53 2022 +++ src/tests/usr.bin/xlint/lint1/expr_precedence.c Thu Aug 25 19:03:48 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: expr_precedence.c,v 1.9 2022/06/17 18:54:53 rillig Exp $ */ +/* $NetBSD: expr_precedence.c,v 1.10 2022/08/25 19:03:48 rillig Exp $ */ # 3 "expr_precedence.c" /* @@ -30,7 +30,6 @@ void __attribute__((format(printf, * * See lex.c, function 'search', keyword 'in_gcc_attribute'. */ - /* expect+2: error: 'var' undefined [99] */ /* expect+1: error: syntax error '=' [249] */ var = 1, /* Syntactically ok, must be a constant expression though. */ Index: src/tests/usr.bin/xlint/lint1/gcc_attribute.c diff -u src/tests/usr.bin/xlint/lint1/gcc_attribute.c:1.11 src/tests/usr.bin/xlint/lint1/gcc_attribute.c:1.12 --- src/tests/usr.bin/xlint/lint1/gcc_attribute.c:1.11 Fri Jun 17 18:54:53 2022 +++ src/tests/usr.bin/xlint/lint1/gcc_attribute.c Thu Aug 25 19:03:48 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: gcc_attribute.c,v 1.11 2022/06/17 18:54:53 rillig Exp $ */ +/* $NetBSD: gcc_attribute.c,v 1.12 2022/08/25 19:03:48 rillig Exp $ */ # 3 "gcc_attribute.c" /* @@ -29,7 +29,10 @@ function_nonnull_list(void *, const void void __attribute__((nonnull(1, 2))) function_nonnull_list(void *, const void *, int); -/* expect+1: error: syntax error 'unknown_attribute' [249] */ +/* + * Unknown attributes are skipped, as lint does not have a list of all known + * GCC attributes. + */ void __attribute__((unknown_attribute)) function_with_unknown_attribute(void); Index: src/tests/usr.bin/xlint/lint1/gcc_attribute_type.c diff -u src/tests/usr.bin/xlint/lint1/gcc_attribute_type.c:1.2 src/tests/usr.bin/xlint/lint1/gcc_attribute_type.c:1.3 --- src/tests/usr.bin/xlint/lint1/gcc_attribute_type.c:1.2 Sun Jul 25 19:05:27 2021 +++ src/tests/usr.bin/xlint/lint1/gcc_attribute_type.c Thu Aug 25 19:03:48 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: gcc_attribute_type.c,v 1.2 2021/07/25 19:05:27 rillig Exp $ */ +/* $NetBSD: gcc_attribute_type.c,v 1.3 2022/08/25 19:03:48 rillig Exp $ */ # 3 "gcc_attribute_type.c" /* @@ -27,5 +27,5 @@ struct attribute_before_keyword { }; /* just to trigger _some_ error, to keep the .exp file */ -/* expect+1: error: syntax error 'syntax_error' [249] */ +/* expect+1: error: syntax error ';' [249] */ __attribute__((syntax_error)); Index: src/tests/usr.bin/xlint/lint1/gcc_attribute_var.c diff -u src/tests/usr.bin/xlint/lint1/gcc_attribute_var.c:1.5 src/tests/usr.bin/xlint/lint1/gcc_attribute_var.c:1.6 --- src/tests/usr.bin/xlint/lint1/gcc_attribute_var.c:1.5 Wed Aug 11 05:19:33 2021 +++ src/tests/usr.bin/xlint/lint1/gcc_attribute_var.c Thu Aug 25 19:03:48 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: gcc_attribute_var.c,v 1.5 2021/08/11 05:19:33 rillig Exp $ */ +/* $NetBSD: gcc_attribute_var.c,v 1.6 2022/08/25 19:03:48 rillig Exp $ */ # 3 "gcc_attribute_var.c" /* @@ -71,5 +71,5 @@ attribute_after_array_brackets( } /* just to trigger _some_ error, to keep the .exp file */ -/* expect+1: error: syntax error 'syntax_error' [249] */ +/* expect+1: error: syntax error ';' [249] */ __attribute__((syntax_error)); Index: src/usr.bin/xlint/lint1/cgram.y diff -u src/usr.bin/xlint/lint1/cgram.y:1.420 src/usr.bin/xlint/lint1/cgram.y:1.421 --- src/usr.bin/xlint/lint1/cgram.y:1.420 Mon Jun 20 21:13:35 2022 +++ src/usr.bin/xlint/lint1/cgram.y Thu Aug 25 19:03:47 2022 @@ -1,5 +1,5 @@ %{ -/* $NetBSD: cgram.y,v 1.420 2022/06/20 21:13:35 rillig Exp $ */ +/* $NetBSD: cgram.y,v 1.421 2022/08/25 19:03:47 rillig Exp $ */ /* * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. @@ -35,7 +35,7 @@ #include <sys/cdefs.h> #if defined(__RCSID) -__RCSID("$NetBSD: cgram.y,v 1.420 2022/06/20 21:13:35 rillig Exp $"); +__RCSID("$NetBSD: cgram.y,v 1.421 2022/08/25 19:03:47 rillig Exp $"); #endif #include <limits.h> @@ -128,6 +128,12 @@ anonymize(sym_t *s) s->u.s_member.sm_sou_type = NULL; } +static bool +is_either(const char *s, const char *a, const char *b) +{ + return strcmp(s, a) == 0 || strcmp(s, b) == 0; +} + #if YYDEBUG && (YYBYACC || YYBISON) #define YYSTYPE_TOSTRING cgram_to_string #endif @@ -226,60 +232,6 @@ anonymize(sym_t *s) %token T_STATIC_ASSERT %token T_ATTRIBUTE -%token T_AT_ALIAS -%token T_AT_ALIGNED -%token T_AT_ALLOC_SIZE -%token T_AT_ALWAYS_INLINE -%token T_AT_BOUNDED -%token T_AT_BUFFER -%token T_AT_COLD -%token T_AT_COMMON -%token T_AT_CONSTRUCTOR -%token T_AT_DEPRECATED -%token T_AT_DESTRUCTOR -%token T_AT_DISABLE_SANITIZER_INSTRUMENTATION -%token T_AT_FALLTHROUGH -%token T_AT_FORMAT -%token T_AT_FORMAT_ARG -%token T_AT_FORMAT_GNU_PRINTF -%token T_AT_FORMAT_PRINTF -%token T_AT_FORMAT_SCANF -%token T_AT_FORMAT_STRFMON -%token T_AT_FORMAT_STRFTIME -%token T_AT_FORMAT_SYSLOG -%token T_AT_GNU_INLINE -%token T_AT_HOT -%token T_AT_MALLOC -%token T_AT_MAY_ALIAS -%token T_AT_MINBYTES -%token T_AT_MODE -%token T_AT_NO_SANITIZE -%token T_AT_NO_SANITIZE_THREAD -%token T_AT_NOINLINE -%token T_AT_NONNULL -%token T_AT_NONSTRING -%token T_AT_NORETURN -%token T_AT_NOTHROW -%token T_AT_NO_INSTRUMENT_FUNCTION -%token T_AT_OPTIMIZE -%token T_AT_OPTNONE -%token T_AT_PACKED -%token T_AT_PCS -%token T_AT_PURE -%token T_AT_REGPARM -%token T_AT_RETURNS_NONNULL -%token T_AT_RETURNS_TWICE -%token T_AT_SECTION -%token T_AT_SENTINEL -%token T_AT_STRING -%token T_AT_TARGET -%token T_AT_TLS_MODEL -%token T_AT_TUNION -%token T_AT_UNUSED -%token T_AT_USED -%token T_AT_VISIBILITY -%token T_AT_WARN_UNUSED_RESULT -%token T_AT_WEAK %left T_THEN %left T_ELSE @@ -734,16 +686,6 @@ expression: } ; -constant_expr_list_opt: /* helper for gcc_attribute */ - /* empty */ - | constant_expr_list - ; - -constant_expr_list: /* helper for gcc_attribute */ - constant_expr - | constant_expr_list T_COMMA constant_expr - ; - constant_expr: /* C99 6.6 */ conditional_expression ; @@ -875,7 +817,7 @@ type_attribute_opt: ; type_attribute: /* See C11 6.7 declaration-specifiers */ - gcc_attribute + gcc_attribute_specifier | T_ALIGNAS T_LPAREN type_specifier T_RPAREN /* C11 6.7.5 */ | T_ALIGNAS T_LPAREN constant_expr T_RPAREN /* C11 6.7.5 */ | T_PACKED { @@ -1079,17 +1021,17 @@ type_struct_declarator: /* K&R ---, C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2 */ enum_specifier: /* C99 6.7.2.2 */ - enum gcc_attribute_list_opt identifier_sym { + enum gcc_attribute_specifier_list_opt identifier_sym { $$ = mktag($3, ENUM, false, false); } - | enum gcc_attribute_list_opt identifier_sym { + | enum gcc_attribute_specifier_list_opt identifier_sym { dcs->d_tagtyp = mktag($3, ENUM, true, false); - } enum_declaration /*gcc_attribute_list_opt*/ { + } enum_declaration /*gcc_attribute_specifier_list_opt*/ { $$ = complete_tag_enum(dcs->d_tagtyp, $5); } - | enum gcc_attribute_list_opt { + | enum gcc_attribute_specifier_list_opt { dcs->d_tagtyp = mktag(NULL, ENUM, true, false); - } enum_declaration /*gcc_attribute_list_opt*/ { + } enum_declaration /*gcc_attribute_specifier_list_opt*/ { $$ = complete_tag_enum(dcs->d_tagtyp, $4); } | enum error { @@ -1143,10 +1085,11 @@ enumerator_list: /* C99 6.7.2.2 */ ; enumerator: /* C99 6.7.2.2 */ - identifier_sym gcc_attribute_list_opt { + identifier_sym gcc_attribute_specifier_list_opt { $$ = enumeration_constant($1, enumval, true); } - | identifier_sym gcc_attribute_list_opt T_ASSIGN constant_expr { + | identifier_sym gcc_attribute_specifier_list_opt + T_ASSIGN constant_expr { $$ = enumeration_constant($1, to_int_constant($4, true), false); } @@ -1318,7 +1261,7 @@ direct_param_declarator: $$ = $2; } | direct_param_declarator T_LBRACK array_size_opt T_RBRACK - gcc_attribute_list_opt { + gcc_attribute_specifier_list_opt { $$ = add_array($1, $3.has_dim, $3.dim); } | direct_param_declarator param_list asm_or_symbolrename_opt { @@ -1645,11 +1588,12 @@ asm_or_symbolrename_opt: /* GCC extensio /* empty */ { $$ = NULL; } - | T_ASM T_LPAREN T_STRING T_RPAREN gcc_attribute_list_opt { + | T_ASM T_LPAREN T_STRING T_RPAREN gcc_attribute_specifier_list_opt { freeyyv(&$3, T_STRING); $$ = NULL; } - | T_SYMBOLRENAME T_LPAREN T_NAME T_RPAREN gcc_attribute_list_opt { + | T_SYMBOLRENAME T_LPAREN T_NAME T_RPAREN + gcc_attribute_specifier_list_opt { $$ = $3; } ; @@ -1660,7 +1604,7 @@ statement: /* C99 6.8 */ ; non_expr_statement: /* helper for C99 6.8 */ - gcc_attribute /* ((__fallthrough__)) */ T_SEMI + gcc_attribute_specifier /* ((__fallthrough__)) */ T_SEMI | labeled_statement | compound_statement | selection_statement @@ -1672,7 +1616,7 @@ non_expr_statement: /* helper for C99 6 ; labeled_statement: /* C99 6.8.1 */ - label gcc_attribute_list_opt statement + label gcc_attribute_specifier_list_opt statement ; label: @@ -2072,112 +2016,54 @@ arg_declaration: | begin_type_declaration_specifiers error ; -gcc_attribute_list_opt: +/* https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html */ +gcc_attribute_specifier_list_opt: /* empty */ - | gcc_attribute_list + | gcc_attribute_specifier_list ; -gcc_attribute_list: - gcc_attribute - | gcc_attribute_list gcc_attribute +gcc_attribute_specifier_list: + gcc_attribute_specifier + | gcc_attribute_specifier_list gcc_attribute_specifier ; -gcc_attribute: +gcc_attribute_specifier: T_ATTRIBUTE T_LPAREN T_LPAREN { in_gcc_attribute = true; - } gcc_attribute_spec_list { + } gcc_attribute_list { in_gcc_attribute = false; } T_RPAREN T_RPAREN ; -gcc_attribute_spec_list: - gcc_attribute_spec - | gcc_attribute_spec_list T_COMMA gcc_attribute_spec +gcc_attribute_list: + gcc_attribute + | gcc_attribute_list T_COMMA gcc_attribute ; -gcc_attribute_spec: +gcc_attribute: /* empty */ - | T_AT_ALWAYS_INLINE - | T_AT_ALIAS T_LPAREN string T_RPAREN - | T_AT_ALIGNED T_LPAREN constant_expr T_RPAREN - | T_AT_ALIGNED - | T_AT_ALLOC_SIZE T_LPAREN constant_expr T_COMMA constant_expr T_RPAREN - | T_AT_ALLOC_SIZE T_LPAREN constant_expr T_RPAREN - | T_AT_BOUNDED T_LPAREN gcc_attribute_bounded - T_COMMA constant_expr T_COMMA constant_expr T_RPAREN - | T_AT_COLD - | T_AT_COMMON - | T_AT_CONSTRUCTOR T_LPAREN constant_expr T_RPAREN - | T_AT_CONSTRUCTOR - | T_AT_DEPRECATED T_LPAREN string T_RPAREN - | T_AT_DEPRECATED - | T_AT_DESTRUCTOR T_LPAREN constant_expr T_RPAREN - | T_AT_DESTRUCTOR - | T_AT_DISABLE_SANITIZER_INSTRUMENTATION - | T_AT_FALLTHROUGH { - fallthru(1); - } - | T_AT_FORMAT T_LPAREN gcc_attribute_format T_COMMA - constant_expr T_COMMA constant_expr T_RPAREN - | T_AT_FORMAT_ARG T_LPAREN constant_expr T_RPAREN - | T_AT_GNU_INLINE - | T_AT_HOT - | T_AT_MALLOC - | T_AT_MAY_ALIAS - | T_AT_MODE T_LPAREN T_NAME T_RPAREN - | T_AT_NO_SANITIZE T_LPAREN T_NAME T_RPAREN - | T_AT_NO_SANITIZE_THREAD - | T_AT_NOINLINE - | T_AT_NONNULL T_LPAREN constant_expr_list_opt T_RPAREN - | T_AT_NONNULL - | T_AT_NONSTRING - | T_AT_NORETURN - | T_AT_NOTHROW - | T_AT_NO_INSTRUMENT_FUNCTION - | T_AT_OPTIMIZE T_LPAREN string T_RPAREN - | T_AT_OPTNONE - | T_AT_PACKED { - addpacked(); - } - | T_AT_PCS T_LPAREN string T_RPAREN - | T_AT_PURE - | T_AT_REGPARM T_LPAREN constant_expr T_RPAREN - | T_AT_RETURNS_NONNULL - | T_AT_RETURNS_TWICE - | T_AT_SECTION T_LPAREN string T_RPAREN - | T_AT_SENTINEL T_LPAREN constant_expr T_RPAREN - | T_AT_SENTINEL - | T_AT_TARGET T_LPAREN string T_RPAREN - | T_AT_TLS_MODEL T_LPAREN string T_RPAREN - | T_AT_TUNION - | T_AT_UNUSED { - add_attr_used(); - } - | T_AT_USED { - add_attr_used(); - } - | T_AT_VISIBILITY T_LPAREN constant_expr T_RPAREN - | T_AT_WARN_UNUSED_RESULT - | T_AT_WEAK + | T_NAME { + const char *name = $1->sb_name; + if (is_either(name, "packed", "__packed__")) + addpacked(); + else if (is_either(name, "used", "__used__") || + is_either(name, "unused", "__unused__")) + add_attr_used(); + else if (is_either(name, "fallthrough", + "__fallthrough__")) + fallthru(1); + } + | T_NAME T_LPAREN T_RPAREN + | T_NAME T_LPAREN gcc_attribute_parameters T_RPAREN | T_QUAL { if ($1 != CONST) yyerror("Bad attribute"); } ; -gcc_attribute_bounded: - T_AT_MINBYTES - | T_AT_STRING - | T_AT_BUFFER - ; - -gcc_attribute_format: - T_AT_FORMAT_GNU_PRINTF - | T_AT_FORMAT_PRINTF - | T_AT_FORMAT_SCANF - | T_AT_FORMAT_STRFMON - | T_AT_FORMAT_STRFTIME - | T_AT_FORMAT_SYSLOG +gcc_attribute_parameters: + constant_expr + | gcc_attribute_parameters T_COMMA constant_expr ; sys: Index: src/usr.bin/xlint/lint1/lex.c diff -u src/usr.bin/xlint/lint1/lex.c:1.132 src/usr.bin/xlint/lint1/lex.c:1.133 --- src/usr.bin/xlint/lint1/lex.c:1.132 Sat Jun 11 13:19:28 2022 +++ src/usr.bin/xlint/lint1/lex.c Thu Aug 25 19:03:47 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: lex.c,v 1.132 2022/06/11 13:19:28 rillig Exp $ */ +/* $NetBSD: lex.c,v 1.133 2022/08/25 19:03:47 rillig Exp $ */ /* * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. @@ -38,7 +38,7 @@ #include <sys/cdefs.h> #if defined(__RCSID) -__RCSID("$NetBSD: lex.c,v 1.132 2022/06/11 13:19:28 rillig Exp $"); +__RCSID("$NetBSD: lex.c,v 1.133 2022/08/25 19:03:47 rillig Exp $"); #endif #include <ctype.h> @@ -75,26 +75,24 @@ bool in_system_header; * not defined, it would be interpreted as an implicit function call, leading * to a parse error. */ -#define kwdef(name, token, scl, tspec, tqual, since, gcc, attr, deco) \ +#define kwdef(name, token, scl, tspec, tqual, since, gcc, deco) \ { \ name, token, scl, tspec, tqual, \ (since) == 90, \ /* CONSTCOND */ (since) == 99 || (since) == 11, \ - (gcc) > 0, (attr) > 0, \ + (gcc) > 0, \ ((deco) & 1) != 0, ((deco) & 2) != 0, ((deco) & 4) != 0, \ } #define kwdef_token(name, token, since, gcc, deco) \ - kwdef(name, token, 0, 0, 0, since, gcc, 0, deco) + kwdef(name, token, 0, 0, 0, since, gcc, deco) #define kwdef_sclass(name, sclass, since, gcc, deco) \ - kwdef(name, T_SCLASS, sclass, 0, 0, since, gcc, 0, deco) + kwdef(name, T_SCLASS, sclass, 0, 0, since, gcc, deco) #define kwdef_type(name, tspec, since) \ - kwdef(name, T_TYPE, 0, tspec, 0, since, 0, 0, 1) + kwdef(name, T_TYPE, 0, tspec, 0, since, 0, 1) #define kwdef_tqual(name, tqual, since, gcc, deco) \ - kwdef(name, T_QUAL, 0, 0, tqual, since, gcc, 0, deco) + kwdef(name, T_QUAL, 0, 0, tqual, since, gcc, deco) #define kwdef_keyword(name, token) \ - kwdef(name, token, 0, 0, 0, 78, 0, 0, 1) -#define kwdef_gcc_attr(name, token) \ - kwdef(name, token, 0, 0, 0, 78, 1, 1, 5) + kwdef(name, token, 0, 0, 0, 78, 0, 1) /* During initialization, these keywords are written to the symbol table. */ static const struct keyword { @@ -107,7 +105,6 @@ static const struct keyword { bool kw_c90:1; /* C90 keyword */ bool kw_c99_or_c11:1; /* C99 or C11 keyword */ bool kw_gcc:1; /* GCC keyword */ - bool kw_attr:1; /* GCC attribute */ bool kw_plain:1; /* 'name' */ bool kw_leading:1; /* '__name' */ bool kw_both:1; /* '__name__' */ @@ -151,13 +148,12 @@ static const struct keyword { kwdef_sclass( "register", REG, 78,0,1), kwdef_tqual( "restrict", RESTRICT, 99,0,7), kwdef_keyword( "return", T_RETURN), - kwdef( "section", T_AT_SECTION, 0,0,0, 78,1,1,7), kwdef_type( "short", SHORT, 78), - kwdef( "signed", T_TYPE, 0, SIGNED, 0, 90,0,0,3), + kwdef( "signed", T_TYPE, 0, SIGNED, 0, 90,0,3), kwdef_keyword( "sizeof", T_SIZEOF), kwdef_sclass( "static", STATIC, 78,0,1), kwdef_keyword( "_Static_assert", T_STATIC_ASSERT), - kwdef("struct", T_STRUCT_OR_UNION, 0, STRUCT, 0, 78,0,0,1), + kwdef("struct", T_STRUCT_OR_UNION, 0, STRUCT, 0, 78,0,1), kwdef_keyword( "switch", T_SWITCH), kwdef_token( "__symbolrename", T_SYMBOLRENAME, 78,0,1), kwdef_tqual( "__thread", THREAD, 78,1,1), @@ -167,73 +163,17 @@ static const struct keyword { #ifdef INT128_SIZE kwdef_type( "__uint128_t", UINT128, 99), #endif - kwdef("union", T_STRUCT_OR_UNION, 0, UNION, 0, 78,0,0,1), + kwdef("union", T_STRUCT_OR_UNION, 0, UNION, 0, 78,0,1), kwdef_type( "unsigned", UNSIGN, 78), kwdef_type( "void", VOID, 78), kwdef_tqual( "volatile", VOLATILE, 90,0,7), kwdef_keyword( "while", T_WHILE), - - kwdef_gcc_attr( "alias", T_AT_ALIAS), - kwdef_gcc_attr( "aligned", T_AT_ALIGNED), - kwdef_gcc_attr( "alloc_size", T_AT_ALLOC_SIZE), - kwdef_gcc_attr( "always_inline",T_AT_ALWAYS_INLINE), - kwdef_gcc_attr( "bounded", T_AT_BOUNDED), - kwdef_gcc_attr( "buffer", T_AT_BUFFER), - kwdef_gcc_attr( "cold", T_AT_COLD), - kwdef_gcc_attr( "common", T_AT_COMMON), - kwdef_gcc_attr( "constructor", T_AT_CONSTRUCTOR), - kwdef_gcc_attr( "deprecated", T_AT_DEPRECATED), - kwdef_gcc_attr( "destructor", T_AT_DESTRUCTOR), - kwdef_gcc_attr( "disable_sanitizer_instrumentation", - T_AT_DISABLE_SANITIZER_INSTRUMENTATION), - kwdef_gcc_attr( "fallthrough", T_AT_FALLTHROUGH), - kwdef_gcc_attr( "format", T_AT_FORMAT), - kwdef_gcc_attr( "format_arg", T_AT_FORMAT_ARG), - kwdef_gcc_attr( "gnu_inline", T_AT_GNU_INLINE), - kwdef_gcc_attr( "gnu_printf", T_AT_FORMAT_GNU_PRINTF), - kwdef_gcc_attr( "hot", T_AT_HOT), - kwdef_gcc_attr( "malloc", T_AT_MALLOC), - kwdef_gcc_attr( "may_alias", T_AT_MAY_ALIAS), - kwdef_gcc_attr( "minbytes", T_AT_MINBYTES), - kwdef_gcc_attr( "mode", T_AT_MODE), - kwdef_gcc_attr("no_instrument_function", T_AT_NO_INSTRUMENT_FUNCTION), - kwdef_gcc_attr( "no_sanitize", T_AT_NO_SANITIZE), - kwdef_gcc_attr( "no_sanitize_thread", T_AT_NO_SANITIZE_THREAD), - kwdef_gcc_attr( "noinline", T_AT_NOINLINE), - kwdef_gcc_attr( "nonnull", T_AT_NONNULL), - kwdef_gcc_attr( "nonstring", T_AT_NONSTRING), - kwdef_gcc_attr( "noreturn", T_AT_NORETURN), - kwdef_gcc_attr( "nothrow", T_AT_NOTHROW), - kwdef_gcc_attr( "optimize", T_AT_OPTIMIZE), - kwdef_gcc_attr( "optnone", T_AT_OPTNONE), - kwdef_gcc_attr( "packed", T_AT_PACKED), - kwdef_gcc_attr( "pcs", T_AT_PCS), - kwdef_gcc_attr( "printf", T_AT_FORMAT_PRINTF), - kwdef_gcc_attr( "pure", T_AT_PURE), - kwdef_gcc_attr( "regparm", T_AT_REGPARM), - kwdef_gcc_attr( "returns_nonnull", T_AT_RETURNS_NONNULL), - kwdef_gcc_attr( "returns_twice", T_AT_RETURNS_TWICE), - kwdef_gcc_attr( "scanf", T_AT_FORMAT_SCANF), - kwdef_gcc_attr( "sentinel", T_AT_SENTINEL), - kwdef_gcc_attr( "strfmon", T_AT_FORMAT_STRFMON), - kwdef_gcc_attr( "strftime", T_AT_FORMAT_STRFTIME), - kwdef_gcc_attr( "string", T_AT_STRING), - kwdef_gcc_attr( "syslog", T_AT_FORMAT_SYSLOG), - kwdef_gcc_attr( "target", T_AT_TARGET), - kwdef_gcc_attr( "tls_model", T_AT_TLS_MODEL), - kwdef_gcc_attr( "transparent_union", T_AT_TUNION), - kwdef_gcc_attr( "unused", T_AT_UNUSED), - kwdef_gcc_attr( "used", T_AT_USED), - kwdef_gcc_attr( "visibility", T_AT_VISIBILITY), - kwdef_gcc_attr( "warn_unused_result", T_AT_WARN_UNUSED_RESULT), - kwdef_gcc_attr( "weak", T_AT_WEAK), #undef kwdef #undef kwdef_token #undef kwdef_sclass #undef kwdef_type #undef kwdef_tqual #undef kwdef_keyword -#undef kwdef_gcc_attr }; /* Symbol table */ @@ -282,9 +222,7 @@ symtab_search(sbuf_t *sb) continue; const struct keyword *kw = sym->s_keyword; - if (kw != NULL && !kw->kw_attr) - return sym; - if (kw != NULL && in_gcc_attribute) + if (kw != NULL || in_gcc_attribute) return sym; if (kw == NULL && !in_gcc_attribute && sym->s_kind == symtyp) return sym; @@ -1464,10 +1402,12 @@ getsym(sbuf_t *sb) symtyp = FVFT; - symtab_add(sym); + if (!in_gcc_attribute) { + symtab_add(sym); - *di->d_ldlsym = sym; - di->d_ldlsym = &sym->s_level_next; + *di->d_ldlsym = sym; + di->d_ldlsym = &sym->s_level_next; + } free(sb); return sym; Index: src/usr.bin/xlint/lint1/tree.c diff -u src/usr.bin/xlint/lint1/tree.c:1.476 src/usr.bin/xlint/lint1/tree.c:1.477 --- src/usr.bin/xlint/lint1/tree.c:1.476 Fri Aug 19 19:40:39 2022 +++ src/usr.bin/xlint/lint1/tree.c Thu Aug 25 19:03:47 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: tree.c,v 1.476 2022/08/19 19:40:39 rillig Exp $ */ +/* $NetBSD: tree.c,v 1.477 2022/08/25 19:03:47 rillig Exp $ */ /* * Copyright (c) 1994, 1995 Jochen Pohl @@ -37,7 +37,7 @@ #include <sys/cdefs.h> #if defined(__RCSID) -__RCSID("$NetBSD: tree.c,v 1.476 2022/08/19 19:40:39 rillig Exp $"); +__RCSID("$NetBSD: tree.c,v 1.477 2022/08/25 19:03:47 rillig Exp $"); #endif #include <float.h> @@ -488,7 +488,7 @@ build_name(sym_t *sym, bool is_funcname) { tnode_t *n; - if (sym->s_scl == NOSCL) { + if (sym->s_scl == NOSCL && !in_gcc_attribute) { sym->s_scl = EXTERN; sym->s_def = DECL; if (is_funcname)