[{"id":3676792,"web_url":"http://patchwork.ozlabs.org/comment/3676792/","msgid":"<CACb0b4=m5hWVV1j8o2aknhO_kULZ1WLz5kMSxJO0R-uT37apcA@mail.gmail.com>","list_archive_url":null,"date":"2026-04-13T14:23:59","subject":"Re: [PATCH 0/5] libstdc++: chrono tzdb correctness fixes","submitter":{"id":48004,"url":"http://patchwork.ozlabs.org/api/people/48004/","name":"Jonathan Wakely","email":"jwakely@redhat.com"},"content":"On Sat, 11 Apr 2026 at 14:33, Alvaro Begue <alvaro.begue@gmail.com> wrote:\n>\n> This series fixes five distinct correctness issues in libstdc++'s\n> <chrono> tzdb implementation that cause time-zone conversions to\n> disagree with zic.c / libc localtime_r for specific real-world zones.\n\nThis is really great, thanks. Some of the smaller patches might be\npossible to merge now for GCC 16 but the larger ones will have to wait\nfor GCC 17 (and then maybe get backported later for GCC 16.2).\n\nFor all significant patches to GCC we require either copyright\nassignment to the FSF or a DCO sign-off, please see\nhttps://gcc.gnu.org/contribute.html#legal and let us know which route\nyou want to take.\n\n\n>\n> The motivation was a brute-force comparison harness that walks every\n> IANA zone hourly across 1850-2150 (~563k transition samples) and\n> compares chrono::time_zone::to_local() against libc's localtime_r().\n> Against current master HEAD that harness reports thousands of\n> mismatches across ~190 zones; with this series applied it reports\n> zero mismatches across all 447 zones.  An abbreviation-only sweep\n> (169k samples) likewise reports zero offset and zero abbrev diffs.\n>\n> The series builds on Jonathan Wakely's recent PR 116110 / PR 124513\n> work (commits 663e5ade1, cddf4111c, fbc5d2b1a).  Patch 3 in\n> particular resolves the \"FIXME: PR 116110\" left in operator>>(istream&,\n> ZoneInfo&) for the named-rule wall-UNTIL case.\n>\n> The five commits are deliberately small and independently testable;\n> each adds a hermetic regression test using the same\n> __gnu_cxx::zoneinfo_dir_override pattern as the existing 124513.cc.\n>\n>   1. Fix numeric save offset on Zone lines [PR 124851].\n>\n>      ZoneInfo::m_offset had inconsistent semantics: the parser path\n>      stored stdoff alone, but the two sys_info-taking constructors\n>      stored the total (stdoff + save).  ZoneInfo::to() returned\n>      m_offset as sys_info::offset, dropping the numeric save for\n>      parser-path lines like Africa/Gaborone's \"2 1 CAST\" middle line.\n>      Normalize m_offset to stdoff alone everywhere; to() adds save\n>      back when reconstructing.\n>\n>   2. Support ON-format DAY in Zone UNTIL field [PR 124852].\n>\n>      The UNTIL parser only accepted a plain integer as the DAY,\n>      silently misparsing tzdata.zi entries like Europe/Simferopol's\n>      \"1997 Mar lastSu 1u\".  Reuse the on_day machinery and the\n>      parse_on_day_body helper.\n>\n>   3. Resolve named-rule UNTIL save adjustment [PR 116110].\n>\n>      The remaining FIXME in operator>>(istream&, ZoneInfo&) for\n>      wall-time UNTILs on named-rule zone lines.  At parse time the\n>      active rule cannot be evaluated (rule records aren't all\n>      loaded yet), so the parser leaves the SAVE adjustment pending\n>      and a new fixup pass in reload_tzdb walks every pending\n>      ZoneInfo and applies the adjustment using a new\n>      find_pre_until_rule helper with iterative-boundary cascade\n>      semantics.\n>\n>      A new bit (m_until_save_pending, stolen from m_pos) marks\n>      pending entries.  The seeding code is also updated to use\n>      `t = info.begin + 1s` so a rule firing at exactly info.begin\n>      is included.\n>\n>      Removes the +11h workaround from test_apia in 116110.cc.\n>\n>   4. Cascade wall-time saves in lazy expansion seeding [PR 124853].\n>\n>      The seeding code in _M_get_sys_info interpreted each rule in\n>      isolation against ri.offset() (the line's standard offset\n>      alone), ignoring the running save accumulated by earlier rules\n>      in the same year.  For zones whose rule set has wall-time\n>      rules whose effective firing time depends on a prior rule's\n>      save (Europe/Paris around 1945), this gives a wrong answer.\n>\n>      Replace with a chronological cascade walker (matching zic.c's\n>      outzone() logic) that maintains a running save and interprets\n>      each Wall-time rule's at_time relative to the cascaded state.\n>\n>   5. Implement zic writezone merge optimization [PR 124854].\n>\n>      Two distinct fixes that together let lazy expansion match\n>      zic.c's writezone output for zones with rule firings near\n>      zone-line boundaries:\n>\n>      a. Always seed info.offset and info.save from find_active_rule,\n>         not just when letters is empty.  Previously, partial-\n>         expansion re-entry left info.offset/save at their\n>         (ri.offset(), 0) init values because the seeding was\n>         skipped when letters was already populated from\n>         i[-1].next_letters().  This caused zones like Europe/Berlin\n>         around 1947-06-29 to emit a 2-hour CEST sys_info with\n>         offset=3600 / save=0 — observably wrong.\n>\n>      b. Add the writezone merge optimization itself: when adjacent\n>         zone lines have different total offsets and the new line's\n>         rule set has a rule firing within |jump| of the boundary\n>         (where jump is a backward local-time jump), fold that rule\n>         into the boundary transition.  Canonical cases handled:\n>         America/Argentina/Buenos_Aires 1999-10-03 and Europe/Berlin\n>         1945-05-24.\n>\n> Test plan:\n>   * make check-target-libstdc++-v3 RUNTESTFLAGS=\"conformance.exp=std/time/*\"\n>     -- all existing chrono tests pass, plus the five new ones added\n>     by this series.\n>   * The comparison harness reports zero mismatches across all 447\n>     zones (563600 samples).\n>   * The abbrev sweep reports zero offset and zero abbrev diffs\n>     (169080 samples).\n>\n> Alvaro Begue (5):\n>   libstdc++: Fix numeric save offset on Zone lines [PR 124851]\n>   libstdc++: Support ON-format DAY in Zone UNTIL field [PR 124852]\n>   libstdc++: Resolve named-rule UNTIL save adjustment [PR116110]\n>   libstdc++: Cascade wall-time saves in lazy expansion seeding [PR\n>     124853]\n>   libstdc++: Implement zic writezone merge optimization [PR 124854]\n>\n>  libstdc++-v3/src/c++20/tzdb.cc                | 464 ++++++++++++++----\n>  .../testsuite/std/time/time_zone/116110.cc    |   7 +-\n>  .../std/time/time_zone/numeric_save.cc        |  66 +++\n>  .../std/time/time_zone/pr116110_named.cc      | 106 ++++\n>  .../std/time/time_zone/until_day_on.cc        | 177 +++++++\n>  .../std/time/time_zone/wall_cascade.cc        |  87 ++++\n>  .../std/time/time_zone/zone_merge.cc          | 101 ++++\n>  7 files changed, 920 insertions(+), 88 deletions(-)\n>  create mode 100644 libstdc++-v3/testsuite/std/time/time_zone/numeric_save.cc\n>  create mode 100644 libstdc++-v3/testsuite/std/time/time_zone/pr116110_named.cc\n>  create mode 100644 libstdc++-v3/testsuite/std/time/time_zone/until_day_on.cc\n>  create mode 100644 libstdc++-v3/testsuite/std/time/time_zone/wall_cascade.cc\n>  create mode 100644 libstdc++-v3/testsuite/std/time/time_zone/zone_merge.cc\n>\n> --\n> 2.34.1\n>","headers":{"Return-Path":"<gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org>","X-Original-To":["incoming@patchwork.ozlabs.org","gcc-patches@gcc.gnu.org"],"Delivered-To":["patchwork-incoming@legolas.ozlabs.org","gcc-patches@gcc.gnu.org"],"Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=FICaQU6M;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org\n (client-ip=2620:52:6:3111::32; helo=vm01.sourceware.org;\n envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org;\n receiver=patchwork.ozlabs.org)","sourceware.org;\n\tdkim=pass (1024-bit key,\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=FICaQU6M","sourceware.org; dmarc=pass (p=quarantine dis=none)\n header.from=redhat.com","sourceware.org; spf=pass smtp.mailfrom=redhat.com","server2.sourceware.org;\n arc=none smtp.remote-ip=170.10.133.124"],"Received":["from vm01.sourceware.org (vm01.sourceware.org\n [IPv6:2620:52:6:3111::32])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fvV6p1Sbpz1xtJ\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 14 Apr 2026 00:25:04 +1000 (AEST)","from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id B6EEA4BA2E3C\n\tfor <incoming@patchwork.ozlabs.org>; Mon, 13 Apr 2026 14:25:02 +0000 (GMT)","from us-smtp-delivery-124.mimecast.com\n (us-smtp-delivery-124.mimecast.com [170.10.133.124])\n by sourceware.org (Postfix) with ESMTP id 5F9A04BA2E04\n for <gcc-patches@gcc.gnu.org>; Mon, 13 Apr 2026 14:24:19 +0000 (GMT)","from mail-yx1-f70.google.com (mail-yx1-f70.google.com\n [74.125.224.70]) by relay.mimecast.com with ESMTP with STARTTLS\n (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n us-mta-196-V0RV9IUKN6GuubKosLxCtQ-1; Mon, 13 Apr 2026 10:24:16 -0400","by mail-yx1-f70.google.com with SMTP id\n 956f58d0204a3-64eb0bff77cso6599125d50.0\n for <gcc-patches@gcc.gnu.org>; Mon, 13 Apr 2026 07:24:16 -0700 (PDT)"],"DKIM-Filter":["OpenDKIM Filter v2.11.0 sourceware.org B6EEA4BA2E3C","OpenDKIM Filter v2.11.0 sourceware.org 5F9A04BA2E04"],"DMARC-Filter":"OpenDMARC Filter v1.4.2 sourceware.org 5F9A04BA2E04","ARC-Filter":"OpenARC Filter v1.0.0 sourceware.org 5F9A04BA2E04","ARC-Seal":"i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1776090259; cv=none;\n b=RO6b8ujlo0GSA2D7iEOsvrnBaD/6enLRXMsChUv2RyoGXPNZA2aHTHzVWTC7DUsDxGfTgR8O1aN0ThrzBWZsVUH3r/Gtyqu6gmEotoDraHFwkWgZfUp/1/aY/Gp5Ffoa2UcttdKKN+zX5i62uNTK5RwrpopQTydR2j+/wQW/VfQ=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1776090259; c=relaxed/simple;\n bh=qMLSikO04agluVopGIrrawvSPHPFTqSKPlJ3t7MRYl4=;\n h=DKIM-Signature:MIME-Version:From:Date:Message-ID:Subject:To;\n b=X6OnQaAbKN7wOU0HhRuJFaXzfkypOfp4agFQ7rg+BlYvMIififaZ54T8ZIVm48qir0Jj5h9lHOvQt8m2wzRgCKhux72g8yxgTFRAgeayYkKq68VR6aJTMlVo9zKgGXt1r9fK20xmylHklSpHaMedPxYumCXCDVgIzf7jL5+cnSc=","ARC-Authentication-Results":"i=1; server2.sourceware.org","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1776090259;\n h=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n to:to:cc:cc:mime-version:mime-version:content-type:content-type:\n content-transfer-encoding:content-transfer-encoding:\n in-reply-to:in-reply-to:references:references;\n bh=2Kw7IxAUjOe70+pBvcoJiH1SR56WFf+xKIGeUXcPpiE=;\n b=FICaQU6MrITA4DSlFgrXa00DTode92woaG4eeCFPHGYW+ra4eIS+akOjZBCH793s9Keg3Z\n lQ997JKTiEwMzihCIK0u5HOOraK4IOZ/R+ZrEGhR/RSowy/fU9CTqTHPvPg177DcNBtjj0\n IiZWtdc9OQMLPgC7EcayqGhxaMSfVhA=","X-MC-Unique":"V0RV9IUKN6GuubKosLxCtQ-1","X-Mimecast-MFC-AGG-ID":"V0RV9IUKN6GuubKosLxCtQ_1776090256","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1776090256; x=1776695056;\n h=content-transfer-encoding:cc:to:subject:message-id:date:from\n :in-reply-to:references:mime-version:x-gm-gg:x-gm-message-state:from\n :to:cc:subject:date:message-id:reply-to;\n bh=2Kw7IxAUjOe70+pBvcoJiH1SR56WFf+xKIGeUXcPpiE=;\n b=Gd9sr1k0VZ6QlTOjNiHOyz7a/0exC6StITXsNMhGcRRfw9dDqMRD4uQ02QqEToXJXG\n sGu2MdblnqWA43Cdr7QU6Z1xCssmv9JtFoJ0rc+9gEyTdEph4y2Ee5LqlBu5xl+znpP1\n cOrxwd2prv070ejUQ3bpAL6w8kTE8cVwqYaeS7O1lY5/fZHlVk4VoNvvs6yVcT0ZH+Lh\n pot9Ds5vtpvxOyMFGLuvhX6AmP+Ow0ntphIrk2jHlNs018KE6J3k+OauVlR2r6Xuaiqq\n kouQ2W3M/K+Iq3OIUWKDuYebv3vFO/eI7cJmqeDDYwngClZcjikNdlsmdPPFeksxCiAD\n mfPw==","X-Gm-Message-State":"AOJu0YzGTWKKC04YHVK5YRVL7iAH9WNVqKBqkMNYofGoQ11g3fl2sgf1\n gt0JynAXhgByAsjoASIGIxgP4Mb8nNo7Wj8QsDH+X0HkM4I2oj9iBSZlGRPSiVtuZ9XDiptXh+W\n diVovzqub2ZeSUpgHHoWeTEjzi6Ta6tGHxPDH+IJAdgeZiTgC/UBOS9K1baNL+IEfMEB1a5xzC/\n tc7zTIwaBRhBr5POf7LcU34psoUL2Whv93tw==","X-Gm-Gg":"AeBDies8QYkKc4QNF00DrvntjddLBvb4IjGPv3/zZMqNjinB5KFZcFLTRxbj/Ko5PsF\n hXUUHV17XEdaobVoYF80MOLxtauaWNVR3KS0RnYgbALyk+xaHDOqAWLLxvMvEpKIHIZ+YMr4V9L\n W1WV2a3gb94i9tRK2mSCAuFXUrOdiehsT0H4ODi4pv7PiKeuAJKBE1fkLt3I0Yfhcdcw8DSumVA\n TGLQjlXjL2WEyrGPSax35ZR6Qarnb1lxDUXCKXwwdmlIbTbJLQVzkz+LT0aVfWBeqs=","X-Received":["by 2002:a05:690e:1287:b0:651:daf6:3d76 with SMTP id\n 956f58d0204a3-651daf659ebmr909090d50.28.1776090255747;\n Mon, 13 Apr 2026 07:24:15 -0700 (PDT)","by 2002:a05:690e:1287:b0:651:daf6:3d76 with SMTP id\n 956f58d0204a3-651daf659ebmr909069d50.28.1776090255231; Mon, 13 Apr 2026\n 07:24:15 -0700 (PDT)"],"MIME-Version":"1.0","References":"<cover.1775912642.git.alvaro.begue@gmail.com>","In-Reply-To":"<cover.1775912642.git.alvaro.begue@gmail.com>","From":"Jonathan Wakely <jwakely@redhat.com>","Date":"Mon, 13 Apr 2026 15:23:59 +0100","X-Gm-Features":"AQROBzByQJMYAw8vlA40YpAO7L2zt-7YLi4aG-JJrQKK7Un59aFaRpnOnhj-ZO8","Message-ID":"\n <CACb0b4=m5hWVV1j8o2aknhO_kULZ1WLz5kMSxJO0R-uT37apcA@mail.gmail.com>","Subject":"Re: [PATCH 0/5] libstdc++: chrono tzdb correctness fixes","To":"Alvaro Begue <alvaro.begue@gmail.com>","Cc":"gcc-patches@gcc.gnu.org, libstdc++@gcc.gnu.org","X-Mimecast-Spam-Score":"0","X-Mimecast-MFC-PROC-ID":"KCFBYWyxtrQIKry6AA2cTOd7wnB1LWTmqXbnMPBLL1M_1776090256","X-Mimecast-Originator":"redhat.com","Content-Type":"text/plain; charset=\"UTF-8\"","Content-Transfer-Encoding":"quoted-printable","X-BeenThere":"gcc-patches@gcc.gnu.org","X-Mailman-Version":"2.1.30","Precedence":"list","List-Id":"Gcc-patches mailing list <gcc-patches.gcc.gnu.org>","List-Unsubscribe":"<https://gcc.gnu.org/mailman/options/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe>","List-Archive":"<https://gcc.gnu.org/pipermail/gcc-patches/>","List-Post":"<mailto:gcc-patches@gcc.gnu.org>","List-Help":"<mailto:gcc-patches-request@gcc.gnu.org?subject=help>","List-Subscribe":"<https://gcc.gnu.org/mailman/listinfo/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe>","Errors-To":"gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org"}}]