* [PATCH] c++: Lambda in friend of constrained class [PR94645]
@ 2020-04-23 20:09 Patrick Palka
2020-04-23 20:09 ` [PATCH] c++: zero_init_expr_p of dependent expression Patrick Palka
2020-04-23 21:16 ` [PATCH] c++: Lambda in friend of constrained class [PR94645] Jason Merrill
0 siblings, 2 replies; 6+ messages in thread
From: Patrick Palka @ 2020-04-23 20:09 UTC (permalink / raw)
To: gcc-patches
In the testcase below, when grokfndecl processes the operator() decl for the
lambda inside the friend function foo, processing_template_decl is rightly 1,
but template_class_depth on the lambda's closure type incorrectly returns 0
instead of 1.
Since processing_template_decl > template_class_depth, this makes grokfndecl
think that the operator() has its own set of template arguments, and so we
attach the innermost set of constraints -- those belonging to struct l -- to the
operator() decl. We then get confused when checking constraints_satisfied_p on
the operator() because it doesn't have template information and yet has
constraints associated with it.
This patch fixes template_class_depth to return the correct template nesting
level in cases like these, so that when it hits a friend function it walks into
the DECL_FRIEND_CONTEXT of the friend rather than into the CP_DECL_CONTEXT.
Bootstrapped and regtested on x86_64-pc-linux-gnu, and also tested on cmcstl2,
range-v3, and fmt libraries.
gcc/cp/ChangeLog:
PR c++/94645
* pt.c (template_class_depth): Walk into the DECL_FRIEND_CONTEXT of a
friend declaration rather than into its CP_DECL_CONTEXT.
gcc/testsuite/ChangeLog:
PR c++/94645
* g++.dg/cpp2a/concepts-lambda6.C: New test.
---
gcc/cp/pt.c | 7 ++++++-
gcc/testsuite/g++.dg/cpp2a/concepts-lambda6.C | 19 +++++++++++++++++++
2 files changed, 25 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-lambda6.C
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 0e3e7b2039a..08a35c41007 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -390,7 +390,12 @@ template_class_depth (tree type)
++depth;
if (DECL_P (type))
- type = CP_DECL_CONTEXT (type);
+ {
+ if (tree fctx = DECL_FRIEND_CONTEXT (type))
+ type = fctx;
+ else
+ type = CP_DECL_CONTEXT (type);
+ }
else if (LAMBDA_TYPE_P (type) && LAMBDA_TYPE_EXTRA_SCOPE (type))
type = LAMBDA_TYPE_EXTRA_SCOPE (type);
else
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-lambda6.C b/gcc/testsuite/g++.dg/cpp2a/concepts-lambda6.C
new file mode 100644
index 00000000000..244421e64ec
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-lambda6.C
@@ -0,0 +1,19 @@
+// PR c++/94632
+// { dg-do compile { target concepts } }
+
+struct unordered_map {
+ int cend() const noexcept;
+};
+
+template <typename a> concept HasMapInterface = requires(a t) { t.cend(); };
+
+template <typename Mapper> requires HasMapInterface<decltype(Mapper::map())>
+struct l {
+ friend void foo(l opt) { ([]() {})(); }
+};
+
+struct p {
+ static unordered_map map();
+};
+
+void g(l<p> *y) { foo(*y); }
--
2.26.2.266.ge870325ee8
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH] c++: zero_init_expr_p of dependent expression
2020-04-23 20:09 [PATCH] c++: Lambda in friend of constrained class [PR94645] Patrick Palka
@ 2020-04-23 20:09 ` Patrick Palka
2020-04-23 21:16 ` Jason Merrill
2020-04-23 21:16 ` [PATCH] c++: Lambda in friend of constrained class [PR94645] Jason Merrill
1 sibling, 1 reply; 6+ messages in thread
From: Patrick Palka @ 2020-04-23 20:09 UTC (permalink / raw)
To: gcc-patches
This fixes a ICE coming from mangle.c:write_expression when compiling the
ranges-v3 testsuite; the added testcase is a reduced reproducer of the ICE.
Bootstrapped and regtested on x86_64-pc-linux-gnu, and also tested on the
cmcstl2, fmt and range-v3 libraries. Does this look OK to commit?
gcc/cp/ChangeLog:
* tree.c (zero_init_expr_p): Use uses_template_parms instead of
dependent_type_p.
gcc/testsuite/ChangeLog:
* g++.dg/cpp0x/dependent3.C: New test.
---
gcc/cp/tree.c | 2 +-
gcc/testsuite/g++.dg/cpp0x/dependent3.C | 28 +++++++++++++++++++++++++
2 files changed, 29 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/g++.dg/cpp0x/dependent3.C
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 090c565c093..8840932dba2 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -4486,7 +4486,7 @@ bool
zero_init_expr_p (tree t)
{
tree type = TREE_TYPE (t);
- if (!type || dependent_type_p (type))
+ if (!type || uses_template_parms (type))
return false;
if (zero_init_p (type))
return initializer_zerop (t);
diff --git a/gcc/testsuite/g++.dg/cpp0x/dependent3.C b/gcc/testsuite/g++.dg/cpp0x/dependent3.C
new file mode 100644
index 00000000000..caf7e1cd4a4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/dependent3.C
@@ -0,0 +1,28 @@
+// { dg-do compile { target c++11 } }
+
+template<typename c>
+struct d
+{
+ using e = c;
+};
+
+template<class f>
+struct g
+{
+ using h = typename d<f>::e;
+
+ template<class i, class j>
+ auto operator()(i, j k) -> decltype(h{k});
+};
+
+template<class l>
+void m()
+{
+ int a[1];
+ l{}(a, a);
+}
+
+int main()
+{
+ m<g<int *>>();
+}
--
2.26.2.266.ge870325ee8
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] c++: Lambda in friend of constrained class [PR94645]
2020-04-23 20:09 [PATCH] c++: Lambda in friend of constrained class [PR94645] Patrick Palka
2020-04-23 20:09 ` [PATCH] c++: zero_init_expr_p of dependent expression Patrick Palka
@ 2020-04-23 21:16 ` Jason Merrill
1 sibling, 0 replies; 6+ messages in thread
From: Jason Merrill @ 2020-04-23 21:16 UTC (permalink / raw)
To: Patrick Palka, gcc-patches
On 4/23/20 4:09 PM, Patrick Palka wrote:
> In the testcase below, when grokfndecl processes the operator() decl for the
> lambda inside the friend function foo, processing_template_decl is rightly 1,
> but template_class_depth on the lambda's closure type incorrectly returns 0
> instead of 1.
>
> Since processing_template_decl > template_class_depth, this makes grokfndecl
> think that the operator() has its own set of template arguments, and so we
> attach the innermost set of constraints -- those belonging to struct l -- to the
> operator() decl. We then get confused when checking constraints_satisfied_p on
> the operator() because it doesn't have template information and yet has
> constraints associated with it.
>
> This patch fixes template_class_depth to return the correct template nesting
> level in cases like these, so that when it hits a friend function it walks into
> the DECL_FRIEND_CONTEXT of the friend rather than into the CP_DECL_CONTEXT.
>
> Bootstrapped and regtested on x86_64-pc-linux-gnu, and also tested on cmcstl2,
> range-v3, and fmt libraries.
OK.
> gcc/cp/ChangeLog:
>
> PR c++/94645
> * pt.c (template_class_depth): Walk into the DECL_FRIEND_CONTEXT of a
> friend declaration rather than into its CP_DECL_CONTEXT.
>
> gcc/testsuite/ChangeLog:
>
> PR c++/94645
> * g++.dg/cpp2a/concepts-lambda6.C: New test.
> ---
> gcc/cp/pt.c | 7 ++++++-
> gcc/testsuite/g++.dg/cpp2a/concepts-lambda6.C | 19 +++++++++++++++++++
> 2 files changed, 25 insertions(+), 1 deletion(-)
> create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-lambda6.C
>
> diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
> index 0e3e7b2039a..08a35c41007 100644
> --- a/gcc/cp/pt.c
> +++ b/gcc/cp/pt.c
> @@ -390,7 +390,12 @@ template_class_depth (tree type)
> ++depth;
>
> if (DECL_P (type))
> - type = CP_DECL_CONTEXT (type);
> + {
> + if (tree fctx = DECL_FRIEND_CONTEXT (type))
> + type = fctx;
> + else
> + type = CP_DECL_CONTEXT (type);
> + }
> else if (LAMBDA_TYPE_P (type) && LAMBDA_TYPE_EXTRA_SCOPE (type))
> type = LAMBDA_TYPE_EXTRA_SCOPE (type);
> else
> diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-lambda6.C b/gcc/testsuite/g++.dg/cpp2a/concepts-lambda6.C
> new file mode 100644
> index 00000000000..244421e64ec
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-lambda6.C
> @@ -0,0 +1,19 @@
> +// PR c++/94632
> +// { dg-do compile { target concepts } }
> +
> +struct unordered_map {
> + int cend() const noexcept;
> +};
> +
> +template <typename a> concept HasMapInterface = requires(a t) { t.cend(); };
> +
> +template <typename Mapper> requires HasMapInterface<decltype(Mapper::map())>
> +struct l {
> + friend void foo(l opt) { ([]() {})(); }
> +};
> +
> +struct p {
> + static unordered_map map();
> +};
> +
> +void g(l<p> *y) { foo(*y); }
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] c++: zero_init_expr_p of dependent expression
2020-04-23 20:09 ` [PATCH] c++: zero_init_expr_p of dependent expression Patrick Palka
@ 2020-04-23 21:16 ` Jason Merrill
2020-06-16 13:06 ` Patrick Palka
0 siblings, 1 reply; 6+ messages in thread
From: Jason Merrill @ 2020-04-23 21:16 UTC (permalink / raw)
To: Patrick Palka, gcc-patches
On 4/23/20 4:09 PM, Patrick Palka wrote:
> This fixes a ICE coming from mangle.c:write_expression when compiling the
> ranges-v3 testsuite; the added testcase is a reduced reproducer of the ICE.
>
> Bootstrapped and regtested on x86_64-pc-linux-gnu, and also tested on the
> cmcstl2, fmt and range-v3 libraries. Does this look OK to commit?
OK.
> gcc/cp/ChangeLog:
>
> * tree.c (zero_init_expr_p): Use uses_template_parms instead of
> dependent_type_p.
>
> gcc/testsuite/ChangeLog:
>
> * g++.dg/cpp0x/dependent3.C: New test.
> ---
> gcc/cp/tree.c | 2 +-
> gcc/testsuite/g++.dg/cpp0x/dependent3.C | 28 +++++++++++++++++++++++++
> 2 files changed, 29 insertions(+), 1 deletion(-)
> create mode 100644 gcc/testsuite/g++.dg/cpp0x/dependent3.C
>
> diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
> index 090c565c093..8840932dba2 100644
> --- a/gcc/cp/tree.c
> +++ b/gcc/cp/tree.c
> @@ -4486,7 +4486,7 @@ bool
> zero_init_expr_p (tree t)
> {
> tree type = TREE_TYPE (t);
> - if (!type || dependent_type_p (type))
> + if (!type || uses_template_parms (type))
> return false;
> if (zero_init_p (type))
> return initializer_zerop (t);
> diff --git a/gcc/testsuite/g++.dg/cpp0x/dependent3.C b/gcc/testsuite/g++.dg/cpp0x/dependent3.C
> new file mode 100644
> index 00000000000..caf7e1cd4a4
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp0x/dependent3.C
> @@ -0,0 +1,28 @@
> +// { dg-do compile { target c++11 } }
> +
> +template<typename c>
> +struct d
> +{
> + using e = c;
> +};
> +
> +template<class f>
> +struct g
> +{
> + using h = typename d<f>::e;
> +
> + template<class i, class j>
> + auto operator()(i, j k) -> decltype(h{k});
> +};
> +
> +template<class l>
> +void m()
> +{
> + int a[1];
> + l{}(a, a);
> +}
> +
> +int main()
> +{
> + m<g<int *>>();
> +}
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] c++: zero_init_expr_p of dependent expression
2020-04-23 21:16 ` Jason Merrill
@ 2020-06-16 13:06 ` Patrick Palka
2020-06-16 16:06 ` Jason Merrill
0 siblings, 1 reply; 6+ messages in thread
From: Patrick Palka @ 2020-06-16 13:06 UTC (permalink / raw)
To: Jason Merrill; +Cc: GCC Patches
On Thu, Apr 23, 2020 at 5:17 PM Jason Merrill <jason@redhat.com> wrote:
>
> On 4/23/20 4:09 PM, Patrick Palka wrote:
> > This fixes a ICE coming from mangle.c:write_expression when compiling the
> > ranges-v3 testsuite; the added testcase is a reduced reproducer of the ICE.
> >
> > Bootstrapped and regtested on x86_64-pc-linux-gnu, and also tested on the
> > cmcstl2, fmt and range-v3 libraries. Does this look OK to commit?
>
> OK.
Is it OK to backport the same patch to the 9 branch in order to resolve PR95678?
>
> > gcc/cp/ChangeLog:> >
> > * tree.c (zero_init_expr_p): Use uses_template_parms instead of
> > dependent_type_p.
> >
> > gcc/testsuite/ChangeLog:
> >
> > * g++.dg/cpp0x/dependent3.C: New test.
> > ---
> > gcc/cp/tree.c | 2 +-
> > gcc/testsuite/g++.dg/cpp0x/dependent3.C | 28 +++++++++++++++++++++++++
> > 2 files changed, 29 insertions(+), 1 deletion(-)
> > create mode 100644 gcc/testsuite/g++.dg/cpp0x/dependent3.C
> >
> > diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
> > index 090c565c093..8840932dba2 100644
> > --- a/gcc/cp/tree.c
> > +++ b/gcc/cp/tree.c
> > @@ -4486,7 +4486,7 @@ bool
> > zero_init_expr_p (tree t)
> > {
> > tree type = TREE_TYPE (t);
> > - if (!type || dependent_type_p (type))
> > + if (!type || uses_template_parms (type))
> > return false;
> > if (zero_init_p (type))
> > return initializer_zerop (t);
> > diff --git a/gcc/testsuite/g++.dg/cpp0x/dependent3.C b/gcc/testsuite/g++.dg/cpp0x/dependent3.C
> > new file mode 100644
> > index 00000000000..caf7e1cd4a4
> > --- /dev/null
> > +++ b/gcc/testsuite/g++.dg/cpp0x/dependent3.C
> > @@ -0,0 +1,28 @@
> > +// { dg-do compile { target c++11 } }
> > +
> > +template<typename c>
> > +struct d
> > +{
> > + using e = c;
> > +};
> > +
> > +template<class f>
> > +struct g
> > +{
> > + using h = typename d<f>::e;
> > +
> > + template<class i, class j>
> > + auto operator()(i, j k) -> decltype(h{k});
> > +};
> > +
> > +template<class l>
> > +void m()
> > +{
> > + int a[1];
> > + l{}(a, a);
> > +}
> > +
> > +int main()
> > +{
> > + m<g<int *>>();
> > +}
> >
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] c++: zero_init_expr_p of dependent expression
2020-06-16 13:06 ` Patrick Palka
@ 2020-06-16 16:06 ` Jason Merrill
0 siblings, 0 replies; 6+ messages in thread
From: Jason Merrill @ 2020-06-16 16:06 UTC (permalink / raw)
To: Patrick Palka; +Cc: GCC Patches
On 6/16/20 9:06 AM, Patrick Palka wrote:
> On Thu, Apr 23, 2020 at 5:17 PM Jason Merrill <jason@redhat.com> wrote:
>>
>> On 4/23/20 4:09 PM, Patrick Palka wrote:
>>> This fixes a ICE coming from mangle.c:write_expression when compiling the
>>> ranges-v3 testsuite; the added testcase is a reduced reproducer of the ICE.
>>>
>>> Bootstrapped and regtested on x86_64-pc-linux-gnu, and also tested on the
>>> cmcstl2, fmt and range-v3 libraries. Does this look OK to commit?
>>
>> OK.
>
> Is it OK to backport the same patch to the 9 branch in order to resolve PR95678?
OK.
>>
>>> gcc/cp/ChangeLog:> >
>>> * tree.c (zero_init_expr_p): Use uses_template_parms instead of
>>> dependent_type_p.
>>>
>>> gcc/testsuite/ChangeLog:
>>>
>>> * g++.dg/cpp0x/dependent3.C: New test.
>>> ---
>>> gcc/cp/tree.c | 2 +-
>>> gcc/testsuite/g++.dg/cpp0x/dependent3.C | 28 +++++++++++++++++++++++++
>>> 2 files changed, 29 insertions(+), 1 deletion(-)
>>> create mode 100644 gcc/testsuite/g++.dg/cpp0x/dependent3.C
>>>
>>> diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
>>> index 090c565c093..8840932dba2 100644
>>> --- a/gcc/cp/tree.c
>>> +++ b/gcc/cp/tree.c
>>> @@ -4486,7 +4486,7 @@ bool
>>> zero_init_expr_p (tree t)
>>> {
>>> tree type = TREE_TYPE (t);
>>> - if (!type || dependent_type_p (type))
>>> + if (!type || uses_template_parms (type))
>>> return false;
>>> if (zero_init_p (type))
>>> return initializer_zerop (t);
>>> diff --git a/gcc/testsuite/g++.dg/cpp0x/dependent3.C b/gcc/testsuite/g++.dg/cpp0x/dependent3.C
>>> new file mode 100644
>>> index 00000000000..caf7e1cd4a4
>>> --- /dev/null
>>> +++ b/gcc/testsuite/g++.dg/cpp0x/dependent3.C
>>> @@ -0,0 +1,28 @@
>>> +// { dg-do compile { target c++11 } }
>>> +
>>> +template<typename c>
>>> +struct d
>>> +{
>>> + using e = c;
>>> +};
>>> +
>>> +template<class f>
>>> +struct g
>>> +{
>>> + using h = typename d<f>::e;
>>> +
>>> + template<class i, class j>
>>> + auto operator()(i, j k) -> decltype(h{k});
>>> +};
>>> +
>>> +template<class l>
>>> +void m()
>>> +{
>>> + int a[1];
>>> + l{}(a, a);
>>> +}
>>> +
>>> +int main()
>>> +{
>>> + m<g<int *>>();
>>> +}
>>>
>>
>
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2020-06-16 16:06 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-23 20:09 [PATCH] c++: Lambda in friend of constrained class [PR94645] Patrick Palka
2020-04-23 20:09 ` [PATCH] c++: zero_init_expr_p of dependent expression Patrick Palka
2020-04-23 21:16 ` Jason Merrill
2020-06-16 13:06 ` Patrick Palka
2020-06-16 16:06 ` Jason Merrill
2020-04-23 21:16 ` [PATCH] c++: Lambda in friend of constrained class [PR94645] Jason Merrill
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).