]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/36019 (template parameter does not hide class name)
authorDodji Seketeli <dodji@redhat.com>
Mon, 12 Jan 2009 22:41:19 +0000 (22:41 +0000)
committerDodji Seketeli <dodji@gcc.gnu.org>
Mon, 12 Jan 2009 22:41:19 +0000 (23:41 +0100)
gcc/cp/ChangeLog:
2009-01-12  Dodji Seketeli  <dodji@redhat.com>

PR c++/36019
* pt.c (parameter_of_template_p): New function.
* pt.c (get_template_info): Ditto.
* cp-tree.h: Declare those.
* 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.
* gcc/testsuite/g++.old-deja/g++.benjamin/tem03.C: Adjust testcase.

From-SVN: r143313

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/name-lookup.c
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/lookup/hidden-class12.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lookup/hidden-class13.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lookup/hidden-class14.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lookup/hidden-class15.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lookup/hidden-class16.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.benjamin/tem03.C

index 172ccf76b9eff5453a729408862f75a82ecbc7e4..9708b213866245ff00d7d06bddb9d72a739ed2f1 100644 (file)
@@ -1,3 +1,14 @@
+2009-01-12  Dodji Seketeli  <dodji@redhat.com>
+
+       PR c++/36019
+       * pt.c (parameter_of_template_p): New function.
+       * pt.c (get_template_info): Ditto.
+       * cp-tree.h: Declare those.
+       * 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.
+
 2008-11-19  Dodji Seketeli  <dodji@redhat.com>
 
        PR c++/37142
index 48d8de8ff20213101698f3821b0b809feeccc003..576fc28d79c0342d3cb06d34fbc85b7ea2cabeb5 100644 (file)
@@ -4163,6 +4163,8 @@ extern bool reregister_specialization             (tree, tree, tree);
 extern tree fold_non_dependent_expr            (tree);
 extern bool explicit_class_specialization_p     (tree);
 extern tree outermost_tinst_level              (void);
+extern tree get_template_info                  (tree t);
+extern bool parameter_of_template_p            (tree, tree);
 
 /* in repo.c */
 extern void init_repo                          (void);
index f02bf269fad34039f0d00a172c3f6f23d2031244..f990a3bd616e848dc2971658d90191813df44c2a 100644 (file)
@@ -3850,9 +3850,33 @@ 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,
@@ -3900,6 +3924,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;
       }
 
index 67654df9d9106546487d9cd433abcd7a217ec6f0..3bc9edff9a96b8f29087b17272f29205cfac8605 100644 (file)
@@ -251,6 +251,25 @@ finish_member_template_decl (tree decl)
   return error_mark_node;
 }
 
+/* Return the template info node corresponding to T, whatever T is.  */
+
+tree
+get_template_info (tree t)
+{
+  tree tinfo = NULL_TREE;
+
+  if (DECL_P (t) && DECL_LANG_SPECIFIC (t))
+    tinfo = DECL_TEMPLATE_INFO (t);
+
+  if (!tinfo && TREE_CODE (t) == TYPE_DECL)
+    t = TREE_TYPE (t);
+
+  if (TAGGED_TYPE_P (t))
+    tinfo = TYPE_TEMPLATE_INFO (t);
+
+  return tinfo;
+}
+
 /* Returns the template nesting level of the indicated class TYPE.
 
    For example, in:
@@ -5327,6 +5346,30 @@ outermost_tinst_level (void)
   return tree_last (current_tinst_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.
 
index 268fbe0e15189b36f016e5d92076ae39150d6166..666bc5d7e1024eb17be3acd9258ca4fbfc914981 100644 (file)
@@ -1,3 +1,13 @@
+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.
+       * gcc/testsuite/g++.old-deja/g++.benjamin/tem03.C: Adjust testcase.
+
 2008-12-05  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gcc.dg/union-5.c: Run only on x86 and x86-64.
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class12.C b/gcc/testsuite/g++.dg/lookup/hidden-class12.C
new file mode 100644 (file)
index 0000000..4a3f2d7
--- /dev/null
@@ -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 (file)
index 0000000..2f685b2
--- /dev/null
@@ -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 (file)
index 0000000..99bd673
--- /dev/null
@@ -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 (file)
index 0000000..b0ed660
--- /dev/null
@@ -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 (file)
index 0000000..25cc402
--- /dev/null
@@ -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;
+}
+
index 73b99659e121d4264c6b6bec7af185e933d9b907..791850366df9b416eca3e1c76538418aa04de7d5 100644 (file)
@@ -83,7 +83,7 @@ public:
 template <class T10, int i> struct Xfour {// { dg-error "" } .*
   int T10; // { dg-error "" } .*
   void f(){
-    char T10;
+    char T10; // { dg-error "declaration of 'char T10'" }
   }
 };
 
@@ -126,8 +126,8 @@ public:
   template <class T161>
   friend bool foo(T161 u)
     {
-      Xseven<T161, 5, int> obj; // { dg-error "" } .*
-      return (obj.inst == u.inst); // { dg-error "" } .*
+      Xseven<T161, 5, int> obj;
+      return (obj.inst == u.inst);
     }
 
 };