aboutsummaryrefslogtreecommitdiff
path: root/gcc/c
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2019-11-15 00:06:30 +0000
committerJoseph Myers <jsm28@gcc.gnu.org>2019-11-15 00:06:30 +0000
commit2cc94aa8d817bab3af6ff5b41135ad30ee50f09b (patch)
treeb815f47b6482a5df0d39aa4b4e98970218369860 /gcc/c
parent1a4ec3250596b03e1b2edcfbc9d903c1f189f077 (diff)
downloadgcc-2cc94aa8d817bab3af6ff5b41135ad30ee50f09b.zip
gcc-2cc94aa8d817bab3af6ff5b41135ad30ee50f09b.tar.gz
gcc-2cc94aa8d817bab3af6ff5b41135ad30ee50f09b.tar.bz2
Support C2x [[deprecated]] attribute.
This patch adds support for the C2x [[deprecated]] attribute. All the actual logic for generating warnings can be identical to the GNU __attribute__ ((deprecated)), as can the attribute handler, so this is just a matter of wiring things up appropriately and adding the checks specified in the standard. Unlike for C++, this patch gives "deprecated" an entry in a table of standard attributes rather than remapping it internally to the GNU attribute, as that seems a cleaner approach to me. Specifically, the only form of arguments to the attribute permitted in the standard is (string-literal); empty parentheses are not permitted in the case of no arguments, and a string literal (which includes concatenated adjacent string literals, because concatenation is an earlier phase of translation) cannot have further redundant parentheses around it. For the case of empty parentheses, this patch makes the C parser disallow them for all known attributes using the [[]] syntax, as done for C++. For string literals (where the C++ front end is missing the check to avoid redundant parentheses, 92521 filed for that issue), a special case is inserted in the C parser. A known issue that I think can be addressed later as a bug fix is that the warnings for the attribute being ignored in certain cases (attribute declarations, statements, most uses on types) ought to be pedwarns, as those usages are constraint violations. Bad handling of wide string literals with this attribute is also a pre-existing bug (91182 - although that's filed as a C++ bug, the code in question is language-independent, in tree.c). Bootstrapped with no regressions on x86_64-pc-linux-gnu. gcc/c: * c-decl.c (std_attribute_table): New. (c_init_decl_processing): Register attributes from std_attribute_table. * c-parser.c (c_parser_attribute_arguments): Add arguments require_string and allow_empty_args. All callers changed. (c_parser_std_attribute): Set require_string argument for "deprecated" attribute. gcc/c-family: * c-attribs.c (handle_deprecated_attribute): Remove static. * c-common.h (handle_deprecated_attribute): Declare. gcc/testsuite: * gcc.dg/c2x-attr-deprecated-1.c, gcc.dg/c2x-attr-deprecated-2.c, gcc.dg/c2x-attr-deprecated-3.c: New tests. From-SVN: r278268
Diffstat (limited to 'gcc/c')
-rw-r--r--gcc/c/ChangeLog10
-rw-r--r--gcc/c/c-decl.c12
-rw-r--r--gcc/c/c-parser.c28
3 files changed, 46 insertions, 4 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index b881cab..fdc9153 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,13 @@
+2019-11-15 Joseph Myers <joseph@codesourcery.com>
+
+ * c-decl.c (std_attribute_table): New.
+ (c_init_decl_processing): Register attributes from
+ std_attribute_table.
+ * c-parser.c (c_parser_attribute_arguments): Add arguments
+ require_string and allow_empty_args. All callers changed.
+ (c_parser_std_attribute): Set require_string argument for
+ "deprecated" attribute.
+
2019-11-14 Joseph Myers <joseph@codesourcery.com>
* c-parser.c (c_parser_postfix_expression)
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index f809059..a7f7c69 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -4336,6 +4336,16 @@ lookup_name_fuzzy (tree name, enum lookup_name_fuzzy_kind kind, location_t loc)
}
+/* Table of supported standard (C2x) attributes. */
+const struct attribute_spec std_attribute_table[] =
+{
+ /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
+ affects_type_identity, handler, exclude } */
+ { "deprecated", 0, 1, false, false, false, false,
+ handle_deprecated_attribute, NULL },
+ { NULL, 0, 0, false, false, false, false, NULL, NULL }
+};
+
/* Create the predefined scalar types of C,
and some nodes representing standard constants (0, 1, (void *) 0).
Initialize the global scope.
@@ -4349,6 +4359,8 @@ c_init_decl_processing (void)
/* Initialize reserved words for parser. */
c_parse_init ();
+ register_scoped_attributes (std_attribute_table, NULL);
+
current_function_decl = NULL_TREE;
gcc_obstack_init (&parser_obstack);
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 8ce4e70..721158a 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -4478,7 +4478,8 @@ c_parser_gnu_attribute_any_word (c_parser *parser)
allow identifiers declared as types to start the arguments? */
static tree
-c_parser_attribute_arguments (c_parser *parser, bool takes_identifier)
+c_parser_attribute_arguments (c_parser *parser, bool takes_identifier,
+ bool require_string, bool allow_empty_args)
{
vec<tree, va_gc> *expr_list;
tree attr_args;
@@ -4518,7 +4519,21 @@ c_parser_attribute_arguments (c_parser *parser, bool takes_identifier)
else
{
if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
- attr_args = NULL_TREE;
+ {
+ if (!allow_empty_args)
+ error_at (c_parser_peek_token (parser)->location,
+ "parentheses must be omitted if "
+ "attribute argument list is empty");
+ attr_args = NULL_TREE;
+ }
+ else if (require_string)
+ {
+ /* The only valid argument for this attribute is a string
+ literal. Handle this specially here to avoid accepting
+ string literals with excess parentheses. */
+ tree string = c_parser_string_literal (parser, false, true).value;
+ attr_args = build_tree_list (NULL_TREE, string);
+ }
else
{
expr_list = c_parser_expr_list (parser, false, true,
@@ -4601,7 +4616,8 @@ c_parser_gnu_attribute (c_parser *parser, tree attrs,
tree attr_args
= c_parser_attribute_arguments (parser,
- attribute_takes_identifier_p (attr_name));
+ attribute_takes_identifier_p (attr_name),
+ false, true);
attr = build_tree_list (attr_name, attr_args);
if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
@@ -4835,8 +4851,12 @@ c_parser_std_attribute (c_parser *parser)
= (ns != NULL_TREE
&& strcmp (IDENTIFIER_POINTER (ns), "gnu") == 0
&& attribute_takes_identifier_p (name));
+ bool require_string
+ = (ns == NULL_TREE
+ && strcmp (IDENTIFIER_POINTER (name), "deprecated") == 0);
TREE_VALUE (attribute)
- = c_parser_attribute_arguments (parser, takes_identifier);
+ = c_parser_attribute_arguments (parser, takes_identifier,
+ require_string, false);
}
else
c_parser_balanced_token_sequence (parser);