aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/parser.c
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2020-11-06 12:33:53 -0500
committerMarek Polacek <polacek@redhat.com>2020-11-09 18:22:58 -0500
commit04126e46eb2d829d7b4149d394b667e878912cc8 (patch)
treed335d40d1f5e99dad16532ef1f34e6099465ff31 /gcc/cp/parser.c
parentd3fd75d869480044213553000d2c9dc236a4f7af (diff)
downloadgcc-04126e46eb2d829d7b4149d394b667e878912cc8.zip
gcc-04126e46eb2d829d7b4149d394b667e878912cc8.tar.gz
gcc-04126e46eb2d829d7b4149d394b667e878912cc8.tar.bz2
c++: DR 1914 - Allow duplicate standard attributes.
Following Joseph's change for C to allow duplicate C2x standard attributes <https://gcc.gnu.org/pipermail/gcc-patches/2020-October/557272.html>, this patch does a similar thing for C++. This is DR 1914, to be resolved by <wg21.link/p2156>, which is not part of the standard yet, but has wide support so looks like a shoo-in. The duplications now produce warnings instead, but only if the attribute wasn't specified via a macro. gcc/c-family/ChangeLog: DR 1914 * c-common.c (attribute_fallthrough_p): Tweak the warning message. gcc/cp/ChangeLog: DR 1914 * parser.c (cp_parser_check_std_attribute): Return bool. Add a location_t parameter. Return true if the attribute wasn't duplicated. Give a warning instead of an error. Check more attributes. (cp_parser_std_attribute_list): Don't add duplicated attributes to the list. Pass location to cp_parser_check_std_attribute. gcc/testsuite/ChangeLog: DR 1914 * c-c++-common/attr-fallthrough-2.c: Adjust dg-warning. * g++.dg/cpp0x/fallthrough2.C: Likewise. * g++.dg/cpp0x/gen-attrs-60.C: Turn dg-error into dg-warning. * g++.dg/cpp1y/attr-deprecated-2.C: Likewise. * g++.dg/cpp2a/attr-likely2.C: Adjust dg-warning. * g++.dg/cpp2a/nodiscard-once.C: Turn dg-error into dg-warning. * g++.dg/cpp0x/gen-attrs-72.C: New test.
Diffstat (limited to 'gcc/cp/parser.c')
-rw-r--r--gcc/cp/parser.c51
1 files changed, 27 insertions, 24 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index b14b4c9..4c819ea 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -27280,30 +27280,30 @@ cp_parser_std_attribute (cp_parser *parser, tree attr_ns)
return attribute;
}
-/* Check that the attribute ATTRIBUTE appears at most once in the
- attribute-list ATTRIBUTES. This is enforced for noreturn (7.6.3),
- nodiscard, and deprecated (7.6.5). Note that
- carries_dependency (7.6.4) isn't implemented yet in GCC. */
+/* Warn if the attribute ATTRIBUTE appears more than once in the
+ attribute-list ATTRIBUTES. This used to be enforced for certain
+ attributes, but the restriction was removed in P2156. Note that
+ carries_dependency ([dcl.attr.depend]) isn't implemented yet in GCC.
+ LOC is the location of ATTRIBUTE. Returns true if ATTRIBUTE was not
+ found in ATTRIBUTES. */
-static void
-cp_parser_check_std_attribute (tree attributes, tree attribute)
+static bool
+cp_parser_check_std_attribute (location_t loc, tree attributes, tree attribute)
{
+ static auto alist = { "noreturn", "deprecated", "nodiscard", "maybe_unused",
+ "likely", "unlikely", "fallthrough",
+ "no_unique_address" };
if (attributes)
- {
- tree name = get_attribute_name (attribute);
- if (is_attribute_p ("noreturn", name)
- && lookup_attribute ("noreturn", attributes))
- error ("attribute %<noreturn%> can appear at most once "
- "in an attribute-list");
- else if (is_attribute_p ("deprecated", name)
- && lookup_attribute ("deprecated", attributes))
- error ("attribute %<deprecated%> can appear at most once "
- "in an attribute-list");
- else if (is_attribute_p ("nodiscard", name)
- && lookup_attribute ("nodiscard", attributes))
- error ("attribute %<nodiscard%> can appear at most once "
- "in an attribute-list");
- }
+ for (const auto &a : alist)
+ if (is_attribute_p (a, get_attribute_name (attribute))
+ && lookup_attribute (a, attributes))
+ {
+ if (!from_macro_expansion_at (loc))
+ warning_at (loc, OPT_Wattributes, "attribute %qs specified "
+ "multiple times", a);
+ return false;
+ }
+ return true;
}
/* Parse a list of standard C++-11 attributes.
@@ -27323,14 +27323,17 @@ cp_parser_std_attribute_list (cp_parser *parser, tree attr_ns)
while (true)
{
+ location_t loc = cp_lexer_peek_token (parser->lexer)->location;
attribute = cp_parser_std_attribute (parser, attr_ns);
if (attribute == error_mark_node)
break;
if (attribute != NULL_TREE)
{
- cp_parser_check_std_attribute (attributes, attribute);
- TREE_CHAIN (attribute) = attributes;
- attributes = attribute;
+ if (cp_parser_check_std_attribute (loc, attributes, attribute))
+ {
+ TREE_CHAIN (attribute) = attributes;
+ attributes = attribute;
+ }
}
token = cp_lexer_peek_token (parser->lexer);
if (token->type == CPP_ELLIPSIS)