[PATCH] PR c++/51641 - Lookup finds enclosing class member

Dodji Seketeli dodji@redhat.com
Tue Mar 13 18:00:00 GMT 2012


Hello,

This patch was previously accepted[1] before stage 1.  I have rebased,
bootstrapped and tested it against trunk on x86_64-unknown-linux-gnu.

I am applying it to trunk.

[1]: http://gcc.gnu.org/ml/gcc-patches/2012-01/msg01571.html

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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@183726 138bc75d-0d04-0410-961f-82ee72b054a4

Conflicts:

	gcc/cp/pt.c
---
 gcc/cp/ChangeLog                             |   11 ++++++
 gcc/cp/cp-tree.h                             |    2 +-
 gcc/cp/name-lookup.c                         |   28 ++++++++++++++--
 gcc/cp/pt.c                                  |   44 +++++++-------------------
 gcc/testsuite/ChangeLog                      |    5 +++
 gcc/testsuite/g++.dg/lookup/hidden-class17.C |   22 +++++++++++++
 6 files changed, 75 insertions(+), 37 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/lookup/hidden-class17.C

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index f04ac60..6ef5545 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
+
 2011-12-15  Dodji Seketeli  <dodji@redhat.com>
 
 	* call.c (standard_conversion, build_integral_nontype_arg_conv)
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 71573ff..d24c596 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5361,10 +5361,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);
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index e85d603..886a7b1 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -4466,8 +4466,8 @@ static bool
 binding_to_template_parms_of_scope_p (cxx_binding *binding,
 				      cp_binding_level *scope)
 {
-  tree binding_value;
-  tree tinfo;
+  tree binding_value, tmpl, tinfo;
+  int level;
 
   if (!binding || !scope || !scope->this_entity)
     return false;
@@ -4475,9 +4475,29 @@ binding_to_template_parms_of_scope_p (cxx_binding *binding,
   binding_value = binding->value ?  binding->value : binding->type;
   tinfo = get_template_info (scope->this_entity);
 
-  return (tinfo
+  /* BINDING_VALUE must be a template parm.  */
+  if (binding_value == NULL_TREE
+      || (!DECL_P (binding_value)
+          || !DECL_TEMPLATE_PARM_P (binding_value)))
+    return false;
+
+  /*  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 = (tinfo
 	  && PRIMARY_TEMPLATE_P (TI_TEMPLATE (tinfo))
-	  && parameter_of_template_p (binding_value, TI_TEMPLATE (tinfo)));
+	  ? TI_TEMPLATE (tinfo)
+	  : 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
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 54d540d..6dd004e 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -2869,6 +2869,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.  */
 
@@ -8118,38 +8130,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.
 
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 8a6c975..3d606b8 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2012-01-30  Dodji Seketeli  <dodji@redhat.com>
+
+	PR c++/51641
+	* g++.dg/lookup/hidden-class17.C: New test.
+
 2012-03-12  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
 
 	PR tree-optimization/46728
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class17.C b/gcc/testsuite/g++.dg/lookup/hidden-class17.C
new file mode 100644
index 0000000..3d5ccec
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/hidden-class17.C
@@ -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;
+
-- 
1.7.6.5


-- 
		Dodji



More information about the Gcc-patches mailing list