PR c++/15664, c++/18276
authorKriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
Thu, 2 Dec 2004 12:00:43 +0000 (12:00 +0000)
committerKriang Lerdsuwanakij <lerdsuwa@gcc.gnu.org>
Thu, 2 Dec 2004 12:00:43 +0000 (12:00 +0000)
PR c++/15664, c++/18276
* pt.c (tsubst_decl) <TEMPLATE_DECL case>: Reorganize.  Correctly
tsubst TEMPLATE_DECL that is a TEMPLATE_TEMPLATE_PARM.

* g++.dg/template/ttp13.C: New test.
* g++.dg/template/ttp14.C: Likewise.

From-SVN: r91633

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

index 4ad1c6e6cecd8688bd99a24f93d3af897abb3146..4a486372fa1dc0c1ab493c3a21adc0309383ac65 100644 (file)
@@ -1,3 +1,9 @@
+2004-12-02  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>
+
+       PR c++/15664, c++/18276
+       * pt.c (tsubst_decl) <TEMPLATE_DECL case>: Reorganize.  Correctly
+       tsubst TEMPLATE_DECL that is a TEMPLATE_TEMPLATE_PARM.
+
 2004-12-02  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>
 
        PR c++/18123
index 34e86c8e09a32e7424479c3e78275443f5c75907..a0cc45cce7416cdf6598ffb9128afed2ff2df8f8 100644 (file)
@@ -6159,38 +6159,54 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
     {
     case TEMPLATE_DECL:
       {
-       /* We can get here when processing a member template function
-          of a template class.  */
+       /* We can get here when processing a member function template,
+          member class template, and template template parameter of
+          a template class.  */
        tree decl = DECL_TEMPLATE_RESULT (t);
        tree spec;
-       int is_template_template_parm = DECL_TEMPLATE_TEMPLATE_PARM_P (t);
+       tree tmpl_args;
+       tree full_args;
 
-       if (!is_template_template_parm)
+       if (DECL_TEMPLATE_TEMPLATE_PARM_P (t))
          {
-           /* We might already have an instance of this template.
-              The ARGS are for the surrounding class type, so the
-              full args contain the tsubst'd args for the context,
-              plus the innermost args from the template decl.  */
-           tree tmpl_args = DECL_CLASS_TEMPLATE_P (t) 
-             ? CLASSTYPE_TI_ARGS (TREE_TYPE (t))
-             : DECL_TI_ARGS (DECL_TEMPLATE_RESULT (t));
-           tree full_args;
-           
-           full_args = tsubst_template_args (tmpl_args, args,
-                                             complain, in_decl);
+           /* Template template parameter is treated here.  */
+           tree new_type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+           if (new_type == error_mark_node)
+             return error_mark_node;
 
-           /* tsubst_template_args doesn't copy the vector if
-              nothing changed.  But, *something* should have
-              changed.  */
-           gcc_assert (full_args != tmpl_args);
+           r = copy_decl (t);
+           TREE_CHAIN (r) = NULL_TREE;
+           TREE_TYPE (r) = new_type;
+           DECL_TEMPLATE_RESULT (r)
+             = build_decl (TYPE_DECL, DECL_NAME (decl), new_type);
+           DECL_TEMPLATE_PARMS (r) 
+             = tsubst_template_parms (DECL_TEMPLATE_PARMS (t), args,
+                                      complain);
+           TYPE_NAME (new_type) = r;
+           break;
+         }
 
-           spec = retrieve_specialization (t, full_args,
-                                           /*class_specializations_p=*/true);
-           if (spec != NULL_TREE)
-             {
-               r = spec;
-               break;
-             }
+       /* We might already have an instance of this template.
+          The ARGS are for the surrounding class type, so the
+          full args contain the tsubst'd args for the context,
+          plus the innermost args from the template decl.  */
+       tmpl_args = DECL_CLASS_TEMPLATE_P (t) 
+         ? CLASSTYPE_TI_ARGS (TREE_TYPE (t))
+         : DECL_TI_ARGS (DECL_TEMPLATE_RESULT (t));
+       full_args = tsubst_template_args (tmpl_args, args,
+                                         complain, in_decl);
+
+       /* tsubst_template_args doesn't copy the vector if
+          nothing changed.  But, *something* should have
+          changed.  */
+       gcc_assert (full_args != tmpl_args);
+
+       spec = retrieve_specialization (t, full_args,
+                                       /*class_specializations_p=*/true);
+       if (spec != NULL_TREE)
+         {
+           r = spec;
+           break;
          }
 
        /* Make a new template decl.  It will be similar to the
@@ -6202,14 +6218,6 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
        gcc_assert (DECL_LANG_SPECIFIC (r) != 0);
        TREE_CHAIN (r) = NULL_TREE;
 
-       if (is_template_template_parm)
-         {
-           tree new_decl = tsubst (decl, args, complain, in_decl);
-           DECL_TEMPLATE_RESULT (r) = new_decl;
-           TREE_TYPE (r) = TREE_TYPE (new_decl);
-           break;
-         }
-
        DECL_CONTEXT (r) 
          = tsubst_aggr_type (DECL_CONTEXT (t), args, 
                              complain, in_decl, 
index 84eae74e3ceef9ba5e9c216158da0581d142d203..c55808a3115f3d7dc7d2da5cf03a3a8e260b2966 100644 (file)
@@ -1,3 +1,9 @@
+2004-12-02  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>
+
+       PR c++/15664, c++/18276
+       * g++.dg/template/ttp13.C: New test.
+       * g++.dg/template/ttp14.C: Likewise.
+
 2004-12-02  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>
 
        PR c++/18123
diff --git a/gcc/testsuite/g++.dg/template/ttp13.C b/gcc/testsuite/g++.dg/template/ttp13.C
new file mode 100644 (file)
index 0000000..2c35b3a
--- /dev/null
@@ -0,0 +1,20 @@
+// { dg-do compile }
+
+// Origin: Wolfgang Bangerth <bangerth@dealii.org>
+
+// PR c++/15664: Template substitution of template template parameter
+
+template <int N> struct S { 
+    template<template<typename> class A> 
+    friend void foo(); 
+}; 
+template<template<typename> class A> 
+void foo(); 
+template <typename> struct X {}; 
+int main () { 
+  S<1> s; 
+  foo<X>(); 
+}
diff --git a/gcc/testsuite/g++.dg/template/ttp14.C b/gcc/testsuite/g++.dg/template/ttp14.C
new file mode 100644 (file)
index 0000000..2b21609
--- /dev/null
@@ -0,0 +1,15 @@
+// { dg-do compile }
+
+// Origin: akim@epita.fr
+//        Volker Reichelt <reichelt@gcc.gnu.org>
+
+// PR c++/18276: Template substitution of template template parameter
+
+template<template<int> class> struct A;
+
+template<int> struct B
+{
+    template<template<int> class> friend class A;
+};
+
+B<0> b;