-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Mark templates users shouldn't specialize with _NO_SPECIALIZATIONS
#5536
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
This comment was marked as off-topic.
This comment was marked as off-topic.
# AttributeMacros: | ||
# - __capability | ||
AttributeMacros: | ||
- _NO_SPECIALIZATIONS |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding the macro here is needed to avoid incorrect formatting like:
-struct _NO_SPECIALIZATIONS enable_if {};
+struct _NO_SPECIALIZATIONS enable_if{};
This PR doesn't include tests because I'm not sure how to implement them; unless I missed something, the std testing suite has no examples of tests verifying that a warning is triggered or compilation fails (only that a warning is not triggered, or compilation succeeds). |
_NO_SPECIALIZATIONS
CI is failing because |
I'd suggest adding to /tests/libcxx/expected_results.txt for now, so that the PR would otherwise pass CI |
@@ -756,8 +758,9 @@ struct _Default_allocator_traits { // traits for std::allocator | |||
}; | |||
|
|||
_EXPORT_STD template <class _Alloc> | |||
struct allocator_traits : conditional_t<_Is_default_allocator<_Alloc>::value, _Default_allocator_traits<_Alloc>, | |||
_Normal_allocator_traits<_Alloc>> {}; | |||
struct _NO_SPECIALIZATIONS allocator_traits : conditional_t<_Is_default_allocator<_Alloc>::value, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pedantically speaking, program-defined specialization of allocator_traits
is only forbidden since C++23. But it's possibly a good thing to "extend" the restriction to old modes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a clear migration path that's valid in all modes (define the relevant members in the allocator class), which could be an argument for extending the restriction.
stl/inc/initializer_list
Outdated
_STD_BEGIN | ||
_EXPORT_STD template <class _Elem> | ||
class initializer_list { | ||
class _NO_SPECIALIZATIONS initializer_list { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is only necessary for Clang. MSVC and EDG can forbid program-defined initializer_list
specializations themselves.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
Done |
I discovered that specializing |
This comment was marked as off-topic.
This comment was marked as off-topic.
/azp run STL-CI |
Azure Pipelines successfully started running 1 pipeline(s). |
This PR marks templates users shouldn't specialize with
[[msvc::no_specializations]]
or[[clang::no_specializations]]
, depending on the compiler.Resolves #5179.
The rule goes [namespace.std]:
Specializing class templates is allowed, with the exception of:
initializer_list
allocator_traits
coroutine_handle
compare_three_way_result
is_execution_policy
basic_format_arg
is_clock
generator
range_adaptor_closure
variant
tuple
unary_function
binary_function
Specializing variable templates is forbidden, with the exception of:
format_kind
disable_sized_sentinel_for
enable_borrowed_range
disable_sized_range
enable_view
enable_nonlocking_formatter_optimization
e_v
log2e_v
log10e_v
pi_v
inv_pi_v
inv_sqrtpi_v
ln2_v
ln10_v
sqrt2_v
sqrt3_v
inv_sqrt3_v
egamma_v
phi_v
Specializing any template in
<type_traits>
is forbidden, with the exception of:common_type
basic_common_reference
Specializing function templates is forbidden, but, following the decision made in P0551R3 Thou Shalt Not Specialize std Function Templates! #24, this PR doesn't touch any of them (except for
is_pointer_interconvertible_with_class
andis_corresponding_member
in<type_traits>
, as specializing those has always been forbidden).Relevant: PR implementing this warning in libc++