Patchwork Go patch committed: Correct handling of recursive types

login
register
mail settings
Submitter Ian Taylor
Date Dec. 14, 2010, 5:57 p.m.
Message ID <mcr62uwxmnv.fsf@google.com>
Download mbox | patch
Permalink /patch/75516/
State New
Headers show

Comments

Ian Taylor - Dec. 14, 2010, 5:57 p.m.
Go permits types to be refer to themselves in ways that can not be
written in C/C++ and are not permitted in GENERIC.  The existing code
looks for specific cases, but it breaks in more complex cases in which
types refer to themselves indirectly via other types.  This patch
simplifies the code so that these cases are handled correctly, or at
least as correctly as they can be given the limitations on GENERIC.
Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu.
Committed to mainline.

Ian

Patch

diff -r 1c613f1babbc go/types.cc
--- a/go/types.cc	Mon Dec 13 21:53:48 2010 -0800
+++ b/go/types.cc	Tue Dec 14 09:42:36 2010 -0800
@@ -6795,14 +6795,10 @@ 
       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))
+      // Don't recur infinitely if a function type refers to itself.
+      // Ideally we would build a circular data structure here, but
+      // GENERIC can't handle them.
+      if (this->seen_)
 	return ptr_type_node;
       this->seen_ = true;
       t = Type::get_named_type_tree(gogo, this->type_);
@@ -6813,9 +6809,10 @@ 
       break;
 
     case TYPE_POINTER:
-      // 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)
+      // Don't recur infinitely if a pointer type refers to itself.
+      // Ideally we would build a circular data structure here, but
+      // GENERIC can't handle them.
+      if (this->seen_)
 	return ptr_type_node;
       this->seen_ = true;
       t = Type::get_named_type_tree(gogo, this->type_);