This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] PR c++/51641 - Lookup finds enclosing class member instead of template parameter


Hello,

In the example of the patch, the U in 'typename U::X r' should bind to
the template parameter U rather than the class member U.

I think the problem comes from parameter_of_template_p that compares
parameters by using pointer equality, rather than by using type
equivalence like compparms does.

As a result, binding_to_template_parms_of_scope_p and then
outer_binding (via binding_to_template_parms_of_scope_p) misses the
template parameter U and returns the class member U instead.

Fixed thus, tested on x86_64-unknown-linux-gnu against trunk.

OK for trunk when stage 1 opens?

gcc/cp/

	PR c++/51641
	* cp-tree.h (template_type_parameter_p): Declare ...
	* pt.c (template_type_parameter_p): ... new function.
	(parameter_of_template_p):  Rely on type equivalence rather
	than pointer equality to compare template parms.

gcc/testsuite/

	PR c++/51641
	* g++.dg/lookup/hidden-class17.C: New test.
---
 gcc/cp/cp-tree.h                             |    1 +
 gcc/cp/pt.c                                  |   29 ++++++++++++++++++++++---
 gcc/testsuite/g++.dg/lookup/hidden-class17.C |   22 +++++++++++++++++++
 3 files changed, 48 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/lookup/hidden-class17.C

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index f27755e..972c600 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5361,6 +5361,7 @@ 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/pt.c b/gcc/cp/pt.c
index e440be7..cb9554a 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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.  */
 
@@ -8160,10 +8172,19 @@ parameter_of_template_p (tree parm, tree templ)
       if (p == error_mark_node)
 	continue;
 
-      if (parm == p
-	  || (DECL_INITIAL (parm)
-	      && DECL_INITIAL (parm) == DECL_INITIAL (p)))
-	return true;
+      if (template_type_parameter_p (parm))
+	{
+	  if (same_type_p (TREE_TYPE (parm), TREE_TYPE (p)))
+	    return true;
+	}
+      else
+	{
+	  if (DECL_INITIAL (parm)
+	      && DECL_INITIAL (p)
+	      && same_type_p (TREE_TYPE (DECL_INITIAL (parm)),
+			      TREE_TYPE (DECL_INITIAL (p))))
+	    return true;
+	}
     }
 
   return false;
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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]