From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 1F0AC385703F for ; Tue, 12 Dec 2023 22:46:59 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 1F0AC385703F Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 1F0AC385703F Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1702421220; cv=none; b=ZPpsWhP+iHbWNqu1Yo4Dl/UUNoD2+4oTfguWqYGS9FkNmuH2sqNaCZyD6/BMpD4EpsPKR0cbzLvbp5T4B+COGEUU3BGl6S763JaE45Qzq7waKSCUxi72qEjAFCjyArMAtYrMS8crwvcSvR3GUG/f6nNUIIy9+fRnEsVxjigdkIY= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1702421220; c=relaxed/simple; bh=F+V/1AI0umHJcIZcb7Rqw+8j3Ct17qgYQ94ajhvpI0k=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=Ejc1HxGx4ieSLf6FbH1C5yH0eveXExWRxPBkRi0h9ym9T8t9/GuMK0mAKGagFdjCPROFt7IradFneG/Nrpwd+M2VBroIrlT/GIF1NntyFwz2oIK8WjGV+hJRT65MH2PXi5H85W2EsR7etp3tNq8B6UPXVsg7aQP9uSrTjn0b650= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1702421218; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=1TkLLinqiIlRy9Is7PVnqQv+W2Av6TjMth1+lqotw68=; b=Q4u1W5JMOPvPW2Jx6LN/wLbhwbcIei3KE9jsrWoKuzoadeg3zLAcvP9cnFfvhhfW9SIgwq e8C3LcLXeYjSA4p1JvzqbG6JrySy/jnrlITD8j9PN9xeLLp/t95+/F/d5HEtOO4emS/a3v 0ushH8a3KGa3NPfCS72O4waSvve99zI= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-182-2w_wo6MDOI6WxjBWF04LGQ-1; Tue, 12 Dec 2023 17:46:55 -0500 X-MC-Unique: 2w_wo6MDOI6WxjBWF04LGQ-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 81714881C82; Tue, 12 Dec 2023 22:46:55 +0000 (UTC) Received: from localhost (unknown [10.42.28.145]) by smtp.corp.redhat.com (Postfix) with ESMTP id 36FAA1C060AF; Tue, 12 Dec 2023 22:46:55 +0000 (UTC) From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [committed] libstdc++: Fix std::format output of %C for negative years Date: Tue, 12 Dec 2023 22:46:47 +0000 Message-ID: <20231212224654.1518338-1-jwakely@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.7 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_NONE,TXREP,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: Tested x86_64-linux. Pushed to trunk. -- >8-- During discussion of LWG 4022 I noticed that we do not correctly implement floored division for the century. We were just truncating towards zero, rather than applying the floor function. For negative values that rounds the wrong way. libstdc++-v3/ChangeLog: * include/bits/chrono_io.h (__formatter_chrono::_M_C_y_Y): Fix rounding for negative centuries. * testsuite/std/time/year/io.cc: Check %C for negative years. --- libstdc++-v3/include/bits/chrono_io.h | 9 +++++++-- libstdc++-v3/testsuite/std/time/year/io.cc | 7 +++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/libstdc++-v3/include/bits/chrono_io.h b/libstdc++-v3/include/bits/chrono_io.h index 16e8fc58dff..b63b8592eba 100644 --- a/libstdc++-v3/include/bits/chrono_io.h +++ b/libstdc++-v3/include/bits/chrono_io.h @@ -820,9 +820,14 @@ namespace __format if (__conv == 'Y' || __conv == 'C') { - if (__is_neg) - __s.assign(1, _S_plus_minus[1]); int __ci = __yi / 100; + if (__is_neg) [[unlikely]] + { + __s.assign(1, _S_plus_minus[1]); + // For floored division -123//100 is -2 and -100//100 is -1 + if ((__ci * 100) != __yi) + ++__ci; + } if (__ci >= 100) [[unlikely]] { __s += std::format(_S_empty_spec, __ci / 100); diff --git a/libstdc++-v3/testsuite/std/time/year/io.cc b/libstdc++-v3/testsuite/std/time/year/io.cc index 6157afae253..a6683ae20df 100644 --- a/libstdc++-v3/testsuite/std/time/year/io.cc +++ b/libstdc++-v3/testsuite/std/time/year/io.cc @@ -43,8 +43,11 @@ test_format() s = std::format("{}", --year::min()); // formatted via ostream VERIFY( s == "-32768 is not a valid year" ); - s = std::format("{:%y} {:%y}", 1976y, -1976y); - VERIFY( s == "76 76" ); // LWG 3831 + s = std::format("{:%C %y} {:%C %y}", 1976y, -1976y); + VERIFY( s == "19 76 -20 76" ); // LWG 3831 + + s = std::format("{:%C %y} {:%C %y} {:%C %y}", -9y, -900y, -555y); + VERIFY( s == "-01 09 -09 00 -06 55" ); // LWG 4022 s = std::format("{0:%EC}{0:%Ey} = {0:%EY}", 1642y); VERIFY( s == "1642 = 1642" ); -- 2.43.0