This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH for c++/83916, C++17 ICE with template template parameters


In the wg21.link/P0522 change to template template parameter matching,
we ran into trouble with this testcase: when we try to form
TTC<TA...>, we need to convert TA to TC, and try to tsubst TC to
produce the real desired type.  But trying to look up TC in the args
for TTC fails, and indeed makes no sense.  Even if we passed in more
args somehow, what we have in outer_args are args for A, not for C, so
that wouldn't help.

I dealt with this situation by recognizing that we are dealing with
multiple levels of template parms and only have a single level of
template args, so we can't possibly get the right answer, so we
shouldn't do any substitution.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit 31437c878831d15bbccbd8a891a074aacfdeec10
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Mar 14 11:44:50 2018 -0400

            PR c++/83916 - ICE with template template parameters.
    
            * pt.c (convert_template_argument): Don't substitute into type of
            non-type parameter if we don't have enough arg levels.
            (unify): Likewise.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index d720c33cf0a..14321816cde 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -7974,7 +7974,11 @@ convert_template_argument (tree parm,
     {
       tree t = TREE_TYPE (parm);
 
-      if (tree a = type_uses_auto (t))
+      if (TEMPLATE_PARM_LEVEL (get_template_parm_index (parm))
+	  > TMPL_ARGS_DEPTH (args))
+	/* We don't have enough levels of args to do any substitution.  This
+	   can happen in the context of -fnew-ttp-matching.  */;
+      else if (tree a = type_uses_auto (t))
 	{
 	  t = do_auto_deduction (t, arg, a, complain, adc_unify, args);
 	  if (t == error_mark_node)
@@ -21224,14 +21228,22 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
 	 template-parameter exactly, except that a template-argument
 	 deduced from an array bound may be of any integral type.
 	 The non-type parameter might use already deduced type parameters.  */
-      ++processing_template_decl;
-      tparm = tsubst (TREE_TYPE (parm), targs, 0, NULL_TREE);
-      --processing_template_decl;
-      if (tree a = type_uses_auto (tparm))
+      tparm = TREE_TYPE (parm);
+      if (TEMPLATE_PARM_LEVEL (parm) > TMPL_ARGS_DEPTH (targs))
+	/* We don't have enough levels of args to do any substitution.  This
+	   can happen in the context of -fnew-ttp-matching.  */;
+      else
 	{
-	  tparm = do_auto_deduction (tparm, arg, a, complain, adc_unify);
-	  if (tparm == error_mark_node)
-	    return 1;
+	  ++processing_template_decl;
+	  tparm = tsubst (tparm, targs, tf_none, NULL_TREE);
+	  --processing_template_decl;
+
+	  if (tree a = type_uses_auto (tparm))
+	    {
+	      tparm = do_auto_deduction (tparm, arg, a, complain, adc_unify);
+	      if (tparm == error_mark_node)
+		return 1;
+	    }
 	}
 
       if (!TREE_TYPE (arg))
diff --git a/gcc/testsuite/g++.dg/template/ttp31.C b/gcc/testsuite/g++.dg/template/ttp31.C
new file mode 100644
index 00000000000..ff3f1f5c3ac
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/ttp31.C
@@ -0,0 +1,10 @@
+// PR c++/83916
+// { dg-do compile { target c++11 } }
+
+template<class TA,
+	 template<TA...> class TTA, TA... VA>
+struct A { };
+
+template<class UC, class TC,
+	 template<TC...> class TTC, TC... VC>
+struct C : A<TC, TTC, VC...> { };
diff --git a/gcc/testsuite/g++.dg/template/ttp32.C b/gcc/testsuite/g++.dg/template/ttp32.C
new file mode 100644
index 00000000000..a96a62d332f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/ttp32.C
@@ -0,0 +1,10 @@
+// PR c++/83916
+// { dg-do compile { target c++17 } }
+
+template<class TA,
+	 template<auto...> class TTA, TA... VA>
+struct A { };
+
+template<class UC, class TC,
+	 template<auto...> class TTC, TC... VC>
+struct C : A<TC, TTC, VC...> { };

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]