C++ PATCH: PR 20924

Mark Mitchell mark@codesourcery.com
Sat Mar 10 19:46:00 GMT 2007


This patch fixes PR c++/20924, a P1 regression in 4.2.  We were
rejecting a valid template specialization.

The problem was that the C++ front end uses walk_tree to walk over the
type of the specialization, and, at some point, walk_type_fields was
changed not to recur on arrays of pointers, to avoid infinite
recursion in Ada, whose richer type system allows that.

However, the comment:

-      /* Don't follow this nodes's type if a pointer for fear that we'll
-	 have infinite recursion.  Those types are uninteresting anyway.  */

is clearly bogus; this test case shows that they are indeed
"interesting".

In any case, there's no risk of infinite recursion when we have the
PSET argument.  The same trick is already used for the POINTER_TYPE
case; if there's a PSET we recur.

I rather wonder if we shouldn't just always require a PSET argument,
or declare this infinite recursion the problem of the function called
by the tree-walker, which could set *walk_subtrees to false for the
problematic case.  However, I wanted a conservative approach,
especially for 4.2, so I just went with the check-for-PSET approach.

Tested on x86_64-unknown-linux-gnu, applied to mainline and the 4.2
branch.

--
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

2007-03-10  Mark Mitchell  <mark@codesourcery.com>

	PR c++/20924
	* tree.c (walk_type_fields): Recurse into the element type of
	ARRAY_TYPEs if there is a pointer set.

2007-03-10  Mark Mitchell  <mark@codesourcery.com>

	PR c++/20924
	* g++.dg/template/array18.C: New test.

Index: gcc/tree.c
===================================================================
--- gcc/tree.c	(revision 122765)
+++ gcc/tree.c	(working copy)
@@ -7942,10 +7942,12 @@ walk_type_fields (tree type, walk_tree_f
       break;
 
     case ARRAY_TYPE:
-      /* Don't follow this nodes's type if a pointer for fear that we'll
-	 have infinite recursion.  Those types are uninteresting anyway.  */
-      if (!POINTER_TYPE_P (TREE_TYPE (type))
-	  && TREE_CODE (TREE_TYPE (type)) != OFFSET_TYPE)
+      /* Don't follow this nodes's type if a pointer for fear that
+	 we'll have infinite recursion.  If we have a PSET, then we
+	 need not fear.  */
+      if (pset
+	  || (!POINTER_TYPE_P (TREE_TYPE (type))
+	      && TREE_CODE (TREE_TYPE (type)) != OFFSET_TYPE))
 	WALK_SUBTREE (TREE_TYPE (type));
       WALK_SUBTREE (TYPE_DOMAIN (type));
       break;
Index: gcc/testsuite/g++.dg/template/array18.C
===================================================================
--- gcc/testsuite/g++.dg/template/array18.C	(revision 0)
+++ gcc/testsuite/g++.dg/template/array18.C	(revision 0)
@@ -0,0 +1,13 @@
+// PR c++/20924
+
+template<typename T>
+struct x {};
+
+template<typename T, unsigned N>
+struct x<T*[N]> {};
+
+int main() {
+  x<int> a;
+  x<int*[10]> b;
+  return 0;
+}



More information about the Gcc-patches mailing list