Fix candidate for PR c++/43206

gcc/cp/ChangeLog:
	PR c++/43206
	* cp-tree.h (get_template_parms_at_level): Declare ...
	* pt.c (get_template_parms_at_level): ... new function.
	* typeck.c (get_template_parms_of_dependent_type): If a template
	type parm's DECL_CONTEXT isn't yet set, get its siblings from
	current_template_parms. Use get_template_parms_at_level. Remove
	useless test.
	(incompatible_dependent_types_p): If we get empty parms from just one
	of the template type parms we are comparing then the template parms are
	incompatible.

gcc/testsuite/ChangeLog:
	PR c++/43206
	* g++.dg/template/typedef30.C: New test case.

From-SVN: r157730
This commit is contained in:
Dodji Seketeli 2010-03-25 22:08:33 +00:00 committed by Dodji Seketeli
parent 9b7e6950f5
commit 58f5f6b430
6 changed files with 79 additions and 2 deletions

View File

@ -1,3 +1,16 @@
2010-03-25 Dodji Seketeli <dodji@redhat.com>
PR c++/43206
* cp-tree.h (get_template_parms_at_level): Declare ...
* pt.c (get_template_parms_at_level): ... new function.
* typeck.c (get_template_parms_of_dependent_type): If a template
type parm's DECL_CONTEXT isn't yet set, get its siblings from
current_template_parms. Use get_template_parms_at_level. Remove
useless test.
(incompatible_dependent_types_p): If we get empty parms from just one
of the template type parms we are comparing then the template parms are
incompatible.
2010-03-24 Jason Merrill <jason@redhat.com>
PR c++/43502

View File

@ -4973,6 +4973,7 @@ extern void init_template_processing (void);
bool template_template_parameter_p (const_tree);
extern bool primary_template_instantiation_p (const_tree);
extern tree get_primary_template_innermost_parameters (const_tree);
extern tree get_template_parms_at_level (tree, unsigned);
extern tree get_template_innermost_arguments (const_tree);
extern tree get_template_argument_pack_elems (const_tree);
extern tree get_function_template_decl (const_tree);

View File

@ -2839,6 +2839,25 @@ get_primary_template_innermost_parameters (const_tree t)
return parms;
}
/* Return the template parameters of the LEVELth level from the full list
of template parameters PARMS. */
tree
get_template_parms_at_level (tree parms, unsigned level)
{
tree p;
if (!parms
|| TREE_CODE (parms) != TREE_LIST
|| level > TMPL_PARMS_DEPTH (parms))
return NULL_TREE;
for (p = parms; p; p = TREE_CHAIN (p))
if (TMPL_PARMS_DEPTH (p) == level)
return p;
return NULL_TREE;
}
/* Returns the template arguments of T if T is a template instantiation,
NULL otherwise. */

View File

@ -1113,9 +1113,17 @@ get_template_parms_of_dependent_type (tree 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 (typedef_variant_p (t)
&& DECL_CONTEXT (TYPE_NAME (t))
&& !NAMESPACE_SCOPE_P (TYPE_NAME (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));
else if (TYPE_CONTEXT (t)
&& !NAMESPACE_SCOPE_P (t))
tinfo = get_template_info (TYPE_CONTEXT (t));
@ -1170,6 +1178,17 @@ incompatible_dependent_types_p (tree t1, tree t2)
tparms1 = get_template_parms_of_dependent_type (t1);
tparms2 = get_template_parms_of_dependent_type (t2);
/* If T2 is a template type parm and if we could not get the template
parms it belongs to, that means we have not finished parsing the
full set of template parameters of the template declaration it
belongs to yet. If we could get the template parms T1 belongs to,
that mostly means T1 and T2 belongs to templates that are
different and incompatible. */
if (TREE_CODE (t1) == TEMPLATE_TYPE_PARM
&& (tparms1 == NULL_TREE || tparms2 == NULL_TREE)
&& tparms1 != tparms2)
return true;
if (tparms1 == NULL_TREE
|| tparms2 == NULL_TREE
|| tparms1 == tparms2)

View File

@ -1,3 +1,8 @@
2010-03-25 Dodji Seketeli <dodji@redhat.com>
PR c++/43206
* g++.dg/template/typedef30.C: New test case.
2010-03-25 Jakub Jelinek <jakub@redhat.com>
PR c/43385

View File

@ -0,0 +1,20 @@
// Origin: PR c++/43206
// { dg-do compile }
template<class A> struct NumericTraits{ typedef A TInputImage;};
template<class B> class CovariantVector{};
template<class C> struct Image{ typedef C PixelType;};
template<class H, class E, class D>
class F {
typedef H G;
typedef
typename NumericTraits<typename G::PixelType>::RealType
InputRealType;
};
template<typename TInputImage,
typename TOutputImage=Image<CovariantVector<typename NumericTraits<typename TInputImage::PixelType>::TInputImage> > >
class XXX{};
XXX<Image<float> > x;