On Sat, 14 Sept 2024 at 15:16, Jonathan Wakely <jwak...@redhat.com> wrote: > > On Sat, 14 Sept 2024 at 10:39, Arsen Arsenović <ar...@aarsen.me> wrote: > > > > Jonathan Wakely <jwak...@redhat.com> writes: > > > > > This restores support for most of <chrono> with -ffreestanding. In case > > > there are users who want a minimal freestanding implementation that only > > > provides what the standard guarantees, there's a new macro that disables > > > <chrono> again. This can be used to write more portable freestanding > > > code that doesn't rely on <chrono> being usable. As we add other things > > > to the freestanding subset (e.g. <string> for PR 113398 and <cmath> for > > > PR 109814) we can add other _GLIBCXX_NO_FREESTANDING_XXX macros, and a > > > _GLIBCXX_NO_FREESTANDING_EXTRAS to define all of them at once. I haven't > > > done that in this patch, because there's on the CHRONO one for now. > > > > That seems reasonable to me. > > > > Do we want to count the headers that we moved into the non-hosted > > configuration into this 'extras' set also (such as tuple)? Or just > > things not installed in the --disable-hosted-libstdcxx configuration? > > Ah yes, good point. I think logically it makes sense for the macro to > disable all extensions, including <tuple> etc. > > That's assuming the macros will actually be used. Somebody emailed me > off-list saying maybe we should support "freestanding plus extras" and > "freestanding without extras" but I don't know if they actually want > to use the latter, or if it was just a thought they had. > > > > > That also impacts what we do if/when we move the stuff that was made not > > freestanding due to std::allocator (IIRC vector and string are in this > > set) into the std_freestanding subset. > > Yup. > > > The patch seems OK either way. > > Thanks for looking.
I've pushed this now (after adding Arsen's Reviewed-by tag). > > > > > Tested x86_64-linux. > > > > > > -- >8 -- > > > > > > This makes durations, time points and calendrical types available for > > > freestanding. The clocks and time zone utilities are disabled for > > > freestanding, as they require functions in the hosted lib. > > > > > > Add support for a new macro _GLIBCXX_NO_FREESTANDING_CHRONO which can be > > > used to explicitly disable <chrono> for freestanding. > > > > > > libstdc++-v3/ChangeLog: > > > > > > * doc/xml/manual/using.xml (_GLIBCXX_NO_FREESTANDING_CHRONO): > > > Document macro. > > > * doc/html/*: Regenerate. > > > * include/bits/chrono.h [_GLIBCXX_NO_FREESTANDING_CHRONO]: > > > Only include <bits/require_hosted.h> when this macro is defined. > > > [_GLIBCXX_HOSTED]: Only define clocks for hosted. > > > * include/bits/version.def (chrono_udls): Remove hosted=yes. > > > * include/bits/version.h: Regenerate. > > > * include/std/chrono [_GLIBCXX_HOSTED]: Only define clocks and > > > time zone utilities for hosted. > > > * testsuite/std/time/freestanding.cc: New test. > > > --- > > > .../doc/html/manual/using_macros.html | 7 +++ > > > libstdc++-v3/doc/xml/manual/using.xml | 12 +++++ > > > libstdc++-v3/include/bits/chrono.h | 24 ++++++--- > > > libstdc++-v3/include/bits/version.def | 1 - > > > libstdc++-v3/include/bits/version.h | 2 +- > > > libstdc++-v3/include/std/chrono | 24 +++++++-- > > > .../testsuite/std/time/freestanding.cc | 52 +++++++++++++++++++ > > > 7 files changed, 109 insertions(+), 13 deletions(-) > > > create mode 100644 libstdc++-v3/testsuite/std/time/freestanding.cc > > > > > > diff --git a/libstdc++-v3/doc/html/manual/using_macros.html > > > b/libstdc++-v3/doc/html/manual/using_macros.html > > > index ae564692630..67623b5e2af 100644 > > > --- a/libstdc++-v3/doc/html/manual/using_macros.html > > > +++ b/libstdc++-v3/doc/html/manual/using_macros.html > > > @@ -124,4 +124,11 @@ > > > must be present on all vector operations or none, so this macro > > > must > > > be defined to the same value for all translation units that > > > create, > > > destroy, or modify vectors. > > > + </p></dd><dt><span class="term"><code > > > class="code">_GLIBCXX_NO_FREESTANDING_CHRONO</code></span></dt><dd><p> > > > + Undefined by default. When defined, the > > > + <code class="filename"><chrono></code> header cannot > > > + be used with <code class="option">-ffreestanding</code>. > > > + When not defined, durations, time points, and calendar types are > > > + available for freestanding, but the standard clocks and the time > > > zone > > > + database are not (because they require OS support). > > > </p></dd></dl></div></div><div class="navfooter"><hr /><table > > > width="100%" summary="Navigation footer"><tr><td width="40%" > > > align="left"><a accesskey="p" href="using_headers.html">Prev</a> </td><td > > > width="20%" align="center"><a accesskey="u" > > > href="using.html">Up</a></td><td width="40%" align="right"> <a > > > accesskey="n" href="using_dual_abi.html">Next</a></td></tr><tr><td > > > width="40%" align="left" valign="top">Headers </td><td width="20%" > > > align="center"><a accesskey="h" href="../index.html">Home</a></td><td > > > width="40%" align="right" valign="top"> Dual > > > ABI</td></tr></table></div></body></html> > > > \ No newline at end of file > > > diff --git a/libstdc++-v3/doc/xml/manual/using.xml > > > b/libstdc++-v3/doc/xml/manual/using.xml > > > index 6675359f3b3..4e1c70040b5 100644 > > > --- a/libstdc++-v3/doc/xml/manual/using.xml > > > +++ b/libstdc++-v3/doc/xml/manual/using.xml > > > @@ -1321,6 +1321,18 @@ g++ -Winvalid-pch -I. -include stdc++.h -H -g -O2 > > > hello.cc -o test.exe > > > destroy, or modify vectors. > > > </para> > > > </listitem></varlistentry> > > > + > > > + > > > <varlistentry><term><code>_GLIBCXX_NO_FREESTANDING_CHRONO</code></term> > > > + <listitem> > > > + <para> > > > + Undefined by default. When defined, the > > > + <filename class="headerfile"><chrono></filename> header cannot > > > + be used with <option>-ffreestanding</option>. > > > + When not defined, durations, time points, and calendar types are > > > + available for freestanding, but the standard clocks and the time > > > zone > > > + database are not (because they require OS support). > > > + </para> > > > + </listitem></varlistentry> > > > </variablelist> > > > > > > </section> > > > diff --git a/libstdc++-v3/include/bits/chrono.h > > > b/libstdc++-v3/include/bits/chrono.h > > > index 0773867da71..fd9c4642f4f 100644 > > > --- a/libstdc++-v3/include/bits/chrono.h > > > +++ b/libstdc++-v3/include/bits/chrono.h > > > @@ -37,7 +37,9 @@ > > > #include <ratio> > > > #include <type_traits> > > > #include <limits> > > > -#include <ctime> > > > +#if _GLIBCXX_HOSTED > > > +# include <ctime> > > > +#endif > > > #include <bits/parse_numbers.h> // for literals support. > > > #if __cplusplus >= 202002L > > > # include <concepts> > > > @@ -50,7 +52,7 @@ namespace std _GLIBCXX_VISIBILITY(default) > > > { > > > _GLIBCXX_BEGIN_NAMESPACE_VERSION > > > > > > -#if __cplusplus >= 201703L > > > +#if __cplusplus >= 201703L && _GLIBCXX_HOSTED > > > namespace filesystem { struct __file_clock; }; > > > #endif > > > > > > @@ -372,7 +374,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > > > { }; > > > #endif // C++20 > > > > > > -#ifdef __glibcxx_chrono // C++ >= 17 && HOSTED > > > +#if __cplusplus >= 201703L // C++ >= 17 > > > /** Convert a `duration` to type `ToDur` and round down. > > > * > > > * If the duration cannot be represented exactly in the result type, > > > @@ -1196,6 +1198,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > > > /// @} > > > /// @} group chrono > > > > > > +#if _GLIBCXX_HOSTED > > > // Clocks. > > > > > > // Why nanosecond resolution as the default? > > > @@ -1310,9 +1313,18 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2) > > > template<> inline constexpr bool is_clock_v<file_clock> = true; > > > /// @} > > > #endif // C++20 > > > +#elif __cplusplus >= 202002L > > > + // Define a fake clock like chrono::local_t so that sys_time etc. > > > + // can be used for freestanding. > > > + struct __sys_t; > > > + template<typename _Duration> > > > + using sys_time = time_point<__sys_t, _Duration>; > > > + using sys_seconds = sys_time<seconds>; > > > + using sys_days = sys_time<days>; > > > +#endif // _GLIBCXX_HOSTED > > > } // namespace chrono > > > > > > -#ifdef __glibcxx_chrono_udls // C++ >= 14 && HOSTED > > > +#ifdef __glibcxx_chrono_udls // C++ >= 14 > > > inline namespace literals > > > { > > > /** ISO C++ 2014 namespace for suffixes for duration literals. > > > @@ -1435,7 +1447,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2) > > > } // namespace chrono > > > #endif // __glibcxx_chrono_udls > > > > > > -#if __cplusplus >= 201703L > > > +#if __cplusplus >= 201703L && _GLIBCXX_HOSTED > > > namespace filesystem > > > { > > > struct __file_clock > > > @@ -1497,7 +1509,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2) > > > } > > > }; > > > } // namespace filesystem > > > -#endif // C++17 > > > +#endif // C++17 && HOSTED > > > > > > _GLIBCXX_END_NAMESPACE_VERSION > > > } // namespace std > > > diff --git a/libstdc++-v3/include/bits/version.def > > > b/libstdc++-v3/include/bits/version.def > > > index bd3af9cba99..36f9ea429c4 100644 > > > --- a/libstdc++-v3/include/bits/version.def > > > +++ b/libstdc++-v3/include/bits/version.def > > > @@ -275,7 +275,6 @@ ftms = { > > > values = { > > > v = 201304; > > > cxxmin = 14; > > > - hosted = yes; > > > }; > > > }; > > > > > > diff --git a/libstdc++-v3/include/bits/version.h > > > b/libstdc++-v3/include/bits/version.h > > > index 364e3a05f0e..fb97e67fb99 100644 > > > --- a/libstdc++-v3/include/bits/version.h > > > +++ b/libstdc++-v3/include/bits/version.h > > > @@ -289,7 +289,7 @@ > > > #undef __glibcxx_want_to_chars > > > > > > #if !defined(__cpp_lib_chrono_udls) > > > -# if (__cplusplus >= 201402L) && _GLIBCXX_HOSTED > > > +# if (__cplusplus >= 201402L) > > > # define __glibcxx_chrono_udls 201304L > > > # if defined(__glibcxx_want_all) || defined(__glibcxx_want_chrono_udls) > > > # define __cpp_lib_chrono_udls 201304L > > > diff --git a/libstdc++-v3/include/std/chrono > > > b/libstdc++-v3/include/std/chrono > > > index 7ffa5360728..aa78254dac9 100644 > > > --- a/libstdc++-v3/include/std/chrono > > > +++ b/libstdc++-v3/include/std/chrono > > > @@ -32,7 +32,9 @@ > > > > > > #pragma GCC system_header > > > > > > -#include <bits/requires_hosted.h> // for <ctime> and clocks > > > +#ifdef _GLIBCXX_NO_FREESTANDING_CHRONO > > > +# include <bits/requires_hosted.h> // for <ctime> and clocks > > > +#endif > > > > > > #if __cplusplus < 201103L > > > # include <bits/c++0x_warning.h> > > > @@ -41,7 +43,9 @@ > > > #include <bits/chrono.h> > > > > > > #if __cplusplus >= 202002L > > > -# include <bit> > > > +# include <bit> // __countr_zero > > > +#endif > > > +#if __cplusplus >= 202002L && _GLIBCXX_HOSTED > > > # include <sstream> > > > # include <string> > > > # include <vector> > > > @@ -82,6 +86,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > > > using local_seconds = local_time<seconds>; > > > using local_days = local_time<days>; > > > > > > +#if _GLIBCXX_HOSTED > > > class utc_clock; > > > class tai_clock; > > > class gps_clock; > > > @@ -234,7 +239,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > > > return gps_time<_CDur>{__t.time_since_epoch()} - 315964809s; > > > } > > > }; > > > - > > > +#endif // _GLIBCXX_HOSTED > > > > > > template<typename _DestClock, typename _SourceClock> > > > struct clock_time_conversion > > > @@ -251,6 +256,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > > > { return __t; } > > > }; > > > > > > +#if _GLIBCXX_HOSTED > > > template<> > > > struct clock_time_conversion<system_clock, system_clock> > > > { > > > @@ -355,6 +361,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > > > return _DestClock::from_utc(__t); > > > } > > > }; > > > +#endif // _GLIBCXX_HOSTED > > > > > > /// @cond undocumented > > > namespace __detail > > > @@ -365,6 +372,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > > > clock_time_conversion<_DestClock, _SourceClock>{}(__t); > > > }; > > > > > > +#if _GLIBCXX_HOSTED > > > template<typename _DestClock, typename _SourceClock, typename > > > _Duration> > > > concept __clock_convs_sys > > > = requires (const time_point<_SourceClock, _Duration>& __t) { > > > @@ -394,7 +402,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > > > clock_time_conversion<system_clock, utc_clock>{}( > > > clock_time_conversion<utc_clock, _SourceClock>{}(__t))); > > > }; > > > - > > > +#endif // _GLIBCXX_HOSTED > > > } // namespace __detail > > > /// @endcond > > > > > > @@ -404,10 +412,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > > > inline auto > > > clock_cast(const time_point<_SourceClock, _Duration>& __t) > > > requires __detail::__clock_convs<_DestClock, _SourceClock, > > > _Duration> > > > +#if _GLIBCXX_HOSTED > > > || __detail::__clock_convs_sys<_DestClock, _SourceClock, _Duration> > > > || __detail::__clock_convs_utc<_DestClock, _SourceClock, _Duration> > > > || __detail::__clock_convs_sys_utc<_DestClock, _SourceClock, > > > _Duration> > > > || __detail::__clock_convs_utc_sys<_DestClock, _SourceClock, > > > _Duration> > > > +#endif // _GLIBCXX_HOSTED > > > { > > > constexpr bool __direct > > > = __detail::__clock_convs<_DestClock, _SourceClock, _Duration>; > > > @@ -415,6 +425,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > > > { > > > return clock_time_conversion<_DestClock, _SourceClock>{}(__t); > > > } > > > +#if _GLIBCXX_HOSTED > > > else > > > { > > > constexpr bool __convert_via_sys_clock > > > @@ -465,6 +476,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > > > } > > > } > > > } > > > +#endif // _GLIBCXX_HOSTED > > > } > > > > > > // CALENDRICAL TYPES > > > @@ -2530,6 +2542,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > > > } > > > } > > > > > > +#if _GLIBCXX_HOSTED > > > #if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI > > > // C++20 [time.zones] Time zones > > > > > > @@ -3324,6 +3337,7 @@ namespace __detail > > > const auto __li = __detail::__get_leap_second_info(__s, false); > > > return utc_time<_CDur>{__t.time_since_epoch()} + __li.elapsed; > > > } > > > +#endif // _GLIBCXX_HOSTED > > > > > > /// @} group chrono > > > #endif // C++20 > > > @@ -3358,7 +3372,7 @@ namespace __detail > > > _GLIBCXX_END_NAMESPACE_VERSION > > > } // namespace std > > > > > > -#if __cplusplus >= 202002L > > > +#if __cplusplus >= 202002L && _GLIBCXX_HOSTED > > > # include <bits/chrono_io.h> > > > #endif > > > > > > diff --git a/libstdc++-v3/testsuite/std/time/freestanding.cc > > > b/libstdc++-v3/testsuite/std/time/freestanding.cc > > > new file mode 100644 > > > index 00000000000..afda0d5e561 > > > --- /dev/null > > > +++ b/libstdc++-v3/testsuite/std/time/freestanding.cc > > > @@ -0,0 +1,52 @@ > > > +// { dg-options "-ffreestanding" } > > > +// { dg-do compile { target c++11 } } > > > + > > > +#include <chrono> > > > + > > > +using namespace std::chrono; > > > + > > > +milliseconds > > > +test_duration() > > > +{ > > > + seconds sec{1}; > > > + sec = sec + -sec; > > > + return duration_cast<milliseconds>(sec + microseconds{100}); > > > +} > > > + > > > +struct Clock > > > +{ > > > + using rep = long; > > > + using period = std::ratio<1,10>; > > > + using duration = std::chrono::duration<rep, period>; > > > + using time_point = std::chrono::time_point<Clock>; > > > + > > > + static const bool is_steady = true; > > > + > > > + static time_point now() noexcept > > > + { > > > + static time_point tick{duration{0}}; > > > + return tick + tick.time_since_epoch(); > > > + } > > > +}; > > > + > > > +Clock::time_point > > > +test_time_point() > > > +{ > > > + auto t = Clock::now() + milliseconds{1}; > > > + return time_point_cast<Clock::duration>(t); > > > +} > > > + > > > +#if __cplusplus > 202002L > > > +static_assert( is_clock_v<Clock> ); > > > + > > > +bool > > > +test_calendar() > > > +{ > > > + auto t = test_time_point(); > > > + t = clock_cast<Clock>(t); > > > + local_days d{floor<days>(t + 1h + 1min + 1s).time_since_epoch()}; > > > + year_month_day ymd{d}; > > > + weekday w{d}; > > > + return w.ok(); > > > +} > > > +#endif > > > > -- > > Arsen Arsenović