[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