Title
§[time.zone.leap] recursive constraint in <=>
Status
new
Section
[time.zone.leap]
Submitter
Corentin

Created on 2024-08-18.00:00:00 last changed 4 months ago

Messages

Date: 2024-08-15.00:00:00

[ 2024-08-21; Reflector poll ]

Set priority to 3 after reflector poll. Support for changing all relational ops for calendar types to hidden friends, but only doing it for `leap_second` would be in scope for this issue.

Date: 2024-08-18.00:00:00

Consider

decltype(std::declval<std::chrono::leap_second&>() <=> std::chrono::system_clock::now())

There is a <=> operator for leap second defined as

template<class Duration>
  requires three_way_comparable_with<sys_seconds, sys_time<Duration>>
  constexpr auto operator<=>(const leap_second& x, const sys_time<Duration>& y) noexcept;

In order to resolve this overload, we need to check the constraints. three_way_comparable_with will end up checking that sys_seconds{} < sys_time<Duration>{} is a valid expression. To do that, we run overload resolution, find a bunch of operator<=>, including the leap_second overload mentioned above. We check its constraints... and we find ourselves doing that recursively.

This problem currently doesn't manifest in production compilers because of a number of non-conforming behaviors of all implementations, but surfaced while fixing some of these issues in clang.

libstdc++ also does not suffer from this issue because leap_seconds comparisons operators are all hidden friends (in fact, libstdc++ define hidden friends comparison operators for most of the objects in chrono, which is nice!)

Suggested resolution:

Specify that leap_seconds operators are hidden friends. This would avoid the recursion, and would be easier on compilers.

History
Date User Action Args
2024-08-21 15:02:31adminsetmessages: + msg14330
2024-08-18 00:00:00admincreate