On Wed, Jul 15, 2026 at 03:47:55PM +0100, Jonathan Wakely wrote:
> > --- libstdc++-v3/include/bits/c++config.jj  2026-01-02 22:41:17.624547836 
> > +0100
> > +++ libstdc++-v3/include/bits/c++config     2026-07-15 12:24:00.321648893 
> > +0200
> > @@ -927,6 +927,14 @@ namespace __gnu_cxx
> > # define _GLIBCXX_USE_BUILTIN_TRAIT(BT) 0
> > #endif
> > 
> > +#if __has_cpp_attribute(_Clang::__no_specializations__)
> > +# define _GLIBCXX_NO_SPECIALIZATIONS(T) \
> > +  [[_Clang::__no_specializations__ ("explicit or partial specialization of 
> > " \
> > +                               #T)]]
> > +#else
> > +# define _GLIBCXX_NO_SPECIALIZATIONS(T)
> > +#endif
> 
> I wonder if we should do:
> 
> #if __has_cpp_attribute(_Clang::__no_specializations__)
> # define _GLIBCXX_NO_SPECIALIZATIONS(T) \
>   [[_Clang::__no_specializations__ ("explicit or partial specialization of 
> std::" \
>                                   #T)]] T
> #else
> # define _GLIBCXX_NO_SPECIALIZATIONS(T) T
> #endif
> 
> And then we would not have to repeat the type:
> 
>   class _GLIBCXX_NO_SPECIALIZATIONS(tuple) {
> 
> But that's minor and could be changed later.

Up to you.  One thing is leaving out the std::, i.e. implying we only use
the macro on std:: namespace templates and not std::something:: etc.
And the other thing is the inclusion of T in there.  Wonder if that won't
upset doxygen or if users reading the sources won't be confused by that.

> > @@ -1942,6 +1946,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >     tuple(allocator_arg_t, _Alloc, tuple<_UTypes...>) -> tuple<_UTypes...>;
> > #endif
> > 
> > +#pragma GCC diagnostic push
> > +#pragma GCC diagnostic ignored "-Winvalid-specialization"
> 
> Does this need '#pragma clang diagnostic' as well?

Apparently not needed.
https://godbolt.org/z/WhTEcM6Yr
seems all of clang 20, 21, 22 and trunk handle it,
 template <typename T>
 struct [[clang::no_specializations]] S {};
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Winvalid-specialization"
 template <>
 struct S <int> {};
 #pragma GCC diagnostic pop
 template <>
 struct S <long> {};
error on S <long> specialization and are quiet on S <int>.
And clang 19 and older doesn't support _Clang::__no_specializations__.

If you want, perhaps the
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Winvalid-specialization"
and
#pragma GCC diagnostic pop
lines could be wrapped with
#if __has_cpp_attribute (_Clang::__no_specializations__)
...
#endif
so that older clang++ doesn't emit there -Wunknown-warning-option
warning with -Wsystem-headers.

        Jakub

Reply via email to