From d7df0b912eeed2fbe9c42dddd6f2c6a6a4ed4b17 Mon Sep 17 00:00:00 2001 From: Dodji Seketeli Date: Wed, 31 Mar 2010 09:21:02 +0000 Subject: [PATCH] re PR c++/43558 (Rejects specialization) Fix PR c++/43558 gcc/cp/ChangeLog: PR c++/43558 * cp-tree.h (TEMPLATE_TYPE_PARM_SIBLING_PARMS): New accessor macro. * pt.c (end_template_parm_list): Store sibling template parms of each TEMPLATE_TYPE_PARMs into its TEMPLATE_TYPE_PARM_SIBLING_PARMS. (push_template_decl_real): Don't store the containing template decl into the DECL_CONTEXT of TEMPLATE_TYPE_PARMs anymore. * typeck.c (get_template_parms_of_dependent_type): Get sibling parms of a TEMPLATE_TYPE_PARM from TEMPLATE_TYPE_PARM_SIBLING_PARMS. Simplify the logic. gcc/testsuite/ChangeLog: PR c++/43558 * g++.dg/template/typedef31.C: New test. From-SVN: r157857 --- gcc/cp/ChangeLog | 12 ++++++++++ gcc/cp/cp-tree.h | 4 ++++ gcc/cp/pt.c | 6 ++--- gcc/cp/typeck.c | 28 ++++++----------------- gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/g++.dg/template/typedef31.C | 21 +++++++++++++++++ 6 files changed, 52 insertions(+), 24 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/typedef31.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 9138ee1f1aa..56c11b89c89 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,15 @@ +2010-03-31 Dodji Seketeli + + PR c++/43558 + * cp-tree.h (TEMPLATE_TYPE_PARM_SIBLING_PARMS): New accessor macro. + * pt.c (end_template_parm_list): Store sibling template parms of + each TEMPLATE_TYPE_PARMs into its TEMPLATE_TYPE_PARM_SIBLING_PARMS. + (push_template_decl_real): Don't store the containing template decl + into the DECL_CONTEXT of TEMPLATE_TYPE_PARMs anymore. + * typeck.c (get_template_parms_of_dependent_type): Get sibling parms + of a TEMPLATE_TYPE_PARM from TEMPLATE_TYPE_PARM_SIBLING_PARMS. + Simplify the logic. + 2010-03-30 Jason Merrill PR c++/43076 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 2eaee8408b2..fb67965b209 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4240,6 +4240,10 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG }; (TEMPLATE_PARM_DECL (TEMPLATE_TYPE_PARM_INDEX (NODE))) #define TEMPLATE_TYPE_PARAMETER_PACK(NODE) \ (TEMPLATE_PARM_PARAMETER_PACK (TEMPLATE_TYPE_PARM_INDEX (NODE))) +/* The list of template parms that a given template parameter of type + TEMPLATE_TYPE_PARM belongs to.*/ +#define TEMPLATE_TYPE_PARM_SIBLING_PARMS(NODE) \ + (TREE_CHECK ((NODE), TEMPLATE_TYPE_PARM))->type.maxval /* These constants can used as bit flags in the process of tree formatting. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index a8e1b78b73c..3e2927c1613 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -3571,6 +3571,9 @@ end_template_parm_list (tree parms) next = TREE_CHAIN (parm); TREE_VEC_ELT (saved_parmlist, nparms) = parm; TREE_CHAIN (parm) = NULL_TREE; + if (TREE_CODE (TREE_VALUE (parm)) == TYPE_DECL) + TEMPLATE_TYPE_PARM_SIBLING_PARMS (TREE_TYPE (TREE_VALUE (parm))) = + current_template_parms; } --processing_template_parmlist; @@ -4622,9 +4625,6 @@ template arguments to %qD do not match original template %qD", tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i)); if (TREE_CODE (parm) == TEMPLATE_DECL) DECL_CONTEXT (parm) = tmpl; - - if (TREE_CODE (TREE_TYPE (parm)) == TEMPLATE_TYPE_PARM) - DECL_CONTEXT (TYPE_NAME (TREE_TYPE (parm))) = tmpl; } } diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index a4c64ea85bd..4b91912b9e6 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -1110,36 +1110,22 @@ get_template_parms_of_dependent_type (tree t) template info from T itself. */ if ((tinfo = get_template_info (t))) ; - /* If T1 is a typedef or whatever has a template info associated - to its context, get the template parameters from that context. */ + else if (TREE_CODE (t) == TEMPLATE_TYPE_PARM) + return TEMPLATE_TYPE_PARM_SIBLING_PARMS (t); else if (typedef_variant_p (t) && !NAMESPACE_SCOPE_P (TYPE_NAME (t))) tinfo = get_template_info (DECL_CONTEXT (TYPE_NAME (t))); - else if (TREE_CODE (t) == TEMPLATE_TYPE_PARM - && DECL_CONTEXT (TYPE_NAME (t)) == NULL_TREE) - /* We have not yet created the DECL_TEMPLATE this - template type parm belongs to. It probably means - that we are in the middle of parsing the template parameters - of a template, and T is one of the parameters we have parsed. - Let's return the list of template parms we have parsed so far. */ - return get_template_parms_at_level (current_template_parms, - TEMPLATE_TYPE_LEVEL (t)); + /* If T is a TYPENAME_TYPE which context is a template type + parameter, get the template parameters from that context. */ + else if (TYPE_CONTEXT (t) + && TREE_CODE (TYPE_CONTEXT (t)) == TEMPLATE_TYPE_PARM) + return TEMPLATE_TYPE_PARM_SIBLING_PARMS (TYPE_CONTEXT (t)); else if (TYPE_CONTEXT (t) && !NAMESPACE_SCOPE_P (t)) tinfo = get_template_info (TYPE_CONTEXT (t)); if (tinfo) tparms = DECL_TEMPLATE_PARMS (TI_TEMPLATE (tinfo)); - /* If T is a template type parameter, get the template parameter - set it is part of. */ - else if (TREE_CODE (t) == TEMPLATE_TYPE_PARM - && DECL_CONTEXT (TYPE_NAME (t))) - tparms = DECL_TEMPLATE_PARMS (DECL_CONTEXT (TYPE_NAME (t))); - /* If T is a TYPENAME_TYPE which context is a template type - parameter, get the template parameters from that context. */ - else if (TYPE_CONTEXT (t) - && TREE_CODE (TYPE_CONTEXT (t)) == TEMPLATE_TYPE_PARM) - tparms = get_template_parms_of_dependent_type (TYPE_CONTEXT (t)); return tparms; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3e9329a86f4..4b0fb1a2be8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-03-31 Dodji Seketeli + + PR c++/43558 + * g++.dg/template/typedef31.C: New test. + 2010-03-31 Rainer Orth * g++.dg/ext/visibility/pragma-override1.C: Allow for .hidden in diff --git a/gcc/testsuite/g++.dg/template/typedef31.C b/gcc/testsuite/g++.dg/template/typedef31.C new file mode 100644 index 00000000000..7d66e3f5b0d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef31.C @@ -0,0 +1,21 @@ +// Origin: PR c++/43558 +// { dg-do compile } + +class Compressible; +template class Engine; +template +class Engine +{ + public: + typedef T Element_t; + //Element_t read(int); + T read(int); +}; + +template +T Engine::read(int) +{ +} + +Engine x; +