PR c++/51641 - Lookup finds enclosing class member instead of template parameter
gcc/cp/ PR c++/51641 * cp-tree.h (template_type_parameter_p): Declare new function. (parameter_of_template_p): Remove * pt.c (template_type_parameter_p): Define new function. (parameter_of_template_p): Remove. * name-lookup.c (binding_to_template_parms_of_scope_p): Don't rely on parameter_of_template_p anymore. Compare the level of the template parameter to the depth of the template. gcc/testsuite/ PR c++/51641 * g++.dg/lookup/hidden-class17.C: New test. Conflicts: gcc/cp/pt.c From-SVN: r185357
This commit is contained in:
parent
40703fdf12
commit
74788b8009
6 changed files with 75 additions and 37 deletions
|
@ -1,3 +1,14 @@
|
|||
2012-01-30 Dodji Seketeli <dodji@redhat.com>
|
||||
|
||||
PR c++/51641
|
||||
* cp-tree.h (template_type_parameter_p): Declare new function.
|
||||
(parameter_of_template_p): Remove
|
||||
* pt.c (template_type_parameter_p): Define new function.
|
||||
(parameter_of_template_p): Remove.
|
||||
* name-lookup.c (binding_to_template_parms_of_scope_p): Don't rely
|
||||
on parameter_of_template_p anymore. Compare the level of the
|
||||
template parameter to the depth of the template.
|
||||
|
||||
2011-12-15 Dodji Seketeli <dodji@redhat.com>
|
||||
|
||||
* call.c (standard_conversion, build_integral_nontype_arg_conv)
|
||||
|
|
|
@ -5361,10 +5361,10 @@ extern bool explicit_class_specialization_p (tree);
|
|||
extern int push_tinst_level (tree);
|
||||
extern void pop_tinst_level (void);
|
||||
extern struct tinst_level *outermost_tinst_level(void);
|
||||
extern bool parameter_of_template_p (tree, tree);
|
||||
extern void init_template_processing (void);
|
||||
extern void print_template_statistics (void);
|
||||
bool template_template_parameter_p (const_tree);
|
||||
bool template_type_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, int);
|
||||
|
|
|
@ -4466,8 +4466,8 @@ static bool
|
|||
binding_to_template_parms_of_scope_p (cxx_binding *binding,
|
||||
cp_binding_level *scope)
|
||||
{
|
||||
tree binding_value;
|
||||
tree tinfo;
|
||||
tree binding_value, tmpl, tinfo;
|
||||
int level;
|
||||
|
||||
if (!binding || !scope || !scope->this_entity)
|
||||
return false;
|
||||
|
@ -4475,9 +4475,29 @@ binding_to_template_parms_of_scope_p (cxx_binding *binding,
|
|||
binding_value = binding->value ? binding->value : binding->type;
|
||||
tinfo = get_template_info (scope->this_entity);
|
||||
|
||||
return (tinfo
|
||||
/* BINDING_VALUE must be a template parm. */
|
||||
if (binding_value == NULL_TREE
|
||||
|| (!DECL_P (binding_value)
|
||||
|| !DECL_TEMPLATE_PARM_P (binding_value)))
|
||||
return false;
|
||||
|
||||
/* The level of BINDING_VALUE. */
|
||||
level =
|
||||
template_type_parameter_p (binding_value)
|
||||
? TEMPLATE_PARM_LEVEL (TEMPLATE_TYPE_PARM_INDEX
|
||||
(TREE_TYPE (binding_value)))
|
||||
: TEMPLATE_PARM_LEVEL (DECL_INITIAL (binding_value));
|
||||
|
||||
/* The template of the current scope, iff said scope is a primary
|
||||
template. */
|
||||
tmpl = (tinfo
|
||||
&& PRIMARY_TEMPLATE_P (TI_TEMPLATE (tinfo))
|
||||
&& parameter_of_template_p (binding_value, TI_TEMPLATE (tinfo)));
|
||||
? TI_TEMPLATE (tinfo)
|
||||
: NULL_TREE);
|
||||
|
||||
/* If the level of the parm BINDING_VALUE equals the depth of TMPL,
|
||||
then BINDING_VALUE is a parameter of TMPL. */
|
||||
return (tmpl && level == TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl)));
|
||||
}
|
||||
|
||||
/* Return the innermost non-namespace binding for NAME from a scope
|
||||
|
|
44
gcc/cp/pt.c
44
gcc/cp/pt.c
|
@ -2869,6 +2869,18 @@ template_template_parameter_p (const_tree parm)
|
|||
return DECL_TEMPLATE_TEMPLATE_PARM_P (parm);
|
||||
}
|
||||
|
||||
/* Return true iff PARM is a DECL representing a type template
|
||||
parameter. */
|
||||
|
||||
bool
|
||||
template_type_parameter_p (const_tree parm)
|
||||
{
|
||||
return (parm
|
||||
&& (TREE_CODE (parm) == TYPE_DECL
|
||||
|| TREE_CODE (parm) == TEMPLATE_DECL)
|
||||
&& DECL_TEMPLATE_PARM_P (parm));
|
||||
}
|
||||
|
||||
/* Return the template parameters of T if T is a
|
||||
primary template instantiation, NULL otherwise. */
|
||||
|
||||
|
@ -8118,38 +8130,6 @@ outermost_tinst_level (void)
|
|||
return level;
|
||||
}
|
||||
|
||||
/* Returns TRUE if PARM is a parameter of the template TEMPL. */
|
||||
|
||||
bool
|
||||
parameter_of_template_p (tree parm, tree templ)
|
||||
{
|
||||
tree parms;
|
||||
int i;
|
||||
|
||||
if (!parm || !templ)
|
||||
return false;
|
||||
|
||||
gcc_assert (DECL_TEMPLATE_PARM_P (parm));
|
||||
gcc_assert (TREE_CODE (templ) == TEMPLATE_DECL);
|
||||
|
||||
parms = DECL_TEMPLATE_PARMS (templ);
|
||||
parms = INNERMOST_TEMPLATE_PARMS (parms);
|
||||
|
||||
for (i = 0; i < TREE_VEC_LENGTH (parms); ++i)
|
||||
{
|
||||
tree p = TREE_VALUE (TREE_VEC_ELT (parms, i));
|
||||
if (p == error_mark_node)
|
||||
continue;
|
||||
|
||||
if (parm == p
|
||||
|| (DECL_INITIAL (parm)
|
||||
&& DECL_INITIAL (parm) == DECL_INITIAL (p)))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* DECL is a friend FUNCTION_DECL or TEMPLATE_DECL. ARGS is the
|
||||
vector of template arguments, as for tsubst.
|
||||
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2012-01-30 Dodji Seketeli <dodji@redhat.com>
|
||||
|
||||
PR c++/51641
|
||||
* g++.dg/lookup/hidden-class17.C: New test.
|
||||
|
||||
2012-03-13 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c/52577
|
||||
|
|
22
gcc/testsuite/g++.dg/lookup/hidden-class17.C
Normal file
22
gcc/testsuite/g++.dg/lookup/hidden-class17.C
Normal file
|
@ -0,0 +1,22 @@
|
|||
// Origin PR c++/51641
|
||||
// { dg-do compile }
|
||||
|
||||
struct A {
|
||||
struct B { typedef int X; };
|
||||
};
|
||||
|
||||
template<class B> struct C : A {
|
||||
B::X q; // Ok: A::B.
|
||||
struct U { typedef int X; };
|
||||
template<class U>
|
||||
struct D;
|
||||
};
|
||||
|
||||
template<class B>
|
||||
template<class U>
|
||||
struct C<B>::D {
|
||||
typename U::X r; // { dg-error "" }
|
||||
};
|
||||
|
||||
C<int>::D<double> y;
|
||||
|
Loading…
Add table
Reference in a new issue