public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Patrick Palka <ppalka@redhat.com>
To: gcc-patches@gcc.gnu.org
Cc: jason@redhat.com, Patrick Palka <ppalka@redhat.com>
Subject: [PATCH 2/1] c++: passing partially inst ttp as ttp [PR110566]
Date: Fri, 21 Jul 2023 14:34:19 -0400	[thread overview]
Message-ID: <20230721183420.1806906-1-ppalka@redhat.com> (raw)
In-Reply-To: <0001-c-passing-partially-inst-ttp-as-ttp-PR110566.patch>

(This is a follow-up of
https://gcc.gnu.org/pipermail/gcc-patches/2023-July/624951.html)

Bootstrapped and regtested on x86_64-pc-linux-gnu, how does this look?

-- >8 --

The previous fix doesn't work for partially instantiated ttps primarily
because most_general_template doesn't work for them.  This patch fixes
this by giving such ttps a DECL_TEMPLATE_INFO (extending the
r11-734-g2fb595f8348e16 fix) with which we can obtain the original ttp.

This patch additionally makes us be more careful about using the correct
amount of levels from the scope of a ttp argument during
coerce_template_template_parms.

	PR c++/110566

gcc/cp/ChangeLog:

	* pt.cc (reduce_template_parm_level): Set DECL_TEMPLATE_INFO
	on the DECL_TEMPLATE_RESULT of a reduced template template
	parameter.
	(add_defaults_to_ttp): Also update DECL_TEMPLATE_INFO of the
	ttp's DECL_TEMPLATE_RESULT.
	(coerce_template_template_parms): Make sure 'scope_args' has
	the right amount of levels for the ttp argument.
	(most_general_template): Handle template template parameters.

gcc/testsuite/ChangeLog:

	* g++.dg/template/ttp39.C: New test.
---
 gcc/cp/pt.cc                          | 46 ++++++++++++++++++++++++---
 gcc/testsuite/g++.dg/template/ttp39.C | 16 ++++++++++
 2 files changed, 57 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/template/ttp39.C

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index e0ed4bc8bbb..be7119dd9a0 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -4570,8 +4570,14 @@ reduce_template_parm_level (tree index, tree type, int levels, tree args,
 			      TYPE_DECL, DECL_NAME (decl), type);
 	  DECL_TEMPLATE_RESULT (decl) = inner;
 	  DECL_ARTIFICIAL (inner) = true;
-	  DECL_TEMPLATE_PARMS (decl) = tsubst_template_parms
-	    (DECL_TEMPLATE_PARMS (orig_decl), args, complain);
+	  tree parms = tsubst_template_parms (DECL_TEMPLATE_PARMS (orig_decl),
+					      args, complain);
+	  DECL_TEMPLATE_PARMS (decl) = parms;
+	  retrofit_lang_decl (inner);
+	  tree orig_inner = DECL_TEMPLATE_RESULT (orig_decl);
+	  DECL_TEMPLATE_INFO (inner)
+	    = build_template_info (DECL_TI_TEMPLATE (orig_inner),
+				   template_parms_to_args (parms));
 	}
 
       /* Attach the TPI to the decl.  */
@@ -7936,6 +7942,19 @@ add_defaults_to_ttp (tree otmpl)
 	}
     }
 
+  tree oresult = DECL_TEMPLATE_RESULT (otmpl);
+  tree gen_otmpl = DECL_TI_TEMPLATE (oresult);
+  tree gen_ntmpl;
+  if (gen_otmpl == otmpl)
+    gen_ntmpl = ntmpl;
+  else
+    gen_ntmpl = add_defaults_to_ttp (gen_otmpl);
+
+  tree nresult = copy_node (oresult);
+  DECL_TEMPLATE_INFO (nresult) = copy_node (DECL_TEMPLATE_INFO (oresult));
+  DECL_TI_TEMPLATE (nresult) = gen_ntmpl;
+  DECL_TEMPLATE_RESULT (ntmpl) = nresult;
+
   hash_map_safe_put<hm_ggc> (defaulted_ttp_cache, otmpl, ntmpl);
   return ntmpl;
 }
@@ -8121,15 +8140,29 @@ coerce_template_template_parms (tree parm_tmpl,
 	 OUTER_ARGS are not the right outer levels in this case, as they are
 	 the args we're building up for PARM, and for the coercion we want the
 	 args for ARG.  If DECL_CONTEXT isn't set for a template template
-	 parameter, we can assume that it's in the current scope.  In that case
-	 we might end up adding more levels than needed, but that shouldn't be
-	 a problem; any args we need to refer to are at the right level.  */
+	 parameter, we can assume that it's in the current scope.  */
       tree ctx = DECL_CONTEXT (arg_tmpl);
       if (!ctx && DECL_TEMPLATE_TEMPLATE_PARM_P (arg_tmpl))
 	ctx = current_scope ();
       tree scope_args = NULL_TREE;
       if (tree tinfo = get_template_info (ctx))
 	scope_args = TI_ARGS (tinfo);
+      if (DECL_TEMPLATE_TEMPLATE_PARM_P (arg_tmpl))
+	{
+	  int level = TEMPLATE_TYPE_LEVEL (TREE_TYPE (gen_arg_tmpl));
+	  int scope_depth = TMPL_ARGS_DEPTH (scope_args);
+	  if (scope_depth >= level)
+	    /* Only use as many levels from the scope as needed (not
+	       including the level of ARG).  */
+	    scope_args = strip_innermost_template_args
+	      (scope_args, scope_depth - (level - 1));
+
+	  /* Add the arguments that appear at the level of ARG.  */
+	  tree adj_args = DECL_TI_ARGS (DECL_TEMPLATE_RESULT (arg_tmpl));
+	  adj_args = TMPL_ARGS_LEVEL (adj_args, TMPL_ARGS_DEPTH (adj_args) - 1);
+	  scope_args = add_to_template_args (scope_args, adj_args);
+	}
+
       pargs = add_to_template_args (scope_args, pargs);
 
       pargs = coerce_template_parms (gen_arg_parms, pargs, NULL_TREE, tf_none);
@@ -25985,6 +26018,9 @@ most_general_template (tree decl)
 	return NULL_TREE;
     }
 
+  if (DECL_TEMPLATE_TEMPLATE_PARM_P (decl))
+    return DECL_TI_TEMPLATE (DECL_TEMPLATE_RESULT (decl));
+
   /* Look for more and more general templates.  */
   while (DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl))
     {
diff --git a/gcc/testsuite/g++.dg/template/ttp39.C b/gcc/testsuite/g++.dg/template/ttp39.C
new file mode 100644
index 00000000000..03d7c505c4a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/ttp39.C
@@ -0,0 +1,16 @@
+// PR c++/110566
+// { dg-do compile { target c++20 } }
+
+template<template<int N, int M> class>
+struct A;
+
+template<class U>
+struct B {
+  template<class T>
+  struct C {
+    template<template<auto X, auto Y> class TT>
+    using type = A<TT>;
+  };
+};
+
+template struct B<int>::C<int>;
-- 
2.41.0.376.gcba07a324d


       reply	other threads:[~2023-07-21 18:34 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <0001-c-passing-partially-inst-ttp-as-ttp-PR110566.patch>
2023-07-21 18:34 ` Patrick Palka [this message]
2023-07-21 20:32   ` Jason Merrill
2023-07-24 17:03     ` Patrick Palka
2023-07-25 18:04       ` Jason Merrill

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230721183420.1806906-1-ppalka@redhat.com \
    --to=ppalka@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jason@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).