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] Fix PR15664, 18276 (tsubst template template parm)


Hi

This patch fixes PR15664 and PR18276. It turned out that
tsubsting TEMPLATE_DECL that is a template template parameter produces broken tree node. A total of 3 problems found:
- DECL_TEMPLATE_RESULT should point to a TYPE_DECL (not a
TEMPLATE_DECL).
- The substituted TEMPLATE_TEMPLATE_PARM should have TYPE_NAME
point back to the new TEMPLATE_DECL (not the old TEMPLATE_DECL).
- DECL_TEMPLATE_PARMS is not reduced.


I reorganize the case TEMPLATE_DECL in tsubst_decl to group
the codes related to template template parameter together (making it not fragile to surrounding code changes) and add the fix.


Tested on i686-pc-linux-gnu. OK for mainline?

--Kriang


2004-11-12 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-11-12 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>

	PR c++/15664, c++/18276
	* g++.dg/template/ttp13.C: New test.
	* g++.dg/template/ttp14.C: Likewise.


diff -cprN gcc-main-save/gcc/cp/pt.c gcc-main-new/gcc/cp/pt.c
*** gcc-main-save/gcc/cp/pt.c Sun Nov 7 22:40:15 2004
--- gcc-main-new/gcc/cp/pt.c Fri Nov 12 19:13:26 2004
*************** tsubst_decl (tree t, tree args, tree typ
*** 6152,6189 ****
{
case TEMPLATE_DECL:
{
! /* We can get here when processing a member template function
! of a template class. */
tree decl = DECL_TEMPLATE_RESULT (t);
tree spec;
! int is_template_template_parm = DECL_TEMPLATE_TEMPLATE_PARM_P (t);
! if (!is_template_template_parm)
{
! /* 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);
! ! /* 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
--- 6152,6205 ----
{
case TEMPLATE_DECL:
{
! /* 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;
! tree tmpl_args;
! tree full_args;
! if (DECL_TEMPLATE_TEMPLATE_PARM_P (t))
{
! /* 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;
! ! 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;
! }
! ! /* 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
*************** tsubst_decl (tree t, tree args, tree typ
*** 6195,6208 ****
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, --- 6211,6216 ----
diff -cprN gcc-main-save/gcc/testsuite/g++.dg/template/ttp13.C gcc-main-new/gcc/testsuite/g++.dg/template/ttp13.C
*** gcc-main-save/gcc/testsuite/g++.dg/template/ttp13.C Thu Jan 1 07:00:00 1970
--- gcc-main-new/gcc/testsuite/g++.dg/template/ttp13.C Thu Nov 11 22:23:53 2004
***************
*** 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 -cprN gcc-main-save/gcc/testsuite/g++.dg/template/ttp14.C gcc-main-new/gcc/testsuite/g++.dg/template/ttp14.C
*** gcc-main-save/gcc/testsuite/g++.dg/template/ttp14.C Thu Jan 1 07:00:00 1970
--- gcc-main-new/gcc/testsuite/g++.dg/template/ttp14.C Thu Nov 11 22:27:07 2004
***************
*** 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;




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