[PATCH v4] libstdc++: fix __cpp_lib_chrono for old-ABI-only builds
Jonathan Wakely
jwakely@redhat.com
Wed Oct 14 10:18:03 GMT 2026
On Tue, 13 Oct 2026 at 14:44, Jonathan Wakely <jwakely@redhat.com> wrote:
>
>
>
> On Tue, 13 Oct 2026 at 13:53, <hugo@beauzee.fr> wrote:
>>
>> From: Hugo Beauzée-Luyssen <hugo.beauzee@datadoghq.com>
>>
>> The C++20 chrono time zone API is declared when
>> _GLIBCXX_USE_CXX11_ABI || !_GLIBCXX_USE_DUAL_ABI, but
>> __cpp_lib_chrono only gets its C++20 and C++26 values when
>> _GLIBCXX_USE_CXX11_ABI is set. Old-ABI-only builds therefore get
>> the full API but report the C++17 value.
>>
>> Use the same condition for the 201907 and 202306 values, and make the
>> headers check __glibcxx_chrono instead of repeating the ABI condition.
>>
>> Add a chrono_tz effective target for that condition, and use it in
>> the tests that were limited to the new ABI, so they also run on
>> old-ABI-only builds.
>
>
> That doesn't seem functionally different from the existing tzdb effective target.
>
>
>
>>
>>
>> libstdc++-v3/ChangeLog:
>>
>> * include/bits/version.def (chrono): Also define 201907 and
>> 202306 for old-ABI-only builds.
>> * include/bits/version.h: Regenerate.
>> * include/std/chrono: Check __glibcxx_chrono instead of the
>> ABI macros.
>> * include/bits/chrono_io.h: Likewise.
>> * testsuite/lib/libstdc++.exp (check_effective_target_chrono_tz):
>> New proc.
>> (check_effective_target_tzdb): Use it.
>> * testsuite/std/time/syn_c++20.cc: Fix the ABI check for the
>> expected value.
>> * testsuite/std/time/hash.cc: Also test old-ABI-only builds.
>> * testsuite/std/time/format/pr117214.cc: Likewise.
>> * testsuite/libstdc++-prettyprinters/chrono.cc: Likewise.
>> * testsuite/std/time/format/data_not_present_neg.cc: Likewise,
>> and use chrono_tz instead of cxx11_abi.
>> * testsuite/std/time/clock/utc/leap_second_info-2.cc: Require
>> chrono_tz instead of cxx11_abi.
>> * testsuite/std/time/leap_seconds/io.cc: Likewise.
>> * testsuite/std/time/time_zone/116110.cc: Likewise.
>> * testsuite/std/time/time_zone/124513.cc: Likewise.
>> * testsuite/std/time/time_zone/numeric_save.cc: Likewise.
>> * testsuite/std/time/time_zone/pr116110_named.cc: Likewise.
>> * testsuite/std/time/time_zone/requirements.cc: Likewise.
>> * testsuite/std/time/time_zone/sys_info_abbrev.cc: Likewise.
>> * testsuite/std/time/time_zone/until_day_on.cc: Likewise.
>> * testsuite/std/time/time_zone/wall_cascade.cc: Likewise.
>> * testsuite/std/time/time_zone/zone_merge.cc: Likewise.
>> * testsuite/std/time/tzdb/1.cc: Likewise.
>> * testsuite/std/time/tzdb/leap_seconds.cc: Likewise.
>> * testsuite/std/time/tzdb/links.cc: Likewise.
>> * testsuite/std/time/tzdb_list/1.cc: Likewise.
>> * testsuite/std/time/tzdb_list/pr118811.cc: Likewise.
>> * testsuite/std/time/tzdb_list/requirements.cc: Likewise.
>> * testsuite/std/time/tzdb/name_matching.cc: Likewise.
>> * testsuite/std/time/zoned_time/1.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.
>>
>> Assisted-by: Claude (claude-sonnet-5)
>> Signed-off-by: Hugo Beauzée-Luyssen <hugo.beauzee@datadoghq.com>
>> ---
>> Changes since v3:
>> - Use __glibcxx_chrono in <chrono> and <bits/chrono_io.h>.
>> - Use the same condition for the 202306 value, without parentheses.
>> - Add a chrono_tz effective target and use it in the tests that
>> require the time zone API, so they also run on old-ABI-only builds.
>> - Fix the _GLIBCXX_USE_CXX_ABI typo in std/time/syn_c++20.cc.
>>
>> libstdc++-v3/include/bits/chrono_io.h | 8 ++--
>> libstdc++-v3/include/bits/version.def | 4 +-
>> libstdc++-v3/include/bits/version.h | 4 +-
>> libstdc++-v3/include/std/chrono | 12 +++---
>> libstdc++-v3/testsuite/lib/libstdc++.exp | 8 +++-
>> .../libstdc++-prettyprinters/chrono.cc | 4 +-
>> .../std/time/clock/utc/leap_second_info-2.cc | 2 +-
>> .../std/time/format/data_not_present_neg.cc | 38 +++++++++----------
>> .../testsuite/std/time/format/pr117214.cc | 4 +-
>> libstdc++-v3/testsuite/std/time/hash.cc | 8 ++--
>> .../testsuite/std/time/leap_seconds/io.cc | 2 +-
>> libstdc++-v3/testsuite/std/time/syn_c++20.cc | 5 ++-
>> .../testsuite/std/time/time_zone/116110.cc | 2 +-
>> .../testsuite/std/time/time_zone/124513.cc | 2 +-
>> .../std/time/time_zone/numeric_save.cc | 2 +-
>> .../std/time/time_zone/pr116110_named.cc | 2 +-
>> .../std/time/time_zone/requirements.cc | 2 +-
>> .../std/time/time_zone/sys_info_abbrev.cc | 2 +-
>> .../std/time/time_zone/until_day_on.cc | 2 +-
>> .../std/time/time_zone/wall_cascade.cc | 2 +-
>> .../std/time/time_zone/zone_merge.cc | 2 +-
>> libstdc++-v3/testsuite/std/time/tzdb/1.cc | 2 +-
>> .../testsuite/std/time/tzdb/leap_seconds.cc | 2 +-
>> libstdc++-v3/testsuite/std/time/tzdb/links.cc | 2 +-
>> .../testsuite/std/time/tzdb/name_matching.cc | 2 +-
>> .../testsuite/std/time/tzdb_list/1.cc | 2 +-
>> .../testsuite/std/time/tzdb_list/pr118811.cc | 2 +-
>> .../std/time/tzdb_list/requirements.cc | 2 +-
>> .../testsuite/std/time/zoned_time/1.cc | 2 +-
>> .../std/time/zoned_time/deduction.cc | 2 +-
>> .../testsuite/std/time/zoned_time/io.cc | 2 +-
>> .../testsuite/std/time/zoned_time/req_neg.cc | 2 +-
>> .../std/time/zoned_time/requirements.cc | 2 +-
>> .../testsuite/std/time/zoned_traits.cc | 2 +-
>> 34 files changed, 75 insertions(+), 68 deletions(-)
>>
>> diff --git a/libstdc++-v3/include/bits/chrono_io.h b/libstdc++-v3/include/bits/chrono_io.h
>> index 028e6007544..a6be222689d 100644
>> --- a/libstdc++-v3/include/bits/chrono_io.h
>> +++ b/libstdc++-v3/include/bits/chrono_io.h
>> @@ -2083,7 +2083,7 @@ namespace __format
>> }
>> };
>>
>> -#if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
>> +#if __glibcxx_chrono >= 201803L
>> template<typename _CharT>
>> struct __formatter_chrono_info
>> {
>> @@ -3004,7 +3004,7 @@ namespace __format
>> = enable_nonlocking_formatter_optimization<_Duration>;
>> #endif
>>
>> -#if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
>> +#if __glibcxx_chrono >= 201803L
>> template<__format::__char _CharT>
>> struct formatter<chrono::sys_info, _CharT>
>> {
>> @@ -3395,7 +3395,7 @@ namespace __format
>> = enable_nonlocking_formatter_optimization<_Duration>;
>> #endif
>>
>> -#if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
>> +#if __glibcxx_chrono >= 201803L
>> template<typename _Duration, typename _TimeZonePtr, __format::__char _CharT>
>> struct formatter<chrono::zoned_time<_Duration, _TimeZonePtr>, _CharT>
>> : formatter<chrono::__detail::__local_time_fmt_for<_Duration>, _CharT>
>> @@ -3872,7 +3872,7 @@ namespace __detail
>> return __detail::__chrono_write<64>(__os, __hms, __os.getloc());
>> }
>>
>> -#if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
>> +#if __glibcxx_chrono >= 201803L
>> /// Writes a sys_info object to an ostream in an unspecified format.
>> template<typename _CharT, typename _Traits>
>> basic_ostream<_CharT, _Traits>&
>> diff --git a/libstdc++-v3/include/bits/version.def b/libstdc++-v3/include/bits/version.def
>> index 9c523581c65..35ffb87a3ff 100644
>> --- a/libstdc++-v3/include/bits/version.def
>> +++ b/libstdc++-v3/include/bits/version.def
>> @@ -616,13 +616,13 @@ ftms = {
>> v = 202306;
>> cxxmin = 26;
>> hosted = yes;
>> - cxx11abi = yes;
>> + extra_cond = "_GLIBCXX_USE_CXX11_ABI || !_GLIBCXX_USE_DUAL_ABI";
>> };
>> values = {
>> v = 201907;
>> cxxmin = 20;
>> hosted = yes;
>> - cxx11abi = yes; // std::chrono::tzdb requires cxx11 std::string
>> + extra_cond = "_GLIBCXX_USE_CXX11_ABI || !_GLIBCXX_USE_DUAL_ABI";
>> };
>> values = {
>> v = 201611;
>> diff --git a/libstdc++-v3/include/bits/version.h b/libstdc++-v3/include/bits/version.h
>> index e0003054af6..25327bdeb57 100644
>> --- a/libstdc++-v3/include/bits/version.h
>> +++ b/libstdc++-v3/include/bits/version.h
>> @@ -681,12 +681,12 @@
>> #undef __glibcxx_want_boyer_moore_searcher
>>
>> #if !defined(__cpp_lib_chrono)
>> -# if (__cplusplus > 202302L) && _GLIBCXX_USE_CXX11_ABI && _GLIBCXX_HOSTED
>> +# if (__cplusplus > 202302L) && _GLIBCXX_HOSTED && (_GLIBCXX_USE_CXX11_ABI || !_GLIBCXX_USE_DUAL_ABI)
>> # define __glibcxx_chrono 202306L
>> # if defined(__glibcxx_want_all) || defined(__glibcxx_want_chrono)
>> # define __cpp_lib_chrono 202306L
>> # endif
>> -# elif (__cplusplus >= 202002L) && _GLIBCXX_USE_CXX11_ABI && _GLIBCXX_HOSTED
>> +# elif (__cplusplus >= 202002L) && _GLIBCXX_HOSTED && (_GLIBCXX_USE_CXX11_ABI || !_GLIBCXX_USE_DUAL_ABI)
>> # define __glibcxx_chrono 201907L
>> # if defined(__glibcxx_want_all) || defined(__glibcxx_want_chrono)
>> # define __cpp_lib_chrono 201907L
>> diff --git a/libstdc++-v3/include/std/chrono b/libstdc++-v3/include/std/chrono
>> index faa849b75b3..29bc155f743 100644
>> --- a/libstdc++-v3/include/std/chrono
>> +++ b/libstdc++-v3/include/std/chrono
>> @@ -57,7 +57,7 @@
>> # include <bits/stl_algo.h> // upper_bound
>> # include <bits/range_access.h> // begin/end for arrays
>> #endif
>> -#if __cpp_lib_chrono >= 201803L // C++20 && HOSTED && USE_CXX11_ABI
>> +#if __glibcxx_chrono >= 201803L // C++20 && HOSTED
>> # include <sstream>
>> # include <string>
>> # include <vector>
>> @@ -2529,7 +2529,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>> }
>>
>> #if _GLIBCXX_HOSTED
>> -#if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
>> +#if __glibcxx_chrono >= 201803L
>> // C++20 [time.zones] Time zones
>>
>> struct tzdb;
>> @@ -3204,7 +3204,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>> }
>>
>> using zoned_seconds = zoned_time<seconds>;
>> -#endif // _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
>> +#endif // __glibcxx_chrono >= 201803L
>>
>> namespace __detail
>> {
>> @@ -3259,7 +3259,7 @@ namespace __detail
>>
>> if (__ss > __expires)
>> {
>> -#if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI // use chrono::tzdb
>> +#if __glibcxx_chrono >= 201803L // use chrono::tzdb
>> // Call into the library because it might have knowledge of new
>> // leap seconds loaded at runtime from the tzdata files.
>>
>> @@ -3586,7 +3586,7 @@ namespace __detail
>> };
>>
>> #if _GLIBCXX_HOSTED
>> -#if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
>> +#if __glibcxx_chrono >= 201803L
>> // zoned_time
>> template<typename _Duration, typename _TimeZonePtr>
>> requires __is_hash_enabled_for<
>> @@ -3643,7 +3643,7 @@ namespace __detail
>> __val.value().count());
>> }
>> };
>> -#endif // _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
>> +#endif // __glibcxx_chrono >= 201803L
>> #endif // _GLIBCXX_HOSTED
>> #endif // __glibcxx_chrono_cxx20 >= 202306
>>
>> diff --git a/libstdc++-v3/testsuite/lib/libstdc++.exp b/libstdc++-v3/testsuite/lib/libstdc++.exp
>> index 3e8240d73a5..fac59c746e7 100644
>> --- a/libstdc++-v3/testsuite/lib/libstdc++.exp
>> +++ b/libstdc++-v3/testsuite/lib/libstdc++.exp
>> @@ -1641,9 +1641,15 @@ proc check_effective_target_hosted { } {
>> }]
>> }
>>
>> +# Return 1 if the C++20 time zone API (std::chrono::tzdb etc.) is declared.
>> +proc check_effective_target_chrono_tz { } {
>> + set cond "_GLIBCXX_USE_CXX11_ABI || !_GLIBCXX_USE_DUAL_ABI"
>> + return [v3_check_preprocessor_condition chrono_tz $cond]
>> +}
>> +
>> # Return 1 if std::chrono::tzdb is supported.
>> proc check_effective_target_tzdb { } {
>> - if {![check_effective_target_cxx11_abi]} {
>> + if {![check_effective_target_chrono_tz]} {
>> return 0
>> }
>> return [check_v3_target_prop_cached et_tzdb {
>> diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/chrono.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/chrono.cc
>> index c10198df06e..0bbe82726ec 100644
>> --- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/chrono.cc
>> +++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/chrono.cc
>> @@ -39,9 +39,9 @@ main()
>> utc_time utc(467664h);
>> // { dg-final { note-test utc {std::chrono::utc_time = { 467664h }} } }
>>
>> -#if _GLIBCXX_USE_CXX11_ABI && defined TEST_ZONED_TIME
>> +#if (_GLIBCXX_USE_CXX11_ABI || !_GLIBCXX_USE_DUAL_ABI) && defined TEST_ZONED_TIME
>
>
> I meant that the tests should use __cpp_lib_chrono, not the ABI macros.
> Please leave it to me, I'm already testing a fixed patch. I'll incorporate the typo fix in syn_c++20.cc
I've now pushed a v5 patch, thanks for the fix.
Are you actually using the no-sso-string build config, or was this
just an internal inconsistency that you found and wanted to fix
anyway?
More information about the Libstdc++
mailing list