aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/c/ChangeLog5
-rw-r--r--gcc/c/c-parser.c54
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/c2x-attr-deprecated-4.c13
-rw-r--r--gcc/testsuite/gcc.dg/c2x-attr-fallthrough-4.c23
-rw-r--r--gcc/testsuite/gcc.dg/c2x-attr-maybe_unused-4.c13
6 files changed, 111 insertions, 2 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index 75a44e2..0076e83 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,5 +1,10 @@
2019-11-15 Joseph Myers <joseph@codesourcery.com>
+ * c-parser.c (c_parser_std_attribute_specifier): Diagnose
+ duplicate standard attributes.
+
+2019-11-15 Joseph Myers <joseph@codesourcery.com>
+
* c-decl.c (std_attribute_table): Add maybe_unused.
2019-11-15 Joseph Myers <joseph@codesourcery.com>
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 5b290bf..e48760d 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -4873,6 +4873,9 @@ c_parser_std_attribute (c_parser *parser)
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;
@@ -4898,8 +4901,55 @@ c_parser_std_attribute_specifier (c_parser *parser, bool for_tm)
tree attribute = c_parser_std_attribute (parser);
if (attribute != error_mark_node)
{
- TREE_CHAIN (attribute) = attributes;
- attributes = attribute;
+ 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;
+ }
}
if (c_parser_next_token_is_not (parser, CPP_COMMA))
break;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 997096c..4376337 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2019-11-15 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: New tests.
+
2019-11-15 Paolo Carlini <paolo.carlini@oracle.com>
* g++.dg/warn/Walways-true-1.C: Check locations too.
diff --git a/gcc/testsuite/gcc.dg/c2x-attr-deprecated-4.c b/gcc/testsuite/gcc.dg/c2x-attr-deprecated-4.c
new file mode 100644
index 0000000..ce6615b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-attr-deprecated-4.c
@@ -0,0 +1,13 @@
+/* Test C2x deprecated attribute: duplicates. */
+/* { 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" } */
+/* { dg-warning "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]];
diff --git a/gcc/testsuite/gcc.dg/c2x-attr-fallthrough-4.c b/gcc/testsuite/gcc.dg/c2x-attr-fallthrough-4.c
new file mode 100644
index 0000000..75aceff
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-attr-fallthrough-4.c
@@ -0,0 +1,23 @@
+/* Test C2x fallthrough attribute: duplicates. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+int
+f (int a)
+{
+ switch (a)
+ {
+ case 1:
+ a++;
+ [[fallthrough, __fallthrough__]]; /* { dg-error "can appear at most once" } */
+ 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++;
+ }
+ return a;
+}
diff --git a/gcc/testsuite/gcc.dg/c2x-attr-maybe_unused-4.c b/gcc/testsuite/gcc.dg/c2x-attr-maybe_unused-4.c
new file mode 100644
index 0000000..ae7e1dc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-attr-maybe_unused-4.c
@@ -0,0 +1,13 @@
+/* Test C2x maybe_unused attribute: duplicates. */
+/* { 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" } */
+/* { dg-warning "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]];