diff mbox

Go patch committed: Fix handling of mutually recursive named types

Message ID mcrty88f66q.fsf@coign.corp.google.com
State New
Headers show

Commit Message

Ian Lance Taylor Sept. 19, 2011, 11:44 p.m. UTC
The Go frontend was overloading Named_type::seen_ to mean too many
different things.  It caused a compiler crash compiling mutually
recursive types as in:

type T18 *[10]T19
type T19 T18

This patch fixes the problem by splitting off the only complex use of
seen_ into a new field.  I also changed seen_ to a bool since that
matches all existing uses.  Bootstrapped and ran Go testsuite on
x86_64-unknown-linux-gnu.  Committed to mainline.

Ian
diff mbox

Patch

diff -r cbdcb2604973 go/types.cc
--- a/go/types.cc	Fri Sep 16 17:09:41 2011 -0700
+++ b/go/types.cc	Mon Sep 19 16:41:38 2011 -0700
@@ -6251,22 +6251,22 @@ 
 Type*
 Named_type::named_base()
 {
-  if (this->seen_ > 0)
+  if (this->seen_)
     return this;
-  ++this->seen_;
+  this->seen_ = true;
   Type* ret = this->type_->base();
-  --this->seen_;
+  this->seen_ = false;
   return ret;
 }
 
 const Type*
 Named_type::named_base() const
 {
-  if (this->seen_ > 0)
+  if (this->seen_)
     return this;
-  ++this->seen_;
+  this->seen_ = true;
   const Type* ret = this->type_->base();
-  --this->seen_;
+  this->seen_ = false;
   return ret;
 }
 
@@ -6276,11 +6276,11 @@ 
 bool
 Named_type::is_named_error_type() const
 {
-  if (this->seen_ > 0)
+  if (this->seen_)
     return false;
-  ++this->seen_;
+  this->seen_ = true;
   bool ret = this->type_->is_error_type();
-  --this->seen_;
+  this->seen_ = false;
   return ret;
 }
 
@@ -6430,11 +6430,11 @@ 
 bool
 Named_type::named_type_has_hidden_fields(std::string* reason) const
 {
-  if (this->seen_ > 0)
+  if (this->seen_)
     return false;
-  ++this->seen_;
+  this->seen_ = true;
   bool ret = this->type_->has_hidden_fields(this, reason);
-  --this->seen_;
+  this->seen_ = false;
   return ret;
 }
 
@@ -6600,11 +6600,11 @@ 
 bool
 Named_type::do_has_pointer() const
 {
-  if (this->seen_ > 0)
+  if (this->seen_)
     return false;
-  ++this->seen_;
+  this->seen_ = true;
   bool ret = this->type_->has_pointer();
-  --this->seen_;
+  this->seen_ = false;
   return ret;
 }
 
@@ -6906,14 +6906,14 @@ 
     case TYPE_FUNCTION:
       // Don't build a circular data structure.  GENERIC can't handle
       // it.
-      if (this->seen_ > 0)
+      if (this->seen_in_get_backend_)
 	{
 	  this->is_circular_ = true;
 	  return gogo->backend()->circular_pointer_type(bt, true);
 	}
-      ++this->seen_;
+      this->seen_in_get_backend_ = true;
       bt1 = Type::get_named_base_btype(gogo, base);
-      --this->seen_;
+      this->seen_in_get_backend_ = false;
       if (this->is_circular_)
 	bt1 = gogo->backend()->circular_pointer_type(bt, true);
       if (!gogo->backend()->set_placeholder_function_type(bt, bt1))
@@ -6923,14 +6923,14 @@ 
     case TYPE_POINTER:
       // Don't build a circular data structure. GENERIC can't handle
       // it.
-      if (this->seen_ > 0)
+      if (this->seen_in_get_backend_)
 	{
 	  this->is_circular_ = true;
 	  return gogo->backend()->circular_pointer_type(bt, false);
 	}
-      ++this->seen_;
+      this->seen_in_get_backend_ = true;
       bt1 = Type::get_named_base_btype(gogo, base);
-      --this->seen_;
+      this->seen_in_get_backend_ = false;
       if (this->is_circular_)
 	bt1 = gogo->backend()->circular_pointer_type(bt, false);
       if (!gogo->backend()->set_placeholder_pointer_type(bt, bt1))
diff -r cbdcb2604973 go/types.h
--- a/go/types.h	Fri Sep 16 17:09:41 2011 -0700
+++ b/go/types.h	Mon Sep 19 16:41:38 2011 -0700
@@ -2387,7 +2387,7 @@ 
       interface_method_tables_(NULL), pointer_interface_method_tables_(NULL),
       location_(location), named_btype_(NULL), dependencies_(),
       is_visible_(true), is_error_(false), is_converted_(false),
-      is_circular_(false), seen_(0)
+      is_circular_(false), seen_(false), seen_in_get_backend_(false)
   { }
 
   // Return the associated Named_object.  This holds the actual name.
@@ -2647,7 +2647,9 @@ 
   // used to prevent infinite recursion when a type refers to itself.
   // This is mutable because it is always reset to false when the
   // function exits.
-  mutable int seen_;
+  mutable bool seen_;
+  // Like seen_, but used only by do_get_backend.
+  bool seen_in_get_backend_;
 };
 
 // A forward declaration.  This handles a type which has been declared