Commit a6bede1b by Ian Lance Taylor

Fix handling of mutually recursive named types.

From-SVN: r178989
parent 4ec5affa
...@@ -6251,22 +6251,22 @@ Named_type::message_name() const ...@@ -6251,22 +6251,22 @@ Named_type::message_name() const
Type* Type*
Named_type::named_base() Named_type::named_base()
{ {
if (this->seen_ > 0) if (this->seen_)
return this; return this;
++this->seen_; this->seen_ = true;
Type* ret = this->type_->base(); Type* ret = this->type_->base();
--this->seen_; this->seen_ = false;
return ret; return ret;
} }
const Type* const Type*
Named_type::named_base() const Named_type::named_base() const
{ {
if (this->seen_ > 0) if (this->seen_)
return this; return this;
++this->seen_; this->seen_ = true;
const Type* ret = this->type_->base(); const Type* ret = this->type_->base();
--this->seen_; this->seen_ = false;
return ret; return ret;
} }
...@@ -6276,11 +6276,11 @@ Named_type::named_base() const ...@@ -6276,11 +6276,11 @@ Named_type::named_base() const
bool bool
Named_type::is_named_error_type() const Named_type::is_named_error_type() const
{ {
if (this->seen_ > 0) if (this->seen_)
return false; return false;
++this->seen_; this->seen_ = true;
bool ret = this->type_->is_error_type(); bool ret = this->type_->is_error_type();
--this->seen_; this->seen_ = false;
return ret; return ret;
} }
...@@ -6430,11 +6430,11 @@ Named_type::interface_method_table(Gogo* gogo, const Interface_type* interface, ...@@ -6430,11 +6430,11 @@ Named_type::interface_method_table(Gogo* gogo, const Interface_type* interface,
bool bool
Named_type::named_type_has_hidden_fields(std::string* reason) const Named_type::named_type_has_hidden_fields(std::string* reason) const
{ {
if (this->seen_ > 0) if (this->seen_)
return false; return false;
++this->seen_; this->seen_ = true;
bool ret = this->type_->has_hidden_fields(this, reason); bool ret = this->type_->has_hidden_fields(this, reason);
--this->seen_; this->seen_ = false;
return ret; return ret;
} }
...@@ -6600,11 +6600,11 @@ Named_type::do_verify() ...@@ -6600,11 +6600,11 @@ Named_type::do_verify()
bool bool
Named_type::do_has_pointer() const Named_type::do_has_pointer() const
{ {
if (this->seen_ > 0) if (this->seen_)
return false; return false;
++this->seen_; this->seen_ = true;
bool ret = this->type_->has_pointer(); bool ret = this->type_->has_pointer();
--this->seen_; this->seen_ = false;
return ret; return ret;
} }
...@@ -6906,14 +6906,14 @@ Named_type::do_get_backend(Gogo* gogo) ...@@ -6906,14 +6906,14 @@ Named_type::do_get_backend(Gogo* gogo)
case TYPE_FUNCTION: case TYPE_FUNCTION:
// Don't build a circular data structure. GENERIC can't handle // Don't build a circular data structure. GENERIC can't handle
// it. // it.
if (this->seen_ > 0) if (this->seen_in_get_backend_)
{ {
this->is_circular_ = true; this->is_circular_ = true;
return gogo->backend()->circular_pointer_type(bt, 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); bt1 = Type::get_named_base_btype(gogo, base);
--this->seen_; this->seen_in_get_backend_ = false;
if (this->is_circular_) if (this->is_circular_)
bt1 = gogo->backend()->circular_pointer_type(bt, true); bt1 = gogo->backend()->circular_pointer_type(bt, true);
if (!gogo->backend()->set_placeholder_function_type(bt, bt1)) if (!gogo->backend()->set_placeholder_function_type(bt, bt1))
...@@ -6923,14 +6923,14 @@ Named_type::do_get_backend(Gogo* gogo) ...@@ -6923,14 +6923,14 @@ Named_type::do_get_backend(Gogo* gogo)
case TYPE_POINTER: case TYPE_POINTER:
// Don't build a circular data structure. GENERIC can't handle // Don't build a circular data structure. GENERIC can't handle
// it. // it.
if (this->seen_ > 0) if (this->seen_in_get_backend_)
{ {
this->is_circular_ = true; this->is_circular_ = true;
return gogo->backend()->circular_pointer_type(bt, false); return gogo->backend()->circular_pointer_type(bt, false);
} }
++this->seen_; this->seen_in_get_backend_ = true;
bt1 = Type::get_named_base_btype(gogo, base); bt1 = Type::get_named_base_btype(gogo, base);
--this->seen_; this->seen_in_get_backend_ = false;
if (this->is_circular_) if (this->is_circular_)
bt1 = gogo->backend()->circular_pointer_type(bt, false); bt1 = gogo->backend()->circular_pointer_type(bt, false);
if (!gogo->backend()->set_placeholder_pointer_type(bt, bt1)) if (!gogo->backend()->set_placeholder_pointer_type(bt, bt1))
......
...@@ -2387,7 +2387,7 @@ class Named_type : public Type ...@@ -2387,7 +2387,7 @@ class Named_type : public Type
interface_method_tables_(NULL), pointer_interface_method_tables_(NULL), interface_method_tables_(NULL), pointer_interface_method_tables_(NULL),
location_(location), named_btype_(NULL), dependencies_(), location_(location), named_btype_(NULL), dependencies_(),
is_visible_(true), is_error_(false), is_converted_(false), 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. // Return the associated Named_object. This holds the actual name.
...@@ -2647,7 +2647,9 @@ class Named_type : public Type ...@@ -2647,7 +2647,9 @@ class Named_type : public Type
// used to prevent infinite recursion when a type refers to itself. // used to prevent infinite recursion when a type refers to itself.
// This is mutable because it is always reset to false when the // This is mutable because it is always reset to false when the
// function exits. // 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 // A forward declaration. This handles a type which has been declared
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment