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:
parent
856c450bd5
commit
172a459435
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
24
gcc/cp/pt.c
24
gcc/cp/pt.c
@ -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.
|
||||
|
||||
|
@ -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.
|
||||
|
24
gcc/testsuite/g++.dg/lookup/hidden-class12.C
Normal file
24
gcc/testsuite/g++.dg/lookup/hidden-class12.C
Normal 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;
|
||||
}
|
||||
|
25
gcc/testsuite/g++.dg/lookup/hidden-class13.C
Normal file
25
gcc/testsuite/g++.dg/lookup/hidden-class13.C
Normal 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;
|
||||
}
|
23
gcc/testsuite/g++.dg/lookup/hidden-class14.C
Normal file
23
gcc/testsuite/g++.dg/lookup/hidden-class14.C
Normal 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 ;
|
||||
}
|
||||
|
30
gcc/testsuite/g++.dg/lookup/hidden-class15.C
Normal file
30
gcc/testsuite/g++.dg/lookup/hidden-class15.C
Normal 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;
|
||||
}
|
||||
|
27
gcc/testsuite/g++.dg/lookup/hidden-class16.C
Normal file
27
gcc/testsuite/g++.dg/lookup/hidden-class16.C
Normal 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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user