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