Skip to content

Commit 6f68481

Browse files
authored
[libc++] Use [[clang::no_specializations]] to diagnose invalid user specializations (#118167)
Some templates in the standard library are illegal to specialize for users (even if the specialization contains user-defined types). The [[clang::no_specializations]] attribute allows marking such base templates so that the compiler will diagnose if users try adding a specialization.
1 parent 0236cb6 commit 6f68481

File tree

93 files changed

+591
-204
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

93 files changed

+591
-204
lines changed

libcxx/include/__compare/compare_three_way_result.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ struct _LIBCPP_HIDE_FROM_ABI __compare_three_way_result<
3333
};
3434

3535
template <class _Tp, class _Up = _Tp>
36-
struct _LIBCPP_TEMPLATE_VIS compare_three_way_result : __compare_three_way_result<_Tp, _Up, void> {};
36+
struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS compare_three_way_result
37+
: __compare_three_way_result<_Tp, _Up, void> {};
3738

3839
template <class _Tp, class _Up = _Tp>
3940
using compare_three_way_result_t = typename compare_three_way_result<_Tp, _Up>::type;

libcxx/include/__config

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1168,6 +1168,13 @@ typedef __char32_t char32_t;
11681168

11691169
# define _LIBCPP_NODEBUG [[__gnu__::__nodebug__]]
11701170

1171+
# if __has_cpp_attribute(_Clang::__no_specializations__)
1172+
# define _LIBCPP_NO_SPECIALIZATIONS \
1173+
[[_Clang::__no_specializations__("Users are not allowed to specialize this standard library entity")]]
1174+
# else
1175+
# define _LIBCPP_NO_SPECIALIZATIONS
1176+
# endif
1177+
11711178
# if __has_attribute(__standalone_debug__)
11721179
# define _LIBCPP_STANDALONE_DEBUG __attribute__((__standalone_debug__))
11731180
# else

libcxx/include/__format/format_arg.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ class __basic_format_arg_value {
277277
};
278278

279279
template <class _Context>
280-
class _LIBCPP_TEMPLATE_VIS basic_format_arg {
280+
class _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS basic_format_arg {
281281
public:
282282
class _LIBCPP_TEMPLATE_VIS handle;
283283

libcxx/include/__ranges/range_adaptor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ template <_RangeAdaptorClosure _Closure, _RangeAdaptorClosure _OtherClosure>
8585
# if _LIBCPP_STD_VER >= 23
8686
template <class _Tp>
8787
requires is_class_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
88-
class range_adaptor_closure : public __range_adaptor_closure<_Tp> {};
88+
class _LIBCPP_NO_SPECIALIZATIONS range_adaptor_closure : public __range_adaptor_closure<_Tp> {};
8989
# endif // _LIBCPP_STD_VER >= 23
9090

9191
} // namespace ranges

libcxx/include/__type_traits/add_cv_quals.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
_LIBCPP_BEGIN_NAMESPACE_STD
1919

2020
template <class _Tp>
21-
struct _LIBCPP_TEMPLATE_VIS add_const {
21+
struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS add_const {
2222
using type _LIBCPP_NODEBUG = const _Tp;
2323
};
2424

@@ -28,7 +28,7 @@ using add_const_t = typename add_const<_Tp>::type;
2828
#endif
2929

3030
template <class _Tp>
31-
struct _LIBCPP_TEMPLATE_VIS add_cv {
31+
struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS add_cv {
3232
using type _LIBCPP_NODEBUG = const volatile _Tp;
3333
};
3434

@@ -38,7 +38,7 @@ using add_cv_t = typename add_cv<_Tp>::type;
3838
#endif
3939

4040
template <class _Tp>
41-
struct _LIBCPP_TEMPLATE_VIS add_volatile {
41+
struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS add_volatile {
4242
using type _LIBCPP_NODEBUG = volatile _Tp;
4343
};
4444

libcxx/include/__type_traits/add_lvalue_reference.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ using __add_lvalue_reference_t = typename __add_lvalue_reference_impl<_Tp>::type
4040
#endif // __has_builtin(__add_lvalue_reference)
4141

4242
template <class _Tp>
43-
struct add_lvalue_reference {
43+
struct _LIBCPP_NO_SPECIALIZATIONS add_lvalue_reference {
4444
using type _LIBCPP_NODEBUG = __add_lvalue_reference_t<_Tp>;
4545
};
4646

libcxx/include/__type_traits/add_pointer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ using __add_pointer_t = typename __add_pointer_impl<_Tp>::type;
4141
#endif // !defined(_LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS) && __has_builtin(__add_pointer)
4242

4343
template <class _Tp>
44-
struct add_pointer {
44+
struct _LIBCPP_NO_SPECIALIZATIONS add_pointer {
4545
using type _LIBCPP_NODEBUG = __add_pointer_t<_Tp>;
4646
};
4747

libcxx/include/__type_traits/add_rvalue_reference.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ using __add_rvalue_reference_t = typename __add_rvalue_reference_impl<_Tp>::type
4040
#endif // __has_builtin(__add_rvalue_reference)
4141

4242
template <class _Tp>
43-
struct add_rvalue_reference {
43+
struct _LIBCPP_NO_SPECIALIZATIONS add_rvalue_reference {
4444
using type = __add_rvalue_reference_t<_Tp>;
4545
};
4646

libcxx/include/__type_traits/aligned_storage.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ struct __find_max_align<__type_list<_Head, _Tail...>, _Len>
6868
__select_align<_Len, _Head::value, __find_max_align<__type_list<_Tail...>, _Len>::value>::value> {};
6969

7070
template <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::value>
71-
struct _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_TEMPLATE_VIS aligned_storage {
71+
struct _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS aligned_storage {
7272
union _ALIGNAS(_Align) type {
7373
unsigned char __data[(_Len + _Align - 1) / _Align * _Align];
7474
};

libcxx/include/__type_traits/aligned_union.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ struct __static_max<_I0, _I1, _In...> {
3333
};
3434

3535
template <size_t _Len, class _Type0, class... _Types>
36-
struct _LIBCPP_DEPRECATED_IN_CXX23 aligned_union {
36+
struct _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_NO_SPECIALIZATIONS aligned_union {
3737
static const size_t alignment_value =
3838
__static_max<_LIBCPP_PREFERRED_ALIGNOF(_Type0), _LIBCPP_PREFERRED_ALIGNOF(_Types)...>::value;
3939
static const size_t __len = __static_max<_Len, sizeof(_Type0), sizeof(_Types)...>::value;

0 commit comments

Comments
 (0)