aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2024-12-18 11:52:31 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2024-12-18 11:52:31 +0100
commit49b142f2ef5d985dd6c4509d692ee4dfedfd4658 (patch)
tree48dff8bb6b4648c032d55ed33ec1da6af4a24ec8
parent35c4a383d6d8f7a9a094d364201daf0d098e4f42 (diff)
downloadgcc-49b142f2ef5d985dd6c4509d692ee4dfedfd4658.zip
gcc-49b142f2ef5d985dd6c4509d692ee4dfedfd4658.tar.gz
gcc-49b142f2ef5d985dd6c4509d692ee4dfedfd4658.tar.bz2
c++: Handle enum attributes like class attributes [PR110345]
As the following testcase shows, cp_parser_decl_specifier_seq was calling warn_misplaced_attr_for_class_type only for class types and not for enum types, while check_tag_decl calls them for both class and enum types. Enum types are really the same case here, the attribute needs to go before the type name to apply to all instances of the type. Additionally, when warn_misplaced_attr_for_class_type is called, it diagnoses something and so it is fine to drop the attributes then on the floor, but in case it wasn't a type decision, it silently discarded the attributes, which is invalid for the ignorability of standard attributes paper. This patch in that case adds them to decl_specs->std_attributes and let it be diagnosed later (e.g. in grokdeclarator). 2024-12-18 Jakub Jelinek <jakub@redhat.com> PR c++/110345 * parser.cc (cp_parser_decl_specifier_seq): Call warn_misplaced_attr_for_class_type for all OVERLOAD_TYPE_P types, not just CLASS_TYPE_P. When not calling warn_misplaced_attr_for_class_type, don't clear attrs and add it to decl_specs->std_attributes instead. * g++.dg/cpp0x/gen-attrs-85.C: New test.
-rw-r--r--gcc/cp/parser.cc12
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/gen-attrs-85.C7
2 files changed, 13 insertions, 6 deletions
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 88641c3..815901b 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -16813,13 +16813,13 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
diagnose_misapplied_contracts (attrs);
attrs = NULL_TREE;
}
- else if (decl_specs->type && CLASS_TYPE_P (decl_specs->type))
+ else if (decl_specs->type
+ && decl_specs->type_definition_p
+ && OVERLOAD_TYPE_P (decl_specs->type))
{
- /* This is an attribute following a
- class-specifier. */
- if (decl_specs->type_definition_p)
- warn_misplaced_attr_for_class_type (token->location,
- decl_specs->type);
+ /* This is an attribute following a class-specifier. */
+ warn_misplaced_attr_for_class_type (token->location,
+ decl_specs->type);
attrs = NULL_TREE;
}
else
diff --git a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-85.C b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-85.C
new file mode 100644
index 0000000..d401e19
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-85.C
@@ -0,0 +1,7 @@
+// { dg-do compile { target c++11 } }
+
+struct S {};
+struct S [[gnu::deprecated]] s; // { dg-warning "attribute ignored" }
+// { dg-message "an attribute that appertains to a type-specifier is ignored" "" { target *-*-* } .-1 }
+enum E {} [[gnu::deprecated]]; // { dg-warning "attribute ignored in declaration of 'enum E'" }
+// { dg-message "attribute for 'enum E' must follow the 'enum' keyword" "" { target *-*-* } .-1 }