[libcxx-commits] [libcxx] [libc++] Use [[clang::no_specializations]] to diagnose invalid user specializations (PR #118167)

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Sat Nov 30 03:10:02 PST 2024


https://github.com/philnik777 created https://github.com/llvm/llvm-project/pull/118167

None

>From 427a291ddd1ee162b856d7b23842c24d35b6796f Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Thu, 1 Aug 2024 23:09:15 +0200
Subject: [PATCH] [libc++] Use [[clang::no_specializations]] to diagnose
 invalid user specializations

---
 .../__compare/compare_three_way_result.h      |   3 +-
 libcxx/include/__config                       |   6 +
 .../include/__cxx03/__type_traits/add_const.h |   2 +-
 libcxx/include/__cxx03/__type_traits/add_cv.h |   2 +-
 .../__cxx03/__type_traits/add_volatile.h      |   2 +-
 libcxx/include/__format/format_arg.h          |   2 +-
 libcxx/include/__ranges/range_adaptor.h       |   2 +-
 libcxx/include/__type_traits/add_cv_quals.h   |   6 +-
 .../__type_traits/add_lvalue_reference.h      |   2 +-
 libcxx/include/__type_traits/add_pointer.h    |   2 +-
 .../__type_traits/add_rvalue_reference.h      |   2 +-
 .../include/__type_traits/aligned_storage.h   |   2 +-
 libcxx/include/__type_traits/aligned_union.h  |   2 +-
 libcxx/include/__type_traits/alignment_of.h   |   5 +-
 libcxx/include/__type_traits/conjunction.h    |   2 +-
 libcxx/include/__type_traits/decay.h          |   2 +-
 libcxx/include/__type_traits/disjunction.h    |   4 +-
 libcxx/include/__type_traits/extent.h         |   5 +-
 .../has_unique_object_representation.h        |   5 +-
 .../__type_traits/has_virtual_destructor.h    |   5 +-
 .../include/__type_traits/integral_constant.h |   2 +-
 libcxx/include/__type_traits/invoke.h         |  24 ++-
 libcxx/include/__type_traits/is_abstract.h    |   5 +-
 libcxx/include/__type_traits/is_aggregate.h   |   5 +-
 libcxx/include/__type_traits/is_arithmetic.h  |   4 +-
 libcxx/include/__type_traits/is_array.h       |   4 +-
 libcxx/include/__type_traits/is_assignable.h  |  13 +-
 libcxx/include/__type_traits/is_base_of.h     |  11 +-
 libcxx/include/__type_traits/is_class.h       |   5 +-
 libcxx/include/__type_traits/is_compound.h    |   4 +-
 libcxx/include/__type_traits/is_const.h       |   4 +-
 .../include/__type_traits/is_constructible.h  |  18 +-
 libcxx/include/__type_traits/is_convertible.h |   5 +-
 .../include/__type_traits/is_destructible.h   |   4 +-
 libcxx/include/__type_traits/is_empty.h       |   5 +-
 libcxx/include/__type_traits/is_enum.h        |   9 +-
 libcxx/include/__type_traits/is_final.h       |   5 +-
 .../include/__type_traits/is_floating_point.h |   5 +-
 libcxx/include/__type_traits/is_function.h    |   5 +-
 libcxx/include/__type_traits/is_fundamental.h |   4 +-
 .../__type_traits/is_implicit_lifetime.h      |   5 +-
 libcxx/include/__type_traits/is_integral.h    |   4 +-
 .../include/__type_traits/is_literal_type.h   |   7 +-
 .../include/__type_traits/is_member_pointer.h |  15 +-
 .../__type_traits/is_nothrow_assignable.h     |  16 +-
 .../__type_traits/is_nothrow_constructible.h  |  20 +-
 .../__type_traits/is_nothrow_convertible.h    |   4 +-
 .../__type_traits/is_nothrow_destructible.h   |   5 +-
 .../include/__type_traits/is_null_pointer.h   |   5 +-
 libcxx/include/__type_traits/is_object.h      |   4 +-
 libcxx/include/__type_traits/is_pod.h         |   4 +-
 libcxx/include/__type_traits/is_pointer.h     |   4 +-
 libcxx/include/__type_traits/is_polymorphic.h |   5 +-
 libcxx/include/__type_traits/is_reference.h   |  14 +-
 libcxx/include/__type_traits/is_same.h        |   4 +-
 libcxx/include/__type_traits/is_scalar.h      |   4 +-
 libcxx/include/__type_traits/is_signed.h      |   4 +-
 .../__type_traits/is_standard_layout.h        |   5 +-
 libcxx/include/__type_traits/is_swappable.h   |  20 +-
 libcxx/include/__type_traits/is_trivial.h     |   5 +-
 .../__type_traits/is_trivially_assignable.h   |  15 +-
 .../is_trivially_constructible.h              |  20 +-
 .../__type_traits/is_trivially_copyable.h     |   5 +-
 .../__type_traits/is_trivially_destructible.h |   5 +-
 libcxx/include/__type_traits/is_union.h       |   5 +-
 libcxx/include/__type_traits/is_unsigned.h    |   4 +-
 libcxx/include/__type_traits/is_void.h        |   5 +-
 libcxx/include/__type_traits/is_volatile.h    |   4 +-
 libcxx/include/__type_traits/make_signed.h    |   2 +-
 libcxx/include/__type_traits/make_unsigned.h  |   2 +-
 libcxx/include/__type_traits/negation.h       |   4 +-
 .../__type_traits/remove_all_extents.h        |   2 +-
 libcxx/include/__type_traits/remove_const.h   |   2 +-
 libcxx/include/__type_traits/remove_cv.h      |   2 +-
 libcxx/include/__type_traits/remove_cvref.h   |   2 +-
 libcxx/include/__type_traits/remove_extent.h  |   2 +-
 libcxx/include/__type_traits/remove_pointer.h |   2 +-
 .../include/__type_traits/remove_reference.h  |   2 +-
 .../include/__type_traits/remove_volatile.h   |   2 +-
 libcxx/include/__type_traits/type_identity.h  |   2 +-
 .../include/__type_traits/underlying_type.h   |   2 +-
 libcxx/include/__type_traits/unwrap_ref.h     |   4 +-
 libcxx/include/variant                        |   2 +-
 .../algorithms/no_specializations.verify.cpp  |  19 ++
 .../no_specializations.verify.cpp             |  19 ++
 .../ranges/no_specializations.verify.cpp      |  19 ++
 .../type_traits/no_specializations.verify.cpp | 172 ++++++++++++++++++
 .../format/no_specializations.verify.cpp      |  19 ++
 .../utilities/no_specializations.verify.cpp   |  19 ++
 89 files changed, 526 insertions(+), 196 deletions(-)
 create mode 100644 libcxx/test/libcxx/algorithms/no_specializations.verify.cpp
 create mode 100644 libcxx/test/libcxx/language.support/no_specializations.verify.cpp
 create mode 100644 libcxx/test/libcxx/ranges/no_specializations.verify.cpp
 create mode 100644 libcxx/test/libcxx/type_traits/no_specializations.verify.cpp
 create mode 100644 libcxx/test/libcxx/utilities/format/no_specializations.verify.cpp
 create mode 100644 libcxx/test/libcxx/utilities/no_specializations.verify.cpp

diff --git a/libcxx/include/__compare/compare_three_way_result.h b/libcxx/include/__compare/compare_three_way_result.h
index d7508073433af4..6ee2eff00302d0 100644
--- a/libcxx/include/__compare/compare_three_way_result.h
+++ b/libcxx/include/__compare/compare_three_way_result.h
@@ -33,7 +33,8 @@ struct _LIBCPP_HIDE_FROM_ABI __compare_three_way_result<
 };
 
 template <class _Tp, class _Up = _Tp>
-struct _LIBCPP_TEMPLATE_VIS compare_three_way_result : __compare_three_way_result<_Tp, _Up, void> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS compare_three_way_result
+    : __compare_three_way_result<_Tp, _Up, void> {};
 
 template <class _Tp, class _Up = _Tp>
 using compare_three_way_result_t = typename compare_three_way_result<_Tp, _Up>::type;
diff --git a/libcxx/include/__config b/libcxx/include/__config
index fe01b58b8e6274..da0b9038a6dafe 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -1176,6 +1176,12 @@ typedef __char32_t char32_t;
 #    define _LIBCPP_NODEBUG
 #  endif
 
+#  if __has_cpp_attribute(_Clang::__no_specializations__)
+#    define _LIBCPP_NO_SPECIALIZATIONS [[_Clang::__no_specializations__]]
+#  else
+#    define _LIBCPP_NO_SPECIALIZATIONS
+#  endif
+
 #  if __has_attribute(__standalone_debug__)
 #    define _LIBCPP_STANDALONE_DEBUG __attribute__((__standalone_debug__))
 #  else
diff --git a/libcxx/include/__cxx03/__type_traits/add_const.h b/libcxx/include/__cxx03/__type_traits/add_const.h
index ce670824873ee2..afaebf16f0f378 100644
--- a/libcxx/include/__cxx03/__type_traits/add_const.h
+++ b/libcxx/include/__cxx03/__type_traits/add_const.h
@@ -18,7 +18,7 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS add_const {
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DIAGNOSE_SPECIALIZATIONS add_const {
   typedef _LIBCPP_NODEBUG const _Tp type;
 };
 
diff --git a/libcxx/include/__cxx03/__type_traits/add_cv.h b/libcxx/include/__cxx03/__type_traits/add_cv.h
index 43eb05fa40487f..5612c551788fa3 100644
--- a/libcxx/include/__cxx03/__type_traits/add_cv.h
+++ b/libcxx/include/__cxx03/__type_traits/add_cv.h
@@ -18,7 +18,7 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS add_cv {
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DIAGNOSE_SPECIALIZATIONS add_cv {
   typedef _LIBCPP_NODEBUG const volatile _Tp type;
 };
 
diff --git a/libcxx/include/__cxx03/__type_traits/add_volatile.h b/libcxx/include/__cxx03/__type_traits/add_volatile.h
index 35ff8d7435c6d9..221d415eb4c13a 100644
--- a/libcxx/include/__cxx03/__type_traits/add_volatile.h
+++ b/libcxx/include/__cxx03/__type_traits/add_volatile.h
@@ -18,7 +18,7 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS add_volatile {
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DIAGNOSE_SPECIALIZATIONS add_volatile {
   typedef _LIBCPP_NODEBUG volatile _Tp type;
 };
 
diff --git a/libcxx/include/__format/format_arg.h b/libcxx/include/__format/format_arg.h
index a973ccd43c4207..06922bce5a1b4b 100644
--- a/libcxx/include/__format/format_arg.h
+++ b/libcxx/include/__format/format_arg.h
@@ -277,7 +277,7 @@ class __basic_format_arg_value {
 };
 
 template <class _Context>
-class _LIBCPP_TEMPLATE_VIS basic_format_arg {
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS basic_format_arg {
 public:
   class _LIBCPP_TEMPLATE_VIS handle;
 
diff --git a/libcxx/include/__ranges/range_adaptor.h b/libcxx/include/__ranges/range_adaptor.h
index d944a83406ba7f..4bcb53e1a58465 100644
--- a/libcxx/include/__ranges/range_adaptor.h
+++ b/libcxx/include/__ranges/range_adaptor.h
@@ -85,7 +85,7 @@ template <_RangeAdaptorClosure _Closure, _RangeAdaptorClosure _OtherClosure>
 #  if _LIBCPP_STD_VER >= 23
 template <class _Tp>
   requires is_class_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
-class range_adaptor_closure : public __range_adaptor_closure<_Tp> {};
+class _LIBCPP_NO_SPECIALIZATIONS range_adaptor_closure : public __range_adaptor_closure<_Tp> {};
 #  endif // _LIBCPP_STD_VER >= 23
 
 } // namespace ranges
diff --git a/libcxx/include/__type_traits/add_cv_quals.h b/libcxx/include/__type_traits/add_cv_quals.h
index 1d35b89f42c2d1..d4525457d72754 100644
--- a/libcxx/include/__type_traits/add_cv_quals.h
+++ b/libcxx/include/__type_traits/add_cv_quals.h
@@ -18,7 +18,7 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS add_const {
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS add_const {
   typedef _LIBCPP_NODEBUG const _Tp type;
 };
 
@@ -28,7 +28,7 @@ using add_const_t = typename add_const<_Tp>::type;
 #endif
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS add_cv {
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS add_cv {
   typedef _LIBCPP_NODEBUG const volatile _Tp type;
 };
 
@@ -38,7 +38,7 @@ using add_cv_t = typename add_cv<_Tp>::type;
 #endif
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS add_volatile {
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS add_volatile {
   typedef _LIBCPP_NODEBUG volatile _Tp type;
 };
 
diff --git a/libcxx/include/__type_traits/add_lvalue_reference.h b/libcxx/include/__type_traits/add_lvalue_reference.h
index a633e390453205..fa3e830aff18c8 100644
--- a/libcxx/include/__type_traits/add_lvalue_reference.h
+++ b/libcxx/include/__type_traits/add_lvalue_reference.h
@@ -40,7 +40,7 @@ using __add_lvalue_reference_t = typename __add_lvalue_reference_impl<_Tp>::type
 #endif // __has_builtin(__add_lvalue_reference)
 
 template <class _Tp>
-struct add_lvalue_reference {
+struct _LIBCPP_NO_SPECIALIZATIONS add_lvalue_reference {
   using type _LIBCPP_NODEBUG = __add_lvalue_reference_t<_Tp>;
 };
 
diff --git a/libcxx/include/__type_traits/add_pointer.h b/libcxx/include/__type_traits/add_pointer.h
index 5aac7d5cfa90d8..bb5dd212ea00aa 100644
--- a/libcxx/include/__type_traits/add_pointer.h
+++ b/libcxx/include/__type_traits/add_pointer.h
@@ -41,7 +41,7 @@ using __add_pointer_t = typename __add_pointer_impl<_Tp>::type;
 #endif // !defined(_LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS) && __has_builtin(__add_pointer)
 
 template <class _Tp>
-struct add_pointer {
+struct _LIBCPP_NO_SPECIALIZATIONS add_pointer {
   using type _LIBCPP_NODEBUG = __add_pointer_t<_Tp>;
 };
 
diff --git a/libcxx/include/__type_traits/add_rvalue_reference.h b/libcxx/include/__type_traits/add_rvalue_reference.h
index a54aae7ec8de5d..39121d70bc5d8b 100644
--- a/libcxx/include/__type_traits/add_rvalue_reference.h
+++ b/libcxx/include/__type_traits/add_rvalue_reference.h
@@ -40,7 +40,7 @@ using __add_rvalue_reference_t = typename __add_rvalue_reference_impl<_Tp>::type
 #endif // __has_builtin(__add_rvalue_reference)
 
 template <class _Tp>
-struct add_rvalue_reference {
+struct _LIBCPP_NO_SPECIALIZATIONS add_rvalue_reference {
   using type = __add_rvalue_reference_t<_Tp>;
 };
 
diff --git a/libcxx/include/__type_traits/aligned_storage.h b/libcxx/include/__type_traits/aligned_storage.h
index 2e39afb7f88088..ecc65c76cdb603 100644
--- a/libcxx/include/__type_traits/aligned_storage.h
+++ b/libcxx/include/__type_traits/aligned_storage.h
@@ -70,7 +70,7 @@ struct __find_max_align<__type_list<_Hp, _Tp>, _Len>
     : public integral_constant<size_t, __select_align<_Len, _Hp::value, __find_max_align<_Tp, _Len>::value>::value> {};
 
 template <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::value>
-struct _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_TEMPLATE_VIS aligned_storage {
+struct _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS aligned_storage {
   union _ALIGNAS(_Align) type {
     unsigned char __data[(_Len + _Align - 1) / _Align * _Align];
   };
diff --git a/libcxx/include/__type_traits/aligned_union.h b/libcxx/include/__type_traits/aligned_union.h
index de62a4b1c2a331..dd88d54f5979b3 100644
--- a/libcxx/include/__type_traits/aligned_union.h
+++ b/libcxx/include/__type_traits/aligned_union.h
@@ -34,7 +34,7 @@ struct __static_max<_I0, _I1, _In...> {
 };
 
 template <size_t _Len, class _Type0, class... _Types>
-struct _LIBCPP_DEPRECATED_IN_CXX23 aligned_union {
+struct _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_NO_SPECIALIZATIONS aligned_union {
   static const size_t alignment_value =
       __static_max<_LIBCPP_PREFERRED_ALIGNOF(_Type0), _LIBCPP_PREFERRED_ALIGNOF(_Types)...>::value;
   static const size_t __len = __static_max<_Len, sizeof(_Type0), sizeof(_Types)...>::value;
diff --git a/libcxx/include/__type_traits/alignment_of.h b/libcxx/include/__type_traits/alignment_of.h
index 8871c8ce110d67..9801cac2cadd26 100644
--- a/libcxx/include/__type_traits/alignment_of.h
+++ b/libcxx/include/__type_traits/alignment_of.h
@@ -20,11 +20,12 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS alignment_of : public integral_constant<size_t, _LIBCPP_ALIGNOF(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS alignment_of
+    : public integral_constant<size_t, _LIBCPP_ALIGNOF(_Tp)> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr size_t alignment_of_v = _LIBCPP_ALIGNOF(_Tp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr size_t alignment_of_v = _LIBCPP_ALIGNOF(_Tp);
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/conjunction.h b/libcxx/include/__type_traits/conjunction.h
index c2995591bbc28f..e18ae46b01aee9 100644
--- a/libcxx/include/__type_traits/conjunction.h
+++ b/libcxx/include/__type_traits/conjunction.h
@@ -56,7 +56,7 @@ template <class _Arg, class... _Args>
 struct conjunction<_Arg, _Args...> : conditional_t<!bool(_Arg::value), _Arg, conjunction<_Args...>> {};
 
 template <class... _Args>
-inline constexpr bool conjunction_v = conjunction<_Args...>::value;
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool conjunction_v = conjunction<_Args...>::value;
 
 #endif // _LIBCPP_STD_VER >= 17
 
diff --git a/libcxx/include/__type_traits/decay.h b/libcxx/include/__type_traits/decay.h
index 7412044f931796..aa6bd459853a08 100644
--- a/libcxx/include/__type_traits/decay.h
+++ b/libcxx/include/__type_traits/decay.h
@@ -30,7 +30,7 @@ template <class _Tp>
 using __decay_t _LIBCPP_NODEBUG = __decay(_Tp);
 
 template <class _Tp>
-struct decay {
+struct _LIBCPP_NO_SPECIALIZATIONS decay {
   using type _LIBCPP_NODEBUG = __decay_t<_Tp>;
 };
 
diff --git a/libcxx/include/__type_traits/disjunction.h b/libcxx/include/__type_traits/disjunction.h
index 2c89528d9f2fc0..9d26d8d752faa3 100644
--- a/libcxx/include/__type_traits/disjunction.h
+++ b/libcxx/include/__type_traits/disjunction.h
@@ -46,10 +46,10 @@ using _Or _LIBCPP_NODEBUG = typename _OrImpl<sizeof...(_Args) != 0>::template _R
 #if _LIBCPP_STD_VER >= 17
 
 template <class... _Args>
-struct disjunction : _Or<_Args...> {};
+struct _LIBCPP_NO_SPECIALIZATIONS disjunction : _Or<_Args...> {};
 
 template <class... _Args>
-inline constexpr bool disjunction_v = _Or<_Args...>::value;
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool disjunction_v = _Or<_Args...>::value;
 
 #endif // _LIBCPP_STD_VER >= 17
 
diff --git a/libcxx/include/__type_traits/extent.h b/libcxx/include/__type_traits/extent.h
index 1c34a4db1c4b52..77e59193d3fc63 100644
--- a/libcxx/include/__type_traits/extent.h
+++ b/libcxx/include/__type_traits/extent.h
@@ -22,11 +22,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 #if __has_builtin(__array_extent)
 
 template <class _Tp, size_t _Dim = 0>
-struct _LIBCPP_TEMPLATE_VIS extent : integral_constant<size_t, __array_extent(_Tp, _Dim)> {};
+struct _LIBCPP_NO_SPECIALIZATIONS _LIBCPP_TEMPLATE_VIS extent
+    : integral_constant<size_t, __array_extent(_Tp, _Dim)> {};
 
 #  if _LIBCPP_STD_VER >= 17
 template <class _Tp, unsigned _Ip = 0>
-inline constexpr size_t extent_v = __array_extent(_Tp, _Ip);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr size_t extent_v = __array_extent(_Tp, _Ip);
 #  endif
 
 #else // __has_builtin(__array_extent)
diff --git a/libcxx/include/__type_traits/has_unique_object_representation.h b/libcxx/include/__type_traits/has_unique_object_representation.h
index 98c440c16bf26b..d92fef0b5d2baa 100644
--- a/libcxx/include/__type_traits/has_unique_object_representation.h
+++ b/libcxx/include/__type_traits/has_unique_object_representation.h
@@ -22,7 +22,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 #if _LIBCPP_STD_VER >= 17
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS has_unique_object_representations
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS has_unique_object_representations
     // TODO: We work around a Clang and GCC bug in __has_unique_object_representations by using remove_all_extents
     //       even though it should not be necessary. This was reported to the compilers:
     //         - Clang: https://github.com/llvm/llvm-project/issues/95311
@@ -31,7 +31,8 @@ struct _LIBCPP_TEMPLATE_VIS has_unique_object_representations
     : public integral_constant<bool, __has_unique_object_representations(remove_all_extents_t<_Tp>)> {};
 
 template <class _Tp>
-inline constexpr bool has_unique_object_representations_v = __has_unique_object_representations(_Tp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool has_unique_object_representations_v =
+    __has_unique_object_representations(_Tp);
 
 #endif
 
diff --git a/libcxx/include/__type_traits/has_virtual_destructor.h b/libcxx/include/__type_traits/has_virtual_destructor.h
index 4ce96e649e67a1..98fa3cf6923987 100644
--- a/libcxx/include/__type_traits/has_virtual_destructor.h
+++ b/libcxx/include/__type_traits/has_virtual_destructor.h
@@ -19,11 +19,12 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS has_virtual_destructor : public integral_constant<bool, __has_virtual_destructor(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS has_virtual_destructor
+    : public integral_constant<bool, __has_virtual_destructor(_Tp)> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool has_virtual_destructor_v = __has_virtual_destructor(_Tp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool has_virtual_destructor_v = __has_virtual_destructor(_Tp);
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/integral_constant.h b/libcxx/include/__type_traits/integral_constant.h
index b8c75c546aa942..8feeff630d8741 100644
--- a/libcxx/include/__type_traits/integral_constant.h
+++ b/libcxx/include/__type_traits/integral_constant.h
@@ -18,7 +18,7 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp, _Tp __v>
-struct _LIBCPP_TEMPLATE_VIS integral_constant {
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS integral_constant {
   static inline _LIBCPP_CONSTEXPR const _Tp value = __v;
   typedef _Tp value_type;
   typedef integral_constant type;
diff --git a/libcxx/include/__type_traits/invoke.h b/libcxx/include/__type_traits/invoke.h
index 71db32ae6a3cef..aa3b7cd2fe7791 100644
--- a/libcxx/include/__type_traits/invoke.h
+++ b/libcxx/include/__type_traits/invoke.h
@@ -230,35 +230,39 @@ struct __invoke_void_return_wrapper<_Ret, true> {
 // is_invocable
 
 template <class _Fn, class... _Args>
-struct _LIBCPP_TEMPLATE_VIS is_invocable : integral_constant<bool, __invokable<_Fn, _Args...>::value> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_invocable
+    : integral_constant<bool, __invokable<_Fn, _Args...>::value> {};
 
 template <class _Ret, class _Fn, class... _Args>
-struct _LIBCPP_TEMPLATE_VIS is_invocable_r : integral_constant<bool, __invokable_r<_Ret, _Fn, _Args...>::value> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_invocable_r
+    : integral_constant<bool, __invokable_r<_Ret, _Fn, _Args...>::value> {};
 
 template <class _Fn, class... _Args>
-inline constexpr bool is_invocable_v = is_invocable<_Fn, _Args...>::value;
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_invocable_v = is_invocable<_Fn, _Args...>::value;
 
 template <class _Ret, class _Fn, class... _Args>
-inline constexpr bool is_invocable_r_v = is_invocable_r<_Ret, _Fn, _Args...>::value;
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_invocable_r_v = is_invocable_r<_Ret, _Fn, _Args...>::value;
 
 // is_nothrow_invocable
 
 template <class _Fn, class... _Args>
-struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable : integral_constant<bool, __nothrow_invokable<_Fn, _Args...>::value> {
-};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_nothrow_invocable
+    : integral_constant<bool, __nothrow_invokable<_Fn, _Args...>::value> {};
 
 template <class _Ret, class _Fn, class... _Args>
-struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable_r
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_nothrow_invocable_r
     : integral_constant<bool, __nothrow_invokable_r<_Ret, _Fn, _Args...>::value> {};
 
 template <class _Fn, class... _Args>
-inline constexpr bool is_nothrow_invocable_v = is_nothrow_invocable<_Fn, _Args...>::value;
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_nothrow_invocable_v =
+    is_nothrow_invocable<_Fn, _Args...>::value;
 
 template <class _Ret, class _Fn, class... _Args>
-inline constexpr bool is_nothrow_invocable_r_v = is_nothrow_invocable_r<_Ret, _Fn, _Args...>::value;
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_nothrow_invocable_r_v =
+    is_nothrow_invocable_r<_Ret, _Fn, _Args...>::value;
 
 template <class _Fn, class... _Args>
-struct _LIBCPP_TEMPLATE_VIS invoke_result : __invoke_of<_Fn, _Args...> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS invoke_result : __invoke_of<_Fn, _Args...> {};
 
 template <class _Fn, class... _Args>
 using invoke_result_t = typename invoke_result<_Fn, _Args...>::type;
diff --git a/libcxx/include/__type_traits/is_abstract.h b/libcxx/include/__type_traits/is_abstract.h
index 4aa456be1c48e8..20b9e56cd60ebd 100644
--- a/libcxx/include/__type_traits/is_abstract.h
+++ b/libcxx/include/__type_traits/is_abstract.h
@@ -19,11 +19,12 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_abstract : public integral_constant<bool, __is_abstract(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_abstract
+    : public integral_constant<bool, __is_abstract(_Tp)> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_abstract_v = __is_abstract(_Tp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_abstract_v = __is_abstract(_Tp);
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_aggregate.h b/libcxx/include/__type_traits/is_aggregate.h
index 4e0988071adeec..b5098ee1bcf1a2 100644
--- a/libcxx/include/__type_traits/is_aggregate.h
+++ b/libcxx/include/__type_traits/is_aggregate.h
@@ -21,10 +21,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 #if _LIBCPP_STD_VER >= 17
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_aggregate : public integral_constant<bool, __is_aggregate(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_aggregate
+    : public integral_constant<bool, __is_aggregate(_Tp)> {};
 
 template <class _Tp>
-inline constexpr bool is_aggregate_v = __is_aggregate(_Tp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_aggregate_v = __is_aggregate(_Tp);
 
 #endif // _LIBCPP_STD_VER >= 17
 
diff --git a/libcxx/include/__type_traits/is_arithmetic.h b/libcxx/include/__type_traits/is_arithmetic.h
index c9713e1840a7b1..fcb31e9f5d5da4 100644
--- a/libcxx/include/__type_traits/is_arithmetic.h
+++ b/libcxx/include/__type_traits/is_arithmetic.h
@@ -21,12 +21,12 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_arithmetic
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_arithmetic
     : public integral_constant<bool, is_integral<_Tp>::value || is_floating_point<_Tp>::value> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value;
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value;
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_array.h b/libcxx/include/__type_traits/is_array.h
index f34204e19ed899..0bde0aa970f884 100644
--- a/libcxx/include/__type_traits/is_array.h
+++ b/libcxx/include/__type_traits/is_array.h
@@ -23,11 +23,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD
     (!defined(_LIBCPP_COMPILER_CLANG_BASED) || (defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 1900))
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_array : _BoolConstant<__is_array(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_array : _BoolConstant<__is_array(_Tp)> {};
 
 #  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_array_v = __is_array(_Tp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_array_v = __is_array(_Tp);
 #  endif
 
 #else
diff --git a/libcxx/include/__type_traits/is_assignable.h b/libcxx/include/__type_traits/is_assignable.h
index cfb46997778782..926ef3f4a4c21d 100644
--- a/libcxx/include/__type_traits/is_assignable.h
+++ b/libcxx/include/__type_traits/is_assignable.h
@@ -21,30 +21,31 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp, class _Up>
-struct _LIBCPP_TEMPLATE_VIS is_assignable : _BoolConstant<__is_assignable(_Tp, _Up)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_assignable : _BoolConstant<__is_assignable(_Tp, _Up)> {
+};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp, class _Arg>
-inline constexpr bool is_assignable_v = __is_assignable(_Tp, _Arg);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_assignable_v = __is_assignable(_Tp, _Arg);
 #endif
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_copy_assignable
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_copy_assignable
     : public integral_constant<bool,
                                __is_assignable(__add_lvalue_reference_t<_Tp>, __add_lvalue_reference_t<const _Tp>)> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_copy_assignable_v = is_copy_assignable<_Tp>::value;
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_copy_assignable_v = is_copy_assignable<_Tp>::value;
 #endif
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_move_assignable
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_move_assignable
     : public integral_constant<bool, __is_assignable(__add_lvalue_reference_t<_Tp>, __add_rvalue_reference_t<_Tp>)> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_move_assignable_v = is_move_assignable<_Tp>::value;
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_move_assignable_v = is_move_assignable<_Tp>::value;
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_base_of.h b/libcxx/include/__type_traits/is_base_of.h
index 488b63719eb600..e1958eff5f9157 100644
--- a/libcxx/include/__type_traits/is_base_of.h
+++ b/libcxx/include/__type_traits/is_base_of.h
@@ -19,21 +19,24 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Bp, class _Dp>
-struct _LIBCPP_TEMPLATE_VIS is_base_of : public integral_constant<bool, __is_base_of(_Bp, _Dp)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_base_of
+    : public integral_constant<bool, __is_base_of(_Bp, _Dp)> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Bp, class _Dp>
-inline constexpr bool is_base_of_v = __is_base_of(_Bp, _Dp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_base_of_v = __is_base_of(_Bp, _Dp);
 #endif
 
 #if _LIBCPP_STD_VER >= 26
 #  if __has_builtin(__builtin_is_virtual_base_of)
 
 template <class _Base, class _Derived>
-struct _LIBCPP_TEMPLATE_VIS is_virtual_base_of : public bool_constant<__builtin_is_virtual_base_of(_Base, _Derived)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_virtual_base_of
+    : public bool_constant<__builtin_is_virtual_base_of(_Base, _Derived)> {};
 
 template <class _Base, class _Derived>
-inline constexpr bool is_virtual_base_of_v = __builtin_is_virtual_base_of(_Base, _Derived);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_virtual_base_of_v =
+    __builtin_is_virtual_base_of(_Base, _Derived);
 
 #  endif
 #endif
diff --git a/libcxx/include/__type_traits/is_class.h b/libcxx/include/__type_traits/is_class.h
index 034f76a7865e3d..6cff58a479d417 100644
--- a/libcxx/include/__type_traits/is_class.h
+++ b/libcxx/include/__type_traits/is_class.h
@@ -19,11 +19,12 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_class : public integral_constant<bool, __is_class(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_class
+    : public integral_constant<bool, __is_class(_Tp)> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_class_v = __is_class(_Tp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_class_v = __is_class(_Tp);
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_compound.h b/libcxx/include/__type_traits/is_compound.h
index cd208ceab28863..6dc22f8a911164 100644
--- a/libcxx/include/__type_traits/is_compound.h
+++ b/libcxx/include/__type_traits/is_compound.h
@@ -22,11 +22,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 #if __has_builtin(__is_compound)
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_compound : _BoolConstant<__is_compound(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_compound : _BoolConstant<__is_compound(_Tp)> {};
 
 #  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_compound_v = __is_compound(_Tp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_compound_v = __is_compound(_Tp);
 #  endif
 
 #else // __has_builtin(__is_compound)
diff --git a/libcxx/include/__type_traits/is_const.h b/libcxx/include/__type_traits/is_const.h
index 47ef70872b790a..78f98f3a96d4ff 100644
--- a/libcxx/include/__type_traits/is_const.h
+++ b/libcxx/include/__type_traits/is_const.h
@@ -21,11 +21,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 #if __has_builtin(__is_const)
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_const : _BoolConstant<__is_const(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_const : _BoolConstant<__is_const(_Tp)> {};
 
 #  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_const_v = __is_const(_Tp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_const_v = __is_const(_Tp);
 #  endif
 
 #else
diff --git a/libcxx/include/__type_traits/is_constructible.h b/libcxx/include/__type_traits/is_constructible.h
index 567bd165c71520..6c7636e0bb5098 100644
--- a/libcxx/include/__type_traits/is_constructible.h
+++ b/libcxx/include/__type_traits/is_constructible.h
@@ -21,37 +21,39 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp, class... _Args>
-struct _LIBCPP_TEMPLATE_VIS is_constructible : public integral_constant<bool, __is_constructible(_Tp, _Args...)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_constructible
+    : public integral_constant<bool, __is_constructible(_Tp, _Args...)> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp, class... _Args>
-inline constexpr bool is_constructible_v = __is_constructible(_Tp, _Args...);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_constructible_v = __is_constructible(_Tp, _Args...);
 #endif
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_copy_constructible
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_copy_constructible
     : public integral_constant<bool, __is_constructible(_Tp, __add_lvalue_reference_t<const _Tp>)> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_copy_constructible_v = is_copy_constructible<_Tp>::value;
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_copy_constructible_v = is_copy_constructible<_Tp>::value;
 #endif
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_move_constructible
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_move_constructible
     : public integral_constant<bool, __is_constructible(_Tp, __add_rvalue_reference_t<_Tp>)> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_move_constructible_v = is_move_constructible<_Tp>::value;
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_move_constructible_v = is_move_constructible<_Tp>::value;
 #endif
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_default_constructible : public integral_constant<bool, __is_constructible(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_default_constructible
+    : public integral_constant<bool, __is_constructible(_Tp)> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_default_constructible_v = __is_constructible(_Tp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_default_constructible_v = __is_constructible(_Tp);
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_convertible.h b/libcxx/include/__type_traits/is_convertible.h
index 414c2a6d6a0de0..61f6cf644124e1 100644
--- a/libcxx/include/__type_traits/is_convertible.h
+++ b/libcxx/include/__type_traits/is_convertible.h
@@ -19,11 +19,12 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _T1, class _T2>
-struct _LIBCPP_TEMPLATE_VIS is_convertible : public integral_constant<bool, __is_convertible(_T1, _T2)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_convertible
+    : public integral_constant<bool, __is_convertible(_T1, _T2)> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _From, class _To>
-inline constexpr bool is_convertible_v = __is_convertible(_From, _To);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_convertible_v = __is_convertible(_From, _To);
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_destructible.h b/libcxx/include/__type_traits/is_destructible.h
index 3248b07d36ee67..5fe923d303c531 100644
--- a/libcxx/include/__type_traits/is_destructible.h
+++ b/libcxx/include/__type_traits/is_destructible.h
@@ -25,11 +25,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 #if __has_builtin(__is_destructible)
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_destructible : _BoolConstant<__is_destructible(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_destructible : _BoolConstant<__is_destructible(_Tp)> {};
 
 #  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_destructible_v = __is_destructible(_Tp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_destructible_v = __is_destructible(_Tp);
 #  endif
 
 #else // __has_builtin(__is_destructible)
diff --git a/libcxx/include/__type_traits/is_empty.h b/libcxx/include/__type_traits/is_empty.h
index 951d93b5a2f10e..6056b1ae838a9f 100644
--- a/libcxx/include/__type_traits/is_empty.h
+++ b/libcxx/include/__type_traits/is_empty.h
@@ -19,11 +19,12 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_empty : public integral_constant<bool, __is_empty(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_empty
+    : public integral_constant<bool, __is_empty(_Tp)> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_empty_v = __is_empty(_Tp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_empty_v = __is_empty(_Tp);
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_enum.h b/libcxx/include/__type_traits/is_enum.h
index 2fab6db2c8d50f..c6496f8644e8f7 100644
--- a/libcxx/include/__type_traits/is_enum.h
+++ b/libcxx/include/__type_traits/is_enum.h
@@ -19,20 +19,21 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_enum : public integral_constant<bool, __is_enum(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_enum : public integral_constant<bool, __is_enum(_Tp)> {
+};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_enum_v = __is_enum(_Tp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_enum_v = __is_enum(_Tp);
 #endif
 
 #if _LIBCPP_STD_VER >= 23
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_scoped_enum : bool_constant<__is_scoped_enum(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_scoped_enum : bool_constant<__is_scoped_enum(_Tp)> {};
 
 template <class _Tp>
-inline constexpr bool is_scoped_enum_v = __is_scoped_enum(_Tp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_scoped_enum_v = __is_scoped_enum(_Tp);
 
 #endif // _LIBCPP_STD_VER >= 23
 
diff --git a/libcxx/include/__type_traits/is_final.h b/libcxx/include/__type_traits/is_final.h
index 499c5e3a1edca4..bdda264ed11178 100644
--- a/libcxx/include/__type_traits/is_final.h
+++ b/libcxx/include/__type_traits/is_final.h
@@ -23,12 +23,13 @@ struct _LIBCPP_TEMPLATE_VIS __libcpp_is_final : public integral_constant<bool, _
 
 #if _LIBCPP_STD_VER >= 14
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_final : public integral_constant<bool, __is_final(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_final
+    : public integral_constant<bool, __is_final(_Tp)> {};
 #endif
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_final_v = __is_final(_Tp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_final_v = __is_final(_Tp);
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_floating_point.h b/libcxx/include/__type_traits/is_floating_point.h
index add34782dfa099..563ecce891f22d 100644
--- a/libcxx/include/__type_traits/is_floating_point.h
+++ b/libcxx/include/__type_traits/is_floating_point.h
@@ -27,11 +27,12 @@ template <>          struct __libcpp_is_floating_point<long double> : public tru
 // clang-format on
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_floating_point : public __libcpp_is_floating_point<__remove_cv_t<_Tp> > {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_floating_point
+    : public __libcpp_is_floating_point<__remove_cv_t<_Tp> > {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_floating_point_v = is_floating_point<_Tp>::value;
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_floating_point_v = is_floating_point<_Tp>::value;
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_function.h b/libcxx/include/__type_traits/is_function.h
index 98fedd0ad96d9b..2dbb3be8c1c7ee 100644
--- a/libcxx/include/__type_traits/is_function.h
+++ b/libcxx/include/__type_traits/is_function.h
@@ -19,11 +19,12 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_function : integral_constant<bool, __is_function(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_function : integral_constant<bool, __is_function(_Tp)> {
+};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_function_v = __is_function(_Tp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_function_v = __is_function(_Tp);
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_fundamental.h b/libcxx/include/__type_traits/is_fundamental.h
index 55f8e41f75f457..03e25474bea777 100644
--- a/libcxx/include/__type_traits/is_fundamental.h
+++ b/libcxx/include/__type_traits/is_fundamental.h
@@ -23,11 +23,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 #if __has_builtin(__is_fundamental)
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_fundamental : _BoolConstant<__is_fundamental(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_fundamental : _BoolConstant<__is_fundamental(_Tp)> {};
 
 #  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_fundamental_v = __is_fundamental(_Tp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_fundamental_v = __is_fundamental(_Tp);
 #  endif
 
 #else // __has_builtin(__is_fundamental)
diff --git a/libcxx/include/__type_traits/is_implicit_lifetime.h b/libcxx/include/__type_traits/is_implicit_lifetime.h
index 2aba420bd2b59d..8b992095f105b9 100644
--- a/libcxx/include/__type_traits/is_implicit_lifetime.h
+++ b/libcxx/include/__type_traits/is_implicit_lifetime.h
@@ -22,10 +22,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 #  if __has_builtin(__builtin_is_implicit_lifetime)
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_implicit_lifetime : public bool_constant<__builtin_is_implicit_lifetime(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_implicit_lifetime
+    : public bool_constant<__builtin_is_implicit_lifetime(_Tp)> {};
 
 template <class _Tp>
-inline constexpr bool is_implicit_lifetime_v = __builtin_is_implicit_lifetime(_Tp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_implicit_lifetime_v = __builtin_is_implicit_lifetime(_Tp);
 
 #  endif
 #endif
diff --git a/libcxx/include/__type_traits/is_integral.h b/libcxx/include/__type_traits/is_integral.h
index 763b6ac3d1077d..6ae9b31a8e9b63 100644
--- a/libcxx/include/__type_traits/is_integral.h
+++ b/libcxx/include/__type_traits/is_integral.h
@@ -50,11 +50,11 @@ template <>          struct __libcpp_is_integral<__uint128_t>        { enum { va
 #if __has_builtin(__is_integral)
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_integral : _BoolConstant<__is_integral(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_integral : _BoolConstant<__is_integral(_Tp)> {};
 
 #  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_integral_v = __is_integral(_Tp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_integral_v = __is_integral(_Tp);
 #  endif
 
 #else
diff --git a/libcxx/include/__type_traits/is_literal_type.h b/libcxx/include/__type_traits/is_literal_type.h
index 10e23bceffbda3..9381cfb1039785 100644
--- a/libcxx/include/__type_traits/is_literal_type.h
+++ b/libcxx/include/__type_traits/is_literal_type.h
@@ -20,12 +20,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS)
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS
-_LIBCPP_DEPRECATED_IN_CXX17 is_literal_type : public integral_constant<bool, __is_literal_type(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_NO_SPECIALIZATIONS is_literal_type
+    : public integral_constant<bool, __is_literal_type(_Tp)> {};
 
 #  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-_LIBCPP_DEPRECATED_IN_CXX17 inline constexpr bool is_literal_type_v = __is_literal_type(_Tp);
+_LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_literal_type_v =
+    __is_literal_type(_Tp);
 #  endif // _LIBCPP_STD_VER >= 17
 #endif   // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS)
 
diff --git a/libcxx/include/__type_traits/is_member_pointer.h b/libcxx/include/__type_traits/is_member_pointer.h
index 3e2753ac4228c2..b82262044020e3 100644
--- a/libcxx/include/__type_traits/is_member_pointer.h
+++ b/libcxx/include/__type_traits/is_member_pointer.h
@@ -19,23 +19,26 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_member_pointer : _BoolConstant<__is_member_pointer(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_member_pointer
+    : _BoolConstant<__is_member_pointer(_Tp)> {};
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_member_object_pointer : _BoolConstant<__is_member_object_pointer(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_member_object_pointer
+    : _BoolConstant<__is_member_object_pointer(_Tp)> {};
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_member_function_pointer : _BoolConstant<__is_member_function_pointer(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_member_function_pointer
+    : _BoolConstant<__is_member_function_pointer(_Tp)> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_member_pointer_v = __is_member_pointer(_Tp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_member_pointer_v = __is_member_pointer(_Tp);
 
 template <class _Tp>
-inline constexpr bool is_member_object_pointer_v = __is_member_object_pointer(_Tp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_member_object_pointer_v = __is_member_object_pointer(_Tp);
 
 template <class _Tp>
-inline constexpr bool is_member_function_pointer_v = __is_member_function_pointer(_Tp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_member_function_pointer_v = __is_member_function_pointer(_Tp);
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_nothrow_assignable.h b/libcxx/include/__type_traits/is_nothrow_assignable.h
index 7e00c741f83e30..ba67c8a05bbd5c 100644
--- a/libcxx/include/__type_traits/is_nothrow_assignable.h
+++ b/libcxx/include/__type_traits/is_nothrow_assignable.h
@@ -21,34 +21,36 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp, class _Arg>
-struct _LIBCPP_TEMPLATE_VIS is_nothrow_assignable : public integral_constant<bool, __is_nothrow_assignable(_Tp, _Arg)> {
-};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_nothrow_assignable
+    : public integral_constant<bool, __is_nothrow_assignable(_Tp, _Arg)> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp, class _Arg>
-inline constexpr bool is_nothrow_assignable_v = __is_nothrow_assignable(_Tp, _Arg);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_nothrow_assignable_v = __is_nothrow_assignable(_Tp, _Arg);
 #endif
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_nothrow_copy_assignable
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_nothrow_copy_assignable
     : public integral_constant<
           bool,
           __is_nothrow_assignable(__add_lvalue_reference_t<_Tp>, __add_lvalue_reference_t<const _Tp>)> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_nothrow_copy_assignable_v = is_nothrow_copy_assignable<_Tp>::value;
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_nothrow_copy_assignable_v =
+    is_nothrow_copy_assignable<_Tp>::value;
 #endif
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_nothrow_move_assignable
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_nothrow_move_assignable
     : public integral_constant<bool,
                                __is_nothrow_assignable(__add_lvalue_reference_t<_Tp>, __add_rvalue_reference_t<_Tp>)> {
 };
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_nothrow_move_assignable_v = is_nothrow_move_assignable<_Tp>::value;
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_nothrow_move_assignable_v =
+    is_nothrow_move_assignable<_Tp>::value;
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_nothrow_constructible.h b/libcxx/include/__type_traits/is_nothrow_constructible.h
index 58d2b2475140b6..28f2ffde12c5a4 100644
--- a/libcxx/include/__type_traits/is_nothrow_constructible.h
+++ b/libcxx/include/__type_traits/is_nothrow_constructible.h
@@ -21,39 +21,43 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template < class _Tp, class... _Args>
-struct _LIBCPP_TEMPLATE_VIS is_nothrow_constructible
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_nothrow_constructible
     : public integral_constant<bool, __is_nothrow_constructible(_Tp, _Args...)> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp, class... _Args>
-inline constexpr bool is_nothrow_constructible_v = is_nothrow_constructible<_Tp, _Args...>::value;
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_nothrow_constructible_v =
+    is_nothrow_constructible<_Tp, _Args...>::value;
 #endif
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_nothrow_copy_constructible
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_nothrow_copy_constructible
     : public integral_constant< bool, __is_nothrow_constructible(_Tp, __add_lvalue_reference_t<const _Tp>)> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_nothrow_copy_constructible_v = is_nothrow_copy_constructible<_Tp>::value;
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_nothrow_copy_constructible_v =
+    is_nothrow_copy_constructible<_Tp>::value;
 #endif
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_nothrow_move_constructible
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_nothrow_move_constructible
     : public integral_constant<bool, __is_nothrow_constructible(_Tp, __add_rvalue_reference_t<_Tp>)> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_nothrow_move_constructible_v = is_nothrow_move_constructible<_Tp>::value;
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_nothrow_move_constructible_v =
+    is_nothrow_move_constructible<_Tp>::value;
 #endif
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_nothrow_default_constructible
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_nothrow_default_constructible
     : public integral_constant<bool, __is_nothrow_constructible(_Tp)> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_nothrow_default_constructible_v = __is_nothrow_constructible(_Tp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_nothrow_default_constructible_v =
+    __is_nothrow_constructible(_Tp);
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_nothrow_convertible.h b/libcxx/include/__type_traits/is_nothrow_convertible.h
index bfc5a94cbadec6..8b1aacf8f28768 100644
--- a/libcxx/include/__type_traits/is_nothrow_convertible.h
+++ b/libcxx/include/__type_traits/is_nothrow_convertible.h
@@ -29,10 +29,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 #  if __has_builtin(__is_nothrow_convertible)
 
 template <class _Tp, class _Up>
-struct is_nothrow_convertible : bool_constant<__is_nothrow_convertible(_Tp, _Up)> {};
+struct _LIBCPP_NO_SPECIALIZATIONS is_nothrow_convertible : bool_constant<__is_nothrow_convertible(_Tp, _Up)> {};
 
 template <class _Tp, class _Up>
-inline constexpr bool is_nothrow_convertible_v = __is_nothrow_convertible(_Tp, _Up);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_nothrow_convertible_v = __is_nothrow_convertible(_Tp, _Up);
 
 #  else // __has_builtin(__is_nothrow_convertible)
 
diff --git a/libcxx/include/__type_traits/is_nothrow_destructible.h b/libcxx/include/__type_traits/is_nothrow_destructible.h
index 41271a38f37116..a363ad6b4af3bc 100644
--- a/libcxx/include/__type_traits/is_nothrow_destructible.h
+++ b/libcxx/include/__type_traits/is_nothrow_destructible.h
@@ -24,7 +24,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 #if __has_builtin(__is_nothrow_destructible)
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible : integral_constant<bool, __is_nothrow_destructible(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_nothrow_destructible
+    : integral_constant<bool, __is_nothrow_destructible(_Tp)> {};
 
 #else
 
@@ -55,7 +56,7 @@ struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible<_Tp&&> : public true_type {}
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_nothrow_destructible_v = is_nothrow_destructible<_Tp>::value;
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_nothrow_destructible_v = is_nothrow_destructible<_Tp>::value;
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_null_pointer.h b/libcxx/include/__type_traits/is_null_pointer.h
index abc5d142562f1e..fc6c6a69de338a 100644
--- a/libcxx/include/__type_traits/is_null_pointer.h
+++ b/libcxx/include/__type_traits/is_null_pointer.h
@@ -24,11 +24,12 @@ inline const bool __is_null_pointer_v = __is_same(__remove_cv(_Tp), nullptr_t);
 
 #if _LIBCPP_STD_VER >= 14
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_null_pointer : integral_constant<bool, __is_null_pointer_v<_Tp>> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_null_pointer
+    : integral_constant<bool, __is_null_pointer_v<_Tp>> {};
 
 #  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_null_pointer_v = __is_null_pointer_v<_Tp>;
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_null_pointer_v = __is_null_pointer_v<_Tp>;
 #  endif
 #endif // _LIBCPP_STD_VER >= 14
 
diff --git a/libcxx/include/__type_traits/is_object.h b/libcxx/include/__type_traits/is_object.h
index ec04508402ce51..eba4ab5cb8806e 100644
--- a/libcxx/include/__type_traits/is_object.h
+++ b/libcxx/include/__type_traits/is_object.h
@@ -19,11 +19,11 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_object : _BoolConstant<__is_object(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_object : _BoolConstant<__is_object(_Tp)> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_object_v = __is_object(_Tp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_object_v = __is_object(_Tp);
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_pod.h b/libcxx/include/__type_traits/is_pod.h
index 5888fbf457d8b1..a57662400394a8 100644
--- a/libcxx/include/__type_traits/is_pod.h
+++ b/libcxx/include/__type_traits/is_pod.h
@@ -19,11 +19,11 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_pod : public integral_constant<bool, __is_pod(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_pod : public integral_constant<bool, __is_pod(_Tp)> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_pod_v = __is_pod(_Tp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_pod_v = __is_pod(_Tp);
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_pointer.h b/libcxx/include/__type_traits/is_pointer.h
index 9701e57807cf6f..5647bf4045ff3d 100644
--- a/libcxx/include/__type_traits/is_pointer.h
+++ b/libcxx/include/__type_traits/is_pointer.h
@@ -22,11 +22,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 #if __has_builtin(__is_pointer)
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_pointer : _BoolConstant<__is_pointer(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_pointer : _BoolConstant<__is_pointer(_Tp)> {};
 
 #  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_pointer_v = __is_pointer(_Tp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_pointer_v = __is_pointer(_Tp);
 #  endif
 
 #else // __has_builtin(__is_pointer)
diff --git a/libcxx/include/__type_traits/is_polymorphic.h b/libcxx/include/__type_traits/is_polymorphic.h
index d122e1c87775bd..17e9c21c0d6a17 100644
--- a/libcxx/include/__type_traits/is_polymorphic.h
+++ b/libcxx/include/__type_traits/is_polymorphic.h
@@ -19,11 +19,12 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_polymorphic : public integral_constant<bool, __is_polymorphic(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_polymorphic
+    : public integral_constant<bool, __is_polymorphic(_Tp)> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_polymorphic_v = __is_polymorphic(_Tp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_polymorphic_v = __is_polymorphic(_Tp);
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_reference.h b/libcxx/include/__type_traits/is_reference.h
index cc157a438e4913..65d7de6a2e4b72 100644
--- a/libcxx/include/__type_traits/is_reference.h
+++ b/libcxx/include/__type_traits/is_reference.h
@@ -19,26 +19,28 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_reference : _BoolConstant<__is_reference(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_reference : _BoolConstant<__is_reference(_Tp)> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_reference_v = __is_reference(_Tp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_reference_v = __is_reference(_Tp);
 #endif
 
 #if __has_builtin(__is_lvalue_reference) && __has_builtin(__is_rvalue_reference)
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference : _BoolConstant<__is_lvalue_reference(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_lvalue_reference
+    : _BoolConstant<__is_lvalue_reference(_Tp)> {};
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_rvalue_reference : _BoolConstant<__is_rvalue_reference(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_rvalue_reference
+    : _BoolConstant<__is_rvalue_reference(_Tp)> {};
 
 #  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_lvalue_reference_v = __is_lvalue_reference(_Tp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_lvalue_reference_v = __is_lvalue_reference(_Tp);
 template <class _Tp>
-inline constexpr bool is_rvalue_reference_v = __is_rvalue_reference(_Tp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_rvalue_reference_v = __is_rvalue_reference(_Tp);
 #  endif
 
 #else // __has_builtin(__is_lvalue_reference)
diff --git a/libcxx/include/__type_traits/is_same.h b/libcxx/include/__type_traits/is_same.h
index 9561b7b5d6da3c..da07233eff4a4b 100644
--- a/libcxx/include/__type_traits/is_same.h
+++ b/libcxx/include/__type_traits/is_same.h
@@ -19,11 +19,11 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp, class _Up>
-struct _LIBCPP_TEMPLATE_VIS is_same : _BoolConstant<__is_same(_Tp, _Up)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_same : _BoolConstant<__is_same(_Tp, _Up)> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp, class _Up>
-inline constexpr bool is_same_v = __is_same(_Tp, _Up);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_same_v = __is_same(_Tp, _Up);
 #endif
 
 // _IsSame<T,U> has the same effect as is_same<T,U> but instantiates fewer types:
diff --git a/libcxx/include/__type_traits/is_scalar.h b/libcxx/include/__type_traits/is_scalar.h
index 242023a6877c94..6ef57e1dd22d56 100644
--- a/libcxx/include/__type_traits/is_scalar.h
+++ b/libcxx/include/__type_traits/is_scalar.h
@@ -26,11 +26,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 #if __has_builtin(__is_scalar)
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_scalar : _BoolConstant<__is_scalar(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_scalar : _BoolConstant<__is_scalar(_Tp)> {};
 
 #  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_scalar_v = __is_scalar(_Tp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_scalar_v = __is_scalar(_Tp);
 #  endif
 
 #else // __has_builtin(__is_scalar)
diff --git a/libcxx/include/__type_traits/is_signed.h b/libcxx/include/__type_traits/is_signed.h
index fd6f93e1823627..535324fdbfc142 100644
--- a/libcxx/include/__type_traits/is_signed.h
+++ b/libcxx/include/__type_traits/is_signed.h
@@ -23,11 +23,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 #if __has_builtin(__is_signed)
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_signed : _BoolConstant<__is_signed(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_signed : _BoolConstant<__is_signed(_Tp)> {};
 
 #  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_signed_v = __is_signed(_Tp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_signed_v = __is_signed(_Tp);
 #  endif
 
 #else // __has_builtin(__is_signed)
diff --git a/libcxx/include/__type_traits/is_standard_layout.h b/libcxx/include/__type_traits/is_standard_layout.h
index 76484f3e2a301f..e70d0f365416e4 100644
--- a/libcxx/include/__type_traits/is_standard_layout.h
+++ b/libcxx/include/__type_traits/is_standard_layout.h
@@ -19,11 +19,12 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_standard_layout : public integral_constant<bool, __is_standard_layout(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_standard_layout
+    : public integral_constant<bool, __is_standard_layout(_Tp)> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_standard_layout_v = __is_standard_layout(_Tp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_standard_layout_v = __is_standard_layout(_Tp);
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_swappable.h b/libcxx/include/__type_traits/is_swappable.h
index 221f017700a2e4..6ac2c4a1a903b7 100644
--- a/libcxx/include/__type_traits/is_swappable.h
+++ b/libcxx/include/__type_traits/is_swappable.h
@@ -73,30 +73,34 @@ inline const bool __is_nothrow_swappable_with_v<_Tp, _Up, true> =
 #if _LIBCPP_STD_VER >= 17
 
 template <class _Tp, class _Up>
-inline constexpr bool is_swappable_with_v = __is_swappable_with_v<_Tp, _Up>;
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_swappable_with_v = __is_swappable_with_v<_Tp, _Up>;
 
 template <class _Tp, class _Up>
-struct _LIBCPP_TEMPLATE_VIS is_swappable_with : bool_constant<is_swappable_with_v<_Tp, _Up>> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_swappable_with
+    : bool_constant<is_swappable_with_v<_Tp, _Up>> {};
 
 template <class _Tp>
-inline constexpr bool is_swappable_v =
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_swappable_v =
     is_swappable_with_v<__add_lvalue_reference_t<_Tp>, __add_lvalue_reference_t<_Tp>>;
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_swappable : bool_constant<is_swappable_v<_Tp>> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_swappable : bool_constant<is_swappable_v<_Tp>> {};
 
 template <class _Tp, class _Up>
-inline constexpr bool is_nothrow_swappable_with_v = __is_nothrow_swappable_with_v<_Tp, _Up>;
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_nothrow_swappable_with_v =
+    __is_nothrow_swappable_with_v<_Tp, _Up>;
 
 template <class _Tp, class _Up>
-struct _LIBCPP_TEMPLATE_VIS is_nothrow_swappable_with : bool_constant<is_nothrow_swappable_with_v<_Tp, _Up>> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_nothrow_swappable_with
+    : bool_constant<is_nothrow_swappable_with_v<_Tp, _Up>> {};
 
 template <class _Tp>
-inline constexpr bool is_nothrow_swappable_v =
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_nothrow_swappable_v =
     is_nothrow_swappable_with_v<__add_lvalue_reference_t<_Tp>, __add_lvalue_reference_t<_Tp>>;
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_nothrow_swappable : bool_constant<is_nothrow_swappable_v<_Tp>> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_nothrow_swappable
+    : bool_constant<is_nothrow_swappable_v<_Tp>> {};
 
 #endif // _LIBCPP_STD_VER >= 17
 
diff --git a/libcxx/include/__type_traits/is_trivial.h b/libcxx/include/__type_traits/is_trivial.h
index 0007c7446d5e5f..a2863329a5026d 100644
--- a/libcxx/include/__type_traits/is_trivial.h
+++ b/libcxx/include/__type_traits/is_trivial.h
@@ -19,11 +19,12 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_trivial : public integral_constant<bool, __is_trivial(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_trivial
+    : public integral_constant<bool, __is_trivial(_Tp)> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_trivial_v = __is_trivial(_Tp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_trivial_v = __is_trivial(_Tp);
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_trivially_assignable.h b/libcxx/include/__type_traits/is_trivially_assignable.h
index 7720c3e637506a..d91b6d89c7e21b 100644
--- a/libcxx/include/__type_traits/is_trivially_assignable.h
+++ b/libcxx/include/__type_traits/is_trivially_assignable.h
@@ -21,33 +21,36 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp, class _Arg>
-struct is_trivially_assignable : integral_constant<bool, __is_trivially_assignable(_Tp, _Arg)> {};
+struct _LIBCPP_NO_SPECIALIZATIONS is_trivially_assignable
+    : integral_constant<bool, __is_trivially_assignable(_Tp, _Arg)> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp, class _Arg>
-inline constexpr bool is_trivially_assignable_v = __is_trivially_assignable(_Tp, _Arg);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_trivially_assignable_v = __is_trivially_assignable(_Tp, _Arg);
 #endif
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_trivially_copy_assignable
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_trivially_copy_assignable
     : public integral_constant<
           bool,
           __is_trivially_assignable(__add_lvalue_reference_t<_Tp>, __add_lvalue_reference_t<const _Tp>)> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_trivially_copy_assignable_v = is_trivially_copy_assignable<_Tp>::value;
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_trivially_copy_assignable_v =
+    is_trivially_copy_assignable<_Tp>::value;
 #endif
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_trivially_move_assignable
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_trivially_move_assignable
     : public integral_constant<
           bool,
           __is_trivially_assignable(__add_lvalue_reference_t<_Tp>, __add_rvalue_reference_t<_Tp>)> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_trivially_move_assignable_v = is_trivially_move_assignable<_Tp>::value;
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_trivially_move_assignable_v =
+    is_trivially_move_assignable<_Tp>::value;
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_trivially_constructible.h b/libcxx/include/__type_traits/is_trivially_constructible.h
index 3a77e9fe164da1..4a212d462b63f2 100644
--- a/libcxx/include/__type_traits/is_trivially_constructible.h
+++ b/libcxx/include/__type_traits/is_trivially_constructible.h
@@ -21,39 +21,43 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp, class... _Args>
-struct _LIBCPP_TEMPLATE_VIS is_trivially_constructible
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_trivially_constructible
     : integral_constant<bool, __is_trivially_constructible(_Tp, _Args...)> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp, class... _Args>
-inline constexpr bool is_trivially_constructible_v = __is_trivially_constructible(_Tp, _Args...);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_trivially_constructible_v =
+    __is_trivially_constructible(_Tp, _Args...);
 #endif
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_trivially_copy_constructible
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_trivially_copy_constructible
     : public integral_constant<bool, __is_trivially_constructible(_Tp, __add_lvalue_reference_t<const _Tp>)> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_trivially_copy_constructible_v = is_trivially_copy_constructible<_Tp>::value;
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_trivially_copy_constructible_v =
+    is_trivially_copy_constructible<_Tp>::value;
 #endif
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_trivially_move_constructible
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_trivially_move_constructible
     : public integral_constant<bool, __is_trivially_constructible(_Tp, __add_rvalue_reference_t<_Tp>)> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_trivially_move_constructible_v = is_trivially_move_constructible<_Tp>::value;
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_trivially_move_constructible_v =
+    is_trivially_move_constructible<_Tp>::value;
 #endif
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_trivially_default_constructible
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_trivially_default_constructible
     : public integral_constant<bool, __is_trivially_constructible(_Tp)> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_trivially_default_constructible_v = __is_trivially_constructible(_Tp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_trivially_default_constructible_v =
+    __is_trivially_constructible(_Tp);
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_trivially_copyable.h b/libcxx/include/__type_traits/is_trivially_copyable.h
index 8eb3ba7581af15..72f1d6beae5d43 100644
--- a/libcxx/include/__type_traits/is_trivially_copyable.h
+++ b/libcxx/include/__type_traits/is_trivially_copyable.h
@@ -20,11 +20,12 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_trivially_copyable : public integral_constant<bool, __is_trivially_copyable(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_trivially_copyable
+    : public integral_constant<bool, __is_trivially_copyable(_Tp)> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_trivially_copyable_v = __is_trivially_copyable(_Tp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_trivially_copyable_v = __is_trivially_copyable(_Tp);
 #endif
 
 template <class _Tp>
diff --git a/libcxx/include/__type_traits/is_trivially_destructible.h b/libcxx/include/__type_traits/is_trivially_destructible.h
index 5f9652f2a5011c..c85cf0f10a823c 100644
--- a/libcxx/include/__type_traits/is_trivially_destructible.h
+++ b/libcxx/include/__type_traits/is_trivially_destructible.h
@@ -22,7 +22,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 #if __has_builtin(__is_trivially_destructible)
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_trivially_destructible
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_trivially_destructible
     : public integral_constant<bool, __is_trivially_destructible(_Tp)> {};
 
 #elif __has_builtin(__has_trivial_destructor)
@@ -39,7 +39,8 @@ struct _LIBCPP_TEMPLATE_VIS is_trivially_destructible
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_trivially_destructible_v = is_trivially_destructible<_Tp>::value;
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_trivially_destructible_v =
+    is_trivially_destructible<_Tp>::value;
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_union.h b/libcxx/include/__type_traits/is_union.h
index 1f009d993545ba..d1a7f1e35dab8e 100644
--- a/libcxx/include/__type_traits/is_union.h
+++ b/libcxx/include/__type_traits/is_union.h
@@ -19,11 +19,12 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_union : public integral_constant<bool, __is_union(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_union
+    : public integral_constant<bool, __is_union(_Tp)> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_union_v = __is_union(_Tp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_union_v = __is_union(_Tp);
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_unsigned.h b/libcxx/include/__type_traits/is_unsigned.h
index 48c5751ed70d8e..be855ee1d7fde8 100644
--- a/libcxx/include/__type_traits/is_unsigned.h
+++ b/libcxx/include/__type_traits/is_unsigned.h
@@ -23,11 +23,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 #if __has_builtin(__is_unsigned)
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_unsigned : _BoolConstant<__is_unsigned(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_unsigned : _BoolConstant<__is_unsigned(_Tp)> {};
 
 #  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_unsigned_v = __is_unsigned(_Tp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_unsigned_v = __is_unsigned(_Tp);
 #  endif
 
 #else // __has_builtin(__is_unsigned)
diff --git a/libcxx/include/__type_traits/is_void.h b/libcxx/include/__type_traits/is_void.h
index 562faae9fba2cd..0e2c276ab70841 100644
--- a/libcxx/include/__type_traits/is_void.h
+++ b/libcxx/include/__type_traits/is_void.h
@@ -19,11 +19,12 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_void : _BoolConstant<__is_same(__remove_cv(_Tp), void)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_void
+    : _BoolConstant<__is_same(__remove_cv(_Tp), void)> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_void_v = __is_same(__remove_cv(_Tp), void);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_void_v = __is_same(__remove_cv(_Tp), void);
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_volatile.h b/libcxx/include/__type_traits/is_volatile.h
index 87960a819c8fcb..033d1e3f3b8656 100644
--- a/libcxx/include/__type_traits/is_volatile.h
+++ b/libcxx/include/__type_traits/is_volatile.h
@@ -21,11 +21,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 #if __has_builtin(__is_volatile)
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_volatile : _BoolConstant<__is_volatile(_Tp)> {};
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_volatile : _BoolConstant<__is_volatile(_Tp)> {};
 
 #  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-inline constexpr bool is_volatile_v = __is_volatile(_Tp);
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_volatile_v = __is_volatile(_Tp);
 #  endif
 
 #else
diff --git a/libcxx/include/__type_traits/make_signed.h b/libcxx/include/__type_traits/make_signed.h
index 8070690b3a7a90..3017c8d133a78c 100644
--- a/libcxx/include/__type_traits/make_signed.h
+++ b/libcxx/include/__type_traits/make_signed.h
@@ -75,7 +75,7 @@ using __make_signed_t = __copy_cv_t<_Tp, typename __make_signed<__remove_cv_t<_T
 #endif // __has_builtin(__make_signed)
 
 template <class _Tp>
-struct make_signed {
+struct _LIBCPP_NO_SPECIALIZATIONS make_signed {
   using type _LIBCPP_NODEBUG = __make_signed_t<_Tp>;
 };
 
diff --git a/libcxx/include/__type_traits/make_unsigned.h b/libcxx/include/__type_traits/make_unsigned.h
index 562f7bab8a7fbf..36135d3f6ef6e0 100644
--- a/libcxx/include/__type_traits/make_unsigned.h
+++ b/libcxx/include/__type_traits/make_unsigned.h
@@ -77,7 +77,7 @@ using __make_unsigned_t = __copy_cv_t<_Tp, typename __make_unsigned<__remove_cv_
 #endif // __has_builtin(__make_unsigned)
 
 template <class _Tp>
-struct make_unsigned {
+struct _LIBCPP_NO_SPECIALIZATIONS make_unsigned {
   using type _LIBCPP_NODEBUG = __make_unsigned_t<_Tp>;
 };
 
diff --git a/libcxx/include/__type_traits/negation.h b/libcxx/include/__type_traits/negation.h
index a72e62d3f96e0c..a745a999a8bfbd 100644
--- a/libcxx/include/__type_traits/negation.h
+++ b/libcxx/include/__type_traits/negation.h
@@ -23,9 +23,9 @@ struct _Not : _BoolConstant<!_Pred::value> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp>
-struct negation : _Not<_Tp> {};
+struct _LIBCPP_NO_SPECIALIZATIONS negation : _Not<_Tp> {};
 template <class _Tp>
-inline constexpr bool negation_v = !_Tp::value;
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool negation_v = !_Tp::value;
 #endif // _LIBCPP_STD_VER >= 17
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/remove_all_extents.h b/libcxx/include/__type_traits/remove_all_extents.h
index db7dab4a6c1322..b927b0340a0eab 100644
--- a/libcxx/include/__type_traits/remove_all_extents.h
+++ b/libcxx/include/__type_traits/remove_all_extents.h
@@ -20,7 +20,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 #if __has_builtin(__remove_all_extents)
 template <class _Tp>
-struct remove_all_extents {
+struct _LIBCPP_NO_SPECIALIZATIONS remove_all_extents {
   using type _LIBCPP_NODEBUG = __remove_all_extents(_Tp);
 };
 
diff --git a/libcxx/include/__type_traits/remove_const.h b/libcxx/include/__type_traits/remove_const.h
index a3f0648c478506..55bb03472d13ff 100644
--- a/libcxx/include/__type_traits/remove_const.h
+++ b/libcxx/include/__type_traits/remove_const.h
@@ -19,7 +19,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 #if __has_builtin(__remove_const)
 template <class _Tp>
-struct remove_const {
+struct _LIBCPP_NO_SPECIALIZATIONS remove_const {
   using type _LIBCPP_NODEBUG = __remove_const(_Tp);
 };
 
diff --git a/libcxx/include/__type_traits/remove_cv.h b/libcxx/include/__type_traits/remove_cv.h
index 50e9f3e8aa78d6..f7c8e28fa32060 100644
--- a/libcxx/include/__type_traits/remove_cv.h
+++ b/libcxx/include/__type_traits/remove_cv.h
@@ -18,7 +18,7 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
-struct remove_cv {
+struct _LIBCPP_NO_SPECIALIZATIONS remove_cv {
   using type _LIBCPP_NODEBUG = __remove_cv(_Tp);
 };
 
diff --git a/libcxx/include/__type_traits/remove_cvref.h b/libcxx/include/__type_traits/remove_cvref.h
index 55f894dbd1d815..ce56b8a84434b0 100644
--- a/libcxx/include/__type_traits/remove_cvref.h
+++ b/libcxx/include/__type_traits/remove_cvref.h
@@ -38,7 +38,7 @@ using __is_same_uncvref = _IsSame<__remove_cvref_t<_Tp>, __remove_cvref_t<_Up> >
 
 #if _LIBCPP_STD_VER >= 20
 template <class _Tp>
-struct remove_cvref {
+struct _LIBCPP_NO_SPECIALIZATIONS remove_cvref {
   using type _LIBCPP_NODEBUG = __remove_cvref(_Tp);
 };
 
diff --git a/libcxx/include/__type_traits/remove_extent.h b/libcxx/include/__type_traits/remove_extent.h
index aceeb47069660b..1edc7d7bf505fb 100644
--- a/libcxx/include/__type_traits/remove_extent.h
+++ b/libcxx/include/__type_traits/remove_extent.h
@@ -20,7 +20,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 #if __has_builtin(__remove_extent)
 template <class _Tp>
-struct remove_extent {
+struct _LIBCPP_NO_SPECIALIZATIONS remove_extent {
   using type _LIBCPP_NODEBUG = __remove_extent(_Tp);
 };
 
diff --git a/libcxx/include/__type_traits/remove_pointer.h b/libcxx/include/__type_traits/remove_pointer.h
index 1048f67055a287..ddbb3e25cbd08e 100644
--- a/libcxx/include/__type_traits/remove_pointer.h
+++ b/libcxx/include/__type_traits/remove_pointer.h
@@ -19,7 +19,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 #if !defined(_LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS) && __has_builtin(__remove_pointer)
 template <class _Tp>
-struct remove_pointer {
+struct _LIBCPP_NO_SPECIALIZATIONS remove_pointer {
   using type _LIBCPP_NODEBUG = __remove_pointer(_Tp);
 };
 
diff --git a/libcxx/include/__type_traits/remove_reference.h b/libcxx/include/__type_traits/remove_reference.h
index ba67891758adce..be8917a104be49 100644
--- a/libcxx/include/__type_traits/remove_reference.h
+++ b/libcxx/include/__type_traits/remove_reference.h
@@ -19,7 +19,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 #if __has_builtin(__remove_reference_t)
 template <class _Tp>
-struct remove_reference {
+struct _LIBCPP_NO_SPECIALIZATIONS remove_reference {
   using type _LIBCPP_NODEBUG = __remove_reference_t(_Tp);
 };
 
diff --git a/libcxx/include/__type_traits/remove_volatile.h b/libcxx/include/__type_traits/remove_volatile.h
index 7600ae0ec5167e..c6e75455e815ff 100644
--- a/libcxx/include/__type_traits/remove_volatile.h
+++ b/libcxx/include/__type_traits/remove_volatile.h
@@ -19,7 +19,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 #if __has_builtin(__remove_volatile)
 template <class _Tp>
-struct remove_volatile {
+struct _LIBCPP_NO_SPECIALIZATIONS remove_volatile {
   using type _LIBCPP_NODEBUG = __remove_volatile(_Tp);
 };
 
diff --git a/libcxx/include/__type_traits/type_identity.h b/libcxx/include/__type_traits/type_identity.h
index b0b5a1277d5962..f526aef4d5b2ff 100644
--- a/libcxx/include/__type_traits/type_identity.h
+++ b/libcxx/include/__type_traits/type_identity.h
@@ -27,7 +27,7 @@ using __type_identity_t _LIBCPP_NODEBUG = typename __type_identity<_Tp>::type;
 
 #if _LIBCPP_STD_VER >= 20
 template <class _Tp>
-struct type_identity {
+struct _LIBCPP_NO_SPECIALIZATIONS type_identity {
   typedef _Tp type;
 };
 template <class _Tp>
diff --git a/libcxx/include/__type_traits/underlying_type.h b/libcxx/include/__type_traits/underlying_type.h
index 16e7501dee17df..45a9b40e3e4c9b 100644
--- a/libcxx/include/__type_traits/underlying_type.h
+++ b/libcxx/include/__type_traits/underlying_type.h
@@ -30,7 +30,7 @@ struct __underlying_type_impl<_Tp, true> {
 };
 
 template <class _Tp>
-struct underlying_type : __underlying_type_impl<_Tp, is_enum<_Tp>::value> {};
+struct _LIBCPP_NO_SPECIALIZATIONS underlying_type : __underlying_type_impl<_Tp, is_enum<_Tp>::value> {};
 
 #if _LIBCPP_STD_VER >= 14
 template <class _Tp>
diff --git a/libcxx/include/__type_traits/unwrap_ref.h b/libcxx/include/__type_traits/unwrap_ref.h
index 6bd74550f30921..31462f1f359b3f 100644
--- a/libcxx/include/__type_traits/unwrap_ref.h
+++ b/libcxx/include/__type_traits/unwrap_ref.h
@@ -31,13 +31,13 @@ struct __unwrap_reference<reference_wrapper<_Tp> > {
 
 #if _LIBCPP_STD_VER >= 20
 template <class _Tp>
-struct unwrap_reference : __unwrap_reference<_Tp> {};
+struct _LIBCPP_NO_SPECIALIZATIONS unwrap_reference : __unwrap_reference<_Tp> {};
 
 template <class _Tp>
 using unwrap_reference_t = typename unwrap_reference<_Tp>::type;
 
 template <class _Tp>
-struct unwrap_ref_decay : unwrap_reference<__decay_t<_Tp> > {};
+struct _LIBCPP_NO_SPECIALIZATIONS unwrap_ref_decay : unwrap_reference<__decay_t<_Tp> > {};
 
 template <class _Tp>
 using unwrap_ref_decay_t = typename unwrap_ref_decay<_Tp>::type;
diff --git a/libcxx/include/variant b/libcxx/include/variant
index f604527cd22569..d7ab533f354d37 100644
--- a/libcxx/include/variant
+++ b/libcxx/include/variant
@@ -1154,7 +1154,7 @@ visit(_Visitor&& __visitor, _Vs&&... __vs);
 #  endif
 
 template <class... _Types>
-class _LIBCPP_TEMPLATE_VIS _LIBCPP_DECLSPEC_EMPTY_BASES variant
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DECLSPEC_EMPTY_BASES _LIBCPP_NO_SPECIALIZATIONS variant
     : private __sfinae_ctor_base< __all<is_copy_constructible_v<_Types>...>::value,
                                   __all<is_move_constructible_v<_Types>...>::value>,
       private __sfinae_assign_base<
diff --git a/libcxx/test/libcxx/algorithms/no_specializations.verify.cpp b/libcxx/test/libcxx/algorithms/no_specializations.verify.cpp
new file mode 100644
index 00000000000000..3997ca22adbcc2
--- /dev/null
+++ b/libcxx/test/libcxx/algorithms/no_specializations.verify.cpp
@@ -0,0 +1,19 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+// Check that user-specializations are diagnosed
+// See [execpol.type]/3
+
+#include <execution>
+
+struct S {};
+
+template <>
+class std::is_execution_policy<S>; // TODO
diff --git a/libcxx/test/libcxx/language.support/no_specializations.verify.cpp b/libcxx/test/libcxx/language.support/no_specializations.verify.cpp
new file mode 100644
index 00000000000000..615406dbcf1c8b
--- /dev/null
+++ b/libcxx/test/libcxx/language.support/no_specializations.verify.cpp
@@ -0,0 +1,19 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// Check that user-specializations are diagnosed
+// See [cmp.result]/1
+
+#include <compare>
+
+struct S {};
+
+template <>
+class std::compare_three_way_result<S>; // expected-error {{cannot be specialized}}
diff --git a/libcxx/test/libcxx/ranges/no_specializations.verify.cpp b/libcxx/test/libcxx/ranges/no_specializations.verify.cpp
new file mode 100644
index 00000000000000..15dc476ec4d354
--- /dev/null
+++ b/libcxx/test/libcxx/ranges/no_specializations.verify.cpp
@@ -0,0 +1,19 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// Check that user-specializations are diagnosed
+// See [range.adaptor.object]/5
+
+#include <ranges>
+
+struct S {};
+
+template <>
+class std::ranges::range_adaptor_closure<S>; // expected-error {{cannot be specialized}}
diff --git a/libcxx/test/libcxx/type_traits/no_specializations.verify.cpp b/libcxx/test/libcxx/type_traits/no_specializations.verify.cpp
new file mode 100644
index 00000000000000..a283f904358258
--- /dev/null
+++ b/libcxx/test/libcxx/type_traits/no_specializations.verify.cpp
@@ -0,0 +1,172 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+// Check that user-specializations are diagnosed
+// See [meta.rqmts]/4, [meta.trans.other]/5, [meta.trans.other]/7
+
+#include <type_traits>
+
+#include "test_macros.h"
+
+struct S {};
+
+#define SPECIALIZE_TRAIT(Trait)                                                                                        \
+  template <>                                                                                                          \
+  struct std::Trait<S>
+
+SPECIALIZE_TRAIT(add_const);            // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(add_cv);               // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(add_volatile);         // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(add_lvalue_reference); // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(add_rvalue_reference); // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(add_pointer);          // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(alignment_of);         // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(conjunction);          // TODO
+SPECIALIZE_TRAIT(disjunction);          // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(decay);                // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(extent);               // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(invoke_result);        // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(make_unsigned);        // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(negation);             // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(rank);                 // TODO
+SPECIALIZE_TRAIT(remove_all_extents);   // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(remove_const);         // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(remove_cv);            // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(remove_cvref);         // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(remove_extent);        // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(remove_pointer);       // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(remove_reference);     // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(remove_volatile);      // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(type_identity);        // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(underlying_type);      // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(unwrap_reference);     // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(unwrap_ref_decay);     // expected-error {{cannot be specialized}}
+
+#undef SPECIALIZE_TRAIT
+#define SPECIALIZE_UTT(Trait)                                                                                          \
+  template <>                                                                                                          \
+  struct std::Trait<S>;                                                                                                \
+  template <>                                                                                                          \
+  inline constexpr bool std::Trait##_v<S> = false
+
+#define SPECIALIZE_BTT(Trait)                                                                                          \
+  template <>                                                                                                          \
+  struct std::Trait<S, S>;                                                                                             \
+  template <>                                                                                                          \
+  inline constexpr bool std::Trait##_v<S, S> = false
+
+SPECIALIZE_UTT(has_unique_object_representations);  // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_abstract);                        // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_aggregate);                       // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_arithmetic);                      // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_array);                           // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_BTT(is_assignable);                      // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_BTT(is_base_of);                         // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_class);                           // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_compound);                        // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_const);                           // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_constructible);                   // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_BTT(is_convertible);                     // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_copy_assignable);                 // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_copy_constructible);              // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_default_constructible);           // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_destructible);                    // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_empty);                           // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_enum);                            // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_final);                           // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_floating_point);                  // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_function);                        // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_fundamental);                     // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_integral);                        // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_invocable);                       // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_BTT(is_invocable_r);                     // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_lvalue_reference);                // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_member_pointer);                  // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_member_object_pointer);           // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_member_function_pointer);         // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_move_assignable);                 // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_move_constructible);              // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_BTT(is_nothrow_assignable);              // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_nothrow_constructible);           // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_BTT(is_nothrow_convertible);             // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_nothrow_copy_assignable);         // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_nothrow_copy_constructible);      // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_nothrow_default_constructible);   // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_nothrow_destructible);            // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_nothrow_move_assignable);         // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_nothrow_move_constructible);      // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_nothrow_invocable);               // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_BTT(is_nothrow_invocable_r);             // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_nothrow_swappable);               // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_BTT(is_nothrow_swappable_with);          // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_null_pointer);                    // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_object);                          // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_pod);                             // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_pointer);                         // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_polymorphic);                     // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_reference);                       // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_rvalue_reference);                // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_BTT(is_same);                            // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_scalar);                          // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_signed);                          // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_standard_layout);                 // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_swappable);                       // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_BTT(is_swappable_with);                  // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_trivial);                         // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_BTT(is_trivially_assignable);            // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_trivially_constructible);         // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_trivially_copy_assignable);       // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_trivially_copy_constructible);    // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_trivially_copyable);              // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_trivially_default_constructible); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_trivially_destructible);          // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_trivially_move_assignable);       // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_trivially_move_constructible);    // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_unbounded_array);                 // TODO
+SPECIALIZE_UTT(is_union);                           // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_unsigned);                        // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_void);                            // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_volatile);                        // expected-error 2 {{cannot be specialized}}
+
+#if TEST_STD_VER <= 17
+SPECIALIZE_UTT(is_literal_type); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(result_of);       // expected-error 2 {{cannot be specialized}}
+#endif
+
+#if TEST_STD_VER >= 20
+SPECIALIZE_UTT(is_bounded_array); // TODO
+#endif
+
+#if TEST_STD_VER >= 23
+SPECIALIZE_UTT(is_implicit_lifetime); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_scoped_enum);       // expected-error 2 {{cannot be specialized}}
+#endif
+
+#if TEST_STD_VER >= 26
+SPECIALIZE_BTT(is_virtual_base_of); // expected-error 2 {{cannot be specialized}}
+#endif
+
+#undef SPECIALIZE_UTT
+#undef SPECIALIZE_BTT
+
+template <>
+struct std::aligned_storage<1, 3>; // expected-error {{cannot be specialized}}
+
+template <>
+struct std::aligned_union<1, S>; // expected-error {{cannot be specialized}}
+
+template <>
+struct std::conditional<true, S, S>; // TODO
+
+template <>
+struct std::enable_if<true, S>; // TODO
+
+template <>
+struct std::integral_constant<S, {}>; // expected-error {{cannot be specialized}}
diff --git a/libcxx/test/libcxx/utilities/format/no_specializations.verify.cpp b/libcxx/test/libcxx/utilities/format/no_specializations.verify.cpp
new file mode 100644
index 00000000000000..764ca8fcd16e32
--- /dev/null
+++ b/libcxx/test/libcxx/utilities/format/no_specializations.verify.cpp
@@ -0,0 +1,19 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// Check that user-specializations are diagnosed
+// See [format.arg]/2
+
+#include <format>
+
+struct S {};
+
+template <>
+class std::basic_format_arg<S>; // expected-error {{cannot be specialized}}
diff --git a/libcxx/test/libcxx/utilities/no_specializations.verify.cpp b/libcxx/test/libcxx/utilities/no_specializations.verify.cpp
new file mode 100644
index 00000000000000..b785bac02168ae
--- /dev/null
+++ b/libcxx/test/libcxx/utilities/no_specializations.verify.cpp
@@ -0,0 +1,19 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+// Check that user-specializations are diagnosed
+// See [variant.variant.general]/4
+
+#include <variant>
+
+struct S {};
+
+template <>
+class std::variant<S>; // expected-error {{cannot be specialized}}



More information about the libcxx-commits mailing list