diff options
author | Dodji Seketeli <dodji@redhat.com> | 2010-03-31 09:21:02 +0000 |
---|---|---|
committer | Dodji Seketeli <dodji@gcc.gnu.org> | 2010-03-31 11:21:02 +0200 |
commit | d7df0b912eeed2fbe9c42dddd6f2c6a6a4ed4b17 (patch) | |
tree | 9c61e3b92286af000161c01dd1cffdf7c1439882 /gcc | |
parent | f0c01ffd7723295ca7ca90a7e87351c8fb6f20e2 (diff) | |
download | gcc-d7df0b912eeed2fbe9c42dddd6f2c6a6a4ed4b17.zip gcc-d7df0b912eeed2fbe9c42dddd6f2c6a6a4ed4b17.tar.gz gcc-d7df0b912eeed2fbe9c42dddd6f2c6a6a4ed4b17.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 4 | ||||
-rw-r--r-- | gcc/cp/pt.c | 6 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 28 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/typedef31.C | 21 |
6 files changed, 52 insertions, 24 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 9138ee1..56c11b8 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,15 @@ +2010-03-31 Dodji Seketeli <dodji@redhat.com> + + 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 <jason@redhat.com> PR c++/43076 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 2eaee84..fb67965 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 a8e1b78..3e2927c 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 a4c64ea..4b91912 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 3e9329a..4b0fb1a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-03-31 Dodji Seketeli <dodji@redhat.com> + + PR c++/43558 + * g++.dg/template/typedef31.C: New test. + 2010-03-31 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> * 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 0000000..7d66e3f --- /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 T, class EngineTag> class Engine; +template <class T> +class Engine<T, Compressible> +{ + public: + typedef T Element_t; + //Element_t read(int); + T read(int); +}; + +template <class T> +T Engine<T, Compressible>::read(int) +{ +} + +Engine<int, Compressible> x; + |