When using the [[deprecated]] attribute on a class template, a diagnostic is produced even if that class template is never actually instantiated. For example, if that class template is only mentioned from another function template (which is never actually instantiated), we get a diagnostic: template <class Pred> struct [[deprecated]] unary_negate { explicit unary_negate(const Pred&); }; template <class Pred> [[deprecated]] unary_negate<Pred> not1(const Pred& p) { return unary_negate<Pred>(p); } We get: <source>:8:1: warning: 'template<class Pred> struct unary_negate' is deprecated [-Wdeprecated-declarations] 8 | unary_negate<Pred> not1(const Pred& p) { return unary_negate<Pred>(p); } | ^~~~~~~~~~~~ <source>:2:23: note: declared here 2 | struct [[deprecated]] unary_negate { | ^~~~~~~~~~~~ <source>: In function 'unary_negate<Pred> not1(const Pred&)': <source>:8:49: warning: 'template<class Pred> struct unary_negate' is deprecated [-Wdeprecated-declarations] 8 | unary_negate<Pred> not1(const Pred& p) { return unary_negate<Pred>(p); } | ^~~~~~~~~~~~ <source>:2:23: note: declared here 2 | struct [[deprecated]] unary_negate { | ^~~~~~~~~~~~ We are encountering this issue in libc++, where we do mark several things as [[deprecated]] (per the Standard), and those warnings fire off when the headers are used not as system headers. Any other non-system header library would have the same problem. Note that in comparison, Clang does not issue a warning in this case. It only issues a warning if we actually instantiate `not1` or `unary_negate`. Godbolt: https://godbolt.org/z/559EfKn9K
This is a consequence of treating attribute deprecated specially in is_late_template_attribute (it's not a late attribute).
And I think this is the same problem as in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=33911#c18. Not sure if we want to change anything.
(In reply to Marek Polacek from comment #2) > And I think this is the same problem as in > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=33911#c18. Not sure if we want > to change anything. Yup, I agree this is the same problem. However, see my recent comment on that bug report -- I think we should still fix this, and the resolution of PR33911 was IMO incomplete.
CCing Jonathan for insight on what libstdc++ is doing here with [[deprecated]].
Libstdc++ has the attribute on both of these templates. I used diagnostic pragmas to stop the function templates from warning about the use of the class templates. If other code refers to either of them, it gets a warning. But the use of unary_negate within std::not1 doesn't give a warning.
I think I've argued in another bug that it might be reasonable to not warn about uses within the same header (since that is likely to be part of the same library, and the warnings are probably intended for users of the library code, not within the library itself). But in the absence of such a rule, disabling the warnings locally using pragmas seems reasonable to me. That works for any library, not just the std::lib.