https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81764
Martin Sebor <msebor at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW Known to work| |4.1.0 Keywords| |diagnostic Last reconfirmed| |2018-02-15 CC| |msebor at gcc dot gnu.org See Also| |https://gcc.gnu.org/bugzill | |a/show_bug.cgi?id=84318 Ever confirmed|0 |1 Summary|Visibility attributes for |[6/7/8 Regression] |explicitly instantiated |Visibility attributes for |template class get warned |explicitly instantiated |if it has been implicitly |template class get warned |instantiated |if it has been implicitly | |instantiated Known to fail| |4.2.2, 4.3.2, 4.6.0, 5.4.0, | |6.3.0, 7.2.0, 8.0 --- Comment #1 from Martin Sebor <msebor at gcc dot gnu.org> --- The warning might be helpful if the explicit specialization declaration attempted to specify different visibility that the primary template (assuming the declaration of the specialization inherits the attribute from the template) but it's pointless when it simply reiterates the same visibility, and it would be wrong if the specialization didn't "inherit" its attributes from the primary. With that, I would say that it's not desirable (even though it is intended in other cases). With that I confirm it as a bug. The warning wasn't issued prior to r115086 (committed into GCC 4.2) so it's also aa regression, albeit a very old one. As the test case below shows, the warning isn't unique to the visibility attribute. It affects other type attributes as well. Here too the warning is pointless regardless of how attributes are treated. Unfortunately, specifying an attribute on the declaration of an explicit instantiation isn't specified either in C++ or in G++ and it not clear that we know or have consensus what we want it to mean (see for example bug 84318), so this bug isn't likely to get a lot attention until the confusion around attributes and templates has been cleared up. $ cat t.C && gcc -S -Wall -Wextra -Wpedantic t.C template <class = void> class A; template <class> struct alignas (32) A { static int f () { return A<>::f (); } }; extern template struct alignas (32) A<>; static_assert (alignof (A<>) == 32, ""); t.C:9:37: warning: type attributes ignored after type is already defined [-Wattributes] extern template struct alignas (32) A<>; ^~~