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.
