From patchwork Wed Mar 6 03:46:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathaniel Shead X-Patchwork-Id: 86848 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 2C28138582A2 for ; Wed, 6 Mar 2024 03:47:18 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-pf1-x42c.google.com (mail-pf1-x42c.google.com [IPv6:2607:f8b0:4864:20::42c]) by sourceware.org (Postfix) with ESMTPS id A4ADC385843A for ; Wed, 6 Mar 2024 03:46:52 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A4ADC385843A Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org A4ADC385843A Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::42c ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1709696814; cv=none; b=qvvmoJh8oVlkSsmVuWmhFIm8/mVIvlCmkrXGAiAh9L9nJuQs0vKpAqtWsm9QF+6+OtHEm739kyKAIBmvfzwG9X5xgyHAYiLe90U15kL6BsMbd3M/h6oICx4htwT/riS3oiHBuOmR3G7/VRArPPpnjiCHRMVuTzSJwvf6tZIKm5U= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1709696814; c=relaxed/simple; bh=5D0RuDMIq2Zynq7JkB/JTprJVd3DEWX8TAiT500t3uE=; h=DKIM-Signature:Message-ID:Date:From:To:Subject:MIME-Version; b=iexS8N4gPPF1ofd1Fzv71lwy9/B22yJd4rviMM65QmSw0FMIZtsIEns5soh9JeUYiNGXxiiEzxkfdIAv2MIWC4pWxZY42d5yzxcT0LmfnrHt6s+MTNuVYSQydu3QToM+hA7DlsMW/Sw274Pt7gbUw2fGeRaPJAwpSKtPL/854zY= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pf1-x42c.google.com with SMTP id d2e1a72fcca58-6e627596554so2172283b3a.2 for ; Tue, 05 Mar 2024 19:46:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1709696811; x=1710301611; darn=gcc.gnu.org; h=in-reply-to:content-disposition:mime-version:references:subject:cc :to:from:date:message-id:from:to:cc:subject:date:message-id:reply-to; bh=Oy9uiKXfoTo+7LXsg7xaVkdjDUVtlLCY8otSOqxpeiM=; b=bvgITeLlAvEEQq1yxye+bXdVCzG5QxpWnSLC5SvGiACCaEmaUdYLGr35pej6FZLNBk Vr6XydWMtaCpM+auqSO0qjpayt4109FgNVviRvA4XFKi2McGZVLsy4cIBvkCgpLAypuQ 32uDA2ZvuiEkLXn7o+CHsV3vNhLLCV0IBdzgLnrYecnaM0nSrBOT7OqMzzhWUSD8+vC5 lOREFqYgAizYBhJrIqVxkjnm2dO369tOEPyr6Ifspb2/GnQksyWoCGyl6Qq10PXG6xXd 1xOPeCTezxLiZsd2kRewI7pmb0Ibfd/BJ9fgrVXQKk3H8g0hxgfyuWty8wyGaVG47TB4 SHJg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709696811; x=1710301611; h=in-reply-to:content-disposition:mime-version:references:subject:cc :to:from:date:message-id:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=Oy9uiKXfoTo+7LXsg7xaVkdjDUVtlLCY8otSOqxpeiM=; b=FWZF2Ix8f1C+Jw3A65eUMLC3+w+DfW+cjKLtSx/kKUDGtmBCc5c9omk75RElc7eOdr eULFkjCf4/Z1NG5okYkLHGaPXdkcBsJJPAuk4SSv5+IXv94tVfDXunqpd7AIQjsZJSRB XZuV4q81lAuytGf6rEcpwXCOVn+7ClVVDoZVydoxelVP7TqSpmVacFtgFonGhq52mwq0 YjmeK53gPln1NJd8F2lZM5702EARfs0zMof6jwl26ylf6kjLyAinFsW4PyTX4IiG6SKS t+lPqiIhyi9gJmmTP2fD1bIaHAdxvrvZ7liwA3ftyDDWk+Yw/wrpzNXDZIuFrxtjvgZZ rDsQ== X-Gm-Message-State: AOJu0Yy3r312Rv2NXKYz7GdbL4oe7Xq3VaJ5IShbxTPkKSfiDmPtcJC0 Yn1uW8QmT419WQUyeXW6x73LRgzwmV2D2+jGPcEdcLNuk+HVrIS4 X-Google-Smtp-Source: AGHT+IFIo0H61/BLACK5P/B8scDdkaNDmOihQCIETuTQgONwQJNbjl1seJyFbQPUPQLfOC/bAMsBPQ== X-Received: by 2002:a05:6a00:ac5:b0:6e6:4705:a07f with SMTP id c5-20020a056a000ac500b006e64705a07fmr2371035pfl.31.1709696810857; Tue, 05 Mar 2024 19:46:50 -0800 (PST) Received: from Thaum. (124-168-30-222.tpgi.com.au. [124.168.30.222]) by smtp.gmail.com with ESMTPSA id x53-20020a056a000bf500b006e3b868b8b8sm9729155pfu.130.2024.03.05.19.46.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Mar 2024 19:46:50 -0800 (PST) Message-ID: <65e7e72a.050a0220.d77d9.6e86@mx.google.com> X-Google-Original-Message-ID: Date: Wed, 6 Mar 2024 14:46:46 +1100 From: Nathaniel Shead To: Jason Merrill Cc: gcc-patches@gcc.gnu.org Subject: [PATCH v2] c++: Fix template deduction for conversion operators with xobj parameters [PR113629] References: <65e7a11e.050a0220.6580e.c8c8@mx.google.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: X-Spam-Status: No, score=-12.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, 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: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org On Tue, Mar 05, 2024 at 06:19:07PM -0500, Jason Merrill wrote: > On 3/5/24 17:47, Nathaniel Shead wrote: > > Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk? > > > > -- >8 -- > > > > Unification for conversion operators (DEDUCE_CONV) doesn't perform > > transformations like handling forwarding references. This is correct in > > general, but not for xobj parameters, which should be handled "normally" > > for the purposes of deduction: [temp.deduct.conv] only applies to the > > return type of the conversion function. > > > > PR c++/113629 > > > > gcc/cp/ChangeLog: > > > > * pt.cc (type_unification_real): Use DEDUCE_CALL for xobj > > parameters of conversion functions. > > > > gcc/testsuite/ChangeLog: > > > > * g++.dg/cpp23/explicit-obj-conv-op.C: New test. > > > > Signed-off-by: Nathaniel Shead > > --- > > gcc/cp/pt.cc | 15 +++++- > > .../g++.dg/cpp23/explicit-obj-conv-op.C | 49 +++++++++++++++++++ > > 2 files changed, 63 insertions(+), 1 deletion(-) > > create mode 100644 gcc/testsuite/g++.dg/cpp23/explicit-obj-conv-op.C > > > > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc > > index c4bc54a8fdb..632437d3424 100644 > > --- a/gcc/cp/pt.cc > > +++ b/gcc/cp/pt.cc > > @@ -23281,6 +23281,10 @@ type_unification_real (tree tparms, > > in TARGS. */ > > NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs) = NULL_TREE; > > + bool is_xobj_conv_fn > > + = (strict == DEDUCE_CONV > > + && DECL_XOBJ_MEMBER_FUNCTION_P (TREE_TYPE (tparms))); > > + > > again: > > parms = xparms; > > args = xargs; > > @@ -23312,10 +23316,17 @@ type_unification_real (tree tparms, > > parameter pack is a non-deduced context. */ > > continue; > > + /* For explicit object parameters, unification should behave like > > + normal function calls, even for conversion functions. This > > + corresponds to the second (that is, last) argument. */ > > + unification_kind_t kind = strict; > > + if (is_xobj_conv_fn && ia > 0) > > Is it necessary to check the xobj flag? Or can this just be > > if (strict == DEDUCE_CONV && ia > 0) > > ? > > Jason > I restricted it to xobj to be conservative, but I think you're right that it's not necessary: there's nothing special about xobj here apart from this being a new circumstance where we might actually need to unify the object parameter. Here's a new version of the patch. Bootstrapped and regtested (so far only dg.exp) on x86_64-pc-linux-gnu, OK for trunk if full regtest completes successfully? -- >8 -- Unification for conversion operators (DEDUCE_CONV) doesn't perform transformations like handling forwarding references. This is correct in general, but not for xobj parameters, which should be handled "normally" for the purposes of deduction: [temp.deduct.conv] only applies to the return type of the conversion function. PR c++/113629 gcc/cp/ChangeLog: * pt.cc (type_unification_real): Only use DEDUCE_CONV for the return type of a conversion function. gcc/testsuite/ChangeLog: * g++.dg/cpp23/explicit-obj-conv-op.C: New test. Signed-off-by: Nathaniel Shead --- gcc/cp/pt.cc | 12 ++++- .../g++.dg/cpp23/explicit-obj-conv-op.C | 49 +++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp23/explicit-obj-conv-op.C diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index c4bc54a8fdb..a6e6c804130 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -23312,10 +23312,18 @@ type_unification_real (tree tparms, parameter pack is a non-deduced context. */ continue; + /* [temp.deduct.conv] only applies to the deduction of the return + type, which is always the first argument here. Other arguments + (notably, explicit object parameters) should undergo normal + call-like unification. */ + unification_kind_t kind = strict; + if (strict == DEDUCE_CONV && ia > 0) + kind = DEDUCE_CALL; + arg = args[ia]; ++ia; - if (unify_one_argument (tparms, full_targs, parm, arg, subr, strict, + if (unify_one_argument (tparms, full_targs, parm, arg, subr, kind, explain_p)) return 1; } @@ -23324,6 +23332,8 @@ type_unification_real (tree tparms, && parms != void_list_node && TREE_CODE (TREE_VALUE (parms)) == TYPE_PACK_EXPANSION) { + gcc_assert (strict != DEDUCE_CONV); + /* Unify the remaining arguments with the pack expansion type. */ tree argvec; tree parmvec = make_tree_vec (1); diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-conv-op.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-conv-op.C new file mode 100644 index 00000000000..a6ae4ea1dda --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-conv-op.C @@ -0,0 +1,49 @@ +// PR c++/113629 +// { dg-do compile { target c++23 } } + +template constexpr bool is_lvalue = false; +template constexpr bool is_lvalue = true; + +struct A { + constexpr operator bool(this auto&& self) { + return is_lvalue; + } +}; + +constexpr A a; +static_assert(static_cast(a)); +static_assert((bool)a); +static_assert(!static_cast(A{})); +static_assert(!(bool)A{}); + +struct B : A {}; + +constexpr B b; +static_assert(static_cast(b)); +static_assert((bool)b); +static_assert(!static_cast(B{})); +static_assert(!(bool)B{}); + +struct C { + template + explicit constexpr operator R(this T&&) { + return is_lvalue; + } +}; + +constexpr C c; +static_assert(static_cast(c)); +static_assert((bool)c); +static_assert(!static_cast(C{})); +static_assert(!(bool)C{}); + +struct D { + explicit constexpr operator bool(this const D&) { return true; } + explicit constexpr operator bool(this const D&&) { return false; } +}; + +constexpr D d; +static_assert(static_cast(d)); +static_assert((bool)d); +static_assert(!static_cast(D{})); +static_assert(!(bool)D{});