PR c++/51641 - Lookup finds enclosing class member instead of template parameter
authorDodji Seketeli <dodji@redhat.com>
Mon, 30 Jan 2012 14:26:12 +0000 (14:26 +0000)
committerDodji Seketeli <dodji@gcc.gnu.org>
Mon, 30 Jan 2012 14:26:12 +0000 (15:26 +0100)
gcc/cp/

PR c++/51641
* cp-tree.h (template_type_parameter_p): Declare new function.
(parameter_of_template_p): Remove
* pt.c (template_type_parameter_p): Define new function.
(parameter_of_template_p): Remove.
* name-lookup.c (binding_to_template_parms_of_scope_p): Don't rely
on parameter_of_template_p anymore.  Compare the level of the
template parameter to the depth of the template.

gcc/testsuite/

PR c++/51641
* g++.dg/lookup/hidden-class17.C: New test.

From-SVN: r183726

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-class17.C [new file with mode: 0644]

index 5c022598a2e809b02c61d13f93c505d0b97761ab..78e03837bc0adfa119bd8d1386c2304d4a7852af 100644 (file)
@@ -1,3 +1,14 @@
+2012-01-30  Dodji Seketeli  <dodji@redhat.com>
+
+       PR c++/51641
+       * cp-tree.h (template_type_parameter_p): Declare new function.
+       (parameter_of_template_p): Remove
+       * pt.c (template_type_parameter_p): Define new function.
+       (parameter_of_template_p): Remove.
+       * name-lookup.c (binding_to_template_parms_of_scope_p): Don't rely
+       on parameter_of_template_p anymore.  Compare the level of the
+       template parameter to the depth of the template.
+
 2012-01-29  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/51327
index f27755e4cf97ae1e4e00509b319c0b47783345f5..71bca531b43a1a3b25ce112d1b18d606837a4277 100644 (file)
@@ -5357,10 +5357,10 @@ extern bool explicit_class_specialization_p     (tree);
 extern int push_tinst_level                     (tree);
 extern void pop_tinst_level                     (void);
 extern struct tinst_level *outermost_tinst_level(void);
-extern bool parameter_of_template_p            (tree, tree);
 extern void init_template_processing           (void);
 extern void print_template_statistics          (void);
 bool template_template_parameter_p             (const_tree);
+bool template_type_parameter_p                  (const_tree);
 extern bool primary_template_instantiation_p    (const_tree);
 extern tree get_primary_template_innermost_parameters  (const_tree);
 extern tree get_template_parms_at_level (tree, int);
index 235134249acfc2dbec4dd943b39c95dae4292d4d..d39bc1d2564127895a8983c9bb46dc65683c4092 100644 (file)
@@ -4466,21 +4466,39 @@ static bool
 binding_to_template_parms_of_scope_p (cxx_binding *binding,
                                      cp_binding_level *scope)
 {
-  tree binding_value;
+  tree binding_value, tmpl;
+  int level;
 
   if (!binding || !scope)
     return false;
 
   binding_value = binding->value ?  binding->value : binding->type;
+  /* BINDING_VALUE must be a template parm.  */
+  if (binding_value == NULL_TREE
+      || (!DECL_P (binding_value)
+          || !DECL_TEMPLATE_PARM_P (binding_value)))
+    return false;
 
-  return (scope
-         && scope->this_entity
-         && get_template_info (scope->this_entity)
-         && PRIMARY_TEMPLATE_P (TI_TEMPLATE
-                                (get_template_info (scope->this_entity)))
-         && parameter_of_template_p (binding_value,
-                                     TI_TEMPLATE (get_template_info \
-                                                   (scope->this_entity))));
+  /*  The level of BINDING_VALUE.  */
+  level =
+    template_type_parameter_p (binding_value)
+    ? TEMPLATE_PARM_LEVEL (TEMPLATE_TYPE_PARM_INDEX
+                        (TREE_TYPE (binding_value)))
+    : TEMPLATE_PARM_LEVEL (DECL_INITIAL (binding_value));
+
+  /* The template of the current scope, iff said scope is a primary
+     template.  */
+  tmpl =
+    (scope
+     && scope->this_entity
+     && get_template_info (scope->this_entity)
+     && PRIMARY_TEMPLATE_P (TI_TEMPLATE (get_template_info (scope->this_entity))))
+    ? TI_TEMPLATE (get_template_info (scope->this_entity))
+    : NULL_TREE;
+
+  /* If the level of the parm BINDING_VALUE equals the depth of TMPL,
+     then BINDING_VALUE is a parameter of TMPL.  */
+  return (tmpl && level == TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl)));
 }
 
 /* Return the innermost non-namespace binding for NAME from a scope
index ad2b4dfc73674050864e6c53437bf899584c846a..13eef29764fc8717b18702fb13e9fe4c3e764ce8 100644 (file)
@@ -2890,6 +2890,18 @@ template_template_parameter_p (const_tree parm)
   return DECL_TEMPLATE_TEMPLATE_PARM_P (parm);
 }
 
+/* Return true iff PARM is a DECL representing a type template
+   parameter.  */
+
+bool
+template_type_parameter_p (const_tree parm)
+{
+  return (parm
+         && (TREE_CODE (parm) == TYPE_DECL
+             || TREE_CODE (parm) == TEMPLATE_DECL)
+         && DECL_TEMPLATE_PARM_P (parm));
+}
+
 /* Return the template parameters of T if T is a
    primary template instantiation, NULL otherwise.  */
 
@@ -8137,38 +8149,6 @@ 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)
-    {
-      tree p = TREE_VALUE (TREE_VEC_ELT (parms, i));
-      if (p == error_mark_node)
-       continue;
-
-      if (parm == p
-         || (DECL_INITIAL (parm)
-             && DECL_INITIAL (parm) == DECL_INITIAL (p)))
-       return true;
-    }
-
-  return false;
-}
-
 /* DECL is a friend FUNCTION_DECL or TEMPLATE_DECL.  ARGS is the
    vector of template arguments, as for tsubst.
 
index d80e3ab7913f2930fcb884856b5a1923af7e7223..1159dd47222cf740eb5f00111e8c44a20d563d42 100644 (file)
@@ -1,3 +1,8 @@
+2012-01-30  Dodji Seketeli  <dodji@redhat.com>
+
+       PR c++/51641
+       * g++.dg/lookup/hidden-class17.C: New test.
+
 2012-01-30  Jakub Jelinek  <jakub@redhat.com>
 
        PR debug/52027
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class17.C b/gcc/testsuite/g++.dg/lookup/hidden-class17.C
new file mode 100644 (file)
index 0000000..3d5ccec
--- /dev/null
@@ -0,0 +1,22 @@
+// Origin PR c++/51641
+// { dg-do compile }
+
+struct A {
+    struct B { typedef int X; };
+};
+
+template<class B> struct C : A {
+    B::X q; // Ok: A::B.
+    struct U { typedef int X; };
+    template<class U>
+        struct D;
+};
+
+template<class B>
+template<class U>
+struct C<B>::D {
+    typename U::X r; // { dg-error "" }
+};
+
+C<int>::D<double> y;
+