From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-1.mimecast.com (us-smtp-1.mimecast.com [205.139.110.61]) by sourceware.org (Postfix) with ESMTP id BBF5B38708AC for ; Thu, 27 Aug 2020 15:29:36 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org BBF5B38708AC Received: from mail-qk1-f198.google.com (mail-qk1-f198.google.com [209.85.222.198]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-18-RVRbEdZzOBmJXfZfck-W4A-1; Thu, 27 Aug 2020 11:29:34 -0400 X-MC-Unique: RVRbEdZzOBmJXfZfck-W4A-1 Received: by mail-qk1-f198.google.com with SMTP id 8so5115170qkf.16 for ; Thu, 27 Aug 2020 08:29:34 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=0y3fqSg27W2wRJ8e21kh3B3Xu268rgKXjVGXubFIf7Q=; b=sE2LSD2hrkEoGkhBeakB8mOgUc223XVtcNXXvs90E3Wbud5Wk65RePE6AJ0hN6alp8 30DLSFzJnsQTyEjDMdetB+rdI2ZZg0PZ6tD8i1RwFaBAY+JAtwYSdCUx1Dh7avyEd6ZV xyiA9GYJUSpuJ/wUd0a00kU8q+/d4DGp7Bm2VuA6W8AVQMleGpMVFtbArWR6PJrj0B/S p7i+gnURetPgqQsnbIrnahMu/p/IxyzR2uWFAI5QcJoOA0mVo/sJh7HJXBC5F676H3sS 4csxfeD0plapTz8nxaUmftzPfnVsbr8eC1EgA/Mo4Dwzm/94cEIiO2ra+NQNtaK85b3z kGsw== X-Gm-Message-State: AOAM532rxtMUOXO2tWVxKsIXXWzgT6/ivvg0C9G5P5i1/ByJO+Yp4BOV NVZeR/dp51zCKzaoJFY+Ho9a2r14U7aoKC2gN6Q92gz9ibxctwjnNssyh1D9u8Kq/FA6eqEKoxj kyFo9LOvrvdzeY2lZAQ== X-Received: by 2002:aed:2821:: with SMTP id r30mr19096627qtd.3.1598542173715; Thu, 27 Aug 2020 08:29:33 -0700 (PDT) X-Google-Smtp-Source: ABdhPJw7LtZ3ExDiydWMOlR5dWO40Rd4/d8z+Un1/upgbnhm/B+VDj3MapnCyOuu47MEcnLsLhEQ2A== X-Received: by 2002:aed:2821:: with SMTP id r30mr19096598qtd.3.1598542173455; Thu, 27 Aug 2020 08:29:33 -0700 (PDT) Received: from localhost.localdomain (ool-457d493a.dyn.optonline.net. [69.125.73.58]) by smtp.gmail.com with ESMTPSA id q7sm2055506qkf.35.2020.08.27.08.29.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 27 Aug 2020 08:29:32 -0700 (PDT) From: Patrick Palka To: gcc-patches@gcc.gnu.org Cc: libstdc++@gcc.gnu.org, Patrick Palka Subject: [PATCH] libstdc++: Fix arithmetic bug in chrono::year_month::operator+ Date: Thu, 27 Aug 2020 11:29:27 -0400 Message-Id: <20200827152927.1620896-1-ppalka@redhat.com> X-Mailer: git-send-email 2.28.0.337.ge9b77c84a0 MIME-Version: 1.0 X-Mimecast-Spam-Score: 0.001 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-14.2 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_PASS, TXREP autolearn=unavailable autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 27 Aug 2020 15:29:37 -0000 This fixes the months-based addition for year_month when the year_month's month component is zero. Successfully tested on x86_64-pc-linux-gnu, on the 'date' library's calendar and (now) on libcxx's calendar tests. Does this look OK to commit? libstdc++-v3/ChangeLog: * include/std/chrono (year_month::operator+): Properly handle a month value of 0 by casting the month value to int before subtracting 1 from it so that the difference is signed in the subsequent addition. * testsuite/std/time/year_month/1.cc: Test addition of months to a year_month whose month value is below and above the normalized range of [1,12]. --- libstdc++-v3/include/std/chrono | 2 +- libstdc++-v3/testsuite/std/time/year_month/1.cc | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/libstdc++-v3/include/std/chrono b/libstdc++-v3/include/std/chrono index 417954d103b..398008c8f31 100644 --- a/libstdc++-v3/include/std/chrono +++ b/libstdc++-v3/include/std/chrono @@ -2133,7 +2133,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { // TODO: Optimize? auto __m = __ym.month() + __dm; - auto __i = unsigned{__ym.month()} - 1 + __dm.count(); + auto __i = int(unsigned{__ym.month()}) - 1 + __dm.count(); auto __y = (__i < 0 ? __ym.year() + years{(__i - 11) / 12} : __ym.year() + years{__i / 12}); diff --git a/libstdc++-v3/testsuite/std/time/year_month/1.cc b/libstdc++-v3/testsuite/std/time/year_month/1.cc index 007cfeb2f72..4c331dcdb50 100644 --- a/libstdc++-v3/testsuite/std/time/year_month/1.cc +++ b/libstdc++-v3/testsuite/std/time/year_month/1.cc @@ -83,4 +83,16 @@ constexpr_year_month() static_assert(2017y/33 + months{0} == 2019y/9); static_assert(2010y/January + months{-12} == 2009y/January); + + static_assert(2010y/month{0} + months{-1} == 2009y/November); + static_assert(2010y/month{0} + months{0} == 2009y/December); + static_assert(2010y/month{0} + months{1} == 2010y/January); + static_assert(2010y/month{0} + months{2} == 2010y/February); + static_assert(2010y/month{0} + months{11} == 2010y/November); + static_assert(2010y/month{0} + months{12} == 2010y/December); + static_assert(2010y/month{0} + months{13} == 2011y/January); + + static_assert(months{-1} + 2010y/month{37} == 2012y/December); + static_assert(months{0} + 2010y/month{37} == 2013y/January); + static_assert(months{1} + 2010y/month{37} == 2013y/February); } -- 2.28.0.337.ge9b77c84a0