On Mon, 26 Oct 2026 at 13:21, Jonathan Wakely <[email protected]> wrote:
>
> On Mon, 26 Oct 2026 at 13:13, Tomasz Kaminski <[email protected]> wrote:
> >
> > On Fri, Oct 23, 2026 at 2:58 PM Jonathan Wakely <[email protected]> wrote:
> >>
> >> On Tue, 13 Oct 2026 at 21:09, Jonathan Wakely wrote:
> >> >
> >> > A very negative time point will stay negative when info.begin is
> >> > subtracted from it, which means that a negative value will be passed to
> >> > vector::reserve. That will convert to a huge size_t value, and the
> >> > vector will throw length_error. This commit clamps the time point
> >> > argument to be no less than the start of the zone's first info, so that
> >> > `tp - info.begin` will be non-negative.
> >
> > There are no zones and rules that apply before 1900, so I would suggest to
> > change the reserve condition to something like:
> > constexpr eariest_rule = 1900y/Jan/1;
> > if (tp > eariest_rule) [[likely]]
> >   if (int n = ceil<years>(tp - std::max(info.begin, eariest_rule)).count())
> >     new_infos.reserve(std::min(100, n * 2));
> > And let any user-made time zone database simply use normal vector growth 
> > algorithm.
> > There is no point in allocating 2000 elements if someone asks for time at 
> > year 26 AC.
> >
> > This need to be backported up to 14, as the 2026e tzdata introduced a new 
> > entries that
> > applies a rule on the first line (so such earily time is not already 
> > expanded):
> > Z CST6CDT -6 US C%sT
> > Z EST5EDT -5 US E%sT
> > Z MST7MDT -7 US M%sT
> > Z PST8PDT -8 US P%sT
> > The earliest rule in US set in 1918.,
> >
> >> >
> >> > This commit also changes it to chrono::abs(tp - info.begin).  This is
> >> > not strictly necessary now that tp is not less than info.begin, but it
> >> > makes the code more robust. Even if a later change makes it possible for
> >> > the value to be negative again, we will not pass a negative value to
> >> > vector::reserve.
> >> >
> >> > libstdc++-v3/ChangeLog:
> >> >
> >> >         PR libstdc++/127815
> >> >         * src/c++20/tzdb.cc (time_zone::_M_get_sys_info): Clamp
> >> >         parameter to start of first info. Use chrono::abs for argument
> >> >         to vector::reserve.
> >> >         * testsuite/std/time/time_zone/127815.cc: New test.
> >>
> >> gcc.sashiko.dev made some useful comments on this patch
> >> https://gcc.sashiko.dev/#/patchset/20261013200857.3698160-1-jwakely%40redhat.com
> >
> >
> > The comments are valid; however, I do not think the fix for them should be 
> > combined into this patch.
> > While expanding the initial sys_info to start at seconds::min() is 
> > unproblematic I think (we need to be
> > carefull when converting to date), the standard is not clear, what should 
> > happen if zone specifiy
> > UNTIL time for the last rule, and does not have line without any UNTIL.
>
> It's also not clear what should happen if you call time_zone::get_info
> with a time which cannot be represented in sys_seconds, e.g.
> get_info(sys_time{minutes::min()}). That time point is before
> seconds::min() so there's no way that the returned sys_info can meet
> the requirements that st is in the range [i.begin, i.end).

But I agree that we should solve those problems separately from
PR127815 which is about the function failing, not about the function's
postcondition.

Reply via email to