From 28e42b7eac632e5ad97801687192baa1f76a2e0d Mon Sep 17 00:00:00 2001 From: Kriang Lerdsuwanakij Date: Thu, 2 Dec 2004 12:00:43 +0000 Subject: [PATCH] PR c++/15664, c++/18276 PR c++/15664, c++/18276 * pt.c (tsubst_decl) : 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 | 6 +++ gcc/cp/pt.c | 76 +++++++++++++++------------ gcc/testsuite/ChangeLog | 6 +++ gcc/testsuite/g++.dg/template/ttp13.C | 20 +++++++ gcc/testsuite/g++.dg/template/ttp14.C | 15 ++++++ 5 files changed, 89 insertions(+), 34 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/ttp13.C create mode 100644 gcc/testsuite/g++.dg/template/ttp14.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4ad1c6e6cec..4a486372fa1 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2004-12-02 Kriang Lerdsuwanakij + + PR c++/15664, c++/18276 + * pt.c (tsubst_decl) : Reorganize. Correctly + tsubst TEMPLATE_DECL that is a TEMPLATE_TEMPLATE_PARM. + 2004-12-02 Kriang Lerdsuwanakij PR c++/18123 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 34e86c8e09a..a0cc45cce74 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -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, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 84eae74e3ce..c55808a3115 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2004-12-02 Kriang Lerdsuwanakij + + PR c++/15664, c++/18276 + * g++.dg/template/ttp13.C: New test. + * g++.dg/template/ttp14.C: Likewise. + 2004-12-02 Kriang Lerdsuwanakij 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 index 00000000000..2c35b3a79b9 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp13.C @@ -0,0 +1,20 @@ +// { dg-do compile } + +// Origin: Wolfgang Bangerth + +// PR c++/15664: Template substitution of template template parameter + +template struct S { + template class A> + friend void foo(); +}; + +template class A> +void foo(); + +template struct X {}; + +int main () { + S<1> s; + foo(); +} diff --git a/gcc/testsuite/g++.dg/template/ttp14.C b/gcc/testsuite/g++.dg/template/ttp14.C new file mode 100644 index 00000000000..2b216090be3 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp14.C @@ -0,0 +1,15 @@ +// { dg-do compile } + +// Origin: akim@epita.fr +// Volker Reichelt + +// PR c++/18276: Template substitution of template template parameter + +template class> struct A; + +template struct B +{ + template class> friend class A; +}; + +B<0> b; -- 2.30.2