Commit graph

55 commits

Author SHA1 Message Date
Jonathan Wakely
eed7fb1b2f
libstdc++: Support link chains in std::chrono::tzdb::locate_zone [PR114770]
Since 2022 the TZif format defined in the zic(8) man page has said that
links can refer to other links, rather than only referring to a zone.
This isn't supported by the C++20 spec, which assumes that the target()
for a chrono::time_zone_link always names a chrono::time_zone, not
another chrono::time_zone_link.

This hasn't been a problem until now, because there are no entries in
the tzdata file that chain links together. However, Debian Sid has
changed the target of the Asia/Chungking link from the Asia/Shanghai
zone to the Asia/Chongqing link, creating a link chain. The libstdc++
code is unable to handle this, so chrono::locate_zone("Asia/Chungking")
will fail with the tzdata.zi file from Debian Sid.

It seems likely that the C++ spec will need a change to allow link
chains, so that the original structure of the IANA database can be fully
represented by chrono::tzdb. The alternative would be for chrono::tzdb
to flatten all chains when loading the data, so that a link's target is
always a zone, but this means throwing away information present in the
tzdata.zi input file.

In anticipation of a change to the spec, this commit adds support for
chained links to libstdc++. When a name is found to be a link, we try to
find its target in the list of zones as before, but now if the target
isn't the name of a zone we don't fail. Instead we look for another link
with that name, and keep doing that until we reach the end of the chain
of links, and then look up the last target as a zone.

This new logic would get stuck in a loop if the tzdata.zi file is buggy
and defines a link chain that contains a cycle, e.g. two links that
refer to each other. To deal with that unlikely case, we use the
tortoise and hare algorithm to detect cycles in link chains, and throw
an exception if we detect a cycle. Cycles in links should never happen,
and it is expected that link chains will be short (if they occur at all)
and so the code is optimized for short chains without cycles. Longer
chains (four or more links) and cycles will do more work, but won't fail
to resolve a chain or get stuck in a loop.

The new test file checks various forms of broken links and cycles.

Also add a new check in the testsuite that every element in the
get_tzdb().zones and get_tzdb().links sequences can be successfully
found using locate_zone.

libstdc++-v3/ChangeLog:

	PR libstdc++/114770
	* src/c++20/tzdb.cc (do_locate_zone): Support links that have
	another link as their target.
	* testsuite/std/time/tzdb/1.cc: Check that all zones and links
	can be found by locate_zone.
	* testsuite/std/time/tzdb/links.cc: New test.
2024-04-19 21:06:28 +01:00
Jonathan Wakely
4decc1062f
libstdc++: Adjust expected locale-dependent date formats in tests
The std/time/year_month_day/io.cc test assumes that %x in the fr_FR
locale is %d/%m/%Y but on FreeBSD it is %d.%m.%Y instead. Make the test
PASS for either format.

Similarly, 27_io/manipulators/extended/get_time/char/2.cc expects that
%a in the de_DE locale is "Di" but on FreeBSD it's "Di." with a trailing
period. Adjust the input string to be "1971 Di." instead of "Di 1971"
and that way if %a doesn't expect the trailing '.' it simply won't
extract it from the stream.

This fixes:
FAIL: std/time/year_month_day/io.cc  -std=gnu++20 execution test
FAIL: 27_io/manipulators/extended/get_time/char/2.cc  -std=gnu++17 execution test

libstdc++-v3/ChangeLog:

	* testsuite/27_io/manipulators/extended/get_time/char/2.cc:
	Adjust input string so that it matches %a with or without a
	trailing period.
	* testsuite/std/time/year_month_day/io.cc: Adjust expected
	format for %x in the fr_FR locale.
2024-04-10 16:14:25 +01:00
Jonathan Wakely
3e8ee03edd libstdc++: Do not require a time-of-day when parsing sys_days [PR114240]
When parsing a std::chrono::sys_days (or a sys_time with an even longer
period) we should not require a time-of-day to be present in the input,
because we can't represent that in the result type anyway.

Rather than trying to decide which specializations should require a
time-of-date and which should not, follow the direction of Howard
Hinnant's date library, which allows extracting a sys_time of any period
from input that only contains a date, defaulting the time-of-day part to
00:00:00. This seems consistent with the intent of the standard, which
says it's an error "If the parse fails to decode a valid date" (i.e., it
doesn't care about decoding a valid time, only a date).

libstdc++-v3/ChangeLog:

	PR libstdc++/114240
	* include/bits/chrono_io.h (_Parser::operator()): Assume
	hours(0) for a time_point, so that a time is not required
	to be present.
	* testsuite/std/time/parse/114240.cc: New test.
2024-03-09 00:21:42 +00:00
Jonathan Wakely
f4a52c184d libstdc++: Fix parsing of leap seconds as chrono::utc_time [PR114279]
Implementing all chrono::from_stream overloads in terms of
chrono::sys_time meant that a leap second time like 23:59:60.001 cannot
be parsed, because that cannot be represented in a sys_time.

The fix to support parsing leap seconds as utc_time is to convert the
parsed date to utc_time<days> and then add the parsed time to that,
which allows the result to land in a leap second, rather than doing all
the arithmetic with sys_time which doesn't have leap seconds.

For local_time we also allow %S to parse a 60s value, because doing
otherwise might disallow some valid uses. We can't know all use cases
users have for treating times as local_time.

For all other clocks, we can reject times that have 60 or 60.nnn as the
seconds part, because that cannot occur in a valid UNIX, GPS, or TAI
time. Since our chrono::file_clock uses sys_time, it can't occur for
that clock either.

In order to support this a new _M_is_leap_second member is needed in the
_Parser type. This can be added at the end, where most targets currently
have padding bytes. Similar to what I did recently for formatter _Spec
structs, we can also reserve additional padding bits for future
expansion.

This also fixes bugs in the from_stream overloads for utc_time,
tai_time, gps_time, and file_time, which were not using time_point_cast
to explicitly convert to the result type. That's needed because the
result type might have lower precision than the value returned from
from_sys or from_utc, which has a precision no lower than seconds.

libstdc++-v3/ChangeLog:

	PR libstdc++/114279
	* include/bits/chrono_io.h (_Parser::_M_is_leap_second): New
	data member.
	(_Parser::_M_reserved): Reserve padding bits for future use.
	(_Parser::operator()): Set _M_is_leap_second if %S reads 60s.
	(from_stream): Only allow _M_is_leap_second for utc_time and
	local_time. Adjust arithmetic for utc_time so that leap seconds
	are preserved. Use time_point_cast to convert to a possibly
	lower-precision result type.
	* testsuite/std/time/parse.cc: Move to ...
	* testsuite/std/time/parse/parse.cc: ... here.
	* testsuite/std/time/parse/114279.cc: New test.
2024-03-09 00:21:42 +00:00
Jonathan Wakely
ddd347fca0 libstdc++: Update expiry times for leap seconds lists
The list in tzdb.cc isn't the only hardcoded list of leap seconds in the
library, there's the one defined inline in <chrono> (to avoid loading
the tzdb for the common case) and another in a testcase. This updates
them to note that there are no new leap seconds in 2024 either, until at
least 2024-12-28.

libstdc++-v3/ChangeLog:

	* include/std/chrono (__get_leap_second_info): Update expiry
	time for hardcoded list of leap seconds.
	* testsuite/std/time/tzdb/leap_seconds.cc: Update comment.
2024-03-07 20:55:25 +00:00
Jonathan Wakely
5525dd754b libstdc++: Fix check in testsuite/std/time/clock/gps/io.cc
The test_format() function contained an incorrect assertion but wasn't
actually being called from main.

libstdc++-v3/ChangeLog:

	* testsuite/std/time/clock/gps/io.cc: Fix expected result in
	assertion and call test_format() from main.
2024-01-30 14:50:07 +00:00
Jonathan Wakely
8229214fae libstdc++: Fix check in testsuite/std/time/clock/file/io.cc
The test_format() function contained an incorrect assertion but wasn't
actually being called from main.

libstdc++-v3/ChangeLog:

	* testsuite/std/time/clock/file/io.cc: Fix expected result in
	assertion and call test_format() from main.
2024-01-22 13:06:00 +00:00
Jonathan Wakely
7431fcea6b libstdc++: Fix std::format for floating-point chrono::time_point [PR113500]
Currently trying to use std::format with certain specializations of
std::chrono::time_point is ill-formed, due to one member function of the
__formatter_chrono type which tries to write a time_point to an ostream.
For sys_time<floating-point> or sys_time with a period greater than days
there is no operator<< that can be used.

That operator<< is only needed when using an empty chrono-specs in the
format string, like "{}", but the ill-formed expression gives an error
even if not actually used. This means it's not possible to format some
other specializations of chrono::time_point, even when using a non-empty
chrono-specs.

This fixes it by avoiding using 'os << t' for all chrono::time_point
specializations, and instead using std::format("{:L%F %T}", t). So that
we continue to reject std::format("{}", sys_time{1.0s}) a check for
empty chrono-specs is added to the formatter<sys_time<D>, C>
specialization.

While testing this I noticed that the output for %S with a
floating-point duration was incorrect, as the subseconds part was being
appended to the seconds without a decimal point, and without the correct
number of leading zeros.

libstdc++-v3/ChangeLog:

	PR libstdc++/113500
	* include/bits/chrono_io.h (__formatter_chrono::_M_S): Fix
	printing of subseconds with floating-point rep.
	(__formatter_chrono::_M_format_to_ostream): Do not write
	time_point specializations directly to the ostream.
	(formatter<chrono::sys_time<D>, C>::parse): Do not allow an
	empty chrono-spec if the type fails to meet the constraints for
	writing to an ostream with operator<<.
	* testsuite/std/time/clock/file/io.cc: Check formatting
	non-integral times with empty chrono-specs.
	* testsuite/std/time/clock/gps/io.cc: Likewise.
	* testsuite/std/time/clock/utc/io.cc: Likewise.
	* testsuite/std/time/hh_mm_ss/io.cc: Likewise.
2024-01-21 22:15:06 +00:00
Jonathan Wakely
fba15da8fa libstdc++: Fix std::chrono::file_clock conversions for low-precision times
THe std::chrono::file_clock conversions were not using common_type and
so failed to compile when converting anything that should have increased
precision after arithmetic with a std::chrono::seconds value.

libstdc++-v3/ChangeLog:

	* include/bits/chrono.h (__file_clock::from_sys)
	(__file_clock::to_sys, __file_clock::_S_from_sys)
	(__file_clock::_S_to_sys): Use common_type for return type.
	* testsuite/std/time/clock/file/members.cc: Check round trip
	conversion for time with lower precision that seconds.
2024-01-21 22:15:06 +00:00
Jonathan Wakely
2a8ee2592e libstdc++: Implement P2905R2 "Runtime format strings" for C++20
This change makes std::make_format_args refuse to create dangling
references to temporaries. This makes the std::vformat API safer. This
was approved in Kona 2023 as a DR for C++20 so the change is implemented
unconditionally.

libstdc++-v3/ChangeLog:

	* include/bits/chrono_io.h (__formatter_chrono): Always use
	lvalue arguments to make_format_args.
	* include/std/format (make_format_args): Change parameter pack
	from forwarding references to lvalue references. Remove use of
	remove_reference_t which is now unnecessary.
	(format_to, formatted_size): Remove incorrect forwarding of
	arguments.
	* include/std/ostream (print): Remove forwarding of arguments.
	* include/std/print (print): Likewise.
	* testsuite/20_util/duration/io.cc: Use lvalues as arguments to
	make_format_args.
	* testsuite/std/format/arguments/args.cc: Likewise.
	* testsuite/std/format/arguments/lwg3810.cc: Likewise.
	* testsuite/std/format/functions/format.cc: Likewise.
	* testsuite/std/format/functions/vformat_to.cc: Likewise.
	* testsuite/std/format/string.cc: Likewise.
	* testsuite/std/time/day/io.cc: Likewise.
	* testsuite/std/time/month/io.cc: Likewise.
	* testsuite/std/time/weekday/io.cc: Likewise.
	* testsuite/std/time/year/io.cc: Likewise.
	* testsuite/std/time/year_month_day/io.cc: Likewise.
	* testsuite/std/format/arguments/args_neg.cc: New test.
2024-01-08 01:14:50 +00:00
Cassio Neri
2cb3d42d3f libstdc++: Remove UB from month and weekday additions and subtractions.
The following invoke signed integer overflow (UB) [1]:

  month   + months{MAX} // where MAX is the maximum value of months::rep
  month   + months{MIN} // where MIN is the maximum value of months::rep
  month   - months{MIN} // where MIN is the minimum value of months::rep
  weekday + days  {MAX} // where MAX is the maximum value of days::rep
  weekday - days  {MIN} // where MIN is the minimum value of days::rep

For the additions to MAX, the crux of the problem is that, in libstdc++,
months::rep and days::rep are int64_t. Other implementations use int32_t, cast
operands to int64_t and perform arithmetic operations without risk of
overflowing.

For month + months{MIN}, the implementation follows the Standard's "returns
clause" and evaluates:

   modulo(static_cast<long long>(unsigned{__x}) + (__y.count() - 1), 12);

Overflow occurs when MIN - 1 is evaluated. Casting to a larger type could help
but, unfortunately again, this is not possible for libstdc++.

For the subtraction of MIN, the problem is that -MIN is not representable.

It's fair to say that the intention is for these additions/subtractions to
be performed in modulus (12 or 7) arithmetic so that no overflow is expected.

To fix these UB, this patch implements:

  template <unsigned __d, typename _T>
  unsigned __add_modulo(unsigned __x, _T __y);

  template <unsigned __d, typename _T>
  unsigned __sub_modulo(unsigned __x, _T __y);

which respectively, returns the remainder of Euclidean division of, __x + __y
and __x - __y by __d without overflowing. These functions replace

  constexpr unsigned __modulo(long long __n, unsigned __d);

which also calculates the reminder of __n, where __n is the result of the
addition or subtraction. Hence, these operations might invoke UB before __modulo
is called and thus, __modulo can't do anything to remediate the issue.

In addition to solve the UB issues, __add_modulo and __sub_modulo allow better
codegen (shorter and branchless) on x86-64 and ARM [2].

[1] https://godbolt.org/z/a9YfWdn57
[2] https://godbolt.org/z/Gh36cr7E4

libstdc++-v3/ChangeLog:

	* include/std/chrono: Fix + and - for months and weekdays.
	* testsuite/std/time/month/1.cc: Add constexpr tests against overflow.
	* testsuite/std/time/month/2.cc: New test for extreme values.
	* testsuite/std/time/weekday/1.cc: Add constexpr tests against overflow.
	* testsuite/std/time/weekday/2.cc: New test for extreme values.
2024-01-05 10:23:35 +00:00
Jakub Jelinek
a945c346f5 Update copyright years. 2024-01-03 12:19:35 +01:00
Jonathan Wakely
a01462ae8b libstdc++: Fix std::format output of %C for negative years
During discussion of LWG 4022 I noticed that we do not correctly
implement floored division for the century. We were just truncating
towards zero, rather than applying the floor function. For negative
values that rounds the wrong way.

libstdc++-v3/ChangeLog:

	* include/bits/chrono_io.h (__formatter_chrono::_M_C_y_Y): Fix
	rounding for negative centuries.
	* testsuite/std/time/year/io.cc: Check %C for negative years.
2023-12-12 22:33:32 +00:00
Jonathan Wakely
f4ab68469c libstdc++: Test for feature test macros more accurately
Tests which check for feature test macros should use the no_pch option,
so that we're really testing for the definition being in the intended
header, and not just testing that it's present in <bits/stdc++.h> (which
includes all the standard headers and so defines all the macros).

libstdc++-v3/ChangeLog:

	* testsuite/18_support/byte/requirements.cc: Disable PCH.
	* testsuite/18_support/destroying_delete.cc: Likewise.
	* testsuite/18_support/source_location/1.cc: Likewise.
	* testsuite/18_support/source_location/version.cc: Likewise.
	* testsuite/18_support/type_info/constexpr.cc: Likewise.
	* testsuite/18_support/uncaught_exceptions/uncaught_exceptions.cc:
	Likewise.
	* testsuite/19_diagnostics/stacktrace/output.cc: Likewise.
	* testsuite/19_diagnostics/stacktrace/synopsis.cc: Likewise.
	* testsuite/19_diagnostics/stacktrace/version.cc: Likewise.
	* testsuite/20_util/addressof/requirements/constexpr.cc:
	Likewise.
	* testsuite/20_util/allocator_traits/header-2.cc: Likewise.
	* testsuite/20_util/allocator_traits/header.cc: Likewise.
	* testsuite/20_util/as_const/1.cc: Likewise. Likewise.
	* testsuite/20_util/bitset/cons/constexpr_c++23.cc: Likewise.
	* testsuite/20_util/bitset/version.cc: Likewise.
	* testsuite/20_util/duration/arithmetic/constexpr_c++17.cc:
	Likewise.
	* testsuite/20_util/duration_cast/rounding.cc: Likewise.
	* testsuite/20_util/enable_shared_from_this/members/weak_from_this.cc:
	Likewise.
	* testsuite/20_util/exchange/constexpr.cc: Likewise.
	* testsuite/20_util/expected/synopsis.cc: Likewise.
	* testsuite/20_util/expected/version.cc: Likewise.
	* testsuite/20_util/function_objects/bind_front/1.cc: Likewise.
	* testsuite/20_util/function_objects/bind_front/2.cc: Likewise.
	* testsuite/20_util/function_objects/invoke/3.cc: Likewise.
	* testsuite/20_util/function_objects/invoke/4.cc: Likewise.
	* testsuite/20_util/function_objects/invoke/constexpr.cc:
	Likewise.
	* testsuite/20_util/function_objects/invoke/version.cc:
	Likewise.
	* testsuite/20_util/function_objects/searchers.cc: Likewise.
	* testsuite/20_util/integer_comparisons/1.cc: Likewise.
	* testsuite/20_util/integer_comparisons/2.cc: Likewise.
	* testsuite/20_util/is_bounded_array/value.cc: Likewise.
	* testsuite/20_util/is_layout_compatible/value.cc: Likewise.
	* testsuite/20_util/is_layout_compatible/version.cc: Likewise.
	* testsuite/20_util/is_nothrow_swappable/requirements/explicit_instantiation.cc:
	Likewise.
	* testsuite/20_util/is_nothrow_swappable/requirements/typedefs.cc:
	Likewise.
	* testsuite/20_util/is_nothrow_swappable/value.cc: Likewise.
	* testsuite/20_util/is_nothrow_swappable/value.h: Likewise.
	* testsuite/20_util/is_nothrow_swappable_with/requirements/explicit_instantiation.cc:
	Remove redundant checks already tested elsewhere.
	* testsuite/20_util/is_nothrow_swappable_with/requirements/typedefs.cc:
	Likewise.
	* testsuite/20_util/is_nothrow_swappable_with/value.cc: Disable
	PCH.
	* testsuite/20_util/is_pointer_interconvertible/value.cc:
	Likewise.
	* testsuite/20_util/is_pointer_interconvertible/version.cc:
	Likewise.
	* testsuite/20_util/is_scoped_enum/value.cc: Likewise.
	* testsuite/20_util/is_scoped_enum/version.cc: Likewise.
	* testsuite/20_util/is_swappable/requirements/explicit_instantiation.cc:
	Remove redundant checks already tested elsewhere.
	* testsuite/20_util/is_swappable/requirements/typedefs.cc:
	Remove redundant checks already tested elsewhere.
	* testsuite/20_util/is_swappable/value.cc: Disable PCH.
	* testsuite/20_util/is_swappable/value.h: Reorder headers.
	* testsuite/20_util/is_swappable_with/requirements/explicit_instantiation.cc:
	Remove redundant checks already tested elsewhere.
	* testsuite/20_util/is_swappable_with/requirements/typedefs.cc:
	Remove redundant checks already tested elsewhere.
	* testsuite/20_util/is_swappable_with/value.cc: Disable PCH.
	* testsuite/20_util/is_unbounded_array/value.cc: Likewise.
	* testsuite/20_util/move_only_function/cons.cc: Likewise.
	* testsuite/20_util/move_only_function/version.cc: Likewise.
	* testsuite/20_util/optional/monadic/and_then.cc: Likewise.
	* testsuite/20_util/optional/requirements.cc: Likewise.
	* testsuite/20_util/optional/version.cc: Likewise.
	* testsuite/20_util/owner_less/void.cc: Likewise.
	* testsuite/20_util/reference_from_temporary/value.cc: Likewise.
	* testsuite/20_util/reference_from_temporary/version.cc:
	Likewise.
	* testsuite/20_util/shared_ptr/atomic/atomic_shared_ptr.cc:
	Likewise.
	* testsuite/20_util/shared_ptr/creation/array.cc: Likewise.
	* testsuite/20_util/shared_ptr/creation/overwrite.cc: Likewise.
	* testsuite/20_util/shared_ptr/creation/version.cc: Likewise.
	* testsuite/20_util/time_point_cast/rounding.cc: Likewise.
	* testsuite/20_util/to_chars/constexpr.cc: Likewise.
	* testsuite/20_util/to_chars/result.cc: Likewise.
	* testsuite/20_util/to_chars/version.cc: Likewise.
	* testsuite/20_util/to_underlying/1.cc: Likewise.
	* testsuite/20_util/to_underlying/version.cc: Likewise.
	* testsuite/20_util/tuple/apply/1.cc: Likewise.
	* testsuite/20_util/tuple/cons/constexpr_allocator_arg_t.cc:
	Likewise.
	* testsuite/20_util/tuple/make_from_tuple/1.cc: Likewise.
	* testsuite/20_util/tuple/p2321r2.cc: Likewise.
	* testsuite/20_util/tuple/tuple_element_t.cc: Likewise.
	* testsuite/20_util/unique_ptr/cons/constexpr_c++20.cc:
	Likewise.
	* testsuite/20_util/unique_ptr/creation/for_overwrite.cc:
	Likewise.
	* testsuite/20_util/unreachable/1.cc: Likewise.
	* testsuite/20_util/unreachable/version.cc: Likewise.
	* testsuite/20_util/unwrap_reference/1.cc: Likewise.
	* testsuite/20_util/unwrap_reference/3.cc: Likewise.
	* testsuite/20_util/variant/constexpr.cc: Likewise.
	* testsuite/20_util/variant/version.cc: Likewise.
	* testsuite/20_util/variant/visit_inherited.cc: Likewise.
	* testsuite/20_util/void_t/1.cc: Likewise.
	* testsuite/21_strings/basic_string/capacity/char/resize_and_overwrite.cc:
	Likewise.
	* testsuite/21_strings/basic_string/cons/char/constexpr.cc:
	Likewise.
	* testsuite/21_strings/basic_string/cons/wchar_t/constexpr.cc:
	Likewise.
	* testsuite/21_strings/basic_string/erasure.cc: Likewise.
	* testsuite/21_strings/basic_string/numeric_conversions/char/to_string_float.cc:
	Likewise.
	* testsuite/21_strings/basic_string/numeric_conversions/version.cc:
	Likewise.
	* testsuite/21_strings/basic_string/version.cc: Likewise.
	* testsuite/21_strings/basic_string_view/operations/contains/char.cc:
	Likewise.
	* testsuite/21_strings/basic_string_view/operations/contains/char/2.cc:
	Likewise.
	* testsuite/21_strings/basic_string_view/operations/copy/char/constexpr.cc:
	Likewise.
	* testsuite/21_strings/char_traits/requirements/constexpr_functions_c++17.cc:
	Likewise.
	* testsuite/21_strings/char_traits/requirements/constexpr_functions_c++20.cc:
	Likewise.
	* testsuite/21_strings/char_traits/requirements/version.cc:
	Likewise.
	* testsuite/23_containers/array/comparison_operators/constexpr.cc:
	Likewise.
	* testsuite/23_containers/array/creation/1.cc: Likewise.
	* testsuite/23_containers/array/creation/2.cc: Likewise.
	* testsuite/23_containers/array/element_access/constexpr_c++17.cc:
	Likewise.
	* testsuite/23_containers/array/requirements/constexpr_fill.cc:
	Likewise.
	* testsuite/23_containers/array/requirements/constexpr_iter.cc:
	Likewise.
	* testsuite/23_containers/deque/erasure.cc: Likewise.
	* testsuite/23_containers/forward_list/erasure.cc: Likewise.
	* testsuite/23_containers/list/erasure.cc: Likewise.
	* testsuite/23_containers/map/erasure.cc: Likewise.
	* testsuite/23_containers/queue/cons_from_iters.cc: Likewise.
	* testsuite/23_containers/set/erasure.cc: Likewise.
	* testsuite/23_containers/span/1.cc: Likewise.
	* testsuite/23_containers/span/2.cc: Likewise.
	* testsuite/23_containers/stack/cons_from_iters.cc: Likewise.
	* testsuite/23_containers/unordered_map/erasure.cc: Likewise.
	* testsuite/23_containers/unordered_map/operations/1.cc:
	Likewise.
	* testsuite/23_containers/unordered_set/erasure.cc: Likewise.
	* testsuite/23_containers/unordered_set/operations/1.cc:
	Likewise.
	* testsuite/23_containers/vector/cons/constexpr.cc: Likewise.
	* testsuite/23_containers/vector/erasure.cc: Likewise.
	* testsuite/23_containers/vector/requirements/version.cc:
	Likewise.
	* testsuite/24_iterators/insert_iterator/constexpr.cc: Likewise.
	* testsuite/25_algorithms/clamp/constexpr.cc: Likewise.
	* testsuite/25_algorithms/clamp/requirements/explicit_instantiation/1.cc:
	Remove redundant checks already tested elsewhere.
	* testsuite/25_algorithms/constexpr_macro.cc: Likewise.
	* testsuite/25_algorithms/cpp_lib_constexpr.cc: Likewise.
	* testsuite/25_algorithms/fold_left/1.cc: Likewise.
	* testsuite/25_algorithms/pstl/feature_test-2.cc: Likewise.
	* testsuite/25_algorithms/pstl/feature_test-3.cc: Likewise.
	* testsuite/25_algorithms/pstl/feature_test-4.cc: Likewise.
	* testsuite/25_algorithms/pstl/feature_test-5.cc: Likewise.
	* testsuite/25_algorithms/pstl/feature_test.cc: Likewise.
	* testsuite/26_numerics/bit/bit.byteswap/byteswap.cc: Likewise.
	* testsuite/26_numerics/bit/bit.byteswap/version.cc: Likewise.
	* testsuite/26_numerics/bit/bit.cast/bit_cast.cc: Likewise.
	* testsuite/26_numerics/bit/bit.cast/version.cc: Likewise.
	* testsuite/26_numerics/bit/header-2.cc: Likewise.
	* testsuite/26_numerics/bit/header.cc: Likewise.
	* testsuite/26_numerics/complex/1.cc: Likewise.
	* testsuite/26_numerics/complex/2.cc: Likewise.
	* testsuite/26_numerics/endian/2.cc: Likewise.
	* testsuite/26_numerics/endian/3.cc: Likewise.
	* testsuite/26_numerics/gcd/1.cc: Likewise.
	* testsuite/26_numerics/lcm/1.cc: Likewise.
	* testsuite/26_numerics/lerp/1.cc: Likewise.
	* testsuite/26_numerics/lerp/version.cc: Likewise.
	* testsuite/26_numerics/midpoint/integral.cc: Likewise.
	* testsuite/26_numerics/midpoint/version.cc: Likewise.
	* testsuite/26_numerics/numbers/1.cc: Likewise.
	* testsuite/26_numerics/numbers/2.cc: Likewise.
	* testsuite/27_io/basic_filebuf/native_handle/char/1.cc:
	Likewise.
	* testsuite/27_io/basic_filebuf/native_handle/version.cc:
	Likewise.
	* testsuite/27_io/basic_ofstream/open/char/noreplace.cc:
	Likewise.
	* testsuite/27_io/basic_ofstream/open/wchar_t/noreplace.cc:
	Likewise.
	* testsuite/27_io/basic_syncbuf/1.cc: Likewise.
	* testsuite/27_io/basic_syncbuf/2.cc: Likewise.
	* testsuite/27_io/basic_syncstream/1.cc: Likewise.
	* testsuite/27_io/basic_syncstream/2.cc: Likewise.
	* testsuite/27_io/spanstream/1.cc: Likewise.
	* testsuite/27_io/spanstream/version.cc: Likewise.
	* testsuite/29_atomics/atomic/cons/value_init.cc: Likewise.
	* testsuite/29_atomics/atomic/lock_free_aliases.cc: Likewise.
	* testsuite/29_atomics/atomic/wait_notify/1.cc: Likewise.
	* testsuite/29_atomics/atomic/wait_notify/2.cc: Likewise.
	* testsuite/29_atomics/headers/stdatomic.h/c_compat.cc:
	Likewise.
	* testsuite/29_atomics/headers/stdatomic.h/version.cc: Likewise.
	* testsuite/30_threads/barrier/1.cc: Likewise.
	* testsuite/30_threads/barrier/2.cc: Likewise.
	* testsuite/30_threads/condition_variable_any/stop_token/1.cc:
	Likewise.
	* testsuite/30_threads/condition_variable_any/stop_token/2.cc:
	Likewise.
	* testsuite/30_threads/jthread/1.cc: Likewise.
	* testsuite/30_threads/jthread/version.cc: Likewise.
	* testsuite/30_threads/latch/1.cc: Likewise.
	* testsuite/30_threads/latch/2.cc: Likewise.
	* testsuite/30_threads/scoped_lock/requirements/typedefs.cc:
	Likewise.
	* testsuite/30_threads/semaphore/1.cc: Likewise.
	* testsuite/30_threads/semaphore/2.cc: Likewise.
	* testsuite/30_threads/stop_token/1.cc: Likewise.
	* testsuite/30_threads/stop_token/2.cc: Likewise.
	* testsuite/experimental/feat-char8_t.cc: Likewise.
	* testsuite/experimental/iterator/ostream_joiner.cc: Likewise.
	* testsuite/experimental/numeric/gcd.cc: Likewise.
	* testsuite/experimental/scopeguard/uniqueres.cc: Likewise.
	* testsuite/std/concepts/1.cc: Likewise.
	* testsuite/std/concepts/2.cc: Likewise.
	* testsuite/std/ranges/adaptors/as_const/1.cc: Likewise.
	* testsuite/std/ranges/adaptors/as_rvalue/1.cc: Likewise.
	* testsuite/std/ranges/adaptors/chunk/1.cc: Likewise.
	* testsuite/std/ranges/adaptors/chunk_by/1.cc: Likewise.
	* testsuite/std/ranges/adaptors/enumerate/1.cc: Likewise.
	* testsuite/std/ranges/adaptors/join_with/1.cc: Likewise.
	* testsuite/std/ranges/adaptors/slide/1.cc: Likewise.
	* testsuite/std/ranges/adaptors/stride/1.cc: Likewise.
	* testsuite/std/ranges/cartesian_product/1.cc: Likewise.
	* testsuite/std/ranges/headers/ranges/synopsis.cc: Likewise.
	* testsuite/std/ranges/repeat/1.cc: Likewise.
	* testsuite/std/ranges/version_c++23.cc: Likewise.
	* testsuite/std/ranges/zip/1.cc: Likewise.
	* testsuite/std/time/syn_c++20.cc: Likewise.
	* testsuite/experimental/feat-cxx14.cc: Likewise. Include
	<algorithm> and <iterator>.
	* testsuite/23_containers/array/tuple_interface/get_neg.cc:
	Adjust dg-error line numbers.
2023-11-16 08:06:59 +00:00
Cassio Neri
f6ce081d0f libstdc++: Fix UB in weekday::weekday(sys_days) and add test
The following has undefined behaviour (signed overflow) [1]:
    weekday max{sys_days{days{numeric_limits<days::rep>::max()}}};

The issue is in this line when __n is very large and __n + 4 overflows:
    return weekday(__n >= -4 ? (__n + 4) % 7 : (__n + 5) % 7 + 6);

In addition to fixing this bug, the new implementation makes the compiler emit
shorter and branchless code for x86-64 and ARM [2].

[1] https://godbolt.org/z/1s5bv7KfT
[2] https://godbolt.org/z/zKsabzrhs

libstdc++-v3/ChangeLog:

	* include/std/chrono (weekday::_S_from_days): Fix UB.
	* testsuite/std/time/weekday/1.cc: Add test for overflow.
2023-11-14 22:32:08 +00:00
Jonathan Wakely
c28b0326ce libstdc++: Add dg-timeout-factor to remaining <chrono> IO tests
I meant to add these changes as part of r14-4959-g7d06b29f814580 but
missed these files out.

libstdc++-v3/ChangeLog:

	* testsuite/std/time/clock/file/io.cc: Double timeout using
	dg-timeout-factor.
	* testsuite/std/time/clock/gps/io.cc: Likewise.
	* testsuite/std/time/clock/local/io.cc: Likewise.
	* testsuite/std/time/clock/system/io.cc: Likewise.
	* testsuite/std/time/clock/tai/io.cc: Likewise.
	* testsuite/std/time/clock/utc/io.cc: Likewise.
2023-11-13 23:22:19 +00:00
Jonathan Wakely
7d06b29f81 libstdc++: Add dg-timeout-factor to <chrono> IO tests
This avoids failures due to compilation timeouts when testing with a low
tool_timeout value.

libstdc++-v3/ChangeLog:

	* testsuite/20_util/duration/io.cc: Double timeout using
	dg-timeout-factor.
	* testsuite/std/time/day/io.cc: Likewise.
	* testsuite/std/time/format.cc: Likewise.
	* testsuite/std/time/hh_mm_ss/io.cc: Likewise.
	* testsuite/std/time/month/io.cc: Likewise.
	* testsuite/std/time/month_day/io.cc: Likewise.
	* testsuite/std/time/month_day_last/io.cc: Likewise.
	* testsuite/std/time/month_weekday/io.cc: Likewise.
	* testsuite/std/time/month_weekday_last/io.cc: Likewise.
	* testsuite/std/time/weekday/io.cc: Likewise.
	* testsuite/std/time/weekday_indexed/io.cc: Likewise.
	* testsuite/std/time/weekday_last/io.cc: Likewise.
	* testsuite/std/time/year/io.cc: Likewise.
	* testsuite/std/time/year_month/io.cc: Likewise.
	* testsuite/std/time/year_month_day/io.cc: Likewise.
	* testsuite/std/time/year_month_day_last/io.cc: Likewise.
	* testsuite/std/time/year_month_weekday/io.cc: Likewise.
	* testsuite/std/time/year_month_weekday_last/io.cc: Likewise.
	* testsuite/std/time/zoned_time/io.cc: Likewise.
2023-10-26 21:10:47 +01:00
Jonathan Wakely
41cd9d4dfe libstdc++: Remove dg-options "-std=gnu++20" from std::chrono tests
The testsuite will automatically select C++20 for these tests now, and
removing the hardcoded -std option allows them to be tested for C++23
and C++26 as well.

libstdc++-v3/ChangeLog:

	* testsuite/20_util/duration/arithmetic/overflow_c++20.cc:
	Remove dg-options.
	* testsuite/20_util/duration/io.cc: Likewise.
	* testsuite/std/time/clock/file/io.cc: Likewise.
	* testsuite/std/time/clock/file/members.cc: Likewise.
	* testsuite/std/time/clock/file/overview.cc: Likewise.
	* testsuite/std/time/clock/gps/1.cc: Likewise.
	* testsuite/std/time/clock/gps/io.cc: Likewise.
	* testsuite/std/time/clock/local/io.cc: Likewise.
	* testsuite/std/time/clock/system/io.cc: Likewise.
	* testsuite/std/time/clock/tai/1.cc: Likewise.
	* testsuite/std/time/clock/tai/io.cc: Likewise.
	* testsuite/std/time/clock/utc/1.cc: Likewise.
	* testsuite/std/time/clock/utc/io.cc: Likewise.
	* testsuite/std/time/clock/utc/leap_second_info.cc: Likewise.
	* testsuite/std/time/day/1.cc: Likewise.
	* testsuite/std/time/day/io.cc: Likewise.
	* testsuite/std/time/exceptions.cc: Likewise.
	* testsuite/std/time/format.cc: Likewise.
	* testsuite/std/time/hh_mm_ss/1.cc: Likewise.
	* testsuite/std/time/hh_mm_ss/109772.cc: Likewise.
	* testsuite/std/time/hh_mm_ss/io.cc: Likewise.
	* testsuite/std/time/is_am/1.cc: Likewise.
	* testsuite/std/time/is_pm/1.cc: Likewise.
	* testsuite/std/time/make12/1.cc: Likewise.
	* testsuite/std/time/make24/1.cc: Likewise.
	* testsuite/std/time/month/1.cc: Likewise.
	* testsuite/std/time/month/io.cc: Likewise.
	* testsuite/std/time/month_day/1.cc: Likewise.
	* testsuite/std/time/month_day/io.cc: Likewise.
	* testsuite/std/time/month_day_last/1.cc: Likewise.
	* testsuite/std/time/month_day_last/io.cc: Likewise.
	* testsuite/std/time/month_weekday/1.cc: Likewise.
	* testsuite/std/time/month_weekday/io.cc: Likewise.
	* testsuite/std/time/month_weekday_last/1.cc: Likewise.
	* testsuite/std/time/month_weekday_last/io.cc: Likewise.
	* testsuite/std/time/parse.cc: Likewise.
	* testsuite/std/time/syn_c++20.cc: Likewise.
	* testsuite/std/time/time_zone/get_info_local.cc: Likewise.
	* testsuite/std/time/time_zone/get_info_sys.cc: Likewise.
	* testsuite/std/time/time_zone/requirements.cc: Likewise.
	* testsuite/std/time/traits/is_clock.cc: Likewise.
	* testsuite/std/time/tzdb/1.cc: Likewise.
	* testsuite/std/time/tzdb/leap_seconds.cc: Likewise.
	* testsuite/std/time/tzdb_list/1.cc: Likewise.
	* testsuite/std/time/tzdb_list/requirements.cc: Likewise.
	* testsuite/std/time/weekday/1.cc: Likewise.
	* testsuite/std/time/weekday/io.cc: Likewise.
	* testsuite/std/time/weekday_indexed/io.cc: Likewise.
	* testsuite/std/time/weekday_last/1.cc: Likewise.
	* testsuite/std/time/weekday_last/io.cc: Likewise.
	* testsuite/std/time/year/1.cc: Likewise.
	* testsuite/std/time/year/2.cc: Likewise.
	* testsuite/std/time/year/io.cc: Likewise.
	* testsuite/std/time/weekday_indexed/1.cc: Likewise.
	* testsuite/std/time/year_month/1.cc: Likewise.
	* testsuite/std/time/year_month/2.cc: Likewise.
	* testsuite/std/time/year_month/io.cc: Likewise.
	* testsuite/std/time/year_month_day/1.cc: Likewise.
	* testsuite/std/time/year_month_day/2.cc: Likewise.
	* testsuite/std/time/year_month_day/3.cc: Likewise.
	* testsuite/std/time/year_month_day/4.cc: Likewise.
	* testsuite/std/time/year_month_day/io.cc: Likewise.
	* testsuite/std/time/year_month_day_last/1.cc: Likewise.
	* testsuite/std/time/year_month_day_last/2.cc: Likewise.
	* testsuite/std/time/year_month_day_last/io.cc: Likewise.
	* testsuite/std/time/year_month_weekday/1.cc: Likewise.
	* testsuite/std/time/year_month_weekday/2.cc: Likewise.
	* testsuite/std/time/year_month_weekday/3.cc: Likewise.
	* testsuite/std/time/year_month_weekday/io.cc: Likewise.
	* testsuite/std/time/year_month_weekday_last/1.cc: Likewise.
	* testsuite/std/time/year_month_weekday_last/2.cc: Likewise.
	* testsuite/std/time/year_month_weekday_last/io.cc: Likewise.
	* testsuite/std/time/zoned_time/1.cc: Likewise.
	* testsuite/std/time/zoned_time/custom.cc: Likewise.
	* testsuite/std/time/zoned_time/deduction.cc: Likewise.
	* testsuite/std/time/zoned_time/io.cc: Likewise.
	* testsuite/std/time/zoned_time/req_neg.cc: Likewise.
	* testsuite/std/time/zoned_time/requirements.cc: Likewise.
	* testsuite/std/time/zoned_traits.cc: Likewise.
2023-09-15 21:57:39 +01:00
Jonathan Wakely
b1ca841b89 libstdc++: Fix missing/misplaced { dg-options "-std=gnu++20" } in tests
These tests do not run by default, because the c++20 effective target
selector isn't matched.

libstdc++-v3/ChangeLog:

	* testsuite/23_containers/unordered_map/operations/1.cc: Add
	dg-options for C++20 mode.
	* testsuite/23_containers/unordered_multimap/operations/1.cc:
	Likewise.
	* testsuite/23_containers/unordered_multiset/operations/1.cc:
	Likewise.
	* testsuite/23_containers/unordered_set/operations/1.cc:
	Likewise.
	* testsuite/std/time/parse.cc: Move dg-options before dg-do.
2023-09-07 08:10:53 +01:00
Jonathan Wakely
e5af77adef libstdc++: Fix how chrono::parse handles errors for time-of-day values
We fail to diagnose an error and extract an incorrect time for cases
like "25:59" >> parse("%H:%M", mins). The bad "25" hour value gets
ignored (on the basis that we might not care about it if trying to
extract something like a weekday or a month name), but then when we get
to the end of the function we think we have a valid time from "59" and
so the result is 00:59.

The problem is that the '__bad_h' value is used for "no hour value read
yet" as well as "bad hour value read". If we just set __h = __bad_h and
continue, we can't tell later that we read an invalid hour.

The fix is to set failbit early when we're trying to extract a
time-of-day (e.g. duration or time_point) and we encounter an invalid
hour, minute, or second value. We can still delay other error checking
to the end.

libstdc++-v3/ChangeLog:

	* include/bits/chrono_io.h (_Parser::operator()): Set failbit
	early if invalid values are read when _M_need & _TimeOfDay is
	non-zero.
	* testsuite/std/time/parse.cc: Check that "25:59" cannot be
	parsed for "%H:%M".
2023-09-01 09:55:48 +01:00
Jonathan Wakely
207c507499 libstdc++: Do not allow chrono::parse to overflow for %C [PR111162]
libstdc++-v3/ChangeLog:

	PR libstdc++/111162
	* include/bits/chrono_io.h (_Parser::Operator()): Check %C
	values are in range of year::min() to year::max().
	* testsuite/std/time/parse.cc: Check out of range centuries.
2023-09-01 09:55:48 +01:00
Jonathan Wakely
ce6c4d3b4d libstdc++: Implement C++20 std::chrono::parse [PR104167]
This adds the missing C++20 features to <chrono>.

I've implemented my proposed resolutions to LWG issues 3960, 3961, and
3962. There are some unimplemented flags such as %OI which I think are
not implementable in general. It might be possible to use na_llanginfo
with ALT_DIGITS, but that isn't available on all targets. I intend to
file another LWG issue about that.

libstdc++-v3/ChangeLog:

	PR libstdc++/104167
	* include/bits/chrono_io.h (operator|=, operator|): Add noexcept
	to _ChronoParts operators.
	(from_stream, parse): Define new functions.
	(__detail::_Parse, __detail::_Parser): New class templates.
	* include/std/chrono (__cpp_lib_chrono): Define to 201907L for
	C++20.
	* include/std/version (__cpp_lib_chrono): Likewise.
	* testsuite/20_util/duration/arithmetic/constexpr_c++17.cc:
	Adjust expected value of feature test macro.
	* testsuite/20_util/duration/io.cc: Test parsing.
	* testsuite/std/time/clock/file/io.cc: Likewise.
	* testsuite/std/time/clock/gps/io.cc: Likewise.
	* testsuite/std/time/clock/system/io.cc: Likewise.
	* testsuite/std/time/clock/tai/io.cc: Likewise.
	* testsuite/std/time/clock/utc/io.cc: Likewise.
	* testsuite/std/time/day/io.cc: Likewise.
	* testsuite/std/time/month/io.cc: Likewise.
	* testsuite/std/time/month_day/io.cc: Likewise.
	* testsuite/std/time/weekday/io.cc: Likewise.
	* testsuite/std/time/year/io.cc: Likewise.
	* testsuite/std/time/year_month/io.cc: Likewise.
	* testsuite/std/time/year_month_day/io.cc: Likewise.
	* testsuite/std/time/syn_c++20.cc: Check value of macro and for
	the existence of parse and from_stream in namespace chrono.
	* testsuite/std/time/clock/local/io.cc: New test.
	* testsuite/std/time/parse.cc: New test.
2023-08-11 19:58:06 +01:00
Jonathan Wakely
344f413220 libstdc++: Fix formatting of negative chrono::hh_mm_ss
When formatting with an empty chrono spec ("{}") two minus signs were
being added to hh_mm_ss values. This is because the __is_neg flag was
checked to add one explicitly, and then the ostream operator added
another one.

We should only check the __is_neg flag for durations, because those are
the only types which are modified to be non-negative before calling
_M_format. We don't change hh_mm_ss values to be negative, because that
would require performing arithmetic on the hh_mm_ss members to sum them,
and then again to construct a new hh_mm_ss object with the positive
value.  Instead, we can just be careful about using the __is_neg flag
correctly.

To fix the bug, _M_format_to_ostream no longer checks the __is_neg flag
for non-durations, and _M_format doesn't set it for hh_mm_ss until after
the call to _M_format_to_ostream. We can also avoid setting it for types
that it doesn't apply to, by making the __print_sign lambda only inspect
it for duration and hh_mm_ss types.

libstdc++-v3/ChangeLog:

	* include/bits/chrono_io.h (__formatter_chrono::_M_format):
	Do not set __is_neg for hh_mm_ss before calling
	_M_format_to_ostream. Change __print_sign lambda to only check
	__is_neg for durations and hh_mm_ss types.
	(__formatter_chrono::_M_format_to_ostream): Only check __is_neg
	for duration types.
	* testsuite/std/time/hh_mm_ss/io.cc: Check negative values.
2023-07-19 16:48:56 +01:00
Jonathan Wakely
86b36e9f7e libstdc++: Fix locale-specific duration formatting [PR110719]
The r14-2640-gf4bce119f617dc commit only removed fractional seconds for
time points, but it needs to be done for durations and hh_mm_ss types
too.

libstdc++-v3/ChangeLog:

	PR libstdc++/110719
	* include/bits/chrono_io.h (__formatter_chrono::_S_floor_seconds):
	Handle duration and hh_mm_ss.
	* testsuite/20_util/duration/io.cc: Check locale-specific
	formats.
	* testsuite/std/time/hh_mm_ss/io.cc: Likewise.
2023-07-19 14:51:51 +01:00
Jonathan Wakely
f4bce119f6 libstdc++: Implement correct locale-specific chrono formatting [PR110719]
This fixes some TODOs in the C++20 <chrono> format support, where the
locale-specific output was incorrect or unimplemented. The approach
taken here is to either use the formatting locale's std::time_put facet
to do the formatting, or to remove subsecond precision from time points
so that locale-specific formats don't print fractional seconds. This
ensures that we are consistent with what the std::time_put facet would
print (which never includes fractional seconds) even if we actually
reimplement the formatting by hand instead of using the facet.

This also fixes a misplaced statement that allowed modifiers for %Z
which should have been on %z instead. There was also some ill-formed
code in an untested branch for formatting time zone names to wide
characters. A new test for zoned_time I/O has been added to exercise
that code properly.

libstdc++-v3/ChangeLog:

	PR libstdc++/110719
	* include/bits/chrono_io.h (__formatter_chrono::_M_parse): Fix
	allowed modifiers for %z and %Z. Fix -Wparentheses and
	-Wnarrowing warnings.
	(__formatter_chrono::_M_format): Call new functions for %d, %e,
	%H, %I, %m and %M.
	(__formatter_chrono::_M_c): Use _S_floor_seconds to remove
	subsecond precision.
	(__formatter_chrono::_M_C_y_Y): Use _M_locale_fmt to handle
	modifiers.
	(__formatter_chrono::_M_e): Replace with _M_d_e and use
	_M_locale_fmt.
	(__formatter_chrono::_M_I): Replace with _M_H_I and use
	_M_locale_fmt.
	(__formatter_chrono::_M_m): New function.
	(__formatter_chrono::_M_M): New function.
	(__formatter_chrono::_M_r): Use _M_locale_fmt.
	(__formatter_chrono::_M_S): Likewise.
	(__formatter_chrono::_M_u_w): Likewise.
	(__formatter_chrono::_M_U_V_W): Likewise.
	(__formatter_chrono::_M_X): Use _S_floor_seconds.
	(__formatter_chrono::_M_Z): Fix untested branch for wchar_t.
	(__formatter_chrono::_S_altnum): Remove function.
	(__formatter_chrono::_S_dd_zero_fill): Remove function.
	(__formatter_chrono::_S_floor_seconds): New function.
	(__formatter_chrono::_M_locale_fmt): New function.
	* testsuite/std/time/clock/system/io.cc: Adjust expected output
	for locale-specific formats and check modified formats.
	* testsuite/std/time/clock/utc/io.cc: Likewise.
	* testsuite/std/time/zoned_time/io.cc: New test.
2023-07-19 12:36:59 +01:00
Jonathan Wakely
52bfec7ea0 libstdc++: Check for multiple modifiers in chrono format string [PR110708]
The logic for handling modified chrono specs like %Ey was just
restarting the loop after each modifier, and not checking whether we'd
already seen a modifier.

libstdc++-v3/ChangeLog:

	PR libstdc++/110708
	* include/bits/chrono_io.h (__formatter_chrono::_M_parse): Only
	allow a single modifier.
	* testsuite/std/time/format.cc: Check multiple modifiers.
2023-07-19 11:03:32 +01:00
Jonathan Wakely
aa39ed4467 libstdc++: Fix chrono::hh_mm_ss::subseconds() [PR109772]
I borked the logic in r13-4526-g5329e1a8e1480d so that the selected
partial specialization of hh_mm_ss::__subseconds might not be able to
represent the correct number of subseconds. This can result in a
truncated value being stored for the subseconds, e.g., 4755859375 gets
truncated to 460892079 because the correct value doesn't fit in
uint_least32_t.

Instead of checking whether the maximum value of the incoming duration
type can be represented, we would need to check whether that maximum value
can be represented after being converted to the correct precision type:

       template<typename _Tp>
         static constexpr bool __fits
           = duration_cast<precision>(_Duration::max()).count()
               <= duration_values<_Tp>::max();

However, this can fail to compile, due to integer overflow in the
constexpr multiplications. Instead, we could limit the check to the case
where the incoming duration has the same period as the precision, where
no conversion is needed and so no overflow can happen. But that seems of
very limited value, as it would only benefit specializations like
hh_mm_ss<duration<int, std::pico>>, which can only represent a
time-of-day between -00:00:00.0215 and +00:00:00.0215 measured in
picoseconds!

Additionally, the hh_mm_ss::__subseconds partial specializations do not
have disjoint constraints, so that some hh_mm_ss specializations result
in ambiguities tying to match a __subseconds partial specialization.

The most practical fix is to just stop using the __fits variable
template in the constraints of the partial specializations. This fixes
the truncated values by not selecting an inappropriate partial
specialization, and fixes the ambiguous match by ensuring the
constraints are disjoint.

Fixing this changes the layout of some specializations, so is an ABI
change. It only affects specializations that have a small (less than
64-bit) representation type and either a very small period (e.g. like
the picosecond specialization above) or a non-power-of-ten period like
ratio<1, 1024>.  For example both hh_mm_ss<duration<int, std::pico>> and
hh_mm_ss<duration<int, ratio<1, 1024>> are affected (increasing from 16
bytes to 24 on x86_64), but hh_mm_ss<duration<int, ratio<1, 1000>> and
hh_mm_ss<duration<long, ratio<1, 1024>> are not affected.

libstdc++-v3/ChangeLog:

	PR libstdc++/109772
	* include/std/chrono (hh_mm_ss::__fits): Remove variable
	template.
	(hh_mm_ss::__subseconds): Remove __fits from constraints.
	* testsuite/std/time/hh_mm_ss/109772.cc: New test.
	* testsuite/std/time/hh_mm_ss/1.cc: Adjust expected size for
	hh_mm_ss<duration<int, std::pico>>.
2023-05-11 21:15:22 +01:00
Jonathan Wakely
cf19ef9eca libstdc++: Update tzdata to 2023a [PR109288]
Import the new 2023a tzdata.zi file and update the expiry dates of the
hardcoded lists of leapseconds to 2023-12-28.

With the new data, Africa/Egypt no longer has a single unbroken sys_info
from 2014-09-25 to chrono::year::max(). Only check up to 2014-09-01 so
that the test isn't sensitive to differences between 2022g and 2023a
data.

libstdc++-v3/ChangeLog:

	PR libstdc++/109288
	* include/std/chrono (__detail::__get_leap_second_info): Update
	expiry date of hardcoded leapseconds list.
	* src/c++20/tzdb.cc (tzdb_list::_Node::_S_read_leap_seconds()):
	Likewise.
	* src/c++20/tzdata.zi: Import new file from 2023a release.
	* testsuite/std/time/time_zone/get_info_local.cc: Only check
	transitions for Egypt up to 2014.
2023-03-28 21:12:18 +01:00
Jonathan Wakely
4abd5bc600 libstdc++: Make std::chrono::current_zone() default to UTC
This is consistent with the behaviour of glibc, which assumes UTC when
/etc/localtime and TZ do not identify a valid time zone. The fallback
tzdb used when no valid tzdata exists always contains the UTC zone, so
this change means we have a valid tzdb and valid current zone even in
the degenerate case.

With this default we no longer need the AIX-specific kluge to try and
identify TZ values specifying a 0-offset zone. We can just use the UTC
default for those, as it has the same effect.

It's still possible for chrono::current_zone() to fail, because the user
could have provided a custom tzdata.zi file which doesn't contain the
UTC time zone, so the "UTC" default would fail to find a valid zone, and
throw an exception. That's just user error, they should not provide bad
data and expect reasonable behaviour.

libstdc++-v3/ChangeLog:

	* src/c++20/tzdb.cc (chrono::tzdb::current_zone()) Use "UTC" if
	current time zone cannot be determined.
	* testsuite/std/time/tzdb/1.cc: Remove conditions based on
	HAVE_TZDB macro and test all members unconditionally.
2023-03-01 21:26:08 +00:00
Hans-Peter Nilsson
a939dd8357 libstdc++ testsuite: Correct S0 in std/time/hh_mm_ss/1.cc
For targets where the ABI mandates structure layout that has
no padding, like cris-elf, this test started failing when
introduced as an add-on to the existing 1.cc, thereby
effectively causing a regression in testsuite results.
Adding an empty structure to S0, corresponds better to the
layout of hh_mm_ss<seconds>.

	PR testsuite/108632
	* testsuite/std/time/hh_mm_ss/1.cc (size): Add empty
	struct at end of S0.
2023-02-01 17:58:22 +01:00
Jakub Jelinek
83ffe9cde7 Update copyright years. 2023-01-16 11:52:17 +01:00
Jonathan Wakely
05cd79c242 libstdc++: Remove dg-xfail-run-if in std/time/tzdb_list/1.cc
Use the global override_used to tell whether the target supports the
override functionality that the test_reload and test_erase functions
rely on.

libstdc++-v3/ChangeLog:

	* testsuite/std/time/tzdb_list/1.cc: Remove dg-xfail-run-if
	and fail gracefully if defining the weak symbol doesn't work.
2023-01-15 16:45:57 +00:00
Jonathan Wakely
4dc4584b60 libstdc++: Fix narrowing conversion in std/time/clock/utc/io.cc
For a port with signed char and unsigned wchar_t initializing a wchar_t
array with a char is a narrowing conversion. The code is wrong for
assuming that (int)'a' == (int)L'a' anyway, so fix it properly by using
ctype<wchar_t>::widen(char).

libstdc++-v3/ChangeLog:

	* testsuite/std/time/clock/utc/io.cc: Use ctype to widen char.
2023-01-15 12:44:23 +00:00
Jonathan Wakely
c47dcb9566 libstdc++: Disable unwanted code for --with-libstdcxx-zoneinfo=no
This allows most of the tzdb functionality to be disabled by
configuring with --with-libstdcxx-zoneinfo=no. This might be desirable
for small targets that don't need the time zone support.

libstdc++-v3/ChangeLog:

	* src/c++20/tzdb.cc (TZDB_DISABLED): Disable all code for
	loading tzdb.
	* testsuite/std/time/tzdb/leap_seconds.cc: Require tzdb
	effective target.
	* testsuite/std/time/tzdb_list/1.cc: Likewise.
2023-01-14 18:06:07 +00:00
Jonathan Wakely
9afc914809 libstdc++: Fix ostream insertion operators for calendar types
libstdc++-v3/ChangeLog:

	* include/bits/chrono_io.h (operator<<): Fix syntax errors.
	* testsuite/std/time/month_day/io.cc: New test.
	* testsuite/std/time/month_day_last/io.cc: New test.
	* testsuite/std/time/month_weekday/io.cc: New test.
	* testsuite/std/time/month_weekday_last/io.cc: New test.
	* testsuite/std/time/weekday_indexed/io.cc: New test.
	* testsuite/std/time/weekday_last/io.cc: New test.
	* testsuite/std/time/year_month/io.cc: New test.
	* testsuite/std/time/year_month_day_last/io.cc: New test.
	* testsuite/std/time/year_month_weekday/io.cc: New test.
	* testsuite/std/time/year_month_weekday_last/io.cc: New test.
2023-01-14 16:59:58 +00:00
Jonathan Wakely
e36e57b032 libstdc++: Fix std::chrono::hh_mm_ss with unsigned rep [PR108265]
libstdc++-v3/ChangeLog:

	PR libstdc++/108265
	* include/std/chrono (hh_mm_ss): Do not use chrono::abs if
	duration rep is unsigned.
	* testsuite/std/time/hh_mm_ss/1.cc: Check unsigned rep.
2023-01-05 00:46:00 +00:00
Iain Sandoe
4c3a036be5 libstdc++, testsuite: Correct an init.
in leap_seconds.cc, we are testing to see if the function that
overrides the default zoneinfo directory has been called.  That
is implemented with a static boolean that needs to be initialized
to false.

Signed-off-by: Iain Sandoe <iain@sandoe.co.uk>

libstdc++-v3/ChangeLog:

	* testsuite/std/time/tzdb/leap_seconds.cc: Initialize the
	override_used test var to false.
2022-12-24 17:51:12 +00:00
Jonathan Wakely
f99b94865f libstdc++: Add std::format support to <chrono>
This adds the operator<< overloads and std::formatter specializations
required by C++20 so that <chrono> types can be written to ostreams and
printed with std::format.

libstdc++-v3/ChangeLog:

	* include/Makefile.am: Add new header.
	* include/Makefile.in: Regenerate.
	* include/std/chrono (operator<<): Move to new header.
	(nonexistent_local_time::_M_make_what_str): Define correctly.
	(ambiguous_local_time::_M_make_what_str): Likewise.
	* include/bits/chrono_io.h: New file.
	* src/c++20/tzdb.cc (operator<<(ostream&, const Rule&)): Use
	new ostream output for month and weekday types.
	* testsuite/20_util/duration/io.cc: Test std::format support.
	* testsuite/std/time/exceptions.cc: Check what() strings.
	* testsuite/std/time/syn_c++20.cc: Uncomment local_time_format.
	* testsuite/std/time/time_zone/get_info_local.cc: Enable check
	for formatted output of local_info objects.
	* testsuite/std/time/clock/file/io.cc: New test.
	* testsuite/std/time/clock/gps/io.cc: New test.
	* testsuite/std/time/clock/system/io.cc: New test.
	* testsuite/std/time/clock/tai/io.cc: New test.
	* testsuite/std/time/clock/utc/io.cc: New test.
	* testsuite/std/time/day/io.cc: New test.
	* testsuite/std/time/format.cc: New test.
	* testsuite/std/time/hh_mm_ss/io.cc: New test.
	* testsuite/std/time/month/io.cc: New test.
	* testsuite/std/time/weekday/io.cc: New test.
	* testsuite/std/time/year/io.cc: New test.
	* testsuite/std/time/year_month_day/io.cc: New test.
2022-12-22 23:34:27 +00:00
Jonathan Wakely
9fc61d45fa libstdc++: Implement C++20 time zone support in <chrono>
This is the largest missing piece of C++20 support. Only the cxx11 ABI
is supported, due to the use of std::string in the API for time zones.
For the old gcc4 ABI, utc_clock and leap seconds are supported, but only
using a hardcoded list of leap seconds, no up-to-date tzdb::leap_seconds
information is available, and no time zones or zoned_time conversions.

The implementation currently depends on a tzdata.zi file being provided
by the OS or the user. The expected location is /usr/share/zoneinfo but
that can be changed using --with-libstdcxx-zoneinfo-dir=PATH. On targets
that support it there is also a weak symbol that users can override in
their own program (which also helps with testing):

extern "C++" const char* __gnu_cxx::zoneinfo_dir_override();

If no file is found, a fallback tzdb object will be created which only
contains the "Etc/UTC" and "Etc/GMT" time zones.

A leapseconds file is also expected in the same directory, but if that
isn't present then a hardcoded list of leapseconds is used, which is
correct at least as far as 2023-06-28 (and it currently looks like no
leap second will be inserted for a few years).

The tzdata.zi and leapseconds files from https://www.iana.org/time-zones
are in the public domain, so shipping copies of them with GCC would be
an option. However, the tzdata.zi file will rapidly become outdated, so
users should really provide it themselves (or convince their OS vendor
to do so). It would also be possible to implement an alternative parser
for the compiled tzdata files (one per time zone) under
/usr/share/zoneinfo. Those files are present on more operating systems,
but do not contain all the information present in tzdata.zi.
Specifically, the "links" are not present, so that e.g. "UTC" and
"Universal" are distinct time zones, rather than both being links to the
canonical "Etc/UTC" zone. For some platforms those files are hard links
to the same file, but there's no indication which zone is the canonical
name and which is a link. Other platforms just store them in different
inodes anyway. I do not plan to add such an alternative parser for the
compiled files. That would need to be contributed by maintainers or
users of targets that require it, if making tzdata.zi available is not
an option. The library ABI would not need to change for a new tzdb
implementation, because everything in tzdb_list, tzdb and time_zone is
implemented as a pimpl (except for the shared_ptr links between nodes,
described below). That means the new exported symbols added by this
commit should be stable even if the implementation is completely
rewritten.

The information from tzdata.zi is parsed and stored in data structures
that closely model the info in the file. This is a space-efficient
representation that uses less memory that storing every transition for
every time zone.  It also avoids spending time expanding that
information into time zone transitions that might never be needed by the
program.  When a conversion to/from a local time to UTC is requested the
information will be processed to determine the time zone transitions
close to the time being converted.

There is a bug in some time zone transitions. When generating a sys_info
object immediately after one that was previously generated, we need to
find the previous rule that was in effect and note its offset and
letters. This is so that the start time and abbreviation of the new
sys_info will be correct. This only affects time zones that use a format
like "C%sT" where the LETTERS replacing %s are non-empty for standard
time, e.g. "Asia/Shanghai" which uses "CST" for standard time and "CDT"
for daylight time.

The tzdb_list structure maintains a linked list of tzdb nodes using
shared_ptr links. This allows the iterators into the list to share
ownership with the list itself. This offers a non-portable solution to a
lifetime issue in the API. Because tzdb objects can be erased from the
list using tzdb_list::erase_after, separate modules/libraries in a large
program cannot guarantee that any const tzdb& or const time_zone*
remains valid indefinitely. Holding onto a tzdb_list::const_iterator
will extend the tzdb object's lifetime, even if it's erased from the
list. An alternative design would be for the list iterator to hold a
weak_ptr. This would allow users to test whether the tzdb still exists
when the iterator is dereferenced, which is better than just having a
dangling raw pointer. That doesn't actually extend the tzdb's lifetime
though, and every use of it would need to be preceded by checking the
weak_ptr. Using shared_ptr adds a little bit of overhead but allows
users to solve the lifetime issue if they rely on the libstdc++-specific
iterator property.

libstdc++-v3/ChangeLog:

	* acinclude.m4 (GLIBCXX_ZONEINFO_DIR): New macro.
	* config.h.in: Regenerate.
	* config/abi/pre/gnu.ver: Export new symbols.
	* configure: Regenerate.
	* configure.ac (GLIBCXX_ZONEINFO_DIR): Use new macro.
	* include/std/chrono (utc_clock::from_sys): Correct handling
	of leap seconds.
	(nonexistent_local_time::_M_make_what_str): Define.
	(ambiguous_local_time::_M_make_what_str): Define.
	(__throw_bad_local_time): Define new function.
	(time_zone, tzdb_list, tzdb): Implement all members.
	(remote_version, zoned_time, get_leap_second_info): Define.
	* include/std/version: Add comment for __cpp_lib_chrono.
	* src/c++20/Makefile.am: Add new file.
	* src/c++20/Makefile.in: Regenerate.
	* src/c++20/tzdb.cc: New file.
	* testsuite/lib/libstdc++.exp: Define effective target tzdb.
	* testsuite/std/time/clock/file/members.cc: Check file_time
	alias and file_clock::now() member.
	* testsuite/std/time/clock/gps/1.cc: Likewise for gps_clock.
	* testsuite/std/time/clock/tai/1.cc: Likewise for tai_clock.
	* testsuite/std/time/syn_c++20.cc: Uncomment everything except
	parse.
	* testsuite/std/time/clock/utc/leap_second_info.cc: New test.
	* testsuite/std/time/exceptions.cc: New test.
	* testsuite/std/time/time_zone/get_info_local.cc: New test.
	* testsuite/std/time/time_zone/get_info_sys.cc: New test.
	* testsuite/std/time/time_zone/requirements.cc: New test.
	* testsuite/std/time/tzdb/1.cc: New test.
	* testsuite/std/time/tzdb/leap_seconds.cc: New test.
	* testsuite/std/time/tzdb_list/1.cc: New test.
	* testsuite/std/time/tzdb_list/requirements.cc: New test.
	* testsuite/std/time/zoned_time/1.cc: New test.
	* testsuite/std/time/zoned_time/custom.cc: New test.
	* testsuite/std/time/zoned_time/deduction.cc: New test.
	* testsuite/std/time/zoned_time/req_neg.cc: New test.
	* testsuite/std/time/zoned_time/requirements.cc: New test.
	* testsuite/std/time/zoned_traits.cc: New test.
2022-12-22 23:34:20 +00:00
Jonathan Wakely
5329e1a8e1 libstdc++: Make chrono::hh_mm_ss more compact
This uses a single byte for the minutes and seconds members, and places
the bool member next to those single bytes. This means we do not need 40
bytes to store a time that can fit in a single 8-byte integer.

When there is no subsecond precision we can do away with the _M_ss
member altogether. If the subsecond precision is coarse enough, we can
use a smaller representation for _M_ss, e.g. hh_mm_ss<milliseconds> only
needs uint_least32_t for _M_ss, and hh_mm_ss<duration<long, ratio<1,10>>
and hh_mm_ss<duration<int8_t, nano>> only need a single byte. In the
latter case the type can only ever represent up to 255ns anyway, so we
don't need a larger representation type (in such cases, we could even
remove the _M_h, _M_m and _M_s members, but it's a very unlikely
scenario that isn't worth optimizing for).

Except for specializations with a floating-point rep or using higher
precision than nanoseconds, hh_mm_ss should now fit in 16 bytes, or even
12 bytes for x86-32 where alignof(long long) == 4.

libstdc++-v3/ChangeLog:

	* include/std/chrono (chrono::hh_mm_ss): Do not use 64-bit
	representations for all four duration members. Reorder members.
	(hh_mm_ss::hh_mm_ss()): Define as defaulted.
	(hh_mm_ss::hh_mm_ss(Duration)): Delegate to a new private
	constructor, instead of calling chrono::abs repeatedly.
	* testsuite/std/time/hh_mm_ss/1.cc: Check floating-point
	representations. Check default constructor. Check sizes.
2022-12-06 21:38:46 +00:00
Jonathan Wakely
7026d0455d libstdc++: Add test for chrono::utc_clock leap second offset
This test of leap second handling is taken from the C++20 standard.

libstdc++-v3/ChangeLog:

	* testsuite/std/time/clock/utc/1.cc: Check handling across leap
	second insertion.
2022-11-16 15:07:17 +00:00
Jonathan Wakely
1736bf5a61 libstdc++: Add C++20 clocks
Also add the basic types for timezones, without the non-inline
definitions needed to actually use them.

The get_leap_second_info function currently uses a hardcoded list of
leap seconds, correct as of the end of 2022. That needs to be replaced
with a dynamically generated list read from the system tzdata. That will
be done in a later patch.

libstdc++-v3/ChangeLog:

	* include/std/chrono (utc_clock, tai_clock, gps_clock): Define.
	(clock_time_conversion, clock_cast): Define.
	(sys_info, local_info): Define structs for timezone information.
	(nonexistent_local_time, ambiguous_local_time): Define
	exceptions for invalid times.
	(time_zone, time_zone_link, leap_second, zoned_traits, tzdb)
	(tzdb_list): Define classes representing time zones.
	(get_leap_second_info): Define new function returning leap
	second offset for a given time point.
	* testsuite/std/time/clock/gps/1.cc: New test.
	* testsuite/std/time/clock/tai/1.cc: New test.
	* testsuite/std/time/clock/utc/1.cc: New test.
2022-11-13 01:10:45 +00:00
Jakub Jelinek
7adcbafe45 Update copyright years. 2022-01-03 10:42:10 +01:00
Jonathan Wakely
e7afb82c35 libstdc++: Uncomment more parts of <chrono> synopsis test
libstdc++-v3/ChangeLog:

	* testsuite/std/time/syn_c++20.cc: Enable synopsis checks for
	C++20 calendar types.
2021-03-10 11:14:27 +00:00
Cassio Neri
126793971b libstdc++: More efficient is_leap
This patch reimplements std::chrono::year::is_leap().  Leap year check is
ubiquitously implemented (including here) as:

    y % 4 == 0 && (y % 100 != 0 || y % 400 == 0).

The rationale being that testing divisibility by 4 first implies an earlier
return for 75% of the cases, therefore, avoiding the needless calculations of
y % 100 and y % 400. Although this fact is true, it does not take into account
the cost of branching.  This patch, instead, tests divisibility by 100 first:

    (y % 100 != 0 || y % 400 == 0) && y % 4 == 0.

It is certainly counterintuitive that this could be more efficient since among
the three divisibility tests (4, 100 and 400) the one by 100 is the only one
that can never provide a definitive answer and a second divisibility test (by 4
or 400) is always required. However, measurements [1] in x86_64 suggest this is
3x more efficient!  A possible explanation is that checking divisibility by 100
first implies a split in the execution path with probabilities of (1%, 99%)
rather than (25%, 75%) when divisibility by 4 is checked first.  This decreases
the entropy of the branching distribution which seems to help prediction.

Given that y belongs to [-32767, 32767] [time.cal.year.members], a more
efficient algorithm [2] to check divisibility by 100 is used (instead of
y % 100 != 0).  Measurements suggest that this optimization improves performance
by 20%.

The patch adds a test that exhaustively compares the result of this
implementation with the ubiquitous one for all y in [-32767, 32767]. Although
its completeness, the test completes in a matter of seconds.

References:
[1] https://stackoverflow.com/a/60646967/1137388
[2] https://accu.org/journals/overload/28/155/overload155.pdf#page=16

libstdc++-v3/ChangeLog:

	* include/std/chrono (year::is_leap): New implementation.
	* testsuite/std/time/year/2.cc: New test.
2021-02-24 18:25:18 +00:00
Cassio Neri
97d6161f6a libstdc++: More efficient days from date
This patch reimplements std::chrono::year_month_day::_M_days_since_epoch()
which calculates the number of elapsed days since 1970/01/01.  The new
implementation is based on Proposition 6.2 of Neri and Schneider, "Euclidean
Affine Functions and Applications to Calendar Algorithms" available at
https://arxiv.org/abs/2102.06959.

The aforementioned paper benchmarks the implementation against several
counterparts, including libc++'s (which is identical to the current
implementation).  The results, shown in Figure 3, indicate the new algorithm is
1.7 times faster than the current one.

The patch adds a test which loops through all dates in [-32767/01/01,
32767/12/31], and for each of them, gets the number of days and compares the
result against its expected value. The latter is calculated using a much
simpler and easy to understand algorithm but which is also much slower.

The dates used in the test covers the full range of possible values
[time.cal.year.members].  Despite its completeness the test runs in matter of
seconds.

libstdc++-v3/ChangeLog:

	* include/std/chrono (year_month_day::_M_days_since_epoch):
	New implementation.
	* testsuite/std/time/year_month_day/4.cc: New test.
2021-02-24 17:58:48 +00:00
Cassio Neri
3dfd5493cf libstdc++: More efficient date from days
This patch reimplements std::chrono::year_month_day::_S_from_days() which
retrieves a date from the number of elapsed days since 1970/01/01.  The new
implementation is based on Proposition 6.3 of Neri and Schneider, "Euclidean
Affine Functions and Applications to Calendar Algorithms" available at
https://arxiv.org/abs/2102.06959.

The aforementioned paper benchmarks the implementation against several
counterparts, including libc++'s (which is identical to the current
implementation).  The results, shown in Figure 4, indicate the new algorithm is
2.2 times faster than the current one.

The patch adds a test which loops through all integers in [-12687428, 11248737],
and for each of them, gets the corresponding date and compares the result
against its expected value.  The latter is calculated using a much simpler and
easy to understand algorithm but which is also much slower.

The interval used in the test covers the full range of values for which a
roundtrip must work [time.cal.ymd.members].  Despite its completeness the test
runs in a matter of seconds.

libstdc++-v3/ChangeLog:

	* include/std/chrono (year_month_day::_S_from_days): New
	implementation.
	* testsuite/std/time/year_month_day/3.cc: New test.
2021-02-24 17:58:47 +00:00
Jakub Jelinek
99dee82307 Update copyright years. 2021-01-04 10:26:59 +01:00
Patrick Palka
8572edc828 libstdc++: Fix arithmetic bug in year_month_weekday conversion [PR96713]
The conversion function year_month_weekday::operator sys_days computes
the offset in days from the first weekday of the month with:

 days{(index()-1)*7}
      ^~~~~~~~~~~~~  type 'unsigned'

We want the above to yield -7d when index() is 0u, but our 'days' alias
is based on long instead of int, so the conversion from unsigned to the
underlying type of 'days' instead yields a large positive value.

This patch fixes this by casting the result of index() to int so that
the initializer is sign-extended in the conversion to long.

The added testcase also verifies we do the right thing when index() == 5.

libstdc++-v3/ChangeLog:

	PR libstdc++/96713
	* include/std/chrono (year_month_weekday::operator sys_days):
	Cast the result of index() to int so that the initializer for
	days{} is sign-extended when it's converted to the underlying
	type.
	* testsuite/std/time/year_month_weekday/3.cc: New test.
2020-10-28 12:28:08 -04:00
Patrick Palka
71e9716137 libstdc++: Fix arithmetic bug in chrono::year_month::operator+
This fixes the months-based addition for year_month when the
year_month's month component is 0.

libstdc++-v3/ChangeLog:

	* include/std/chrono (year_month::operator+): Properly handle a
	month value of 0 by casting the month value to int before
	subtracting 1 from it so that the difference is sign-extended in
	the subsequent addition.
	* testsuite/std/time/year_month/1.cc: Test adding months to a
	year_month whose month component is below or above the
	normalized range of [1,12].
2020-08-27 14:11:24 -04:00