From patchwork Thu Sep 23 20:42:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 45399 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E27013857C4A for ; Thu, 23 Sep 2021 20:43:56 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E27013857C4A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1632429836; bh=9CVruJq/naUbGuyyk3oNgCJViv20mqVMeT8Yfc44/CU=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=n9H3Xjysxs82k8E0expI/QpPv0wTMG3IsKE1DGm5tZwDDRd+Mxo6/R+PKJiCoyCE3 yGWc3JlrBLxoNDY8rffYKiI+mK5+OdeL34DZG3gly+eZU1si7nCegme18XMEEzoKy5 chdRFN/OIRbSY1HjOzHp4z0gZZ6Rq3+wTDYFLjjc= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [216.205.24.124]) by sourceware.org (Postfix) with ESMTP id 996043857C48 for ; Thu, 23 Sep 2021 20:42:57 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 996043857C48 Received: from mail-qt1-f198.google.com (mail-qt1-f198.google.com [209.85.160.198]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-549-ws3Dk1_aN4CMAYqQBQXGpw-1; Thu, 23 Sep 2021 16:42:56 -0400 X-MC-Unique: ws3Dk1_aN4CMAYqQBQXGpw-1 Received: by mail-qt1-f198.google.com with SMTP id 100-20020aed30ed000000b002a6b3dc6465so13857532qtf.13 for ; Thu, 23 Sep 2021 13:42:56 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=9CVruJq/naUbGuyyk3oNgCJViv20mqVMeT8Yfc44/CU=; b=YNqMpU2x+wbhiv6N1Z+AEp5d7dEe7Q8/dH4edI0hoF2ACoR/DyLGNhqXTnhZ+IQP20 n71LrNvkVr7iwu1HcCv+cRJm1sY2+lj6W+G/s8PXT3a5c0uGToYng5017c1xRikWrpYQ nUI8TKpTyk7dL38RU89hHiAgyh22d2EDMZVhE7GqIyuGkEb8E2TiP8B01iBuX1tLD97l j3tbeW5rA9IJ+T1JRpdl3g4CRrRZuGSZYyqh9fV+KCpZewRD8G/AVrfXlqgHm834Jf+m eIembI8lNv51yir9Ua3CVWWJ5/z6eJ1gZq91N/MlD8azqmhJ+NaDT6D0BnzM6kzPqAta sZnQ== X-Gm-Message-State: AOAM530wuYFk3oTWGxiTFGAc0svKEloDC3Ul0b4pnF31jF/ODa0WA7gH r4G8t17kSiWu2stEBU1MuN17owUm1D7nZKNa11zHh34bIVPwuIgyb23xGhpxlJ5Dg1z0HfDi5nz ViMqQZIgYtyDIA4cBGDFctCfGXfU3D0To3ENMbNocairjOmsNuABdQiW78+b7Cbhmck0= X-Received: by 2002:a37:40d3:: with SMTP id n202mr6751166qka.357.1632429775445; Thu, 23 Sep 2021 13:42:55 -0700 (PDT) X-Google-Smtp-Source: ABdhPJw6dqghIUwOa0KFsasjf+j+M3u5hJZYnSOrtempmIZ5fgXNYykJ71+tDcnZruMq5y+9+aeUig== X-Received: by 2002:a37:40d3:: with SMTP id n202mr6751133qka.357.1632429775156; Thu, 23 Sep 2021 13:42:55 -0700 (PDT) Received: from localhost.localdomain (ool-457d493a.dyn.optonline.net. [69.125.73.58]) by smtp.gmail.com with ESMTPSA id 188sm5007183qkm.21.2021.09.23.13.42.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 23 Sep 2021 13:42:54 -0700 (PDT) To: gcc-patches@gcc.gnu.org Subject: [PATCH] real: fix encoding of negative IEEE double/quad values [PR98216] Date: Thu, 23 Sep 2021 16:42:53 -0400 Message-Id: <20210923204253.903755-1-ppalka@redhat.com> X-Mailer: git-send-email 2.33.0.514.g99c99ed825 MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-16.5 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_LOW, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) 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-Patchwork-Original-From: Patrick Palka via Gcc-patches From: Patrick Palka Reply-To: Patrick Palka Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" In encode_ieee_double/quad, the assignment unsigned long VAL = r->sign << 31; is intended to set the 31st bit of VAL whenever the given REAL_CST is negative. But on LP64 hosts it also unintentionally sets the upper 32 bits of VAL due to the promotion of r->sign from unsigned:1 to int and the subsequent sign extension of the shifted value from int to long. In the C++ frontend, this bug causes incorrect mangling of negative double values due to the output of real_to_target during write_real_cst unexpectedly having the upper 32 bits of each word set. (I'm not sure if/how this bug manifests itself outside of the frontend..) This patch fixes this by avoiding the unwanted sign extension. Note that r0-53976 fixed the same bug in encode_ieee_single long ago. Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for trunk and perhaps the release branches? PR c++/98216 PR c++/91292 gcc/ChangeLog: * real.c (encode_ieee_double): Avoid incorrect sign extension. (encode_ieee_quad): Likewise. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/nontype-float2.C: New test. --- gcc/real.c | 6 ++++-- gcc/testsuite/g++.dg/cpp2a/nontype-float2.C | 13 +++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/nontype-float2.C diff --git a/gcc/real.c b/gcc/real.c index 555cf44c142..8c7a47a69e6 100644 --- a/gcc/real.c +++ b/gcc/real.c @@ -3150,9 +3150,10 @@ encode_ieee_double (const struct real_format *fmt, long *buf, const REAL_VALUE_TYPE *r) { unsigned long image_lo, image_hi, sig_lo, sig_hi, exp; + unsigned long sign = r->sign; bool denormal = (r->sig[SIGSZ-1] & SIG_MSB) == 0; - image_hi = r->sign << 31; + image_hi = sign << 31; image_lo = 0; if (HOST_BITS_PER_LONG == 64) @@ -3938,10 +3939,11 @@ encode_ieee_quad (const struct real_format *fmt, long *buf, const REAL_VALUE_TYPE *r) { unsigned long image3, image2, image1, image0, exp; + unsigned long sign = r->sign; bool denormal = (r->sig[SIGSZ-1] & SIG_MSB) == 0; REAL_VALUE_TYPE u; - image3 = r->sign << 31; + image3 = sign << 31; image2 = 0; image1 = 0; image0 = 0; diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-float2.C b/gcc/testsuite/g++.dg/cpp2a/nontype-float2.C new file mode 100644 index 00000000000..5db208a05d1 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/nontype-float2.C @@ -0,0 +1,13 @@ +// PR c++/98216 +// { dg-do compile { target c++20 } } + +template void f() { } + +template void f<-1.0f>(); +template void f<-2.0f>(); + +template void f<-1.0>(); +template void f<-2.0>(); + +template void f<-1.0L>(); +template void f<-2.0L>();