From fd948ffb14a27a28cbe28d4beba267c9b5d3aeb0 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 14 Dec 2010 20:54:45 +0000 Subject: [PATCH] Check for duplicate methods. Don't get into an endless loop given invalid recursive types. From-SVN: r167816 --- gcc/go/gofrontend/types.cc | 72 +++++++++++++++++++++++++++++++------- gcc/go/gofrontend/types.h | 11 ++++++ 2 files changed, 71 insertions(+), 12 deletions(-) diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index 98c4a979840..36959034a92 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -53,9 +53,9 @@ Type::base() switch (this->classification_) { case TYPE_NAMED: - return static_cast(this)->real_type()->base(); + return this->named_type()->named_base(); case TYPE_FORWARD: - return static_cast(this)->real_type()->base(); + return this->forward_declaration_type()->real_type()->base(); default: return this; } @@ -67,13 +67,9 @@ Type::base() const switch (this->classification_) { case TYPE_NAMED: - return static_cast(this)->real_type()->base(); + return this->named_type()->named_base(); case TYPE_FORWARD: - { - const Forward_declaration_type* ftype = - static_cast(this); - return ftype->real_type()->base(); - } + return this->forward_declaration_type()->real_type()->base(); default: return this; } @@ -224,7 +220,7 @@ Type::is_error_type() const case TYPE_ERROR: return true; case TYPE_NAMED: - return t->named_type()->real_type()->is_error_type(); + return t->named_type()->is_named_error_type(); default: return false; } @@ -5502,10 +5498,23 @@ Interface_type::finalize_methods() const Typed_identifier* p = &this->methods_->at(from); if (!p->name().empty()) { - if (from != to) - this->methods_->set(to, *p); + size_t i = 0; + for (i = 0; i < to; ++i) + { + if (this->methods_->at(i).name() == p->name()) + { + error_at(p->location(), "duplicate method %qs", + Gogo::message_name(p->name()).c_str()); + break; + } + } + if (i == to) + { + if (from != to) + this->methods_->set(to, *p); + ++to; + } ++from; - ++to; continue; } Interface_type* it = p->type()->interface_type(); @@ -6448,6 +6457,45 @@ Named_type::message_name() const return this->named_object_->message_name(); } +// Return the base type for this type. We have to be careful about +// circular type definitions, which are invalid but may be seen here. + +Type* +Named_type::named_base() +{ + if (this->seen_) + return this; + this->seen_ = true; + Type* ret = this->type_->base(); + this->seen_ = false; + return ret; +} + +const Type* +Named_type::named_base() const +{ + if (this->seen_) + return this; + this->seen_ = true; + const Type* ret = this->type_->base(); + this->seen_ = false; + return ret; +} + +// Return whether this is an error type. We have to be careful about +// circular type definitions, which are invalid but may be seen here. + +bool +Named_type::is_named_error_type() const +{ + if (this->seen_) + return false; + this->seen_ = true; + bool ret = this->type_->is_error_type(); + this->seen_ = false; + return ret; +} + // Add a method to this type. Named_object* diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h index 025f85f401b..3f1b8ba7817 100644 --- a/gcc/go/gofrontend/types.h +++ b/gcc/go/gofrontend/types.h @@ -2457,6 +2457,17 @@ class Named_type : public Type is_builtin() const { return this->location_ == BUILTINS_LOCATION; } + // Return the base type for this type. + Type* + named_base(); + + const Type* + named_base() const; + + // Return whether this is an error type. + bool + is_named_error_type() const; + // Add a method to this type. Named_object* add_method(const std::string& name, Function*); -- 2.30.2