https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116110

--- Comment #16 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Tomasz Kaminski <[email protected]>:

https://gcc.gnu.org/g:020e02fcf281bd24065c8663219a22aba9d0a47d

commit r17-2466-g020e02fcf281bd24065c8663219a22aba9d0a47d
Author: Tomasz KamiÅski <[email protected]>
Date:   Tue Jul 14 16:06:36 2026 +0200

    libstdc++: Resolve named-rule UNTIL save adjustment [PR116110]

    The previous patches for PR 116110 left one case unresolved: a Zone
    line with a wall-time UNTIL whose RULES field is a named rule set.
    The save value used to convert the wall UNTIL to UTC depends on which
    rule of the set was active at the UNTIL instant, but at parse time
    the rule records have not all been loaded, so the active-rule lookup
    can't yet be performed.

    The remaining FIXME in operator>>(istream&, ZoneInfo&) caused zones
    like Africa/Algiers (around 1977-10-21) to place their zone-line
    boundary one save-period off from the canonical zic interpretation,
    producing brief incorrect sys_info windows during DST transitions.

    This commit defers the save adjustment to _M_get_sys_info call,
    and applies it only for the ZoneInfo surrounding the specified
    time. This assumes that applying the save does not change relative
    order of ZoneInfo (i.e. the until members are spaced more than save).

    The m_expanded member is replaced with four state _M_state setting:
    Expanded, and three separte state used for rule based zones:
    * SaveKnown - m_save contains save value at time m_until
    * SavePending - m_save is defualted to zero, m_until is correct
    * UntilPending - as above, but also m_until time need to adjusted
    The parser set the UntilPending state when it sees a wall-time
    UNTIL on a named-rule line, and SaveKnown if not UNTIL date is
    specified.

    The fixup in _M_get_sys_info, is performed by calc_save function
    on previous/current zone. If necessary (depending on m_state) this
    function updates m_save and m_until members, and returns true
    if the m_until was shifted in the process. In such case, we redo
    the comparision of until() against tp, and move iterator to active
    zone info if necessary. The save at boundary for previous/current
    ZoneInfo is required to implement proper zone merging, so it is
    always computed.

    The active-rule lookup either reuses the existing find_active_rule
    overload accepting sys_seconds (if UNTIL is not affected by save),
    or newly introduced overload accepting local_seconds (local time).
    The local_seconds versions, follows the same logic for finding
    rule transitions (extracted to find_surrounding_transitions)
    surrounding the sys_time. The final active rule, is then determined
    after converting the transition times to local time, including the
    running save.

    The test_apia case in 116110.cc had a hardcoded `+11h` workaround
    for the unfixed bug; with this fix in place the workaround is removed
    and the value becomes the canonical `+10h`.

    libstdc++-v3/ChangeLog:

            PR libstdc++/116110
            * src/c++20/tzdb.cc (ZoneInfo::calc_save, ZoneInfo::State): Define.
            (ZoneInfo::m_expanded): Replaced with m_state.
            (ZoneInfo::m_pos): Reduce the bit with to 14.
            (ZoneInfo::m_state): Expands m_expanded with four state enum.
            (ZoneInfo::ZoneInfo, ZoneInfo::expanded, ZoneInfo::set_abbrev):
            Replace m_expanded usage with m_state and State::Expanded.
            (Transitions, find_surrounding_transitions): Extracted from
            find_active_rule.
            (find_active_rule): Define overload for local_seconds. Implement
            both in terms of find_surrounding_transitions.
            (time_zone::_M_get_sys_info): Use ZoneInfo::calc_save to adjust
            until() on surrounding zones, and shift the current zone iterator
            (i) accordingly.
            (operator>>(istream&, ZoneInfo&)): Set m_state for UntilPending
            for UNTIL time using wall time, and SaveKnown for lines without
            end date. For clarity, set m_save to 0 if daylight is not used.
            * testsuite/std/time/time_zone/116110.cc (test_apia): Use correct
            value of the the total offset.
            testsuite/std/time/time_zone/pr116110_named.cc: New test.

    Reviewed-by: Jonathan Wakely <[email protected]>
    Co-authored-by: Álvaro Begué <[email protected]>
    Signed-off-by: Álvaro Begué <[email protected]>
    Signed-off-by: Tomasz KamiÅski <[email protected]>

Reply via email to