aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDodji Seketeli <dodji@redhat.com>2009-01-12 22:47:49 +0000
committerDodji Seketeli <dodji@gcc.gnu.org>2009-01-12 23:47:49 +0100
commit172a459435c48df322c74231fa60b8d10a36e2af (patch)
treed3b45f400b4c42e2a3715c2868a2bee41b7c72e4 /gcc
parent856c450bd55aae6454c3d43f0bb43d665799ac2f (diff)
downloadgcc-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/ChangeLog10
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/name-lookup.c35
-rw-r--r--gcc/cp/pt.c24
-rw-r--r--gcc/testsuite/ChangeLog9
-rw-r--r--gcc/testsuite/g++.dg/lookup/hidden-class12.C24
-rw-r--r--gcc/testsuite/g++.dg/lookup/hidden-class13.C25
-rw-r--r--gcc/testsuite/g++.dg/lookup/hidden-class14.C23
-rw-r--r--gcc/testsuite/g++.dg/lookup/hidden-class15.C30
-rw-r--r--gcc/testsuite/g++.dg/lookup/hidden-class16.C27
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;
+}
+