Message ID | 20230419150931.2047832-1-tromey@adacore.com |
---|---|
State | New |
Headers |
Return-Path: <gdb-patches-bounces+patchwork=sourceware.org@sourceware.org> 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 E35CD385771D for <patchwork@sourceware.org>; Wed, 19 Apr 2023 15:10:04 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E35CD385771D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1681917004; bh=DXbG5g+Fr3H/CJN1y9dNA93MOoZ4JLHF6VJnyEi3hbk=; h=To:Cc:Subject:Date:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:From; b=rQ+87mQZ2og0NzirmiwKF9SWXd6ncroRW5bukHHbLMPxMI1MlmafcA7tglSvgTu5Q lMW7HIU2aCSJZiIojY06mwIaLQ4PCtxrb2Q8Glq45gG5xvK7yPZvS34Pb5af3wccRX ivLOS6GIb2oRwFokmFfg/+ECQNDTWzOiv4zyngNM= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-io1-xd2a.google.com (mail-io1-xd2a.google.com [IPv6:2607:f8b0:4864:20::d2a]) by sourceware.org (Postfix) with ESMTPS id 5862F3857722 for <gdb-patches@sourceware.org>; Wed, 19 Apr 2023 15:09:42 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 5862F3857722 Received: by mail-io1-xd2a.google.com with SMTP id ca18e2360f4ac-7606e2d0376so4573939f.3 for <gdb-patches@sourceware.org>; Wed, 19 Apr 2023 08:09:42 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1681916981; x=1684508981; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=DXbG5g+Fr3H/CJN1y9dNA93MOoZ4JLHF6VJnyEi3hbk=; b=PGEsm91cuXG0gZMe9SmtrT8U12AFQURz9r2ITH3MJSiYkGmgkbI9mdNFc5l5wMx5d6 7xTo4GBZh4S4NCfMAmaQ6l80g8yulIUsjAyE98W8xv7mkfxPIeKj32OEDyMHpptLz4bz 9/Irn2xT6Ucj1E/lJxGSQ+T2FyErc+v6Tog9NNdiSTSxsinejTBr9xBJczd2cOlNdG7o 7oxtgPSpzgeB6FYGwbIr45KxB7gFJ2NBxccOCp4olLWENviJjiggeujvcFPcP3jLM8/R OqTKt0gt9Vz+kUdmJI+jxhVKZoY2Y3/SgSeISVYN+YWip6dyGf1Fj7NCJon51nKphDtJ cOlQ== X-Gm-Message-State: AAQBX9frxK4ZVqdAhZFjawstX1q6A+YqILX3T9we/A9L5DQPLEHpXlnb 6BZKSlDWDDcfOMJTGlrU25bQW0diA8dtgpHlrm0GcA== X-Google-Smtp-Source: AKy350bVRUnQqrequKXdGQiYRFZoSKPuQ5I4PZ2T/9P55DzJC4QdFPB6lsvzNiif+xERvNxZ8qzY9g== X-Received: by 2002:a5d:9c5a:0:b0:763:7a92:7669 with SMTP id 26-20020a5d9c5a000000b007637a927669mr246749iof.14.1681916981494; Wed, 19 Apr 2023 08:09:41 -0700 (PDT) Received: from localhost.localdomain (71-211-191-82.hlrn.qwest.net. [71.211.191.82]) by smtp.gmail.com with ESMTPSA id ck20-20020a0566383f1400b0040f94e539eesm3365106jab.136.2023.04.19.08.09.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Apr 2023 08:09:40 -0700 (PDT) To: gdb-patches@sourceware.org Cc: Tom Tromey <tromey@adacore.com> Subject: [PATCH] Rewrite gdb_mpz::operator== Date: Wed, 19 Apr 2023 09:09:31 -0600 Message-Id: <20230419150931.2047832-1-tromey@adacore.com> X-Mailer: git-send-email 2.39.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-11.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list <gdb-patches.sourceware.org> List-Unsubscribe: <https://sourceware.org/mailman/options/gdb-patches>, <mailto:gdb-patches-request@sourceware.org?subject=unsubscribe> List-Archive: <https://sourceware.org/pipermail/gdb-patches/> List-Post: <mailto:gdb-patches@sourceware.org> List-Help: <mailto:gdb-patches-request@sourceware.org?subject=help> List-Subscribe: <https://sourceware.org/mailman/listinfo/gdb-patches>, <mailto:gdb-patches-request@sourceware.org?subject=subscribe> From: Tom Tromey via Gdb-patches <gdb-patches@sourceware.org> Reply-To: Tom Tromey <tromey@adacore.com> Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" <gdb-patches-bounces+patchwork=sourceware.org@sourceware.org> |
Series |
Rewrite gdb_mpz::operator==
|
|
Commit Message
Tom Tromey
April 19, 2023, 3:09 p.m. UTC
Simon pointed out that the recent changes to gdb_mpz caused a build failure on macOS. It turns out to be somewhat difficult to overload a method in a way that will work "naturally" for all integer types; especially in a case like gdb_mpz::operator==, where it's desirable to special case all integer types that are no wider than 'long'. After a false start, I came up with this patch, which seems to work. It applies the desirable GMP special cases directly in the body, rather than via overloads. --- gdb/gmp-utils.h | 38 ++++++++++++++------------------------ 1 file changed, 14 insertions(+), 24 deletions(-)
Comments
On 4/19/23 11:09, Tom Tromey via Gdb-patches wrote: > Simon pointed out that the recent changes to gdb_mpz caused a build > failure on macOS. It turns out to be somewhat difficult to overload a For some reason, just macOS on amd64, not arm64. > method in a way that will work "naturally" for all integer types; > especially in a case like gdb_mpz::operator==, where it's desirable to > special case all integer types that are no wider than 'long'. > > After a false start, I came up with this patch, which seems to work. > It applies the desirable GMP special cases directly in the body, > rather than via overloads. > --- > gdb/gmp-utils.h | 38 ++++++++++++++------------------------ > 1 file changed, 14 insertions(+), 24 deletions(-) > > diff --git a/gdb/gmp-utils.h b/gdb/gmp-utils.h > index d05c11ecbe4..3586d01b0f9 100644 > --- a/gdb/gmp-utils.h > +++ b/gdb/gmp-utils.h > @@ -323,31 +323,21 @@ struct gdb_mpz > return mpz_cmp_si (m_val, other) < 0; > } > > - bool operator== (int other) const > - { > - return mpz_cmp_si (m_val, other) == 0; > - } > - > - bool operator== (long other) const > - { > - return mpz_cmp_si (m_val, other) == 0; > - } > - > - bool operator== (unsigned long other) const > - { > - return mpz_cmp_ui (m_val, other) == 0; > - } > - > template<typename T, > - typename = gdb::Requires< > - gdb::And<std::is_integral<T>, > - std::integral_constant<bool, > - (sizeof (T) > sizeof (long))>> > - > > - > > - bool operator== (T src) > - { > - return *this == gdb_mpz (src); > + typename = gdb::Requires<std::is_integral<T>>> > + bool operator== (T other) const > + { > + if (std::is_signed<T>::value) > + { > + if (other == (T) (long) other) It's a bit hard to understand what the intent is, if you don't know the problematic already. Could you add a comment explaining that? Also, wouldn't it work to compare size? Like: if (sizeof (T) <= sizeof (long)) Simon
>>>>> "Simon" == Simon Marchi <simark@simark.ca> writes:
Simon> It's a bit hard to understand what the intent is, if you don't know the
Simon> problematic already. Could you add a comment explaining that?
Sure.
Simon> Also, wouldn't it work to compare size? Like:
Simon> if (sizeof (T) <= sizeof (long))
Yeah, though I was concerned that the compiler might emit warnings about
always-true conditions in this case.
Tom
On 4/21/23 09:00, Tom Tromey wrote: >>>>>> "Simon" == Simon Marchi <simark@simark.ca> writes: > > Simon> It's a bit hard to understand what the intent is, if you don't know the > Simon> problematic already. Could you add a comment explaining that? > > Sure. > > Simon> Also, wouldn't it work to compare size? Like: > Simon> if (sizeof (T) <= sizeof (long)) > > Yeah, though I was concerned that the compiler might emit warnings about > always-true conditions in this case. Well, that would be surprising for code in a template, where T is not know in advance. Simon
>>>>> "Simon" == Simon Marchi <simark@simark.ca> writes: >> Yeah, though I was concerned that the compiler might emit warnings about >> always-true conditions in this case. Simon> Well, that would be surprising for code in a template, where T is not Simon> know in advance. I feel like it happened in the past, but maybe it doesn't any more. I'll rewrite this patch. Tom
Tom> I feel like it happened in the past, but maybe it doesn't any more. Tom> I'll rewrite this patch. Here's v3. Tom commit f12c9b23d3ac219e08818935930f5ee891396158 Author: Tom Tromey <tromey@adacore.com> Date: Mon Apr 17 12:59:57 2023 -0600 Rewrite gdb_mpz::operator== Simon pointed out that the recent changes to gdb_mpz caused a build failure on amd64 macOS. It turns out to be somewhat difficult to overload a method in a way that will work "naturally" for all integer types; especially in a case like gdb_mpz::operator==, where it's desirable to special case all integer types that are no wider than 'long'. After a false start, I came up with this patch, which seems to work. It applies the desirable GMP special cases directly in the body, rather than via overloads. diff --git a/gdb/gmp-utils.h b/gdb/gmp-utils.h index d05c11ecbe4..1bbdd9564fa 100644 --- a/gdb/gmp-utils.h +++ b/gdb/gmp-utils.h @@ -323,31 +323,26 @@ struct gdb_mpz return mpz_cmp_si (m_val, other) < 0; } - bool operator== (int other) const - { - return mpz_cmp_si (m_val, other) == 0; - } - - bool operator== (long other) const - { - return mpz_cmp_si (m_val, other) == 0; - } - - bool operator== (unsigned long other) const - { - return mpz_cmp_ui (m_val, other) == 0; - } - + /* We want an operator== that can handle all integer types. For + types that are 'long' or narrower, we can use a GMP function and + avoid boxing the RHS. But, because overloading based on integer + type is a pain in C++, we accept all such types here and check + the size in the body. */ template<typename T, - typename = gdb::Requires< - gdb::And<std::is_integral<T>, - std::integral_constant<bool, - (sizeof (T) > sizeof (long))>> - > - > - bool operator== (T src) - { - return *this == gdb_mpz (src); + typename = gdb::Requires<std::is_integral<T>>> + bool operator== (T other) const + { + if (std::is_signed<T>::value) + { + if (sizeof (T) <= sizeof (long)) + return mpz_cmp_si (m_val, other) == 0; + } + else + { + if (sizeof (T) <= sizeof (unsigned long)) + return mpz_cmp_ui (m_val, other) == 0; + } + return *this == gdb_mpz (other); } bool operator== (const gdb_mpz &other) const
> diff --git a/gdb/gmp-utils.h b/gdb/gmp-utils.h > index d05c11ecbe4..1bbdd9564fa 100644 > --- a/gdb/gmp-utils.h > +++ b/gdb/gmp-utils.h > @@ -323,31 +323,26 @@ struct gdb_mpz > return mpz_cmp_si (m_val, other) < 0; > } > > - bool operator== (int other) const > - { > - return mpz_cmp_si (m_val, other) == 0; > - } > - > - bool operator== (long other) const > - { > - return mpz_cmp_si (m_val, other) == 0; > - } > - > - bool operator== (unsigned long other) const > - { > - return mpz_cmp_ui (m_val, other) == 0; > - } > - > + /* We want an operator== that can handle all integer types. For > + types that are 'long' or narrower, we can use a GMP function and > + avoid boxing the RHS. But, because overloading based on integer > + type is a pain in C++, we accept all such types here and check > + the size in the body. */ > template<typename T, > - typename = gdb::Requires< > - gdb::And<std::is_integral<T>, > - std::integral_constant<bool, > - (sizeof (T) > sizeof (long))>> > - > > - > > - bool operator== (T src) > - { > - return *this == gdb_mpz (src); > + typename = gdb::Requires<std::is_integral<T>>> The template expression would fit on a single line, if you'd prefer to write it that way. Otherwise, LGTM. I think it's now relatively clear what the code tries to achieve. Approved-By: Simon Marchi <simon.marchi@efficios.com> Simon
diff --git a/gdb/gmp-utils.h b/gdb/gmp-utils.h index d05c11ecbe4..3586d01b0f9 100644 --- a/gdb/gmp-utils.h +++ b/gdb/gmp-utils.h @@ -323,31 +323,21 @@ struct gdb_mpz return mpz_cmp_si (m_val, other) < 0; } - bool operator== (int other) const - { - return mpz_cmp_si (m_val, other) == 0; - } - - bool operator== (long other) const - { - return mpz_cmp_si (m_val, other) == 0; - } - - bool operator== (unsigned long other) const - { - return mpz_cmp_ui (m_val, other) == 0; - } - template<typename T, - typename = gdb::Requires< - gdb::And<std::is_integral<T>, - std::integral_constant<bool, - (sizeof (T) > sizeof (long))>> - > - > - bool operator== (T src) - { - return *this == gdb_mpz (src); + typename = gdb::Requires<std::is_integral<T>>> + bool operator== (T other) const + { + if (std::is_signed<T>::value) + { + if (other == (T) (long) other) + return mpz_cmp_si (m_val, other) == 0; + } + else + { + if (other == (T) (unsigned long) other) + return mpz_cmp_ui (m_val, other) == 0; + } + return *this == gdb_mpz (other); } bool operator== (const gdb_mpz &other) const