diff options
author | Dodji Seketeli <dodji@redhat.com> | 2009-01-12 22:47:49 +0000 |
---|---|---|
committer | Dodji Seketeli <dodji@gcc.gnu.org> | 2009-01-12 23:47:49 +0100 |
commit | 172a459435c48df322c74231fa60b8d10a36e2af (patch) | |
tree | d3b45f400b4c42e2a3715c2868a2bee41b7c72e4 /gcc | |
parent | 856c450bd55aae6454c3d43f0bb43d665799ac2f (diff) | |
download | gcc-172a459435c48df322c74231fa60b8d10a36e2af.zip gcc-172a459435c48df322c74231fa60b8d10a36e2af.tar.gz gcc-172a459435c48df322c74231fa60b8d10a36e2af.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/cp/name-lookup.c | 35 | ||||
-rw-r--r-- | gcc/cp/pt.c | 24 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/lookup/hidden-class12.C | 24 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/lookup/hidden-class13.C | 25 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/lookup/hidden-class14.C | 23 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/lookup/hidden-class15.C | 30 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/lookup/hidden-class16.C | 27 |
10 files changed, 206 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 1a9ca4f..542b71d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 9c89d96..718167f 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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); diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 4c06afda..889d9ef 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -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; } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 410641d..de70e53 100644 --- a/gcc/cp/pt.c +++ b/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. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 53ad9ce..6d2fe90 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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. diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class12.C b/gcc/testsuite/g++.dg/lookup/hidden-class12.C new file mode 100644 index 0000000..4a3f2d7 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/hidden-class12.C @@ -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; +} + diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class13.C b/gcc/testsuite/g++.dg/lookup/hidden-class13.C new file mode 100644 index 0000000..2f685b2 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/hidden-class13.C @@ -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; +} diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class14.C b/gcc/testsuite/g++.dg/lookup/hidden-class14.C new file mode 100644 index 0000000..99bd673 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/hidden-class14.C @@ -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 ; +} + diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class15.C b/gcc/testsuite/g++.dg/lookup/hidden-class15.C new file mode 100644 index 0000000..b0ed660 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/hidden-class15.C @@ -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; +} + diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class16.C b/gcc/testsuite/g++.dg/lookup/hidden-class16.C new file mode 100644 index 0000000..25cc402 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/hidden-class16.C @@ -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; +} + |