On Tue, 13 Oct 2026 at 11:14, <[email protected]> wrote:
> From: Hugo Beauzée-Luyssen <[email protected]>
>
> 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 value when
> _GLIBCXX_USE_CXX11_ABI is set. Old-ABI-only builds therefore get
> the full API but report the C++17 value.
>
> Widen the condition for the 201907 value to match, and make the
> headers check __cpp_lib_chrono instead of repeating the ABI
> condition.
>
> libstdc++-v3/ChangeLog:
>
> * include/bits/version.def (chrono): Also define 201907 for
> old-ABI-only builds.
> * include/bits/version.h: Regenerate.
> * include/std/chrono: Check __cpp_lib_chrono instead of the
> ABI macros.
> * include/bits/chrono_io.h: Likewise.
>
> Assisted-by: Claude (claude-sonnet-5)
> Signed-off-by: Hugo Beauzée-Luyssen <[email protected]>
> ---
> libstdc++-v3/include/bits/chrono_io.h | 8 ++++----
> libstdc++-v3/include/bits/version.def | 2 +-
> libstdc++-v3/include/bits/version.h | 2 +-
> libstdc++-v3/include/std/chrono | 12 ++++++------
> 4 files changed, 12 insertions(+), 12 deletions(-)
>
> diff --git a/libstdc++-v3/include/bits/chrono_io.h
> b/libstdc++-v3/include/bits/chrono_io.h
> index 028e6007544..b9e2bb28002 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 __cpp_lib_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 __cpp_lib_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 __cpp_lib_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 __cpp_lib_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..38ff5364a71 100644
> --- a/libstdc++-v3/include/bits/version.def
> +++ b/libstdc++-v3/include/bits/version.def
> @@ -622,7 +622,7 @@ ftms = {
> 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)";
>
Actually, surely we want the same condition for the 202306 case above,
otherwise the std::hash specializations have the same problem and are not
defined when they could/should be.
(and we don't need the parentheses in the condition)
> };
> values = {
> v = 201611;
> diff --git a/libstdc++-v3/include/bits/version.h
> b/libstdc++-v3/include/bits/version.h
> index e0003054af6..1d62f362eb1 100644
> --- a/libstdc++-v3/include/bits/version.h
> +++ b/libstdc++-v3/include/bits/version.h
> @@ -686,7 +686,7 @@
> # 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..9c8a5ced2bc 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 __cpp_lib_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 __cpp_lib_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 // __cpp_lib_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 __cpp_lib_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 __cpp_lib_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 // __cpp_lib_chrono >= 201803L
> #endif // _GLIBCXX_HOSTED
> #endif // __glibcxx_chrono_cxx20 >= 202306
>
> --
> 2.43.0
>
>
>