On 02/14/2012 08:50 PM, Jason Merrill wrote:
While looking at PR 51930, I discovered that we were silently ignoring attributes on explicit instantiations; this patch warns about this. This isn't exactly a regression, but the submitter ran into it as a result of a behavior change in 4.7, and the patch is extremely safe, so I think it should go in.
It turns out that we already had a warning for this situation that also gives a suggestion for how to deal with it, so I'm going to make that warning apply to this case as well.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit fc93bb109ba5d22a5c08ee026d572436a999bdef Author: Jason Merrill <ja...@redhat.com> Date: Wed Feb 29 21:51:33 2012 -0500 PR c++/51930 * decl.c (check_tag_decl): Move warning for misplaced attributes here. (shadow_tag): From here. * parser.c (cp_parser_explicit_instantiation): Don't warn here. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 2a6a516..c47f87c 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -4216,6 +4216,19 @@ check_tag_decl (cp_decl_specifier_seq *declspecs) error ("%<constexpr%> cannot be used for type declarations"); } + if (declspecs->attributes) + { + location_t loc = input_location; + if (!CLASSTYPE_TEMPLATE_INSTANTIATION (declared_type)) + /* For a non-template class, use the name location; for a template + class (an explicit instantiation), use the current location. */ + input_location = location_of (declared_type); + warning (0, "attribute ignored in declaration of %q#T", declared_type); + warning (0, "attribute for %q#T must follow the %qs keyword", + declared_type, class_key_or_enum_as_string (declared_type)); + input_location = loc; + } + return declared_type; } @@ -4240,14 +4253,6 @@ shadow_tag (cp_decl_specifier_seq *declspecs) if (!t) return NULL_TREE; - if (declspecs->attributes) - { - warning (0, "attribute ignored in declaration of %q+#T", t); - warning (0, "attribute for %q+#T must follow the %qs keyword", - t, class_key_or_enum_as_string (t)); - - } - if (maybe_process_partial_specialization (t) == error_mark_node) return NULL_TREE; diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 3e2be97..491f48e 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -13122,9 +13122,6 @@ cp_parser_explicit_instantiation (cp_parser* parser) tree type; type = check_tag_decl (&decl_specifiers); - if (decl_specifiers.attributes) - warning (OPT_Wattributes, - "attributes ignored on explicit type instantiation"); /* Turn access control back on for names used during template instantiation. */ pop_deferring_access_checks (); diff --git a/gcc/testsuite/g++.dg/ext/attrib43.C b/gcc/testsuite/g++.dg/ext/attrib43.C index fe9f072..acae3f2 100644 --- a/gcc/testsuite/g++.dg/ext/attrib43.C +++ b/gcc/testsuite/g++.dg/ext/attrib43.C @@ -2,4 +2,4 @@ template <class T> struct A { }; template __attribute__ ((packed)) -struct A<int>; // { dg-warning "attributes ignored" } +struct A<int>; // { dg-warning "attribute" }