On 14/01/23 18:24 +0000, Jonathan Wakely wrote:
On 23/12/22 17:06 +0000, Iain Sandoe wrote:
This is a patch for comment on the approach - tested on x86_64-darwi21
thoughts?
Iain

--- 8< ---

Testing on Darwin revealed that the GLIBCXX_ZONEINFO_DIR was not doing quite
the right thing (we ended up with ${withval} in the config.h file).

This patch proposes revising the behaviour of the configure flag thus:

--with-libstdcxx-zoneinfo-dir=
unspecified : Set _GLIBCXX_ZONEINFO_DIR to a default suitable for $host
       yes : Set _GLIBCXX_ZONEINFO_DIR to a default suitable for $host
       no  : Do not set _GLIBCXX_ZONEINFO_DIR
/some/path  : set _GLIBCXX_ZONEINFO_DIR = "/some/path"

Here's what I've pushed to trunk now, after discussion with Iain.

This is a small follow-up to elide most of the code in
src/c++20/tzdb.cc when the library is configured with
--with-libstdcxx-zoneinfo=no

Tested x86_64-linux and powerpc64le-linux. Pushed to trunk.

-- >8 --

commit c47dcb95666ce0b48f0ff09aa99483fd12df8714
Author: Jonathan Wakely <jwak...@redhat.com>
Date:   Sat Jan 14 13:39:48 2023

    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.

diff --git a/libstdc++-v3/src/c++20/tzdb.cc b/libstdc++-v3/src/c++20/tzdb.cc
index 94fb0436091..a37859dffdb 100644
--- a/libstdc++-v3/src/c++20/tzdb.cc
+++ b/libstdc++-v3/src/c++20/tzdb.cc
@@ -82,6 +82,14 @@ namespace __gnu_cxx
 #endif
 }
+#if ! defined _GLIBCXX_ZONEINFO_DIR && ! defined _GLIBCXX_STATIC_TZDATA
+# define TZDB_DISABLED
+  [[noreturn]] void __throw_disabled()
+  {
+    std::__throw_runtime_error("tzdb: support for loading tzdata is disabled");
+  }
+#endif
+
 namespace std::chrono
 {
   namespace
@@ -105,7 +113,9 @@ namespace std::chrono
   {
     shared_ptr<_Node> next;
     tzdb db;
+#ifndef TZDB_DISABLED
     vector<Rule> rules;
+#endif
// The following static members are here because making them members
     // of this type gives them access to the private members of time_zone
@@ -175,6 +185,7 @@ namespace std::chrono
   // assume that setting failbit will throw an exception, so individual
   // input operations are not always checked for success.
+#ifndef TZDB_DISABLED
   namespace
   {
     // Used for reading a possibly-quoted string from a stream.
@@ -582,6 +593,7 @@ namespace std::chrono
 #endif
     };
   } // namespace
+#endif // TZDB_DISABLED
// Private constructor used by reload_tzdb() to create time_zone objects.
   time_zone::time_zone(unique_ptr<_Impl> __p) : _M_impl(std::move(__p)) { }
@@ -591,6 +603,7 @@ namespace std::chrono
   // The opaque pimpl class stored in a time_zone object.
   struct time_zone::_Impl
   {
+#ifndef TZDB_DISABLED
     explicit
     _Impl(weak_ptr<tzdb_list::_Node> node) : node(std::move(node)) { }
@@ -677,11 +690,19 @@ namespace std::chrono
          }
        }
       };
-#endif
+#endif // __GTHREADS && __cpp_lib_atomic_wait
RulesCounter<atomic_signed_lock_free> rules_counter;
+#else // TZDB_DISABLED
+    _Impl(weak_ptr<tzdb_list::_Node>) { }
+    struct {
+      sys_info info;
+      void push_back(sys_info i) { info = std::move(i); }
+    } infos;
+#endif // TZDB_DISABLED
   };
+#ifndef TZDB_DISABLED
   namespace
   {
     bool
@@ -731,11 +752,13 @@ namespace std::chrono
        select_std_or_dst_abbrev(info.abbrev, info.save);
     }
   }
+#endif // TZDB_DISABLED
// Implementation of std::chrono::time_zone::get_info(const sys_time<D>&)
   sys_info
   time_zone::_M_get_sys_info(sys_seconds tp) const
   {
+#ifndef TZDB_DISABLED
     // This gives us access to the node->rules vector, but also ensures
     // that the tzdb node won't get erased while we're still using it.
     const auto node = _M_impl->node.lock();
@@ -934,17 +957,20 @@ namespace std::chrono
        // Decrement count of rule-based infos (might also release lock).
        _M_impl->rules_counter.decrement();
       }
-
     return info;
+#else
+    return _M_impl->infos.info;
+#endif // TZDB_DISABLED
   }
// Implementation of std::chrono::time_zone::get_info(const local_time<D>&)
   local_info
   time_zone::_M_get_local_info(local_seconds tp) const
   {
+    local_info info{};
+#ifndef TZDB_DISABLED
     const auto node = _M_impl->node.lock();
- local_info info{};
     // Get sys_info assuming no offset between local time and UTC:
     info.first = _M_get_sys_info(sys_seconds(tp.time_since_epoch()));
@@ -1007,9 +1033,13 @@ namespace std::chrono
          }
        // else tp is a unique local time, info.first is the correct sys_info.
       }
+#else
+    info.first = _M_impl->infos.info;
+#endif // TZDB_DISABLED
     return info;
   }
+#ifndef TZDB_DISABLED
   namespace
   {
     // If a zoneinfo directory is defined (either when the library was built,
@@ -1088,14 +1118,13 @@ namespace std::chrono
       bool using_static_data() const { return this->rdbuf() == &sb; }
     };
   }
+#endif // TZDB_DISABLED
// Return leap_second values, and a bool indicating whether the values are
   // current (true), or potentially out of date (false).
   pair<vector<leap_second>, bool>
   tzdb_list::_Node::_S_read_leap_seconds()
   {
-    const string filename = zoneinfo_file(leaps_file);
-
     // This list is valid until at least 2023-06-28 00:00:00 UTC.
     auto expires = sys_days{2023y/6/28};
     vector<leap_second> leaps
@@ -1137,10 +1166,10 @@ namespace std::chrono
       return {std::move(leaps), true};
 #endif
- auto exp_year = year_month_day(expires).year();
-
-    if (ifstream ls{filename})
+#ifndef TZDB_DISABLED
+    if (ifstream ls{zoneinfo_file(leaps_file)})
       {
+       auto exp_year = year_month_day(expires).year();
        std::string s, w;
        s.reserve(80); // Avoid later reallocations.
        while (std::getline(ls, s))
@@ -1183,10 +1212,11 @@ namespace std::chrono
          }
        return {std::move(leaps), true};
       }
-    else
-      return {std::move(leaps), false};
+#endif
+    return {std::move(leaps), false};
   }
+#ifndef TZDB_DISABLED
   namespace
   {
     // Read the version number from a tzdata.zi file.
@@ -1213,12 +1243,17 @@ namespace std::chrono
       __throw_runtime_error("tzdb: no version found in tzdata.zi");
     }
   }
+#endif
// Definition of std::chrono::remote_version()
   string remote_version()
   {
+#ifndef TZDB_DISABLED
     tzdata_stream zif;
     return remote_version(zif);
+#else
+    __throw_disabled();
+#endif
   }
// Used by chrono::reload_tzdb() to add a new node to the front of the list.
@@ -1255,11 +1290,13 @@ namespace std::chrono
   const tzdb&
   tzdb_list::_Node::_S_init_tzdb()
   {
+#ifndef TZDB_DISABLED
     __try
       {
        return reload_tzdb();
       }
     __catch (const std::exception&)
+#endif
       {
        auto [leaps, ok] = _S_read_leap_seconds();
@@ -1349,6 +1386,7 @@ namespace std::chrono
   const tzdb&
   reload_tzdb()
   {
+#ifndef TZDB_DISABLED
     using Node = tzdb_list::_Node;
tzdata_stream zif;
@@ -1458,6 +1496,9 @@ namespace std::chrono
     shared_ptr<Node> head;
 #endif
     return Node::_S_replace_head(std::move(head), std::move(node));
+#else
+    __throw_disabled();
+#endif // TZDB_DISABLED
   }
// Any call to tzdb_list::front() or tzdb_list::begin() must follow
@@ -1641,6 +1682,7 @@ namespace std::chrono
     return get_tzdb_list().begin()->current_zone();
   }
+#ifndef TZDB_DISABLED
   namespace
   {
     istream& operator>>(istream& in, abbrev_month& am)
@@ -1933,5 +1975,5 @@ namespace std::chrono
       return in;
     }
   } // namespace
-
+#endif // TZDB_DISABLED
 } // namespace std::chrono
diff --git a/libstdc++-v3/testsuite/std/time/tzdb/leap_seconds.cc 
b/libstdc++-v3/testsuite/std/time/tzdb/leap_seconds.cc
index 2b289436583..d27038225c8 100644
--- a/libstdc++-v3/testsuite/std/time/tzdb/leap_seconds.cc
+++ b/libstdc++-v3/testsuite/std/time/tzdb/leap_seconds.cc
@@ -1,5 +1,6 @@
 // { dg-options "-std=gnu++20" }
 // { dg-do run { target c++20 } }
+// { dg-require-effective-target tzdb }
 // { dg-require-effective-target cxx11_abi }
 // { dg-xfail-run-if "no weak override on AIX" { powerpc-ibm-aix* } }
diff --git a/libstdc++-v3/testsuite/std/time/tzdb_list/1.cc b/libstdc++-v3/testsuite/std/time/tzdb_list/1.cc
index 4cbd656efbd..2b121ff219d 100644
--- a/libstdc++-v3/testsuite/std/time/tzdb_list/1.cc
+++ b/libstdc++-v3/testsuite/std/time/tzdb_list/1.cc
@@ -1,5 +1,6 @@
 // { dg-options "-std=gnu++20" }
 // { dg-do run { target c++20 } }
+// { dg-require-effective-target tzdb }
 // { dg-require-effective-target cxx11_abi }
 // { dg-xfail-run-if "no weak override on AIX" { powerpc-ibm-aix* } }

Reply via email to