Message ID | 20211112012529.1829478-1-ppalka@redhat.com |
---|---|
State | Committed |
Commit | 09c24fe42ff2cef3f3291f5a7540a5835c08430c |
Headers |
Return-Path: <gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.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 0D5463858435 for <patchwork@sourceware.org>; Fri, 12 Nov 2021 01:26:04 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0D5463858435 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1636680364; bh=SoIqUetOPsKc7yrRZ7cI+sQmaBMrBtAkg/QtmDr//Zg=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=nCdmyybwwH7kEzWJlQvTODgxIc859y5s4tf8Eoa3dhYRV86jVBxVz25c1YGq7qlCK xFE20CBicYKtoyiypqmdpwYTslZKhUVVzB2yZGeqfyrdwMW2JGr7b32ScvqMdrZ9H1 Qg6u6/erXDhYQnheYwqN2MPttCaYzt8+w119FXYk= 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 [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 9066C3858D28 for <gcc-patches@gcc.gnu.org>; Fri, 12 Nov 2021 01:25:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 9066C3858D28 Received: from mail-qt1-f199.google.com (mail-qt1-f199.google.com [209.85.160.199]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-272-sIFt-y7_O8aHwKdrT8Xx8g-1; Thu, 11 Nov 2021 20:25:33 -0500 X-MC-Unique: sIFt-y7_O8aHwKdrT8Xx8g-1 Received: by mail-qt1-f199.google.com with SMTP id p10-20020a05622a048a00b002ac5ce8261dso6056291qtx.12 for <gcc-patches@gcc.gnu.org>; Thu, 11 Nov 2021 17:25:33 -0800 (PST) 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=SoIqUetOPsKc7yrRZ7cI+sQmaBMrBtAkg/QtmDr//Zg=; b=GnETsoCRG9IRHWzaQrcCimqY1VXBGQIWGmydxSOTWDrbDh8Z3YGs6QJ/xxHDcIIzvL CGU/muInm6bNYrs0lx5WUeV4yatZvc6xXo2WeuVhSlHDbIT9WYNq/dcpC/mMeNVQtc7J iKJvwo9baEnwI/jbnsfpMsbOXqGsLX47B5Ldd20j+6+yMbsjjPpgi/6lXQ8FpqdvaXZ9 mrgrb9jHHvEux925fThke6EoKk2sCq2kjr0K0JsIFmmTFDMgVur+oCx+hr9a1AMcFoNA 8G2cpmciDnWjU1qLFg0Wb+j2jb1VNuhYMu8/nBsffrhITpu2HZzn0toMjlZ9D1j92KLH AOvA== X-Gm-Message-State: AOAM533zHYpheW00q8CqumdLUCsW8L25MABRA7Z9O7wXFyfUMLjoSLrq EeLfI0ChCtS2VoZll/VwCDo6X0PRkE/MjT8ZaKUN9rq3Dt2VolCS6PP9GWhfDLA2Qw+4hckaJCf 7nPxKSgUdh/Bz0pzxdae62puxR0rzZ+lXKF1mWJ3tXvkupt1VRqf45L3RVEZxO/uqU+A= X-Received: by 2002:a05:622a:1196:: with SMTP id m22mr12291699qtk.290.1636680332292; Thu, 11 Nov 2021 17:25:32 -0800 (PST) X-Google-Smtp-Source: ABdhPJynnGWqWjXX2hv8hUSziAfrb8TyumhkmxWbk+7HT54A46zIUivZ2yZKFQ/uhvEaIEqJZmHj4w== X-Received: by 2002:a05:622a:1196:: with SMTP id m22mr12291669qtk.290.1636680332030; Thu, 11 Nov 2021 17:25:32 -0800 (PST) Received: from localhost.localdomain (ool-457d493a.dyn.optonline.net. [69.125.73.58]) by smtp.gmail.com with ESMTPSA id v17sm2087017qkl.123.2021.11.11.17.25.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 11 Nov 2021 17:25:31 -0800 (PST) To: gcc-patches@gcc.gnu.org Subject: [PATCH] c++: implicit dummy object in requires clause [PR103198] Date: Thu, 11 Nov 2021 20:25:29 -0500 Message-Id: <20211112012529.1829478-1-ppalka@redhat.com> X-Mailer: git-send-email 2.34.0.rc2.9.g4d53e91c6b MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="US-ASCII" X-Spam-Status: No, score=-16.0 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 <gcc-patches.gcc.gnu.org> List-Unsubscribe: <https://gcc.gnu.org/mailman/options/gcc-patches>, <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe> List-Archive: <https://gcc.gnu.org/pipermail/gcc-patches/> List-Post: <mailto:gcc-patches@gcc.gnu.org> List-Help: <mailto:gcc-patches-request@gcc.gnu.org?subject=help> List-Subscribe: <https://gcc.gnu.org/mailman/listinfo/gcc-patches>, <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe> From: Patrick Palka via Gcc-patches <gcc-patches@gcc.gnu.org> Reply-To: Patrick Palka <ppalka@redhat.com> Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" <gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org> |
Series |
c++: implicit dummy object in requires clause [PR103198]
|
|
Commit Message
Patrick Palka
Nov. 12, 2021, 1:25 a.m. UTC
In the testcase below satisfaction misbehaves for f and g ultimately because find_template_parameters fails to notice that the constraint 'val.x' depends on the template parameters of the class template. In contrast, satisfaction works just fine for h. The problem seems to come down to a difference in how any_template_parm_r handles 'this' vs a dummy object: we walk TREE_TYPE of the former but not the latter, and this causes us to miss the tparm dependencies in f/g's constraints since in their case the implicit object parameter through which we access 'val' is a dummy object. (For h, since we know it's a non-static member function when parsing its trailing constraints, the implicit object parameter is 'this' instead of a dummy object.) This patch fixes this inconsistency by making any_template_parm_r also walk into the TREE_TYPE of a dummy object, as is already done for 'this'. Bootstrapped and regtested on x86_64-pc-linux-gnu, also tested on cmcstl2 and range-v3, does this look OK for trunk and 11? PR c++/103198 gcc/cp/ChangeLog: * pt.c (any_template_parm_r): Walk the TREE_TYPE of a dummy object. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-this1.C: New test. --- gcc/cp/pt.c | 5 ++++ gcc/testsuite/g++.dg/cpp2a/concepts-this1.C | 30 +++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-this1.C
Comments
On 11/11/21 20:25, Patrick Palka wrote: > In the testcase below satisfaction misbehaves for f and g ultimately > because find_template_parameters fails to notice that the constraint > 'val.x' depends on the template parameters of the class template. > In contrast, satisfaction works just fine for h. > > The problem seems to come down to a difference in how any_template_parm_r > handles 'this' vs a dummy object: we walk TREE_TYPE of the former but > not the latter, and this causes us to miss the tparm dependencies in > f/g's constraints since in their case the implicit object parameter > through which we access 'val' is a dummy object. (For h, since we know > it's a non-static member function when parsing its trailing constraints, > the implicit object parameter is 'this' instead of a dummy object.) > > This patch fixes this inconsistency by making any_template_parm_r also > walk into the TREE_TYPE of a dummy object, as is already done for > 'this'. > > Bootstrapped and regtested on x86_64-pc-linux-gnu, also tested on > cmcstl2 and range-v3, does this look OK for trunk and 11? > > PR c++/103198 > > gcc/cp/ChangeLog: > > * pt.c (any_template_parm_r): Walk the TREE_TYPE of a dummy > object. Should we handle CONVERT_EXPR with the various casts in cp_walk_subtrees? > gcc/testsuite/ChangeLog: > > * g++.dg/cpp2a/concepts-this1.C: New test. > --- > gcc/cp/pt.c | 5 ++++ > gcc/testsuite/g++.dg/cpp2a/concepts-this1.C | 30 +++++++++++++++++++++ > 2 files changed, 35 insertions(+) > create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-this1.C > > diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c > index 82bf7dc26f6..fa55857d783 100644 > --- a/gcc/cp/pt.c > +++ b/gcc/cp/pt.c > @@ -10766,6 +10766,11 @@ any_template_parm_r (tree t, void *data) > WALK_SUBTREE (TREE_TYPE (t)); > break; > > + case CONVERT_EXPR: > + if (is_dummy_object (t)) > + WALK_SUBTREE (TREE_TYPE (t)); > + break; > + > default: > break; > } > diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-this1.C b/gcc/testsuite/g++.dg/cpp2a/concepts-this1.C > new file mode 100644 > index 00000000000..d717028201a > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-this1.C > @@ -0,0 +1,30 @@ > +// PR c++/103198 > +// { dg-do compile { target c++20 } } > + > +template<class T, class = void> > +struct A { > + T val; > + > + template<class U> > + requires requires { val.x; } > + void f(U); > + > + static void g(int) > + requires requires { val.x; }; > + > + void h(int) > + requires requires { val.x; }; > +}; > + > +struct B { int x; }; > +struct C { }; > + > +int main() { > + A<B>().f(0); > + A<B>().g(0); > + A<B>().h(0); > + > + A<C>().f(0); // { dg-error "no match" } > + A<C>().g(0); // { dg-error "no match" } > + A<C>().h(0); // { dg-error "no match" } > +} >
On Wed, 17 Nov 2021, Jason Merrill wrote: > On 11/11/21 20:25, Patrick Palka wrote: > > In the testcase below satisfaction misbehaves for f and g ultimately > > because find_template_parameters fails to notice that the constraint > > 'val.x' depends on the template parameters of the class template. > > In contrast, satisfaction works just fine for h. > > > > The problem seems to come down to a difference in how any_template_parm_r > > handles 'this' vs a dummy object: we walk TREE_TYPE of the former but > > not the latter, and this causes us to miss the tparm dependencies in > > f/g's constraints since in their case the implicit object parameter > > through which we access 'val' is a dummy object. (For h, since we know > > it's a non-static member function when parsing its trailing constraints, > > the implicit object parameter is 'this' instead of a dummy object.) > > > > This patch fixes this inconsistency by making any_template_parm_r also > > walk into the TREE_TYPE of a dummy object, as is already done for > > 'this'. > > > > Bootstrapped and regtested on x86_64-pc-linux-gnu, also tested on > > cmcstl2 and range-v3, does this look OK for trunk and 11? > > > > PR c++/103198 > > > > gcc/cp/ChangeLog: > > > > * pt.c (any_template_parm_r): Walk the TREE_TYPE of a dummy > > object. > > Should we handle CONVERT_EXPR with the various casts in cp_walk_subtrees? This seems to work well too. But I'm not sure about doing this since IIUC cp_walk_subtrees is generally supposed to walk subtrees that are explicitly written in the source code, but when a CONVERT_EXPR corresponds to an implicit conversion then the target type doesn't explicitly appear anywhere. > > > gcc/testsuite/ChangeLog: > > > > * g++.dg/cpp2a/concepts-this1.C: New test. > > --- > > gcc/cp/pt.c | 5 ++++ > > gcc/testsuite/g++.dg/cpp2a/concepts-this1.C | 30 +++++++++++++++++++++ > > 2 files changed, 35 insertions(+) > > create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-this1.C > > > > diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c > > index 82bf7dc26f6..fa55857d783 100644 > > --- a/gcc/cp/pt.c > > +++ b/gcc/cp/pt.c > > @@ -10766,6 +10766,11 @@ any_template_parm_r (tree t, void *data) > > WALK_SUBTREE (TREE_TYPE (t)); > > break; > > + case CONVERT_EXPR: > > + if (is_dummy_object (t)) > > + WALK_SUBTREE (TREE_TYPE (t)); > > + break; > > + > > default: > > break; > > } > > diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-this1.C > > b/gcc/testsuite/g++.dg/cpp2a/concepts-this1.C > > new file mode 100644 > > index 00000000000..d717028201a > > --- /dev/null > > +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-this1.C > > @@ -0,0 +1,30 @@ > > +// PR c++/103198 > > +// { dg-do compile { target c++20 } } > > + > > +template<class T, class = void> > > +struct A { > > + T val; > > + > > + template<class U> > > + requires requires { val.x; } > > + void f(U); > > + > > + static void g(int) > > + requires requires { val.x; }; > > + > > + void h(int) > > + requires requires { val.x; }; > > +}; > > + > > +struct B { int x; }; > > +struct C { }; > > + > > +int main() { > > + A<B>().f(0); > > + A<B>().g(0); > > + A<B>().h(0); > > + > > + A<C>().f(0); // { dg-error "no match" } > > + A<C>().g(0); // { dg-error "no match" } > > + A<C>().h(0); // { dg-error "no match" } > > +} > > > >
On 11/17/21 14:52, Patrick Palka wrote: > On Wed, 17 Nov 2021, Jason Merrill wrote: > >> On 11/11/21 20:25, Patrick Palka wrote: >>> In the testcase below satisfaction misbehaves for f and g ultimately >>> because find_template_parameters fails to notice that the constraint >>> 'val.x' depends on the template parameters of the class template. >>> In contrast, satisfaction works just fine for h. >>> >>> The problem seems to come down to a difference in how any_template_parm_r >>> handles 'this' vs a dummy object: we walk TREE_TYPE of the former but >>> not the latter, and this causes us to miss the tparm dependencies in >>> f/g's constraints since in their case the implicit object parameter >>> through which we access 'val' is a dummy object. (For h, since we know >>> it's a non-static member function when parsing its trailing constraints, >>> the implicit object parameter is 'this' instead of a dummy object.) >>> >>> This patch fixes this inconsistency by making any_template_parm_r also >>> walk into the TREE_TYPE of a dummy object, as is already done for >>> 'this'. >>> >>> Bootstrapped and regtested on x86_64-pc-linux-gnu, also tested on >>> cmcstl2 and range-v3, does this look OK for trunk and 11? >>> >>> PR c++/103198 >>> >>> gcc/cp/ChangeLog: >>> >>> * pt.c (any_template_parm_r): Walk the TREE_TYPE of a dummy >>> object. >> >> Should we handle CONVERT_EXPR with the various casts in cp_walk_subtrees? > > This seems to work well too. But I'm not sure about doing this since > IIUC cp_walk_subtrees is generally supposed to walk subtrees that are > explicitly written in the source code, but when a CONVERT_EXPR > corresponds to an implicit conversion then the target type doesn't > explicitly appear anywhere. We could check is_dummy_object there as well? >> >>> gcc/testsuite/ChangeLog: >>> >>> * g++.dg/cpp2a/concepts-this1.C: New test. >>> --- >>> gcc/cp/pt.c | 5 ++++ >>> gcc/testsuite/g++.dg/cpp2a/concepts-this1.C | 30 +++++++++++++++++++++ >>> 2 files changed, 35 insertions(+) >>> create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-this1.C >>> >>> diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c >>> index 82bf7dc26f6..fa55857d783 100644 >>> --- a/gcc/cp/pt.c >>> +++ b/gcc/cp/pt.c >>> @@ -10766,6 +10766,11 @@ any_template_parm_r (tree t, void *data) >>> WALK_SUBTREE (TREE_TYPE (t)); >>> break; >>> + case CONVERT_EXPR: >>> + if (is_dummy_object (t)) >>> + WALK_SUBTREE (TREE_TYPE (t)); >>> + break; >>> + >>> default: >>> break; >>> } >>> diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-this1.C >>> b/gcc/testsuite/g++.dg/cpp2a/concepts-this1.C >>> new file mode 100644 >>> index 00000000000..d717028201a >>> --- /dev/null >>> +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-this1.C >>> @@ -0,0 +1,30 @@ >>> +// PR c++/103198 >>> +// { dg-do compile { target c++20 } } >>> + >>> +template<class T, class = void> >>> +struct A { >>> + T val; >>> + >>> + template<class U> >>> + requires requires { val.x; } >>> + void f(U); >>> + >>> + static void g(int) >>> + requires requires { val.x; }; >>> + >>> + void h(int) >>> + requires requires { val.x; }; >>> +}; >>> + >>> +struct B { int x; }; >>> +struct C { }; >>> + >>> +int main() { >>> + A<B>().f(0); >>> + A<B>().g(0); >>> + A<B>().h(0); >>> + >>> + A<C>().f(0); // { dg-error "no match" } >>> + A<C>().g(0); // { dg-error "no match" } >>> + A<C>().h(0); // { dg-error "no match" } >>> +} >>> >> >> >
On Thu, 18 Nov 2021, Jason Merrill wrote: > On 11/17/21 14:52, Patrick Palka wrote: > > On Wed, 17 Nov 2021, Jason Merrill wrote: > > > > > On 11/11/21 20:25, Patrick Palka wrote: > > > > In the testcase below satisfaction misbehaves for f and g ultimately > > > > because find_template_parameters fails to notice that the constraint > > > > 'val.x' depends on the template parameters of the class template. > > > > In contrast, satisfaction works just fine for h. > > > > > > > > The problem seems to come down to a difference in how > > > > any_template_parm_r > > > > handles 'this' vs a dummy object: we walk TREE_TYPE of the former but > > > > not the latter, and this causes us to miss the tparm dependencies in > > > > f/g's constraints since in their case the implicit object parameter > > > > through which we access 'val' is a dummy object. (For h, since we know > > > > it's a non-static member function when parsing its trailing constraints, > > > > the implicit object parameter is 'this' instead of a dummy object.) > > > > > > > > This patch fixes this inconsistency by making any_template_parm_r also > > > > walk into the TREE_TYPE of a dummy object, as is already done for > > > > 'this'. > > > > > > > > Bootstrapped and regtested on x86_64-pc-linux-gnu, also tested on > > > > cmcstl2 and range-v3, does this look OK for trunk and 11? > > > > > > > > PR c++/103198 > > > > > > > > gcc/cp/ChangeLog: > > > > > > > > * pt.c (any_template_parm_r): Walk the TREE_TYPE of a dummy > > > > object. > > > > > > Should we handle CONVERT_EXPR with the various casts in cp_walk_subtrees? > > > > This seems to work well too. But I'm not sure about doing this since > > IIUC cp_walk_subtrees is generally supposed to walk subtrees that are > > explicitly written in the source code, but when a CONVERT_EXPR > > corresponds to an implicit conversion then the target type doesn't > > explicitly appear anywhere. > > We could check is_dummy_object there as well? Ah I see, sorry for the misunderstanding. So wouldn't that mean cp_walk_subtrees will wal the TREE_TYPE of a dummy object but not the TREE_TYPE of 'this'? That seems like a weird inconsistency at first glance. > > > > > > > > gcc/testsuite/ChangeLog: > > > > > > > > * g++.dg/cpp2a/concepts-this1.C: New test. > > > > --- > > > > gcc/cp/pt.c | 5 ++++ > > > > gcc/testsuite/g++.dg/cpp2a/concepts-this1.C | 30 > > > > +++++++++++++++++++++ > > > > 2 files changed, 35 insertions(+) > > > > create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-this1.C > > > > > > > > diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c > > > > index 82bf7dc26f6..fa55857d783 100644 > > > > --- a/gcc/cp/pt.c > > > > +++ b/gcc/cp/pt.c > > > > @@ -10766,6 +10766,11 @@ any_template_parm_r (tree t, void *data) > > > > WALK_SUBTREE (TREE_TYPE (t)); > > > > break; > > > > + case CONVERT_EXPR: > > > > + if (is_dummy_object (t)) > > > > + WALK_SUBTREE (TREE_TYPE (t)); > > > > + break; > > > > + > > > > default: > > > > break; > > > > } > > > > diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-this1.C > > > > b/gcc/testsuite/g++.dg/cpp2a/concepts-this1.C > > > > new file mode 100644 > > > > index 00000000000..d717028201a > > > > --- /dev/null > > > > +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-this1.C > > > > @@ -0,0 +1,30 @@ > > > > +// PR c++/103198 > > > > +// { dg-do compile { target c++20 } } > > > > + > > > > +template<class T, class = void> > > > > +struct A { > > > > + T val; > > > > + > > > > + template<class U> > > > > + requires requires { val.x; } > > > > + void f(U); > > > > + > > > > + static void g(int) > > > > + requires requires { val.x; }; > > > > + > > > > + void h(int) > > > > + requires requires { val.x; }; > > > > +}; > > > > + > > > > +struct B { int x; }; > > > > +struct C { }; > > > > + > > > > +int main() { > > > > + A<B>().f(0); > > > > + A<B>().g(0); > > > > + A<B>().h(0); > > > > + > > > > + A<C>().f(0); // { dg-error "no match" } > > > > + A<C>().g(0); // { dg-error "no match" } > > > > + A<C>().h(0); // { dg-error "no match" } > > > > +} > > > > > > > > > > > > > >
On 11/18/21 14:49, Patrick Palka wrote: > On Thu, 18 Nov 2021, Jason Merrill wrote: > >> On 11/17/21 14:52, Patrick Palka wrote: >>> On Wed, 17 Nov 2021, Jason Merrill wrote: >>> >>>> On 11/11/21 20:25, Patrick Palka wrote: >>>>> In the testcase below satisfaction misbehaves for f and g ultimately >>>>> because find_template_parameters fails to notice that the constraint >>>>> 'val.x' depends on the template parameters of the class template. >>>>> In contrast, satisfaction works just fine for h. >>>>> >>>>> The problem seems to come down to a difference in how >>>>> any_template_parm_r >>>>> handles 'this' vs a dummy object: we walk TREE_TYPE of the former but >>>>> not the latter, and this causes us to miss the tparm dependencies in >>>>> f/g's constraints since in their case the implicit object parameter >>>>> through which we access 'val' is a dummy object. (For h, since we know >>>>> it's a non-static member function when parsing its trailing constraints, >>>>> the implicit object parameter is 'this' instead of a dummy object.) >>>>> >>>>> This patch fixes this inconsistency by making any_template_parm_r also >>>>> walk into the TREE_TYPE of a dummy object, as is already done for >>>>> 'this'. >>>>> >>>>> Bootstrapped and regtested on x86_64-pc-linux-gnu, also tested on >>>>> cmcstl2 and range-v3, does this look OK for trunk and 11? >>>>> >>>>> PR c++/103198 >>>>> >>>>> gcc/cp/ChangeLog: >>>>> >>>>> * pt.c (any_template_parm_r): Walk the TREE_TYPE of a dummy >>>>> object. >>>> >>>> Should we handle CONVERT_EXPR with the various casts in cp_walk_subtrees? >>> >>> This seems to work well too. But I'm not sure about doing this since >>> IIUC cp_walk_subtrees is generally supposed to walk subtrees that are >>> explicitly written in the source code, but when a CONVERT_EXPR >>> corresponds to an implicit conversion then the target type doesn't >>> explicitly appear anywhere. >> >> We could check is_dummy_object there as well? > > Ah I see, sorry for the misunderstanding. So wouldn't that mean > cp_walk_subtrees will wal the TREE_TYPE of a dummy object but not the > TREE_TYPE of 'this'? That seems like a weird inconsistency at first > glance. Good point. Go ahead with your original patch, thanks. >>>> >>>>> gcc/testsuite/ChangeLog: >>>>> >>>>> * g++.dg/cpp2a/concepts-this1.C: New test. >>>>> --- >>>>> gcc/cp/pt.c | 5 ++++ >>>>> gcc/testsuite/g++.dg/cpp2a/concepts-this1.C | 30 >>>>> +++++++++++++++++++++ >>>>> 2 files changed, 35 insertions(+) >>>>> create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-this1.C >>>>> >>>>> diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c >>>>> index 82bf7dc26f6..fa55857d783 100644 >>>>> --- a/gcc/cp/pt.c >>>>> +++ b/gcc/cp/pt.c >>>>> @@ -10766,6 +10766,11 @@ any_template_parm_r (tree t, void *data) >>>>> WALK_SUBTREE (TREE_TYPE (t)); >>>>> break; >>>>> + case CONVERT_EXPR: >>>>> + if (is_dummy_object (t)) >>>>> + WALK_SUBTREE (TREE_TYPE (t)); >>>>> + break; >>>>> + >>>>> default: >>>>> break; >>>>> } >>>>> diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-this1.C >>>>> b/gcc/testsuite/g++.dg/cpp2a/concepts-this1.C >>>>> new file mode 100644 >>>>> index 00000000000..d717028201a >>>>> --- /dev/null >>>>> +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-this1.C >>>>> @@ -0,0 +1,30 @@ >>>>> +// PR c++/103198 >>>>> +// { dg-do compile { target c++20 } } >>>>> + >>>>> +template<class T, class = void> >>>>> +struct A { >>>>> + T val; >>>>> + >>>>> + template<class U> >>>>> + requires requires { val.x; } >>>>> + void f(U); >>>>> + >>>>> + static void g(int) >>>>> + requires requires { val.x; }; >>>>> + >>>>> + void h(int) >>>>> + requires requires { val.x; }; >>>>> +}; >>>>> + >>>>> +struct B { int x; }; >>>>> +struct C { }; >>>>> + >>>>> +int main() { >>>>> + A<B>().f(0); >>>>> + A<B>().g(0); >>>>> + A<B>().h(0); >>>>> + >>>>> + A<C>().f(0); // { dg-error "no match" } >>>>> + A<C>().g(0); // { dg-error "no match" } >>>>> + A<C>().h(0); // { dg-error "no match" } >>>>> +} >>>>> >>>> >>>> >>> >> >> >
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 82bf7dc26f6..fa55857d783 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -10766,6 +10766,11 @@ any_template_parm_r (tree t, void *data) WALK_SUBTREE (TREE_TYPE (t)); break; + case CONVERT_EXPR: + if (is_dummy_object (t)) + WALK_SUBTREE (TREE_TYPE (t)); + break; + default: break; } diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-this1.C b/gcc/testsuite/g++.dg/cpp2a/concepts-this1.C new file mode 100644 index 00000000000..d717028201a --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-this1.C @@ -0,0 +1,30 @@ +// PR c++/103198 +// { dg-do compile { target c++20 } } + +template<class T, class = void> +struct A { + T val; + + template<class U> + requires requires { val.x; } + void f(U); + + static void g(int) + requires requires { val.x; }; + + void h(int) + requires requires { val.x; }; +}; + +struct B { int x; }; +struct C { }; + +int main() { + A<B>().f(0); + A<B>().g(0); + A<B>().h(0); + + A<C>().f(0); // { dg-error "no match" } + A<C>().g(0); // { dg-error "no match" } + A<C>().h(0); // { dg-error "no match" } +}