c: Allow duplicate C2x standard attributes

N2557, accepted into C2x at the October WG14 meeting, removes the
requirement that duplicates of standard attributes cannot appear
within an attribute list (so allowing e.g. [[deprecated, deprecated]],
where previously that was disallowed but [[deprecated]] [[deprecated]]
was OK).  Remove the code checking for this (standard attributes
aren't in any released version of the C standard) and update tests
accordingly.

Bootstrapped with no regressions on x86_64-pc-linux-gnu.

gcc/c/
2020-10-27  Joseph Myers  <joseph@codesourcery.com>

	* c-parser.c (c_parser_std_attribute_specifier): Allow duplicate
	standard attributes.

gcc/testsuite/
2020-10-27  Joseph Myers  <joseph@codesourcery.com>

	* gcc.dg/c2x-attr-deprecated-4.c, gcc.dg/c2x-attr-fallthrough-4.c,
	gcc.dg/c2x-attr-maybe_unused-4.c: Allow duplicate attributes.
This commit is contained in:
Joseph Myers 2020-10-27 22:15:46 +00:00
parent 668894d7b5
commit 75ce04fba4
4 changed files with 14 additions and 71 deletions

View File

@ -4977,9 +4977,6 @@ c_parser_std_attribute (c_parser *parser, bool for_tm)
static tree
c_parser_std_attribute_specifier (c_parser *parser, bool for_tm)
{
bool seen_deprecated = false;
bool seen_fallthrough = false;
bool seen_maybe_unused = false;
location_t loc = c_parser_peek_token (parser)->location;
if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
return NULL_TREE;
@ -5005,55 +5002,8 @@ c_parser_std_attribute_specifier (c_parser *parser, bool for_tm)
tree attribute = c_parser_std_attribute (parser, for_tm);
if (attribute != error_mark_node)
{
bool duplicate = false;
tree name = get_attribute_name (attribute);
tree ns = get_attribute_namespace (attribute);
if (ns == NULL_TREE)
{
/* Some standard attributes may appear at most once in
each attribute list. Diagnose duplicates and remove
them from the list to avoid subsequent diagnostics
such as the more general one for multiple
"fallthrough" attributes in the same place (including
in separate attribute lists in the same attribute
specifier sequence, which is not a constraint
violation). */
if (is_attribute_p ("deprecated", name))
{
if (seen_deprecated)
{
error ("attribute %<deprecated%> can appear at most "
"once in an attribute-list");
duplicate = true;
}
seen_deprecated = true;
}
else if (is_attribute_p ("fallthrough", name))
{
if (seen_fallthrough)
{
error ("attribute %<fallthrough%> can appear at most "
"once in an attribute-list");
duplicate = true;
}
seen_fallthrough = true;
}
else if (is_attribute_p ("maybe_unused", name))
{
if (seen_maybe_unused)
{
error ("attribute %<maybe_unused%> can appear at most "
"once in an attribute-list");
duplicate = true;
}
seen_maybe_unused = true;
}
}
if (!duplicate)
{
TREE_CHAIN (attribute) = attributes;
attributes = attribute;
}
TREE_CHAIN (attribute) = attributes;
attributes = attribute;
}
if (c_parser_next_token_is_not (parser, CPP_COMMA))
break;

View File

@ -1,13 +1,11 @@
/* Test C2x deprecated attribute: duplicates. */
/* Test C2x deprecated attribute: duplicates (allowed after N2557). */
/* { dg-do compile } */
/* { dg-options "-std=c2x -pedantic-errors" } */
[[deprecated, __deprecated__]] int a; /* { dg-error "can appear at most once" } */
[[__deprecated__, deprecated("message")]] int b; /* { dg-error "can appear at most once" } */
int c [[deprecated("message"), deprecated]]; /* { dg-error "can appear at most once" } */
[[deprecated, deprecated]]; /* { dg-error "can appear at most once" } */
[[deprecated, __deprecated__]] int a;
[[__deprecated__, deprecated("message")]] int b;
int c [[deprecated("message"), deprecated]];
[[deprecated, deprecated]];
/* { dg-error "ignored" "ignored" { target *-*-* } .-1 } */
/* Separate attribute lists in the same attribute specifier sequence,
with the same attribute in them, are OK. */
[[deprecated]] [[deprecated]] int d [[deprecated]] [[deprecated]];

View File

@ -1,4 +1,4 @@
/* Test C2x fallthrough attribute: duplicates. */
/* Test C2x fallthrough attribute: duplicates (allowed after N2557). */
/* { dg-do compile } */
/* { dg-options "-std=c2x -pedantic-errors" } */
@ -9,12 +9,9 @@ f (int a)
{
case 1:
a++;
[[fallthrough, __fallthrough__]]; /* { dg-error "can appear at most once" } */
[[fallthrough, __fallthrough__]]; /* { dg-warning "specified multiple times" } */
case 2:
a++;
/* Separate attribute lists in the same attribute specifier
sequence, with the same attribute in them, are OK (but
receive a warning). */
[[fallthrough]] [[fallthrough]]; /* { dg-warning "specified multiple times" } */
case 3:
a++;

View File

@ -1,13 +1,11 @@
/* Test C2x maybe_unused attribute: duplicates. */
/* Test C2x maybe_unused attribute: duplicates (allowed after N2557). */
/* { dg-do compile } */
/* { dg-options "-std=c2x -pedantic-errors" } */
[[maybe_unused, __maybe_unused__]] int a; /* { dg-error "can appear at most once" } */
[[__maybe_unused__, maybe_unused]] int b; /* { dg-error "can appear at most once" } */
int c [[maybe_unused, maybe_unused]]; /* { dg-error "can appear at most once" } */
[[maybe_unused, maybe_unused]]; /* { dg-error "can appear at most once" } */
[[maybe_unused, __maybe_unused__]] int a;
[[__maybe_unused__, maybe_unused]] int b;
int c [[maybe_unused, maybe_unused]];
[[maybe_unused, maybe_unused]];
/* { dg-error "ignored" "ignored" { target *-*-* } .-1 } */
/* Separate attribute lists in the same attribute specifier sequence,
with the same attribute in them, are OK. */
[[maybe_unused]] [[maybe_unused]] int d [[maybe_unused]] [[maybe_unused]];