PR c++/83916 - ICE with template template parameters.
authorJason Merrill <jason@redhat.com>
Wed, 14 Mar 2018 19:17:03 +0000 (15:17 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 14 Mar 2018 19:17:03 +0000 (15:17 -0400)
* pt.c (convert_template_argument): Don't substitute into type of
non-type parameter if we don't have enough arg levels.
(unify): Likewise.

From-SVN: r258533

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/g++.dg/template/ttp31.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/ttp32.C [new file with mode: 0644]

index 067d53835b668d392013b318b29ecb4f4bf996cf..a4ffc663dc1aaddf81f9db9879bafa094af8e321 100644 (file)
@@ -1,3 +1,10 @@
+2018-03-14  Jason Merrill  <jason@redhat.com>
+
+       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.
+
 2018-03-14  Marek Polacek  <polacek@redhat.com>
 
        PR c++/84596
index d720c33cf0af8b37277ec7ba75f188b2767c1b05..14321816cdecd073e6828951f165fb9fa894f040 100644 (file)
@@ -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 (file)
index 0000000..ff3f1f5
--- /dev/null
@@ -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 (file)
index 0000000..a96a62d
--- /dev/null
@@ -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...> { };