re PR c++/36019 (template parameter does not hide class name)

gcc/cp/ChangeLog:
2009-01-12  Dodji Seketeli  <dodji@redhat.com>

	PR c++/36019
	* pt.c (parameter_of_template_p): New function.
	* cp-tree.h: Declare it.
	* name-lookup.c (binding_to_template_parms_of_scope_p): New
	function.
	(outer_binding): Take template parameters in account when looking for
	a name binding.

gcc/testsuite/ChangeLog:
2009-01-12  Dodji Seketeli  <dodji@redhat.com>

	PR c++/36019
	* g++.dg/lookup/hidden-class12.C: New test.
	* g++.dg/lookup/hidden-class13.C: New test.
	* g++.dg/lookup/hidden-class14.C: New test.
	* g++.dg/lookup/hidden-class15.C: New test.
	* g++.dg/lookup/hidden-class16.C: New test.

From-SVN: r143315
This commit is contained in:
Dodji Seketeli 2009-01-12 22:47:49 +00:00 committed by Dodji Seketeli
parent 856c450bd5
commit 172a459435
10 changed files with 206 additions and 2 deletions

View File

@ -1,3 +1,13 @@
2009-01-12 Dodji Seketeli <dodji@redhat.com>
PR c++/36019
* pt.c (parameter_of_template_p): New function.
* cp-tree.h: Declare it.
* name-lookup.c (binding_to_template_parms_of_scope_p): New
function.
(outer_binding): Take template parameters in account when looking for
a name binding.
2009-01-12 Jason Merrill <jason@redhat.com>
PR c++/31488

View File

@ -4603,6 +4603,7 @@ extern bool reregister_specialization (tree, tree, tree);
extern tree fold_non_dependent_expr (tree);
extern bool explicit_class_specialization_p (tree);
extern struct tinst_level *outermost_tinst_level(void);
extern bool parameter_of_template_p (tree, tree);
/* in repo.c */
extern void init_repo (void);

View File

@ -3968,9 +3968,34 @@ qualified_lookup_using_namespace (tree name, tree scope,
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, result->value != error_mark_node);
}
/* Subroutine of outer_binding.
Returns TRUE if BINDING is a binding to a template parameter of SCOPE,
FALSE otherwise. */
static bool
binding_to_template_parms_of_scope_p (cxx_binding *binding,
cxx_scope *scope)
{
tree binding_value;
if (!binding || !scope)
return false;
binding_value = binding->value ? binding->value : binding->type;
return (scope
&& scope->this_entity
&& get_template_info (scope->this_entity)
&& parameter_of_template_p (binding_value,
TI_TEMPLATE (get_template_info \
(scope->this_entity))));
}
/* Return the innermost non-namespace binding for NAME from a scope
containing BINDING, or, if BINDING is NULL, the current scope. If
CLASS_P is false, then class bindings are ignored. */
containing BINDING, or, if BINDING is NULL, the current scope.
Please note that for a given template, the template parameters are
considered to be in the scope containing the current scope.
If CLASS_P is false, then class bindings are ignored. */
cxx_binding *
outer_binding (tree name,
@ -4018,6 +4043,12 @@ outer_binding (tree name,
return class_binding;
}
}
/* If SCOPE is a template and if NAME binds to one of its template parameters
return the binding, otherwise we might miss it. */
if (outer_scope && outer_scope->kind == sk_template_parms
&& binding_to_template_parms_of_scope_p (outer, scope))
return outer;
scope = scope->level_chain;
}

View File

@ -6427,6 +6427,30 @@ 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)
if (parm == TREE_VALUE (TREE_VEC_ELT (parms, i)))
return true;
return false;
}
/* DECL is a friend FUNCTION_DECL or TEMPLATE_DECL. ARGS is the
vector of template arguments, as for tsubst.

View File

@ -1,3 +1,12 @@
2009-01-12 Dodji Seketeli <dodji@redhat.com>
PR c++/36019
* g++.dg/lookup/hidden-class12.C: New test.
* g++.dg/lookup/hidden-class13.C: New test.
* g++.dg/lookup/hidden-class14.C: New test.
* g++.dg/lookup/hidden-class15.C: New test.
* g++.dg/lookup/hidden-class16.C: New test.
2009-01-12 Mark Mitchell <mark@codesourcery.com>
* gcc.dg/struct/wo_prof_single_str_global.c: Mask return value.

View File

@ -0,0 +1,24 @@
// Contributed by Dodji Seketeli <dodji@redhat.com>
// Origin PR c++/36019
// { dg-do compile }
struct F {
static const int x = 0;
};
struct A {
template <typename A>
static int f ()
{
return A::x;
}
};
int
main ()
{
int i = A::f<F> ();
return i;
}

View File

@ -0,0 +1,25 @@
// Contributed by Dodji Seketeli <dodji@redhat.com>
// Origin PR c++/36019
// { dg-do compile }
struct F {
static const int x = 0;
};
struct B {
template <typename B>
struct C
{
static int f ()
{
return B::x;
}
};
};
int
main ()
{
int j = B::C<F>::f ();
return 0;
}

View File

@ -0,0 +1,23 @@
// Contributed by Dodji Seketeli <dodji@redhat.com>
// Origin PR c++/36019
// { dg-do compile }
struct F {
static const int x = 0;
typedef int A;
};
struct A {
template <typename A>
struct G : public F
{
static const A i = 0;
};
};
int
main ()
{
return A::G<F>::i ;
}

View File

@ -0,0 +1,30 @@
// Contributed by Dodji Seketeli <dodji@redhat.com>
// Origin PR c++/36019
// { dg-do compile }
struct F {
static const int y = 0;
};
struct A {
static const int x = 0;
};
struct B : public A {
template <typename A>
struct C
{
static int f ()
{
return A::x; // { dg-error "'x' is not a member of 'F'" }
}
};
};
int
main ()
{
int j = B::C<F>::f ();
return 0;
}

View File

@ -0,0 +1,27 @@
// Contributed by Dodji Seketeli <dodji@redhat.com>
// Origin PR c++/36019
// { dg-do compile }
struct F {
static const int y = 0;
};
struct A {
static const int x = 0;
};
struct B : public A {
template <typename A>
static int f ()
{
return A::x; // { dg-error "'x' is not a member of 'F'" }
}
};
int
main ()
{
int j = B::f<F> ();
return 0;
}