Patchwork [gccgo] Only cut off pointer/function type recursion when necessary.

login
register
mail settings
Submitter Ian Taylor
Date Sept. 8, 2010, 9:21 p.m.
Message ID <mcrbp88gcct.fsf@google.com>
Download mbox | patch
Permalink /patch/64226/
State New
Headers show

Comments

Ian Taylor - Sept. 8, 2010, 9:21 p.m.
I forgot that a type can appear recursive, even though it is not,
because of the way the types are walked when converting to GENERIC.
E.g.,
	type F func() *S
	type S { fn F }

This patch changes the handling of pointer and function types to only
cut off the recursion when it actually occurs.  Committed to gccgo
branch.

Ian

Patch

diff -r 3d52709b6979 go/types.cc
--- a/go/types.cc	Wed Sep 08 11:59:25 2010 -0700
+++ b/go/types.cc	Wed Sep 08 14:19:07 2010 -0700
@@ -5707,14 +5707,28 @@ 
       break;
 
     case TYPE_FUNCTION:
+      // GENERIC can't handle a pointer to a function type whose
+      // return type is a pointer to the function type itself.  It
+      // does into infinite loops when walking the types.
+      if (this->seen_
+	  && this->function_type()->results() != NULL
+	  && this->function_type()->results()->size() == 1
+	  && (this->function_type()->results()->front().type()->forwarded()
+	      == this))
+	return ptr_type_node;
+      this->seen_ = true;
+      t = this->type_->get_tree(gogo);
+      this->seen_ = false;
+      if (t == error_mark_node)
+	return error_mark_node;
+      t = build_variant_type_copy(t);
+      break;
+
     case TYPE_POINTER:
-      if (this->seen_)
-	{
-	  // GENERIC can't handle a pointer type which points to
-	  // itself.  It goes into infinite loops when walking the
-	  // types.
-	  return ptr_type_node;
-	}
+      // GENERIC can't handle a pointer type which points to itself.
+      // It goes into infinite loops when walking the types.
+      if (this->seen_ && this->points_to()->forwarded() == this)
+	return ptr_type_node;
       this->seen_ = true;
       t = this->type_->get_tree(gogo);
       this->seen_ = false;