public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] c++: Fix ICE with CTAD in concept [PR98611]
@ 2021-01-09 22:23 Patrick Palka
  2021-01-11 20:09 ` Jason Merrill
  0 siblings, 1 reply; 4+ messages in thread
From: Patrick Palka @ 2021-01-09 22:23 UTC (permalink / raw)
  To: gcc-patches

This patch teaches find_template_parameters to visit the template
represented by a CTAD placeholder, which is normally not visited by
for_each_template_parm.  This template may be a template template
parameter (as in the first testcase), or it may implicitly use the
template parameters of an enclosing class template (as in the second
testcase), and in either case we need to record the template parameters
used therein for later satisfaction.

Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk and perhaps the 10 branch?  Also tested on range-v3 and cmcstl2.

gcc/cp/ChangeLog:

	PR c++/98611
	* pt.c (any_template_parm_r) <case TEMPLATE_TYPE_PARM>: Visit
	the template of a CTAD placeholder.

gcc/testsuite/ChangeLog:

	PR c++/98611
	* g++.dg/cpp2a/concepts-ctad1.C: New test.
	* g++.dg/cpp2a/concepts-ctad2.C: New test.
---
 gcc/cp/pt.c                                 |  4 ++++
 gcc/testsuite/g++.dg/cpp2a/concepts-ctad1.C | 16 ++++++++++++++++
 gcc/testsuite/g++.dg/cpp2a/concepts-ctad2.C | 14 ++++++++++++++
 3 files changed, 34 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-ctad1.C
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-ctad2.C

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 51540ca35a5..d3bb6231926 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -10694,6 +10694,10 @@ any_template_parm_r (tree t, void *data)
       if (is_auto (t))
 	if (tree constr = PLACEHOLDER_TYPE_CONSTRAINTS (t))
 	  WALK_SUBTREE (constr);
+      /* A use of a CTAD placeholder is also a use of the template it
+	 represents.  */
+      if (template_placeholder_p (t))
+	  WALK_SUBTREE (CLASS_PLACEHOLDER_TEMPLATE (t));
       break;
 
     case TEMPLATE_ID_EXPR:
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-ctad1.C b/gcc/testsuite/g++.dg/cpp2a/concepts-ctad1.C
new file mode 100644
index 00000000000..ec2e4b014d7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-ctad1.C
@@ -0,0 +1,16 @@
+// PR c++/98611
+// { dg-do compile { target c++20 } }
+
+template <class T, class U>
+concept IsSame = __is_same(T, U);
+
+template <class T, template <class...> class _Class>
+concept IsInstantiationOf = requires(T object) {
+ { _Class{object} } -> IsSame<T>;
+};
+
+template <class T> struct Degrees {};
+static_assert(IsInstantiationOf<Degrees<int>, Degrees>);
+
+template <class T> struct NotDegrees {};
+static_assert(!IsInstantiationOf<Degrees<int>, NotDegrees>);
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-ctad2.C b/gcc/testsuite/g++.dg/cpp2a/concepts-ctad2.C
new file mode 100644
index 00000000000..de960487713
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-ctad2.C
@@ -0,0 +1,14 @@
+// PR c++/98611
+// { dg-do compile { target c++20 } }
+
+template <class>
+struct S
+{
+  template <class T> struct Tmpl { Tmpl(T); };
+
+  template <class T>
+    requires requires (T object) { Tmpl{object}; }
+  static int f(T);
+};
+
+int a = S<int>::f(0);
-- 
2.30.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] c++: Fix ICE with CTAD in concept [PR98611]
  2021-01-09 22:23 [PATCH] c++: Fix ICE with CTAD in concept [PR98611] Patrick Palka
@ 2021-01-11 20:09 ` Jason Merrill
  2021-01-12  1:08   ` Patrick Palka
  0 siblings, 1 reply; 4+ messages in thread
From: Jason Merrill @ 2021-01-11 20:09 UTC (permalink / raw)
  To: Patrick Palka, gcc-patches

On 1/9/21 5:23 PM, Patrick Palka wrote:
> This patch teaches find_template_parameters to visit the template
> represented by a CTAD placeholder, which is normally not visited by
> for_each_template_parm.  This template may be a template template
> parameter (as in the first testcase), or it may implicitly use the
> template parameters of an enclosing class template (as in the second
> testcase), and in either case we need to record the template parameters
> used therein for later satisfaction.
> 
> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
> trunk and perhaps the 10 branch?  Also tested on range-v3 and cmcstl2.
> 
> gcc/cp/ChangeLog:
> 
> 	PR c++/98611
> 	* pt.c (any_template_parm_r) <case TEMPLATE_TYPE_PARM>: Visit
> 	the template of a CTAD placeholder.

Did you consider doing this in cp_walk_subtrees instead of here?

> gcc/testsuite/ChangeLog:
> 
> 	PR c++/98611
> 	* g++.dg/cpp2a/concepts-ctad1.C: New test.
> 	* g++.dg/cpp2a/concepts-ctad2.C: New test.
> ---
>   gcc/cp/pt.c                                 |  4 ++++
>   gcc/testsuite/g++.dg/cpp2a/concepts-ctad1.C | 16 ++++++++++++++++
>   gcc/testsuite/g++.dg/cpp2a/concepts-ctad2.C | 14 ++++++++++++++
>   3 files changed, 34 insertions(+)
>   create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-ctad1.C
>   create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-ctad2.C
> 
> diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
> index 51540ca35a5..d3bb6231926 100644
> --- a/gcc/cp/pt.c
> +++ b/gcc/cp/pt.c
> @@ -10694,6 +10694,10 @@ any_template_parm_r (tree t, void *data)
>         if (is_auto (t))
>   	if (tree constr = PLACEHOLDER_TYPE_CONSTRAINTS (t))
>   	  WALK_SUBTREE (constr);
> +      /* A use of a CTAD placeholder is also a use of the template it
> +	 represents.  */
> +      if (template_placeholder_p (t))
> +	  WALK_SUBTREE (CLASS_PLACEHOLDER_TEMPLATE (t));
>         break;
>   
>       case TEMPLATE_ID_EXPR:
> diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-ctad1.C b/gcc/testsuite/g++.dg/cpp2a/concepts-ctad1.C
> new file mode 100644
> index 00000000000..ec2e4b014d7
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-ctad1.C
> @@ -0,0 +1,16 @@
> +// PR c++/98611
> +// { dg-do compile { target c++20 } }
> +
> +template <class T, class U>
> +concept IsSame = __is_same(T, U);
> +
> +template <class T, template <class...> class _Class>
> +concept IsInstantiationOf = requires(T object) {
> + { _Class{object} } -> IsSame<T>;
> +};
> +
> +template <class T> struct Degrees {};
> +static_assert(IsInstantiationOf<Degrees<int>, Degrees>);
> +
> +template <class T> struct NotDegrees {};
> +static_assert(!IsInstantiationOf<Degrees<int>, NotDegrees>);
> diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-ctad2.C b/gcc/testsuite/g++.dg/cpp2a/concepts-ctad2.C
> new file mode 100644
> index 00000000000..de960487713
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-ctad2.C
> @@ -0,0 +1,14 @@
> +// PR c++/98611
> +// { dg-do compile { target c++20 } }
> +
> +template <class>
> +struct S
> +{
> +  template <class T> struct Tmpl { Tmpl(T); };
> +
> +  template <class T>
> +    requires requires (T object) { Tmpl{object}; }
> +  static int f(T);
> +};
> +
> +int a = S<int>::f(0);
> 


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] c++: Fix ICE with CTAD in concept [PR98611]
  2021-01-11 20:09 ` Jason Merrill
@ 2021-01-12  1:08   ` Patrick Palka
  2021-01-12  1:47     ` Jason Merrill
  0 siblings, 1 reply; 4+ messages in thread
From: Patrick Palka @ 2021-01-12  1:08 UTC (permalink / raw)
  To: Jason Merrill; +Cc: Patrick Palka, gcc-patches

On Mon, 11 Jan 2021, Jason Merrill wrote:

> On 1/9/21 5:23 PM, Patrick Palka wrote:
> > This patch teaches find_template_parameters to visit the template
> > represented by a CTAD placeholder, which is normally not visited by
> > for_each_template_parm.  This template may be a template template
> > parameter (as in the first testcase), or it may implicitly use the
> > template parameters of an enclosing class template (as in the second
> > testcase), and in either case we need to record the template parameters
> > used therein for later satisfaction.
> > 
> > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
> > trunk and perhaps the 10 branch?  Also tested on range-v3 and cmcstl2.
> > 
> > gcc/cp/ChangeLog:
> > 
> > 	PR c++/98611
> > 	* pt.c (any_template_parm_r) <case TEMPLATE_TYPE_PARM>: Visit
> > 	the template of a CTAD placeholder.
> 
> Did you consider doing this in cp_walk_subtrees instead of here?

Briefly, but I couldn't convince myself which of the three visitors
(cp_walk_subtrees, for_each_template_parm_r or any_template_parm_r) is
the most appropriate place to do it in, so I defaulted to the most
specific routine of the three.

The following passes bootstrap and regtesting on x86_64-pc-linux-gnu.
Shall we go with this?

-- >8 --

gcc/cp/ChangeLog:

	PR c++/98611
	* tree.c (cp_walk_subtrees) <case TEMPLATE_TYPE_PARM>: Visit
	the template of a CTAD placeholder.

gcc/testsuite/ChangeLog:

	PR c++/98611
	* g++.dg/cpp2a/concepts-ctad1.C: New test.
	* g++.dg/cpp2a/concepts-ctad2.C: New test.
---
 gcc/cp/tree.c                               |  5 ++++-
 gcc/testsuite/g++.dg/cpp2a/concepts-ctad1.C | 16 ++++++++++++++++
 gcc/testsuite/g++.dg/cpp2a/concepts-ctad2.C | 13 +++++++++++++
 3 files changed, 33 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-ctad1.C
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-ctad2.C

diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index c536eb581a7..d339036e88e 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -5173,12 +5173,15 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
   result = NULL_TREE;
   switch (code)
     {
+    case TEMPLATE_TYPE_PARM:
+      if (template_placeholder_p (*tp))
+	WALK_SUBTREE (CLASS_PLACEHOLDER_TEMPLATE (*tp));
+      /* Fall through.  */
     case DEFERRED_PARSE:
     case TEMPLATE_TEMPLATE_PARM:
     case BOUND_TEMPLATE_TEMPLATE_PARM:
     case UNBOUND_CLASS_TEMPLATE:
     case TEMPLATE_PARM_INDEX:
-    case TEMPLATE_TYPE_PARM:
     case TYPEOF_TYPE:
     case UNDERLYING_TYPE:
       /* None of these have subtrees other than those already walked
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-ctad1.C b/gcc/testsuite/g++.dg/cpp2a/concepts-ctad1.C
new file mode 100644
index 00000000000..ec2e4b014d7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-ctad1.C
@@ -0,0 +1,16 @@
+// PR c++/98611
+// { dg-do compile { target c++20 } }
+
+template <class T, class U>
+concept IsSame = __is_same(T, U);
+
+template <class T, template <class...> class _Class>
+concept IsInstantiationOf = requires(T object) {
+ { _Class{object} } -> IsSame<T>;
+};
+
+template <class T> struct Degrees {};
+static_assert(IsInstantiationOf<Degrees<int>, Degrees>);
+
+template <class T> struct NotDegrees {};
+static_assert(!IsInstantiationOf<Degrees<int>, NotDegrees>);
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-ctad2.C b/gcc/testsuite/g++.dg/cpp2a/concepts-ctad2.C
new file mode 100644
index 00000000000..0d7f9790777
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-ctad2.C
@@ -0,0 +1,13 @@
+// PR c++/98611
+// { dg-do compile { target c++20 } }
+
+template <class>
+struct S {
+  template <class T> struct Tmpl { Tmpl(T); };
+
+  template <class T>
+    requires requires (T object) { Tmpl{object}; }
+  static int f(T);
+};
+
+int a = S<int>::f(0);
-- 
2.30.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] c++: Fix ICE with CTAD in concept [PR98611]
  2021-01-12  1:08   ` Patrick Palka
@ 2021-01-12  1:47     ` Jason Merrill
  0 siblings, 0 replies; 4+ messages in thread
From: Jason Merrill @ 2021-01-12  1:47 UTC (permalink / raw)
  To: Patrick Palka; +Cc: gcc-patches

On 1/11/21 8:08 PM, Patrick Palka wrote:
> On Mon, 11 Jan 2021, Jason Merrill wrote:
> 
>> On 1/9/21 5:23 PM, Patrick Palka wrote:
>>> This patch teaches find_template_parameters to visit the template
>>> represented by a CTAD placeholder, which is normally not visited by
>>> for_each_template_parm.  This template may be a template template
>>> parameter (as in the first testcase), or it may implicitly use the
>>> template parameters of an enclosing class template (as in the second
>>> testcase), and in either case we need to record the template parameters
>>> used therein for later satisfaction.
>>>
>>> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
>>> trunk and perhaps the 10 branch?  Also tested on range-v3 and cmcstl2.
>>>
>>> gcc/cp/ChangeLog:
>>>
>>> 	PR c++/98611
>>> 	* pt.c (any_template_parm_r) <case TEMPLATE_TYPE_PARM>: Visit
>>> 	the template of a CTAD placeholder.
>>
>> Did you consider doing this in cp_walk_subtrees instead of here?
> 
> Briefly, but I couldn't convince myself which of the three visitors
> (cp_walk_subtrees, for_each_template_parm_r or any_template_parm_r) is
> the most appropriate place to do it in, so I defaulted to the most
> specific routine of the three.
> 
> The following passes bootstrap and regtesting on x86_64-pc-linux-gnu.
> Shall we go with this?

I think so; a class template placeholder is written explicitly in 
whatever we're walking over, so looking at it here makes sense to me. 
The patch is OK.

> -- >8 --
> 
> gcc/cp/ChangeLog:
> 
> 	PR c++/98611
> 	* tree.c (cp_walk_subtrees) <case TEMPLATE_TYPE_PARM>: Visit
> 	the template of a CTAD placeholder.
> 
> gcc/testsuite/ChangeLog:
> 
> 	PR c++/98611
> 	* g++.dg/cpp2a/concepts-ctad1.C: New test.
> 	* g++.dg/cpp2a/concepts-ctad2.C: New test.
> ---
>   gcc/cp/tree.c                               |  5 ++++-
>   gcc/testsuite/g++.dg/cpp2a/concepts-ctad1.C | 16 ++++++++++++++++
>   gcc/testsuite/g++.dg/cpp2a/concepts-ctad2.C | 13 +++++++++++++
>   3 files changed, 33 insertions(+), 1 deletion(-)
>   create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-ctad1.C
>   create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-ctad2.C
> 
> diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
> index c536eb581a7..d339036e88e 100644
> --- a/gcc/cp/tree.c
> +++ b/gcc/cp/tree.c
> @@ -5173,12 +5173,15 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
>     result = NULL_TREE;
>     switch (code)
>       {
> +    case TEMPLATE_TYPE_PARM:
> +      if (template_placeholder_p (*tp))
> +	WALK_SUBTREE (CLASS_PLACEHOLDER_TEMPLATE (*tp));
> +      /* Fall through.  */
>       case DEFERRED_PARSE:
>       case TEMPLATE_TEMPLATE_PARM:
>       case BOUND_TEMPLATE_TEMPLATE_PARM:
>       case UNBOUND_CLASS_TEMPLATE:
>       case TEMPLATE_PARM_INDEX:
> -    case TEMPLATE_TYPE_PARM:
>       case TYPEOF_TYPE:
>       case UNDERLYING_TYPE:
>         /* None of these have subtrees other than those already walked
> diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-ctad1.C b/gcc/testsuite/g++.dg/cpp2a/concepts-ctad1.C
> new file mode 100644
> index 00000000000..ec2e4b014d7
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-ctad1.C
> @@ -0,0 +1,16 @@
> +// PR c++/98611
> +// { dg-do compile { target c++20 } }
> +
> +template <class T, class U>
> +concept IsSame = __is_same(T, U);
> +
> +template <class T, template <class...> class _Class>
> +concept IsInstantiationOf = requires(T object) {
> + { _Class{object} } -> IsSame<T>;
> +};
> +
> +template <class T> struct Degrees {};
> +static_assert(IsInstantiationOf<Degrees<int>, Degrees>);
> +
> +template <class T> struct NotDegrees {};
> +static_assert(!IsInstantiationOf<Degrees<int>, NotDegrees>);
> diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-ctad2.C b/gcc/testsuite/g++.dg/cpp2a/concepts-ctad2.C
> new file mode 100644
> index 00000000000..0d7f9790777
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-ctad2.C
> @@ -0,0 +1,13 @@
> +// PR c++/98611
> +// { dg-do compile { target c++20 } }
> +
> +template <class>
> +struct S {
> +  template <class T> struct Tmpl { Tmpl(T); };
> +
> +  template <class T>
> +    requires requires (T object) { Tmpl{object}; }
> +  static int f(T);
> +};
> +
> +int a = S<int>::f(0);
> 


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2021-01-12  1:47 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-09 22:23 [PATCH] c++: Fix ICE with CTAD in concept [PR98611] Patrick Palka
2021-01-11 20:09 ` Jason Merrill
2021-01-12  1:08   ` Patrick Palka
2021-01-12  1:47     ` 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).