diff options
author | Joseph Myers <joseph@codesourcery.com> | 2019-11-19 00:21:49 +0000 |
---|---|---|
committer | Joseph Myers <jsm28@gcc.gnu.org> | 2019-11-19 00:21:49 +0000 |
commit | 192961ff27503085946caaa92b2f57d291258858 (patch) | |
tree | eb264d8a06f3087a5902e4ba372c16cc11ed24e6 /gcc/c/c-parser.c | |
parent | 95d4434f4777bda919474a06c4b071d3a5d4080e (diff) | |
download | gcc-192961ff27503085946caaa92b2f57d291258858.zip gcc-192961ff27503085946caaa92b2f57d291258858.tar.gz gcc-192961ff27503085946caaa92b2f57d291258858.tar.bz2 |
Change some bad uses of C2x attributes into pedwarns.
Certain bad uses of C2x standard attributes (that is, attributes
inside [[]] with only a name but no namespace specified) are
constraint violations, and so should be diagnosed with a pedwarn (or
error) where GCC currently uses a warning. This patch implements this
in some cases (not yet for attributes used on types, nor for some bad
uses of fallthrough attributes). Specifically, this applies to
unknown standard attributes (taking care not to pedwarn for nodiscard,
which is known but not implemented for C), and to all currently
implemented standard attributes in attribute declarations (including
when mixed with fallthrough) and on statements.
Bootstrapped with no regressions on x86_64-pc-linux-gnu.
gcc/c:
* c-decl.c (c_warn_unused_attributes): Use pedwarn not warning for
standard attributes.
* c-parser.c (c_parser_std_attribute): Take argument for_tm. Use
pedwarn for unknown standard attributes and return error_mark_node
for them.
gcc/c-family:
* c-common.c (attribute_fallthrough_p): In C, use pedwarn not
warning for standard attributes mixed with fallthrough attributes.
gcc/testsuite:
* gcc.dg/c2x-attr-fallthrough-5.c, gcc.dg/c2x-attr-syntax-5.c: New
tests.
* gcc.dg/c2x-attr-deprecated-2.c, gcc.dg/c2x-attr-deprecated-4.c,
gcc.dg/c2x-attr-fallthrough-2.c, gcc.dg/c2x-attr-maybe_unused-2.c,
gcc.dg/c2x-attr-maybe_unused-4.c: Expect errors in place of some
warnings.
From-SVN: r278428
Diffstat (limited to 'gcc/c/c-parser.c')
-rw-r--r-- | gcc/c/c-parser.c | 78 |
1 files changed, 46 insertions, 32 deletions
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 2efa234..03194b4 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -4803,7 +4803,7 @@ c_parser_balanced_token_sequence (c_parser *parser) */ static tree -c_parser_std_attribute (c_parser *parser) +c_parser_std_attribute (c_parser *parser, bool for_tm) { c_token *token = c_parser_peek_token (parser); tree ns, name, attribute; @@ -4834,39 +4834,53 @@ c_parser_std_attribute (c_parser *parser) attribute = build_tree_list (build_tree_list (ns, name), NULL_TREE); /* Parse the arguments, if any. */ - if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN)) - return attribute; - location_t open_loc = c_parser_peek_token (parser)->location; - matching_parens parens; - parens.consume_open (parser); const attribute_spec *as = lookup_attribute_spec (TREE_PURPOSE (attribute)); - if ((as && as->max_length == 0) - /* Special-case the transactional-memory attribute "outer", - which is specially handled but not registered as an - attribute, to avoid allowing arbitrary balanced token - sequences as arguments. */ - || is_attribute_p ("outer", name)) - { - error_at (open_loc, "%qE attribute does not take any arguments", name); - parens.skip_until_found_close (parser); + if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN)) + goto out; + { + location_t open_loc = c_parser_peek_token (parser)->location; + matching_parens parens; + parens.consume_open (parser); + if ((as && as->max_length == 0) + /* Special-case the transactional-memory attribute "outer", + which is specially handled but not registered as an + attribute, to avoid allowing arbitrary balanced token + sequences as arguments. */ + || is_attribute_p ("outer", name)) + { + error_at (open_loc, "%qE attribute does not take any arguments", name); + parens.skip_until_found_close (parser); + return error_mark_node; + } + if (as) + { + bool takes_identifier + = (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, + require_string, false); + } + else + c_parser_balanced_token_sequence (parser); + parens.require_close (parser); + } + out: + if (ns == NULL_TREE && !for_tm && !as && !is_attribute_p ("nodiscard", name)) + { + /* An attribute with standard syntax and no namespace specified + is a constraint violation if it is not one of the known + standard attributes (of which nodiscard is the only one + without a handler in GCC). Diagnose it here with a pedwarn + and then discard it to prevent a duplicate warning later. */ + pedwarn (input_location, OPT_Wattributes, "%qE attribute ignored", + name); return error_mark_node; } - if (as) - { - bool takes_identifier - = (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, - require_string, false); - } - else - c_parser_balanced_token_sequence (parser); - parens.require_close (parser); return attribute; } @@ -4898,7 +4912,7 @@ c_parser_std_attribute_specifier (c_parser *parser, bool for_tm) c_parser_consume_token (parser); continue; } - tree attribute = c_parser_std_attribute (parser); + tree attribute = c_parser_std_attribute (parser, for_tm); if (attribute != error_mark_node) { bool duplicate = false; |