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

via libcxx-commits libcxx-commits at lists.llvm.org
Fri Dec 20 06:59:16 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libcxx

Author: Nikolas Klauser (philnik777)

<details>
<summary>Changes</summary>



---

Patch is 92.66 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/118167.diff


89 Files Affected:

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


``````````diff
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 004ce05c03996f..9b3cf913b46d17 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 8445b863b5c2ef..940e1a4452b00b 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 9f649e4978d65b..e85c92db595df1 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..6f3db916f96dce 100644
--- a/libcxx/include/__type_traits/extent.h
+++ b/libcxx/include/__type_traits/extent.h
@@ -22,11 +22,11 @@ _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..c386355ea0d7bd 100644
--- a/libcxx/include/__type_traits/invoke.h
+++ b/libcxx/include/__type_traits/invoke.h
@@ -230,35 +230,38 @@ 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 con...
[truncated]

``````````

</details>


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


More information about the libcxx-commits mailing list